--- zzzz-none-000/linux-2.4.17/drivers/net/mace.c 2001-10-17 04:56:29.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/drivers/net/mace.c 2004-11-24 13:23:32.000000000 +0000 @@ -24,9 +24,6 @@ static struct net_device *mace_devs; static int port_aaui = -1; -MODULE_PARM(port_aaui, "i"); -MODULE_PARM_DESC(port_aaui, "MACE uses AAUI port (0-1)"); - #define N_RX_RING 8 #define N_TX_RING 6 #define MAX_TX_ACTIVE 1 @@ -59,6 +56,7 @@ struct timer_list tx_timeout; int timeout_active; int port_aaui; + struct device_node* of_node; struct net_device *next_mace; }; @@ -152,9 +150,25 @@ SET_MODULE_OWNER(dev); mp = dev->priv; + mp->of_node = mace; + + if (!request_OF_resource(mace, 0, " (mace)")) { + printk(KERN_ERR "MACE: can't request IO resource !\n"); + goto err_out; + } + if (!request_OF_resource(mace, 1, " (mace tx dma)")) { + printk(KERN_ERR "MACE: can't request TX DMA resource !\n"); + goto err_out; + } + + if (!request_OF_resource(mace, 2, " (mace tx dma)")) { + printk(KERN_ERR "MACE: can't request RX DMA resource !\n"); + goto err_out; + } + dev->base_addr = mace->addrs[0].address; mp->mace = (volatile struct mace *) - ioremap(mace->addrs[0].address, 0x1000); + ioremap(mace->addrs[0].address, 0x1000); dev->irq = mace->intrs[0].line; printk(KERN_INFO "%s: MACE at", dev->name); @@ -221,6 +235,16 @@ mp->next_mace = mace_devs; mace_devs = dev; + return; + +err_out: + unregister_netdev(dev); + if (mp->of_node) { + release_OF_resource(mp->of_node, 0); + release_OF_resource(mp->of_node, 1); + release_OF_resource(mp->of_node, 2); + } + kfree(dev); } static void dbdma_reset(volatile struct dbdma_regs *dma) @@ -273,14 +297,20 @@ __mace_set_address(dev, dev->dev_addr); /* clear the multicast filter */ - out_8(&mb->iac, ADDRCHG | LOGADDR); - while ((in_8(&mb->iac) & ADDRCHG) != 0) - ; - for (i = 0; i < 8; ++i) { - out_8(&mb->ladrf, 0); + if (in_8(&mb->chipid_hi) == 0x09) { + printk("chip 0x09 mcast workaround...\n"); + out_8(&mb->iac, LOGADDR); + } else { + out_8(&mb->iac, ADDRCHG | LOGADDR); + while ((in_8(&mb->iac) & ADDRCHG) != 0) + ; } + for (i = 0; i < 8; ++i) + out_8(&mb->ladrf, 0); + /* done changing address */ - out_8(&mb->iac, 0); + if (in_8(&mb->chipid_hi) != 0x09) + out_8(&mb->iac, 0); if (mp->port_aaui) out_8(&mb->plscc, PORTSEL_AUI + ENPLSIO); @@ -295,11 +325,17 @@ int i; /* load up the hardware address */ - out_8(&mb->iac, ADDRCHG | PHYADDR); - while ((in_8(&mb->iac) & ADDRCHG) != 0) - ; + if (in_8(&mb->chipid_hi) == 0x09) { + printk("chip 0x09 hwaddr workaround...\n"); + out_8(&mb->iac, PHYADDR); + } else { + while ((in_8(&mb->iac) & ADDRCHG) != 0) + ; + } for (i = 0; i < 6; ++i) out_8(&mb->padr, dev->dev_addr[i] = p[i]); + if (in_8(&mb->chipid_hi) != 0x09) + out_8(&mb->iac, 0); } static int mace_set_address(struct net_device *dev, void *addr) @@ -312,7 +348,6 @@ __mace_set_address(dev, addr); - out_8(&mb->iac, 0); /* note: setting ADDRCHG clears ENRCV */ out_8(&mb->maccc, mp->maccc); @@ -557,12 +592,18 @@ printk("\n"); #endif - out_8(&mb->iac, ADDRCHG | LOGADDR); - while ((in_8(&mb->iac) & ADDRCHG) != 0) - ; - for (i = 0; i < 8; ++i) { - out_8(&mb->ladrf, multicast_filter[i]); + if (in_8(&mb->chipid_hi) == 0x09) { + printk("chip 0x09 mcast workaround...\n"); + out_8(&mb->iac, LOGADDR); + } else { + out_8(&mb->iac, ADDRCHG | LOGADDR); + while ((in_8(&mb->iac) & ADDRCHG) != 0) + ; } + for (i = 0; i < 8; ++i) + out_8(&mb->ladrf, multicast_filter[i]); + if (in_8(&mb->chipid_hi) != 0x09) + out_8(&mb->iac, LOGADDR); } /* reset maccc */ out_8(&mb->maccc, mp->maccc); @@ -913,7 +954,10 @@ MODULE_AUTHOR("Paul Mackerras"); MODULE_DESCRIPTION("PowerMac MACE driver."); +MODULE_PARM(port_aaui, "i"); +MODULE_PARM_DESC(port_aaui, "MACE uses AAUI port (0-1)"); MODULE_LICENSE("GPL"); +EXPORT_NO_SYMBOLS; static void __exit mace_cleanup (void) { @@ -921,19 +965,23 @@ struct mace_data *mp; while ((dev = mace_devs) != 0) { - mp = (struct mace_data *) mace_devs->priv; - mace_devs = mp->next_mace; + mp = (struct mace_data *) mace_devs->priv; + mace_devs = mp->next_mace; - free_irq(dev->irq, dev); - free_irq(mp->tx_dma_intr, dev); - free_irq(mp->rx_dma_intr, dev); + unregister_netdev(dev); + free_irq(dev->irq, dev); + free_irq(mp->tx_dma_intr, dev); + free_irq(mp->rx_dma_intr, dev); + + release_OF_resource(mp->of_node, 0); + release_OF_resource(mp->of_node, 1); + release_OF_resource(mp->of_node, 2); - unregister_netdev(dev); - kfree(dev); + kfree(dev); } if (dummy_buf != NULL) { - kfree(dummy_buf); - dummy_buf = NULL; + kfree(dummy_buf); + dummy_buf = NULL; } }