aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDon Fry <pcnet32@verizon.net>2007-03-06 13:45:23 -0500
committerJeff Garzik <jeff@garzik.org>2007-04-28 11:00:58 -0400
commit6ecb766710e5128e3b8f3c775f907dcb8fead8d1 (patch)
tree054a009b93ebad4f85d2e454f6c31fc3fabf3e96 /drivers
parent1c8816c6fe375ed3a1e342fcf7f403cd4f0d5041 (diff)
pcnet32: only allocate init_block dma consistent
The patch below moves the init_block out of the private struct and only allocates init block with pci_alloc_consistent. This has two effects: 1. Performance increase for non cache coherent machines, because the CPU only data in the private struct are now cached 2. locks are working now for platforms, which need to have locks in cached memory Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> Acked-by: Don Fry <pcnet32@verizon.net> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/pcnet32.c77
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 */
255struct pcnet32_private { 255struct 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
1592pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) 1592pcnet32_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)
2707static void pcnet32_load_multicast(struct net_device *dev) 2696static 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 }