patch-2.4.18 linux/drivers/net/bmac.c
Next file: linux/drivers/net/bonding.c
Previous file: linux/drivers/net/au1000_eth.c
Back to the patch index
Back to the overall index
- Lines: 203
- Date:
Wed Dec 26 16:34:02 2001
- Orig file:
linux.orig/drivers/net/bmac.c
- Orig date:
Mon Feb 18 20:18:39 2002
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/bmac.c linux/drivers/net/bmac.c
@@ -22,7 +22,8 @@
#include <asm/io.h>
#include <asm/page.h>
#include <asm/pgtable.h>
-#include <asm/feature.h>
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
#ifdef CONFIG_PMAC_PBOOK
#include <linux/adb.h>
#include <linux/pmu.h>
@@ -155,7 +156,7 @@
static void bmac_start_chip(struct net_device *dev);
static void bmac_init_chip(struct net_device *dev);
static void bmac_init_registers(struct net_device *dev);
-static void bmac_reset_chip(struct net_device *dev);
+static void bmac_enable_and_reset_chip(struct net_device *dev);
static int bmac_set_address(struct net_device *dev, void *addr);
static void bmac_misc_intr(int irq, void *dev_id, struct pt_regs *regs);
static void bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs);
@@ -229,21 +230,18 @@
}
static void
-bmac_reset_chip(struct net_device *dev)
+bmac_enable_and_reset_chip(struct net_device *dev)
{
struct bmac_data *bp = (struct bmac_data *) dev->priv;
volatile struct dbdma_regs *rd = bp->rx_dma;
volatile struct dbdma_regs *td = bp->tx_dma;
- dbdma_reset(rd);
- dbdma_reset(td);
+ if (rd)
+ dbdma_reset(rd);
+ if (td)
+ dbdma_reset(td);
- feature_set(bp->node, FEATURE_BMac_IO_enable);
- udelay(10000);
- feature_set(bp->node, FEATURE_BMac_reset);
- udelay(10000);
- feature_clear(bp->node, FEATURE_BMac_reset);
- udelay(10000);
+ pmac_call_feature(PMAC_FTR_BMAC_ENABLE, bp->node, 0, 1);
}
#define MIFDELAY udelay(10)
@@ -522,10 +520,7 @@
}
}
}
- feature_set(bp->node, FEATURE_BMac_reset);
- mdelay(10);
- feature_clear(bp->node, FEATURE_BMac_IO_enable);
- mdelay(10);
+ pmac_call_feature(PMAC_FTR_BMAC_ENABLE, bp->node, 0, 0);
break;
case PBOOK_WAKE:
/* see if this is enough */
@@ -1267,7 +1262,7 @@
unsigned char *data;
save_flags(flags); cli();
- bmac_reset_chip(dev);
+ bmac_enable_and_reset_chip(dev);
bmac_init_tx_ring(bp);
bmac_init_rx_ring(bp);
bmac_init_chip(dev);
@@ -1350,14 +1345,30 @@
bmac->full_name);
return;
}
+ bp = (struct bmac_data *) dev->priv;
SET_MODULE_OWNER(dev);
+ bp->node = bmac;
+ if (!request_OF_resource(bmac, 0, " (bmac)")) {
+ printk(KERN_ERR "BMAC: can't request IO resource !\n");
+ goto err_out;
+ }
+ if (!request_OF_resource(bmac, 1, " (bmac tx dma)")) {
+ printk(KERN_ERR "BMAC: can't request TX DMA resource !\n");
+ goto err_out;
+ }
+
+ if (!request_OF_resource(bmac, 2, " (bmac rx dma)")) {
+ printk(KERN_ERR "BMAC: can't request RX DMA resource !\n");
+ goto err_out;
+ }
dev->base_addr = (unsigned long)
ioremap(bmac->addrs[0].address, bmac->addrs[0].size);
if (!dev->base_addr)
goto err_out;
dev->irq = bmac->intrs[0].line;
+ bmac_enable_and_reset_chip(dev);
bmwrite(dev, INTDISABLE, DisableAll);
printk(KERN_INFO "%s: BMAC%s at", dev->name, (is_bmac_plus? "+": ""));
@@ -1369,6 +1380,10 @@
XXDEBUG((", base_addr=%#0lx", dev->base_addr));
printk("\n");
+ /* Enable chip without interrupts for now */
+ bmac_enable_and_reset_chip(dev);
+ bmwrite(dev, INTDISABLE, DisableAll);
+
dev->open = bmac_open;
dev->stop = bmac_close;
dev->hard_start_xmit = bmac_output;
@@ -1380,7 +1395,6 @@
if (bmac_verify_checksum(dev) != 0)
goto err_out_iounmap;
- bp = (struct bmac_data *) dev->priv;
bp->is_bmac_plus = is_bmac_plus;
bp->tx_dma = (volatile struct dbdma_regs *)
ioremap(bmac->addrs[1].address, bmac->addrs[1].size);
@@ -1399,7 +1413,6 @@
bp->queue = (struct sk_buff_head *)(bp->rx_cmds + N_RX_RING + 1);
skb_queue_head_init(bp->queue);
- bp->node = bmac;
memset((char *) bp->tx_cmds, 0,
(N_TX_RING + N_RX_RING + 2) * sizeof(struct dbdma_cmd));
/* init_timer(&bp->tx_timeout); */
@@ -1421,6 +1434,12 @@
goto err_out_irq1;
}
+ /* Mask chip interrupts and disable chip, will be
+ * re-enabled on open()
+ */
+ disable_irq(dev->irq);
+ pmac_call_feature(PMAC_FTR_BMAC_ENABLE, bp->node, 0, 0);
+
bp->next_bmac = bmac_devs;
bmac_devs = dev;
return;
@@ -1436,6 +1455,12 @@
err_out_iounmap:
iounmap((void *)dev->base_addr);
err_out:
+ if (bp->node) {
+ release_OF_resource(bp->node, 0);
+ release_OF_resource(bp->node, 1);
+ release_OF_resource(bp->node, 2);
+ pmac_call_feature(PMAC_FTR_BMAC_ENABLE, bp->node, 0, 0);
+ }
unregister_netdev(dev);
kfree(dev);
}
@@ -1447,6 +1472,7 @@
/* reset the chip */
bp->opened = 1;
bmac_reset_and_enable(dev);
+ enable_irq(dev->irq);
dev->flags |= IFF_RUNNING;
return 0;
}
@@ -1459,6 +1485,7 @@
unsigned short config;
int i;
+ bp->sleeping = 1;
dev->flags &= ~(IFF_UP | IFF_RUNNING);
/* disable rx and tx */
@@ -1492,6 +1519,8 @@
XXDEBUG(("bmac: all bufs freed\n"));
bp->opened = 0;
+ disable_irq(dev->irq);
+ pmac_call_feature(PMAC_FTR_BMAC_ENABLE, bp->node, 0, 0);
return 0;
}
@@ -1561,7 +1590,7 @@
bmwrite(dev, TXCFG, (config & ~TxMACEnable));
out_le32(&td->control, DBDMA_CLEAR(RUN|PAUSE|FLUSH|WAKE|ACTIVE|DEAD));
printk(KERN_ERR "bmac: transmit timeout - resetting\n");
- bmac_reset_chip(dev);
+ bmac_enable_and_reset_chip(dev);
/* restart rx dma */
cp = bus_to_virt(ld_le32(&rd->cmdptr));
@@ -1683,11 +1712,15 @@
bp = (struct bmac_data *) dev->priv;
bmac_devs = bp->next_bmac;
+ unregister_netdev(dev);
+
+ release_OF_resource(bp->node, 0);
+ release_OF_resource(bp->node, 1);
+ release_OF_resource(bp->node, 2);
free_irq(dev->irq, dev);
free_irq(bp->tx_dma_intr, dev);
free_irq(bp->rx_dma_intr, dev);
- unregister_netdev(dev);
kfree(dev);
} while (bmac_devs != NULL);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)