patch-2.2.0-pre2 linux/drivers/net/bmac.c
Next file: linux/drivers/net/de4x5.c
Previous file: linux/drivers/net/Makefile
Back to the patch index
Back to the overall index
- Lines: 215
- Date:
Wed Dec 30 10:55:07 1998
- Orig file:
v2.2.0-pre1/linux/drivers/net/bmac.c
- Orig date:
Thu Nov 19 09:56:28 1998
diff -u --recursive --new-file v2.2.0-pre1/linux/drivers/net/bmac.c linux/drivers/net/bmac.c
@@ -5,6 +5,7 @@
* Copyright (C) 1998 Randy Gobbel.
*/
#include <linux/config.h>
+#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -59,7 +60,6 @@
int rx_fill;
int rx_empty;
struct sk_buff *tx_bufs[N_TX_RING];
- char *tx_double[N_TX_RING]; /* yuck--double buffering */
int tx_fill;
int tx_empty;
unsigned char tx_fullup;
@@ -297,7 +297,7 @@
val = bmac_mif_readbits(dev, 17);
bmwrite(dev, MIFCSR, 4);
MIFDELAY;
- printk(KERN_DEBUG "bmac_mif_read(%x) -> %x\n", addr, val);
+ /* printk(KERN_DEBUG "bmac_mif_read(%x) -> %x\n", addr, val); */
return val;
}
@@ -438,9 +438,11 @@
bmac_mif_write(dev, 4, 0xa1);
bmac_mif_write(dev, 0, 0x1200);
}
+#if 0
/* XXX debugging */
bmac_mif_read(dev, 0);
bmac_mif_read(dev, 4);
+#endif
}
bmac_init_registers(dev);
return 1;
@@ -488,23 +490,15 @@
}
static void
-bmac_construct_xmt(struct sk_buff *skb, volatile struct dbdma_cmd *cp,
- char *doubleBuf)
+bmac_construct_xmt(struct sk_buff *skb, volatile struct dbdma_cmd *cp)
{
- void *vaddr, *page_break;
+ void *vaddr;
unsigned long baddr;
unsigned long len;
len = skb->len;
vaddr = skb->data;
baddr = virt_to_bus(vaddr);
- page_break = round_page(vaddr);
- if (trunc_page(vaddr) != trunc_page(vaddr+len) &&
- (unsigned long)round_page(baddr) != virt_to_bus(page_break)) {
- baddr = virt_to_bus(doubleBuf);
- XXDEBUG(("bmac: double buffering, double=%#08x, skb->data=%#08x, len=%d\n", doubleBuf, skb->data, len));
- } else
- flush_page_to_ram((unsigned long)vaddr);
dbdma_setcmd(cp, (OUTPUT_LAST | INTR_ALWAYS | WAIT_IFCLR), len, baddr, 0);
}
@@ -530,17 +524,8 @@
static int
bmac_init_tx_ring(struct bmac_data *bp)
{
- int i;
volatile struct dbdma_regs *td = bp->tx_dma;
- char *addr;
- if (!bp->tx_allocated) {
- /* zero out tx cmds, alloc space for double buffering */
- addr = (char *)kmalloc(ETHERMTU * N_TX_RING, GFP_DMA);
- if (addr == NULL) return 0;
- for (i = 0; i < N_TX_RING; i++, addr += ETHERMTU) bp->tx_double[i] = addr;
- bp->tx_allocated = 1;
- }
memset((char *)bp->tx_cmds, 0, (N_TX_RING+1) * sizeof(struct dbdma_cmd));
bp->tx_empty = 0;
@@ -615,7 +600,7 @@
dbdma_setcmd(&bp->tx_cmds[i], DBDMA_STOP, 0, 0, 0);
- bmac_construct_xmt(skb, &bp->tx_cmds[bp->tx_fill], bp->tx_double[bp->tx_fill]);
+ bmac_construct_xmt(skb, &bp->tx_cmds[bp->tx_fill]);
bp->tx_bufs[bp->tx_fill] = skb;
bp->tx_fill = i;
@@ -1177,6 +1162,8 @@
{
struct bmac_data *bp = dev->priv;
unsigned long flags;
+ struct sk_buff *skb;
+ unsigned char *data;
save_flags(flags); cli();
bp->reset_and_enabled = 0;
@@ -1187,16 +1174,17 @@
bmac_start_chip(dev);
bmwrite(dev, INTDISABLE, EnableNormal);
bp->reset_and_enabled = 1;
- /* { */
- /* unsigned char random_packet[100]; */
- /* unsigned int i; */
- /* struct sk_buff *skb = dev_alloc_skb(RX_BUFLEN+2); */
- /* unsigned char *data = skb_put(skb, sizeof(random_packet)); */
- /* XXDEBUG(("transmitting random packet\n")); */
- /* for (i = 0; i < sizeof(random_packet); i++) data[i] = i; */
- /* bmac_transmit_packet(skb, dev); */
- /* XXDEBUG(("done transmitting random packet\n")); */
- /* } */
+
+ /*
+ * It seems that the bmac can't receive until it's transmitted
+ * a packet. So we give it a dummy packet to transmit.
+ */
+ skb = dev_alloc_skb(ETHERMINPACKET);
+ data = skb_put(skb, ETHERMINPACKET);
+ memset(data, 0, ETHERMINPACKET);
+ memcpy(data, dev->dev_addr, 6);
+ memcpy(data+6, dev->dev_addr, 6);
+ bmac_transmit_packet(skb, dev);
}
restore_flags(flags);
return 1;
@@ -1241,8 +1229,13 @@
dev->priv = kmalloc(PRIV_BYTES, GFP_KERNEL);
if (dev->priv == 0) return -ENOMEM;
}
+
+#ifdef MODULE
+ bmac_devs = dev;
+#endif
- dev->base_addr = bmacs->addrs[0].address;
+ dev->base_addr = (unsigned long)
+ ioremap(bmacs->addrs[0].address, bmacs->addrs[0].size);
dev->irq = bmacs->intrs[0].line;
bmwrite(dev, INTDISABLE, DisableAll);
@@ -1257,7 +1250,7 @@
}
}
- printk(KERN_INFO "%s: BMAC at", dev->name);
+ printk(KERN_INFO "%s: BMAC%s at", dev->name, (is_bmac_plus? "+": ""));
rev = addr[0] == 0 && addr[1] == 0xA0;
for (j = 0; j < 6; ++j) {
dev->dev_addr[j] = rev? bitrev(addr[j]): addr[j];
@@ -1280,9 +1273,11 @@
bp = (struct bmac_data *) dev->priv;
memset(bp, 0, sizeof(struct bmac_data));
- bp->tx_dma = (volatile struct dbdma_regs *) bmacs->addrs[1].address;
+ bp->tx_dma = (volatile struct dbdma_regs *)
+ ioremap(bmacs->addrs[1].address, bmacs->addrs[1].size);
bp->tx_dma_intr = bmacs->intrs[1].line;
- bp->rx_dma = (volatile struct dbdma_regs *) bmacs->addrs[2].address;
+ bp->rx_dma = (volatile struct dbdma_regs *)
+ ioremap(bmacs->addrs[2].address, bmacs->addrs[2].size);
bp->rx_dma_intr = bmacs->intrs[2].line;
bp->tx_cmds = (volatile struct dbdma_cmd *) DBDMA_ALIGN(bp + 1);
@@ -1370,8 +1365,6 @@
}
}
bp->rx_allocated = 0;
- XXDEBUG(("bmac: free doubles\n"));/*MEMORY LEAK BELOW!!! FIX!!! */
- if (bp->tx_double[0] != NULL) kfree(bp->tx_double[0]);
XXDEBUG(("bmac: free tx bufs\n"));
for (i = 0; i<N_TX_RING; i++) {
if (bp->tx_bufs[i] != NULL) {
@@ -1379,7 +1372,6 @@
bp->tx_bufs[i] = NULL;
}
}
- bp->tx_allocated = 0;
bp->reset_and_enabled = 0;
XXDEBUG(("bmac: all bufs freed\n"));
@@ -1539,3 +1531,32 @@
return len;
}
+
+#ifdef MODULE
+
+MODULE_AUTHOR("Randy Gobbel/Paul Mackerras");
+MODULE_DESCRIPTION("PowerMac BMAC ethernet driver.");
+
+int init_module(void)
+{
+ int res;
+
+ if(bmac_devs != NULL)
+ return -EBUSY;
+ res = bmac_probe(NULL);
+ return res;
+}
+void cleanup_module(void)
+{
+ struct bmac_data *bp = (struct bmac_data *) bmac_devs->priv;
+ unregister_netdev(bmac_devs);
+
+ free_irq(bmac_devs->irq, bmac_misc_intr);
+ free_irq(bp->tx_dma_intr, bmac_txdma_intr);
+ free_irq(bp->rx_dma_intr, bmac_rxdma_intr);
+
+ kfree(bmac_devs);
+ bmac_devs = NULL;
+}
+
+#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov