diff options
Diffstat (limited to 'drivers/net/pcnet32.c')
-rw-r--r-- | drivers/net/pcnet32.c | 77 |
1 files changed, 34 insertions, 43 deletions
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 0791360a6a66..cc35bf562f30 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c | |||
@@ -253,12 +253,12 @@ struct pcnet32_access { | |||
253 | * so the structure should be allocated using pci_alloc_consistent(). | 253 | * so the structure should be allocated using pci_alloc_consistent(). |
254 | */ | 254 | */ |
255 | struct pcnet32_private { | 255 | struct pcnet32_private { |
256 | struct pcnet32_init_block init_block; | 256 | struct pcnet32_init_block *init_block; |
257 | /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */ | 257 | /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */ |
258 | struct pcnet32_rx_head *rx_ring; | 258 | struct pcnet32_rx_head *rx_ring; |
259 | struct pcnet32_tx_head *tx_ring; | 259 | struct pcnet32_tx_head *tx_ring; |
260 | dma_addr_t dma_addr;/* DMA address of beginning of this | 260 | dma_addr_t init_dma_addr;/* DMA address of beginning of the init block, |
261 | object, returned by pci_alloc_consistent */ | 261 | returned by pci_alloc_consistent */ |
262 | struct pci_dev *pci_dev; | 262 | struct pci_dev *pci_dev; |
263 | const char *name; | 263 | const char *name; |
264 | /* The saved address of a sent-in-place packet/buffer, for skfree(). */ | 264 | /* The saved address of a sent-in-place packet/buffer, for skfree(). */ |
@@ -1592,7 +1592,6 @@ static int __devinit | |||
1592 | pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) | 1592 | pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) |
1593 | { | 1593 | { |
1594 | struct pcnet32_private *lp; | 1594 | struct pcnet32_private *lp; |
1595 | dma_addr_t lp_dma_addr; | ||
1596 | int i, media; | 1595 | int i, media; |
1597 | int fdx, mii, fset, dxsuflo; | 1596 | int fdx, mii, fset, dxsuflo; |
1598 | int chip_version; | 1597 | int chip_version; |
@@ -1714,7 +1713,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) | |||
1714 | dxsuflo = 1; | 1713 | dxsuflo = 1; |
1715 | } | 1714 | } |
1716 | 1715 | ||
1717 | dev = alloc_etherdev(0); | 1716 | dev = alloc_etherdev(sizeof(*lp)); |
1718 | if (!dev) { | 1717 | if (!dev) { |
1719 | if (pcnet32_debug & NETIF_MSG_PROBE) | 1718 | if (pcnet32_debug & NETIF_MSG_PROBE) |
1720 | printk(KERN_ERR PFX "Memory allocation failed.\n"); | 1719 | printk(KERN_ERR PFX "Memory allocation failed.\n"); |
@@ -1805,25 +1804,22 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) | |||
1805 | } | 1804 | } |
1806 | 1805 | ||
1807 | dev->base_addr = ioaddr; | 1806 | dev->base_addr = ioaddr; |
1807 | lp = dev->priv; | ||
1808 | /* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */ | 1808 | /* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */ |
1809 | if ((lp = | 1809 | if ((lp->init_block = |
1810 | pci_alloc_consistent(pdev, sizeof(*lp), &lp_dma_addr)) == NULL) { | 1810 | pci_alloc_consistent(pdev, sizeof(*lp->init_block), &lp->init_dma_addr)) == NULL) { |
1811 | if (pcnet32_debug & NETIF_MSG_PROBE) | 1811 | if (pcnet32_debug & NETIF_MSG_PROBE) |
1812 | printk(KERN_ERR PFX | 1812 | printk(KERN_ERR PFX |
1813 | "Consistent memory allocation failed.\n"); | 1813 | "Consistent memory allocation failed.\n"); |
1814 | ret = -ENOMEM; | 1814 | ret = -ENOMEM; |
1815 | goto err_free_netdev; | 1815 | goto err_free_netdev; |
1816 | } | 1816 | } |
1817 | |||
1818 | memset(lp, 0, sizeof(*lp)); | ||
1819 | lp->dma_addr = lp_dma_addr; | ||
1820 | lp->pci_dev = pdev; | 1817 | lp->pci_dev = pdev; |
1821 | 1818 | ||
1822 | spin_lock_init(&lp->lock); | 1819 | spin_lock_init(&lp->lock); |
1823 | 1820 | ||
1824 | SET_MODULE_OWNER(dev); | 1821 | SET_MODULE_OWNER(dev); |
1825 | SET_NETDEV_DEV(dev, &pdev->dev); | 1822 | SET_NETDEV_DEV(dev, &pdev->dev); |
1826 | dev->priv = lp; | ||
1827 | lp->name = chipname; | 1823 | lp->name = chipname; |
1828 | lp->shared_irq = shared; | 1824 | lp->shared_irq = shared; |
1829 | lp->tx_ring_size = TX_RING_SIZE; /* default tx ring size */ | 1825 | lp->tx_ring_size = TX_RING_SIZE; /* default tx ring size */ |
@@ -1870,23 +1866,21 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) | |||
1870 | && dev->dev_addr[2] == 0x75) | 1866 | && dev->dev_addr[2] == 0x75) |
1871 | lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI; | 1867 | lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI; |
1872 | 1868 | ||
1873 | lp->init_block.mode = le16_to_cpu(0x0003); /* Disable Rx and Tx. */ | 1869 | lp->init_block->mode = le16_to_cpu(0x0003); /* Disable Rx and Tx. */ |
1874 | lp->init_block.tlen_rlen = | 1870 | lp->init_block->tlen_rlen = |
1875 | le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits); | 1871 | le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits); |
1876 | for (i = 0; i < 6; i++) | 1872 | for (i = 0; i < 6; i++) |
1877 | lp->init_block.phys_addr[i] = dev->dev_addr[i]; | 1873 | lp->init_block->phys_addr[i] = dev->dev_addr[i]; |
1878 | lp->init_block.filter[0] = 0x00000000; | 1874 | lp->init_block->filter[0] = 0x00000000; |
1879 | lp->init_block.filter[1] = 0x00000000; | 1875 | lp->init_block->filter[1] = 0x00000000; |
1880 | lp->init_block.rx_ring = (u32) le32_to_cpu(lp->rx_ring_dma_addr); | 1876 | lp->init_block->rx_ring = (u32) le32_to_cpu(lp->rx_ring_dma_addr); |
1881 | lp->init_block.tx_ring = (u32) le32_to_cpu(lp->tx_ring_dma_addr); | 1877 | lp->init_block->tx_ring = (u32) le32_to_cpu(lp->tx_ring_dma_addr); |
1882 | 1878 | ||
1883 | /* switch pcnet32 to 32bit mode */ | 1879 | /* switch pcnet32 to 32bit mode */ |
1884 | a->write_bcr(ioaddr, 20, 2); | 1880 | a->write_bcr(ioaddr, 20, 2); |
1885 | 1881 | ||
1886 | a->write_csr(ioaddr, 1, (lp->dma_addr + offsetof(struct pcnet32_private, | 1882 | a->write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff)); |
1887 | init_block)) & 0xffff); | 1883 | a->write_csr(ioaddr, 2, (lp->init_dma_addr >> 16)); |
1888 | a->write_csr(ioaddr, 2, (lp->dma_addr + offsetof(struct pcnet32_private, | ||
1889 | init_block)) >> 16); | ||
1890 | 1884 | ||
1891 | if (pdev) { /* use the IRQ provided by PCI */ | 1885 | if (pdev) { /* use the IRQ provided by PCI */ |
1892 | dev->irq = pdev->irq; | 1886 | dev->irq = pdev->irq; |
@@ -1992,7 +1986,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) | |||
1992 | err_free_ring: | 1986 | err_free_ring: |
1993 | pcnet32_free_ring(dev); | 1987 | pcnet32_free_ring(dev); |
1994 | err_free_consistent: | 1988 | err_free_consistent: |
1995 | pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); | 1989 | pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block), |
1990 | lp->init_block, lp->init_dma_addr); | ||
1996 | err_free_netdev: | 1991 | err_free_netdev: |
1997 | free_netdev(dev); | 1992 | free_netdev(dev); |
1998 | err_release_region: | 1993 | err_release_region: |
@@ -2134,8 +2129,7 @@ static int pcnet32_open(struct net_device *dev) | |||
2134 | "%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n", | 2129 | "%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n", |
2135 | dev->name, dev->irq, (u32) (lp->tx_ring_dma_addr), | 2130 | dev->name, dev->irq, (u32) (lp->tx_ring_dma_addr), |
2136 | (u32) (lp->rx_ring_dma_addr), | 2131 | (u32) (lp->rx_ring_dma_addr), |
2137 | (u32) (lp->dma_addr + | 2132 | (u32) (lp->init_dma_addr)); |
2138 | offsetof(struct pcnet32_private, init_block))); | ||
2139 | 2133 | ||
2140 | /* set/reset autoselect bit */ | 2134 | /* set/reset autoselect bit */ |
2141 | val = lp->a.read_bcr(ioaddr, 2) & ~2; | 2135 | val = lp->a.read_bcr(ioaddr, 2) & ~2; |
@@ -2274,7 +2268,7 @@ static int pcnet32_open(struct net_device *dev) | |||
2274 | } | 2268 | } |
2275 | #endif | 2269 | #endif |
2276 | 2270 | ||
2277 | lp->init_block.mode = | 2271 | lp->init_block->mode = |
2278 | le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); | 2272 | le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); |
2279 | pcnet32_load_multicast(dev); | 2273 | pcnet32_load_multicast(dev); |
2280 | 2274 | ||
@@ -2284,12 +2278,8 @@ static int pcnet32_open(struct net_device *dev) | |||
2284 | } | 2278 | } |
2285 | 2279 | ||
2286 | /* Re-initialize the PCNET32, and start it when done. */ | 2280 | /* Re-initialize the PCNET32, and start it when done. */ |
2287 | lp->a.write_csr(ioaddr, 1, (lp->dma_addr + | 2281 | lp->a.write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff)); |
2288 | offsetof(struct pcnet32_private, | 2282 | lp->a.write_csr(ioaddr, 2, (lp->init_dma_addr >> 16)); |
2289 | init_block)) & 0xffff); | ||
2290 | lp->a.write_csr(ioaddr, 2, | ||
2291 | (lp->dma_addr + | ||
2292 | offsetof(struct pcnet32_private, init_block)) >> 16); | ||
2293 | 2283 | ||
2294 | lp->a.write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */ | 2284 | lp->a.write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */ |
2295 | lp->a.write_csr(ioaddr, CSR0, CSR0_INIT); | 2285 | lp->a.write_csr(ioaddr, CSR0, CSR0_INIT); |
@@ -2316,8 +2306,7 @@ static int pcnet32_open(struct net_device *dev) | |||
2316 | printk(KERN_DEBUG | 2306 | printk(KERN_DEBUG |
2317 | "%s: pcnet32 open after %d ticks, init block %#x csr0 %4.4x.\n", | 2307 | "%s: pcnet32 open after %d ticks, init block %#x csr0 %4.4x.\n", |
2318 | dev->name, i, | 2308 | dev->name, i, |
2319 | (u32) (lp->dma_addr + | 2309 | (u32) (lp->init_dma_addr), |
2320 | offsetof(struct pcnet32_private, init_block)), | ||
2321 | lp->a.read_csr(ioaddr, CSR0)); | 2310 | lp->a.read_csr(ioaddr, CSR0)); |
2322 | 2311 | ||
2323 | spin_unlock_irqrestore(&lp->lock, flags); | 2312 | spin_unlock_irqrestore(&lp->lock, flags); |
@@ -2417,12 +2406,12 @@ static int pcnet32_init_ring(struct net_device *dev) | |||
2417 | lp->tx_dma_addr[i] = 0; | 2406 | lp->tx_dma_addr[i] = 0; |
2418 | } | 2407 | } |
2419 | 2408 | ||
2420 | lp->init_block.tlen_rlen = | 2409 | lp->init_block->tlen_rlen = |
2421 | le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits); | 2410 | le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits); |
2422 | for (i = 0; i < 6; i++) | 2411 | for (i = 0; i < 6; i++) |
2423 | lp->init_block.phys_addr[i] = dev->dev_addr[i]; | 2412 | lp->init_block->phys_addr[i] = dev->dev_addr[i]; |
2424 | lp->init_block.rx_ring = (u32) le32_to_cpu(lp->rx_ring_dma_addr); | 2413 | lp->init_block->rx_ring = (u32) le32_to_cpu(lp->rx_ring_dma_addr); |
2425 | lp->init_block.tx_ring = (u32) le32_to_cpu(lp->tx_ring_dma_addr); | 2414 | lp->init_block->tx_ring = (u32) le32_to_cpu(lp->tx_ring_dma_addr); |
2426 | wmb(); /* Make sure all changes are visible */ | 2415 | wmb(); /* Make sure all changes are visible */ |
2427 | return 0; | 2416 | return 0; |
2428 | } | 2417 | } |
@@ -2707,7 +2696,7 @@ static struct net_device_stats *pcnet32_get_stats(struct net_device *dev) | |||
2707 | static void pcnet32_load_multicast(struct net_device *dev) | 2696 | static void pcnet32_load_multicast(struct net_device *dev) |
2708 | { | 2697 | { |
2709 | struct pcnet32_private *lp = dev->priv; | 2698 | struct pcnet32_private *lp = dev->priv; |
2710 | volatile struct pcnet32_init_block *ib = &lp->init_block; | 2699 | volatile struct pcnet32_init_block *ib = lp->init_block; |
2711 | volatile u16 *mcast_table = (u16 *) & ib->filter; | 2700 | volatile u16 *mcast_table = (u16 *) & ib->filter; |
2712 | struct dev_mc_list *dmi = dev->mc_list; | 2701 | struct dev_mc_list *dmi = dev->mc_list; |
2713 | unsigned long ioaddr = dev->base_addr; | 2702 | unsigned long ioaddr = dev->base_addr; |
@@ -2767,12 +2756,12 @@ static void pcnet32_set_multicast_list(struct net_device *dev) | |||
2767 | if (netif_msg_hw(lp)) | 2756 | if (netif_msg_hw(lp)) |
2768 | printk(KERN_INFO "%s: Promiscuous mode enabled.\n", | 2757 | printk(KERN_INFO "%s: Promiscuous mode enabled.\n", |
2769 | dev->name); | 2758 | dev->name); |
2770 | lp->init_block.mode = | 2759 | lp->init_block->mode = |
2771 | le16_to_cpu(0x8000 | (lp->options & PCNET32_PORT_PORTSEL) << | 2760 | le16_to_cpu(0x8000 | (lp->options & PCNET32_PORT_PORTSEL) << |
2772 | 7); | 2761 | 7); |
2773 | lp->a.write_csr(ioaddr, CSR15, csr15 | 0x8000); | 2762 | lp->a.write_csr(ioaddr, CSR15, csr15 | 0x8000); |
2774 | } else { | 2763 | } else { |
2775 | lp->init_block.mode = | 2764 | lp->init_block->mode = |
2776 | le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); | 2765 | le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); |
2777 | lp->a.write_csr(ioaddr, CSR15, csr15 & 0x7fff); | 2766 | lp->a.write_csr(ioaddr, CSR15, csr15 & 0x7fff); |
2778 | pcnet32_load_multicast(dev); | 2767 | pcnet32_load_multicast(dev); |
@@ -2965,7 +2954,8 @@ static void __devexit pcnet32_remove_one(struct pci_dev *pdev) | |||
2965 | unregister_netdev(dev); | 2954 | unregister_netdev(dev); |
2966 | pcnet32_free_ring(dev); | 2955 | pcnet32_free_ring(dev); |
2967 | release_region(dev->base_addr, PCNET32_TOTAL_SIZE); | 2956 | release_region(dev->base_addr, PCNET32_TOTAL_SIZE); |
2968 | pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); | 2957 | pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block), |
2958 | lp->init_block, lp->init_dma_addr); | ||
2969 | free_netdev(dev); | 2959 | free_netdev(dev); |
2970 | pci_disable_device(pdev); | 2960 | pci_disable_device(pdev); |
2971 | pci_set_drvdata(pdev, NULL); | 2961 | pci_set_drvdata(pdev, NULL); |
@@ -3045,7 +3035,8 @@ static void __exit pcnet32_cleanup_module(void) | |||
3045 | unregister_netdev(pcnet32_dev); | 3035 | unregister_netdev(pcnet32_dev); |
3046 | pcnet32_free_ring(pcnet32_dev); | 3036 | pcnet32_free_ring(pcnet32_dev); |
3047 | release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE); | 3037 | release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE); |
3048 | pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); | 3038 | pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block), |
3039 | lp->init_block, lp->init_dma_addr); | ||
3049 | free_netdev(pcnet32_dev); | 3040 | free_netdev(pcnet32_dev); |
3050 | pcnet32_dev = next_dev; | 3041 | pcnet32_dev = next_dev; |
3051 | } | 3042 | } |