diff options
Diffstat (limited to 'drivers/net/e100.c')
| -rw-r--r-- | drivers/net/e100.c | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 5d2f48f02251..d269a68ce354 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
| @@ -157,6 +157,7 @@ | |||
| 157 | #include <linux/init.h> | 157 | #include <linux/init.h> |
| 158 | #include <linux/pci.h> | 158 | #include <linux/pci.h> |
| 159 | #include <linux/dma-mapping.h> | 159 | #include <linux/dma-mapping.h> |
| 160 | #include <linux/dmapool.h> | ||
| 160 | #include <linux/netdevice.h> | 161 | #include <linux/netdevice.h> |
| 161 | #include <linux/etherdevice.h> | 162 | #include <linux/etherdevice.h> |
| 162 | #include <linux/mii.h> | 163 | #include <linux/mii.h> |
| @@ -602,6 +603,7 @@ struct nic { | |||
| 602 | struct mem *mem; | 603 | struct mem *mem; |
| 603 | dma_addr_t dma_addr; | 604 | dma_addr_t dma_addr; |
| 604 | 605 | ||
| 606 | struct pci_pool *cbs_pool; | ||
| 605 | dma_addr_t cbs_dma_addr; | 607 | dma_addr_t cbs_dma_addr; |
| 606 | u8 adaptive_ifs; | 608 | u8 adaptive_ifs; |
| 607 | u8 tx_threshold; | 609 | u8 tx_threshold; |
| @@ -1427,19 +1429,31 @@ static int e100_phy_init(struct nic *nic) | |||
| 1427 | } else | 1429 | } else |
| 1428 | DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id); | 1430 | DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id); |
| 1429 | 1431 | ||
| 1430 | /* Isolate all the PHY ids */ | ||
| 1431 | for (addr = 0; addr < 32; addr++) | ||
| 1432 | mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE); | ||
| 1433 | /* Select the discovered PHY */ | ||
| 1434 | bmcr &= ~BMCR_ISOLATE; | ||
| 1435 | mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr); | ||
| 1436 | |||
| 1437 | /* Get phy ID */ | 1432 | /* Get phy ID */ |
| 1438 | id_lo = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID1); | 1433 | id_lo = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID1); |
| 1439 | id_hi = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID2); | 1434 | id_hi = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID2); |
| 1440 | nic->phy = (u32)id_hi << 16 | (u32)id_lo; | 1435 | nic->phy = (u32)id_hi << 16 | (u32)id_lo; |
| 1441 | DPRINTK(HW, DEBUG, "phy ID = 0x%08X\n", nic->phy); | 1436 | DPRINTK(HW, DEBUG, "phy ID = 0x%08X\n", nic->phy); |
| 1442 | 1437 | ||
| 1438 | /* Select the phy and isolate the rest */ | ||
| 1439 | for (addr = 0; addr < 32; addr++) { | ||
| 1440 | if (addr != nic->mii.phy_id) { | ||
| 1441 | mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE); | ||
| 1442 | } else if (nic->phy != phy_82552_v) { | ||
| 1443 | bmcr = mdio_read(netdev, addr, MII_BMCR); | ||
| 1444 | mdio_write(netdev, addr, MII_BMCR, | ||
| 1445 | bmcr & ~BMCR_ISOLATE); | ||
| 1446 | } | ||
| 1447 | } | ||
| 1448 | /* | ||
| 1449 | * Workaround for 82552: | ||
| 1450 | * Clear the ISOLATE bit on selected phy_id last (mirrored on all | ||
| 1451 | * other phy_id's) using bmcr value from addr discovery loop above. | ||
| 1452 | */ | ||
| 1453 | if (nic->phy == phy_82552_v) | ||
| 1454 | mdio_write(netdev, nic->mii.phy_id, MII_BMCR, | ||
| 1455 | bmcr & ~BMCR_ISOLATE); | ||
| 1456 | |||
| 1443 | /* Handle National tx phys */ | 1457 | /* Handle National tx phys */ |
| 1444 | #define NCS_PHY_MODEL_MASK 0xFFF0FFFF | 1458 | #define NCS_PHY_MODEL_MASK 0xFFF0FFFF |
| 1445 | if ((nic->phy & NCS_PHY_MODEL_MASK) == phy_nsc_tx) { | 1459 | if ((nic->phy & NCS_PHY_MODEL_MASK) == phy_nsc_tx) { |
| @@ -1781,9 +1795,7 @@ static void e100_clean_cbs(struct nic *nic) | |||
| 1781 | nic->cb_to_clean = nic->cb_to_clean->next; | 1795 | nic->cb_to_clean = nic->cb_to_clean->next; |
| 1782 | nic->cbs_avail++; | 1796 | nic->cbs_avail++; |
| 1783 | } | 1797 | } |
| 1784 | pci_free_consistent(nic->pdev, | 1798 | pci_pool_free(nic->cbs_pool, nic->cbs, nic->cbs_dma_addr); |
| 1785 | sizeof(struct cb) * nic->params.cbs.count, | ||
| 1786 | nic->cbs, nic->cbs_dma_addr); | ||
| 1787 | nic->cbs = NULL; | 1799 | nic->cbs = NULL; |
| 1788 | nic->cbs_avail = 0; | 1800 | nic->cbs_avail = 0; |
| 1789 | } | 1801 | } |
| @@ -1801,8 +1813,8 @@ static int e100_alloc_cbs(struct nic *nic) | |||
| 1801 | nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL; | 1813 | nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL; |
| 1802 | nic->cbs_avail = 0; | 1814 | nic->cbs_avail = 0; |
| 1803 | 1815 | ||
| 1804 | nic->cbs = pci_alloc_consistent(nic->pdev, | 1816 | nic->cbs = pci_pool_alloc(nic->cbs_pool, GFP_KERNEL, |
| 1805 | sizeof(struct cb) * count, &nic->cbs_dma_addr); | 1817 | &nic->cbs_dma_addr); |
| 1806 | if (!nic->cbs) | 1818 | if (!nic->cbs) |
| 1807 | return -ENOMEM; | 1819 | return -ENOMEM; |
| 1808 | 1820 | ||
| @@ -2829,7 +2841,11 @@ static int __devinit e100_probe(struct pci_dev *pdev, | |||
| 2829 | DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n"); | 2841 | DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n"); |
| 2830 | goto err_out_free; | 2842 | goto err_out_free; |
| 2831 | } | 2843 | } |
| 2832 | 2844 | nic->cbs_pool = pci_pool_create(netdev->name, | |
| 2845 | nic->pdev, | ||
| 2846 | nic->params.cbs.count * sizeof(struct cb), | ||
| 2847 | sizeof(u32), | ||
| 2848 | 0); | ||
| 2833 | DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n", | 2849 | DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n", |
| 2834 | (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0), | 2850 | (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0), |
| 2835 | pdev->irq, netdev->dev_addr); | 2851 | pdev->irq, netdev->dev_addr); |
| @@ -2859,6 +2875,7 @@ static void __devexit e100_remove(struct pci_dev *pdev) | |||
| 2859 | unregister_netdev(netdev); | 2875 | unregister_netdev(netdev); |
| 2860 | e100_free(nic); | 2876 | e100_free(nic); |
| 2861 | pci_iounmap(pdev, nic->csr); | 2877 | pci_iounmap(pdev, nic->csr); |
| 2878 | pci_pool_destroy(nic->cbs_pool); | ||
| 2862 | free_netdev(netdev); | 2879 | free_netdev(netdev); |
| 2863 | pci_release_regions(pdev); | 2880 | pci_release_regions(pdev); |
| 2864 | pci_disable_device(pdev); | 2881 | pci_disable_device(pdev); |
