diff options
| author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
|---|---|---|
| committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
| commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
| tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/e100.c | |
| parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
| parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) | |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/e100.c')
| -rw-r--r-- | drivers/net/e100.c | 57 |
1 files changed, 39 insertions, 18 deletions
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index d269a68ce354..791080303db1 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
| @@ -166,6 +166,7 @@ | |||
| 166 | #include <linux/ethtool.h> | 166 | #include <linux/ethtool.h> |
| 167 | #include <linux/string.h> | 167 | #include <linux/string.h> |
| 168 | #include <linux/firmware.h> | 168 | #include <linux/firmware.h> |
| 169 | #include <linux/rtnetlink.h> | ||
| 169 | #include <asm/unaligned.h> | 170 | #include <asm/unaligned.h> |
| 170 | 171 | ||
| 171 | 172 | ||
| @@ -208,7 +209,7 @@ MODULE_PARM_DESC(use_io, "Force use of i/o access mode"); | |||
| 208 | #define INTEL_8255X_ETHERNET_DEVICE(device_id, ich) {\ | 209 | #define INTEL_8255X_ETHERNET_DEVICE(device_id, ich) {\ |
| 209 | PCI_VENDOR_ID_INTEL, device_id, PCI_ANY_ID, PCI_ANY_ID, \ | 210 | PCI_VENDOR_ID_INTEL, device_id, PCI_ANY_ID, PCI_ANY_ID, \ |
| 210 | PCI_CLASS_NETWORK_ETHERNET << 8, 0xFFFF00, ich } | 211 | PCI_CLASS_NETWORK_ETHERNET << 8, 0xFFFF00, ich } |
| 211 | static struct pci_device_id e100_id_table[] = { | 212 | static DEFINE_PCI_DEVICE_TABLE(e100_id_table) = { |
| 212 | INTEL_8255X_ETHERNET_DEVICE(0x1029, 0), | 213 | INTEL_8255X_ETHERNET_DEVICE(0x1029, 0), |
| 213 | INTEL_8255X_ETHERNET_DEVICE(0x1030, 0), | 214 | INTEL_8255X_ETHERNET_DEVICE(0x1030, 0), |
| 214 | INTEL_8255X_ETHERNET_DEVICE(0x1031, 3), | 215 | INTEL_8255X_ETHERNET_DEVICE(0x1031, 3), |
| @@ -624,6 +625,7 @@ struct nic { | |||
| 624 | u16 eeprom_wc; | 625 | u16 eeprom_wc; |
| 625 | __le16 eeprom[256]; | 626 | __le16 eeprom[256]; |
| 626 | spinlock_t mdio_lock; | 627 | spinlock_t mdio_lock; |
| 628 | const struct firmware *fw; | ||
| 627 | }; | 629 | }; |
| 628 | 630 | ||
| 629 | static inline void e100_write_flush(struct nic *nic) | 631 | static inline void e100_write_flush(struct nic *nic) |
| @@ -1225,9 +1227,9 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) | |||
| 1225 | static const struct firmware *e100_request_firmware(struct nic *nic) | 1227 | static const struct firmware *e100_request_firmware(struct nic *nic) |
| 1226 | { | 1228 | { |
| 1227 | const char *fw_name; | 1229 | const char *fw_name; |
| 1228 | const struct firmware *fw; | 1230 | const struct firmware *fw = nic->fw; |
| 1229 | u8 timer, bundle, min_size; | 1231 | u8 timer, bundle, min_size; |
| 1230 | int err; | 1232 | int err = 0; |
| 1231 | 1233 | ||
| 1232 | /* do not load u-code for ICH devices */ | 1234 | /* do not load u-code for ICH devices */ |
| 1233 | if (nic->flags & ich) | 1235 | if (nic->flags & ich) |
| @@ -1243,12 +1245,20 @@ static const struct firmware *e100_request_firmware(struct nic *nic) | |||
| 1243 | else /* No ucode on other devices */ | 1245 | else /* No ucode on other devices */ |
| 1244 | return NULL; | 1246 | return NULL; |
| 1245 | 1247 | ||
| 1246 | err = request_firmware(&fw, fw_name, &nic->pdev->dev); | 1248 | /* If the firmware has not previously been loaded, request a pointer |
| 1249 | * to it. If it was previously loaded, we are reinitializing the | ||
| 1250 | * adapter, possibly in a resume from hibernate, in which case | ||
| 1251 | * request_firmware() cannot be used. | ||
| 1252 | */ | ||
| 1253 | if (!fw) | ||
| 1254 | err = request_firmware(&fw, fw_name, &nic->pdev->dev); | ||
| 1255 | |||
| 1247 | if (err) { | 1256 | if (err) { |
| 1248 | DPRINTK(PROBE, ERR, "Failed to load firmware \"%s\": %d\n", | 1257 | DPRINTK(PROBE, ERR, "Failed to load firmware \"%s\": %d\n", |
| 1249 | fw_name, err); | 1258 | fw_name, err); |
| 1250 | return ERR_PTR(err); | 1259 | return ERR_PTR(err); |
| 1251 | } | 1260 | } |
| 1261 | |||
| 1252 | /* Firmware should be precisely UCODE_SIZE (words) plus three bytes | 1262 | /* Firmware should be precisely UCODE_SIZE (words) plus three bytes |
| 1253 | indicating the offsets for BUNDLESMALL, BUNDLEMAX, INTDELAY */ | 1263 | indicating the offsets for BUNDLESMALL, BUNDLEMAX, INTDELAY */ |
| 1254 | if (fw->size != UCODE_SIZE * 4 + 3) { | 1264 | if (fw->size != UCODE_SIZE * 4 + 3) { |
| @@ -1271,7 +1281,10 @@ static const struct firmware *e100_request_firmware(struct nic *nic) | |||
| 1271 | release_firmware(fw); | 1281 | release_firmware(fw); |
| 1272 | return ERR_PTR(-EINVAL); | 1282 | return ERR_PTR(-EINVAL); |
| 1273 | } | 1283 | } |
| 1274 | /* OK, firmware is validated and ready to use... */ | 1284 | |
| 1285 | /* OK, firmware is validated and ready to use. Save a pointer | ||
| 1286 | * to it in the nic */ | ||
| 1287 | nic->fw = fw; | ||
| 1275 | return fw; | 1288 | return fw; |
| 1276 | } | 1289 | } |
| 1277 | 1290 | ||
| @@ -1525,14 +1538,18 @@ static int e100_hw_init(struct nic *nic) | |||
| 1525 | static void e100_multi(struct nic *nic, struct cb *cb, struct sk_buff *skb) | 1538 | static void e100_multi(struct nic *nic, struct cb *cb, struct sk_buff *skb) |
| 1526 | { | 1539 | { |
| 1527 | struct net_device *netdev = nic->netdev; | 1540 | struct net_device *netdev = nic->netdev; |
| 1528 | struct dev_mc_list *list = netdev->mc_list; | 1541 | struct dev_mc_list *list; |
| 1529 | u16 i, count = min(netdev->mc_count, E100_MAX_MULTICAST_ADDRS); | 1542 | u16 i, count = min(netdev_mc_count(netdev), E100_MAX_MULTICAST_ADDRS); |
| 1530 | 1543 | ||
| 1531 | cb->command = cpu_to_le16(cb_multi); | 1544 | cb->command = cpu_to_le16(cb_multi); |
| 1532 | cb->u.multi.count = cpu_to_le16(count * ETH_ALEN); | 1545 | cb->u.multi.count = cpu_to_le16(count * ETH_ALEN); |
| 1533 | for (i = 0; list && i < count; i++, list = list->next) | 1546 | i = 0; |
| 1534 | memcpy(&cb->u.multi.addr[i*ETH_ALEN], &list->dmi_addr, | 1547 | netdev_for_each_mc_addr(list, netdev) { |
| 1548 | if (i == count) | ||
| 1549 | break; | ||
| 1550 | memcpy(&cb->u.multi.addr[i++ * ETH_ALEN], &list->dmi_addr, | ||
| 1535 | ETH_ALEN); | 1551 | ETH_ALEN); |
| 1552 | } | ||
| 1536 | } | 1553 | } |
| 1537 | 1554 | ||
| 1538 | static void e100_set_multicast_list(struct net_device *netdev) | 1555 | static void e100_set_multicast_list(struct net_device *netdev) |
| @@ -1540,7 +1557,7 @@ static void e100_set_multicast_list(struct net_device *netdev) | |||
| 1540 | struct nic *nic = netdev_priv(netdev); | 1557 | struct nic *nic = netdev_priv(netdev); |
| 1541 | 1558 | ||
| 1542 | DPRINTK(HW, DEBUG, "mc_count=%d, flags=0x%04X\n", | 1559 | DPRINTK(HW, DEBUG, "mc_count=%d, flags=0x%04X\n", |
| 1543 | netdev->mc_count, netdev->flags); | 1560 | netdev_mc_count(netdev), netdev->flags); |
| 1544 | 1561 | ||
| 1545 | if (netdev->flags & IFF_PROMISC) | 1562 | if (netdev->flags & IFF_PROMISC) |
| 1546 | nic->flags |= promiscuous; | 1563 | nic->flags |= promiscuous; |
| @@ -1548,7 +1565,7 @@ static void e100_set_multicast_list(struct net_device *netdev) | |||
| 1548 | nic->flags &= ~promiscuous; | 1565 | nic->flags &= ~promiscuous; |
| 1549 | 1566 | ||
| 1550 | if (netdev->flags & IFF_ALLMULTI || | 1567 | if (netdev->flags & IFF_ALLMULTI || |
| 1551 | netdev->mc_count > E100_MAX_MULTICAST_ADDRS) | 1568 | netdev_mc_count(netdev) > E100_MAX_MULTICAST_ADDRS) |
| 1552 | nic->flags |= multicast_all; | 1569 | nic->flags |= multicast_all; |
| 1553 | else | 1570 | else |
| 1554 | nic->flags &= ~multicast_all; | 1571 | nic->flags &= ~multicast_all; |
| @@ -1817,6 +1834,7 @@ static int e100_alloc_cbs(struct nic *nic) | |||
| 1817 | &nic->cbs_dma_addr); | 1834 | &nic->cbs_dma_addr); |
| 1818 | if (!nic->cbs) | 1835 | if (!nic->cbs) |
| 1819 | return -ENOMEM; | 1836 | return -ENOMEM; |
| 1837 | memset(nic->cbs, 0, count * sizeof(struct cb)); | ||
| 1820 | 1838 | ||
| 1821 | for (cb = nic->cbs, i = 0; i < count; cb++, i++) { | 1839 | for (cb = nic->cbs, i = 0; i < count; cb++, i++) { |
| 1822 | cb->next = (i + 1 < count) ? cb + 1 : nic->cbs; | 1840 | cb->next = (i + 1 < count) ? cb + 1 : nic->cbs; |
| @@ -1825,7 +1843,6 @@ static int e100_alloc_cbs(struct nic *nic) | |||
| 1825 | cb->dma_addr = nic->cbs_dma_addr + i * sizeof(struct cb); | 1843 | cb->dma_addr = nic->cbs_dma_addr + i * sizeof(struct cb); |
| 1826 | cb->link = cpu_to_le32(nic->cbs_dma_addr + | 1844 | cb->link = cpu_to_le32(nic->cbs_dma_addr + |
| 1827 | ((i+1) % count) * sizeof(struct cb)); | 1845 | ((i+1) % count) * sizeof(struct cb)); |
| 1828 | cb->skb = NULL; | ||
| 1829 | } | 1846 | } |
| 1830 | 1847 | ||
| 1831 | nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = nic->cbs; | 1848 | nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = nic->cbs; |
| @@ -1852,11 +1869,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) | 1869 | #define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN) |
| 1853 | static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) | 1870 | static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) |
| 1854 | { | 1871 | { |
| 1855 | if (!(rx->skb = netdev_alloc_skb(nic->netdev, RFD_BUF_LEN + NET_IP_ALIGN))) | 1872 | if (!(rx->skb = netdev_alloc_skb_ip_align(nic->netdev, RFD_BUF_LEN))) |
| 1856 | return -ENOMEM; | 1873 | return -ENOMEM; |
| 1857 | 1874 | ||
| 1858 | /* Align, init, and map the RFD. */ | 1875 | /* 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)); | 1876 | 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, | 1877 | rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data, |
| 1862 | RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL); | 1878 | RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL); |
| @@ -2250,8 +2266,13 @@ static void e100_tx_timeout_task(struct work_struct *work) | |||
| 2250 | 2266 | ||
| 2251 | DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n", | 2267 | DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n", |
| 2252 | ioread8(&nic->csr->scb.status)); | 2268 | ioread8(&nic->csr->scb.status)); |
| 2253 | e100_down(netdev_priv(netdev)); | 2269 | |
| 2254 | e100_up(netdev_priv(netdev)); | 2270 | rtnl_lock(); |
| 2271 | if (netif_running(netdev)) { | ||
| 2272 | e100_down(netdev_priv(netdev)); | ||
| 2273 | e100_up(netdev_priv(netdev)); | ||
| 2274 | } | ||
| 2275 | rtnl_unlock(); | ||
| 2255 | } | 2276 | } |
| 2256 | 2277 | ||
| 2257 | static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode) | 2278 | static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode) |
| @@ -2843,7 +2864,7 @@ static int __devinit e100_probe(struct pci_dev *pdev, | |||
| 2843 | } | 2864 | } |
| 2844 | nic->cbs_pool = pci_pool_create(netdev->name, | 2865 | nic->cbs_pool = pci_pool_create(netdev->name, |
| 2845 | nic->pdev, | 2866 | nic->pdev, |
| 2846 | nic->params.cbs.count * sizeof(struct cb), | 2867 | nic->params.cbs.max * sizeof(struct cb), |
| 2847 | sizeof(u32), | 2868 | sizeof(u32), |
| 2848 | 0); | 2869 | 0); |
| 2849 | DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n", | 2870 | DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n", |
