--- zzzz-none-000/linux-2.4.17/drivers/net/bmac.c 2001-11-14 23:16:31.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/drivers/net/bmac.c 2004-11-24 13:23:31.000000000 +0000 @@ -22,7 +22,8 @@ #include #include #include -#include +#include +#include #ifdef CONFIG_PMAC_PBOOK #include #include @@ -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); }