diff options
Diffstat (limited to 'drivers/net/e100.c')
-rw-r--r-- | drivers/net/e100.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 3c29a20b751e..929701ca07d3 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; |
@@ -622,6 +624,7 @@ struct nic { | |||
622 | u16 eeprom_wc; | 624 | u16 eeprom_wc; |
623 | __le16 eeprom[256]; | 625 | __le16 eeprom[256]; |
624 | spinlock_t mdio_lock; | 626 | spinlock_t mdio_lock; |
627 | const struct firmware *fw; | ||
625 | }; | 628 | }; |
626 | 629 | ||
627 | static inline void e100_write_flush(struct nic *nic) | 630 | static inline void e100_write_flush(struct nic *nic) |
@@ -1223,9 +1226,9 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) | |||
1223 | static const struct firmware *e100_request_firmware(struct nic *nic) | 1226 | static const struct firmware *e100_request_firmware(struct nic *nic) |
1224 | { | 1227 | { |
1225 | const char *fw_name; | 1228 | const char *fw_name; |
1226 | const struct firmware *fw; | 1229 | const struct firmware *fw = nic->fw; |
1227 | u8 timer, bundle, min_size; | 1230 | u8 timer, bundle, min_size; |
1228 | int err; | 1231 | int err = 0; |
1229 | 1232 | ||
1230 | /* do not load u-code for ICH devices */ | 1233 | /* do not load u-code for ICH devices */ |
1231 | if (nic->flags & ich) | 1234 | if (nic->flags & ich) |
@@ -1241,12 +1244,20 @@ static const struct firmware *e100_request_firmware(struct nic *nic) | |||
1241 | else /* No ucode on other devices */ | 1244 | else /* No ucode on other devices */ |
1242 | return NULL; | 1245 | return NULL; |
1243 | 1246 | ||
1244 | err = request_firmware(&fw, fw_name, &nic->pdev->dev); | 1247 | /* If the firmware has not previously been loaded, request a pointer |
1248 | * to it. If it was previously loaded, we are reinitializing the | ||
1249 | * adapter, possibly in a resume from hibernate, in which case | ||
1250 | * request_firmware() cannot be used. | ||
1251 | */ | ||
1252 | if (!fw) | ||
1253 | err = request_firmware(&fw, fw_name, &nic->pdev->dev); | ||
1254 | |||
1245 | if (err) { | 1255 | if (err) { |
1246 | DPRINTK(PROBE, ERR, "Failed to load firmware \"%s\": %d\n", | 1256 | DPRINTK(PROBE, ERR, "Failed to load firmware \"%s\": %d\n", |
1247 | fw_name, err); | 1257 | fw_name, err); |
1248 | return ERR_PTR(err); | 1258 | return ERR_PTR(err); |
1249 | } | 1259 | } |
1260 | |||
1250 | /* Firmware should be precisely UCODE_SIZE (words) plus three bytes | 1261 | /* Firmware should be precisely UCODE_SIZE (words) plus three bytes |
1251 | indicating the offsets for BUNDLESMALL, BUNDLEMAX, INTDELAY */ | 1262 | indicating the offsets for BUNDLESMALL, BUNDLEMAX, INTDELAY */ |
1252 | if (fw->size != UCODE_SIZE * 4 + 3) { | 1263 | if (fw->size != UCODE_SIZE * 4 + 3) { |
@@ -1269,7 +1280,10 @@ static const struct firmware *e100_request_firmware(struct nic *nic) | |||
1269 | release_firmware(fw); | 1280 | release_firmware(fw); |
1270 | return ERR_PTR(-EINVAL); | 1281 | return ERR_PTR(-EINVAL); |
1271 | } | 1282 | } |
1272 | /* OK, firmware is validated and ready to use... */ | 1283 | |
1284 | /* OK, firmware is validated and ready to use. Save a pointer | ||
1285 | * to it in the nic */ | ||
1286 | nic->fw = fw; | ||
1273 | return fw; | 1287 | return fw; |
1274 | } | 1288 | } |
1275 | 1289 | ||
@@ -1793,9 +1807,7 @@ static void e100_clean_cbs(struct nic *nic) | |||
1793 | nic->cb_to_clean = nic->cb_to_clean->next; | 1807 | nic->cb_to_clean = nic->cb_to_clean->next; |
1794 | nic->cbs_avail++; | 1808 | nic->cbs_avail++; |
1795 | } | 1809 | } |
1796 | pci_free_consistent(nic->pdev, | 1810 | pci_pool_free(nic->cbs_pool, nic->cbs, nic->cbs_dma_addr); |
1797 | sizeof(struct cb) * nic->params.cbs.count, | ||
1798 | nic->cbs, nic->cbs_dma_addr); | ||
1799 | nic->cbs = NULL; | 1811 | nic->cbs = NULL; |
1800 | nic->cbs_avail = 0; | 1812 | nic->cbs_avail = 0; |
1801 | } | 1813 | } |
@@ -1813,8 +1825,8 @@ static int e100_alloc_cbs(struct nic *nic) | |||
1813 | nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL; | 1825 | nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL; |
1814 | nic->cbs_avail = 0; | 1826 | nic->cbs_avail = 0; |
1815 | 1827 | ||
1816 | nic->cbs = pci_alloc_consistent(nic->pdev, | 1828 | nic->cbs = pci_pool_alloc(nic->cbs_pool, GFP_KERNEL, |
1817 | sizeof(struct cb) * count, &nic->cbs_dma_addr); | 1829 | &nic->cbs_dma_addr); |
1818 | if (!nic->cbs) | 1830 | if (!nic->cbs) |
1819 | return -ENOMEM; | 1831 | return -ENOMEM; |
1820 | 1832 | ||
@@ -1852,11 +1864,10 @@ static inline void e100_start_receiver(struct nic *nic, struct rx *rx) | |||
1852 | #define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN) | 1864 | #define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN) |
1853 | static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) | 1865 | static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) |
1854 | { | 1866 | { |
1855 | if (!(rx->skb = netdev_alloc_skb(nic->netdev, RFD_BUF_LEN + NET_IP_ALIGN))) | 1867 | if (!(rx->skb = netdev_alloc_skb_ip_align(nic->netdev, RFD_BUF_LEN))) |
1856 | return -ENOMEM; | 1868 | return -ENOMEM; |
1857 | 1869 | ||
1858 | /* Align, init, and map the RFD. */ | 1870 | /* Init, and map the RFD. */ |
1859 | skb_reserve(rx->skb, NET_IP_ALIGN); | ||
1860 | skb_copy_to_linear_data(rx->skb, &nic->blank_rfd, sizeof(struct rfd)); | 1871 | skb_copy_to_linear_data(rx->skb, &nic->blank_rfd, sizeof(struct rfd)); |
1861 | rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data, | 1872 | rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data, |
1862 | RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL); | 1873 | RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL); |
@@ -2841,7 +2852,11 @@ static int __devinit e100_probe(struct pci_dev *pdev, | |||
2841 | DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n"); | 2852 | DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n"); |
2842 | goto err_out_free; | 2853 | goto err_out_free; |
2843 | } | 2854 | } |
2844 | 2855 | nic->cbs_pool = pci_pool_create(netdev->name, | |
2856 | nic->pdev, | ||
2857 | nic->params.cbs.count * sizeof(struct cb), | ||
2858 | sizeof(u32), | ||
2859 | 0); | ||
2845 | DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n", | 2860 | DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n", |
2846 | (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0), | 2861 | (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0), |
2847 | pdev->irq, netdev->dev_addr); | 2862 | pdev->irq, netdev->dev_addr); |
@@ -2871,6 +2886,7 @@ static void __devexit e100_remove(struct pci_dev *pdev) | |||
2871 | unregister_netdev(netdev); | 2886 | unregister_netdev(netdev); |
2872 | e100_free(nic); | 2887 | e100_free(nic); |
2873 | pci_iounmap(pdev, nic->csr); | 2888 | pci_iounmap(pdev, nic->csr); |
2889 | pci_pool_destroy(nic->cbs_pool); | ||
2874 | free_netdev(netdev); | 2890 | free_netdev(netdev); |
2875 | pci_release_regions(pdev); | 2891 | pci_release_regions(pdev); |
2876 | pci_disable_device(pdev); | 2892 | pci_disable_device(pdev); |