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", |