diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-24 13:15:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-24 13:15:13 -0400 |
commit | a319a2773a13bab56a0d0b3744ba8703324313b5 (patch) | |
tree | f02c86acabd1031439fd422a167784007e84ebb1 /drivers/net/myri10ge | |
parent | e18fa700c9a31360bc8f193aa543b7ef7b39a06b (diff) | |
parent | 183798799216fad36c7219fe8d4d6dee6b8fa755 (diff) |
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (217 commits)
net/ieee80211: fix more crypto-related build breakage
[PATCH] Spidernet: add ethtool -S (show statistics)
[NET] GT96100: Delete bitrotting ethernet driver
[PATCH] mv643xx_eth: restrict to 32-bit PPC_MULTIPLATFORM
[PATCH] Cirrus Logic ep93xx ethernet driver
r8169: the MMIO region of the 8167 stands behin BAR#1
e1000, ixgb: Remove pointless wrappers
[PATCH] Remove powerpc specific parts of 3c509 driver
[PATCH] s2io: Switch to pci_get_device
[PATCH] gt96100: move to pci_get_device API
[PATCH] ehea: bugfix for register access functions
[PATCH] e1000 disable device on PCI error
drivers/net/phy/fixed: #if 0 some incomplete code
drivers/net: const-ify ethtool_ops declarations
[PATCH] ethtool: allow const ethtool_ops
[PATCH] sky2: big endian
[PATCH] sky2: fiber support
[PATCH] sky2: tx pause bug fix
drivers/net: Trim trailing whitespace
[PATCH] ehea: IBM eHEA Ethernet Device Driver
...
Manually resolved conflicts in drivers/net/ixgb/ixgb_main.c and
drivers/net/sky2.c related to CHECKSUM_HW/CHECKSUM_PARTIAL changes by
commit 84fa7933a33f806bbbaae6775e87459b1ec584c0 that just happened to be
next to unrelated changes in this update.
Diffstat (limited to 'drivers/net/myri10ge')
-rw-r--r-- | drivers/net/myri10ge/myri10ge.c | 230 | ||||
-rw-r--r-- | drivers/net/myri10ge/myri10ge_mcp.h | 47 |
2 files changed, 232 insertions, 45 deletions
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 9f16681d0e7e..4330197994df 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
@@ -187,11 +187,14 @@ struct myri10ge_priv { | |||
187 | u8 mac_addr[6]; /* eeprom mac address */ | 187 | u8 mac_addr[6]; /* eeprom mac address */ |
188 | unsigned long serial_number; | 188 | unsigned long serial_number; |
189 | int vendor_specific_offset; | 189 | int vendor_specific_offset; |
190 | int fw_multicast_support; | ||
190 | u32 devctl; | 191 | u32 devctl; |
191 | u16 msi_flags; | 192 | u16 msi_flags; |
192 | u32 read_dma; | 193 | u32 read_dma; |
193 | u32 write_dma; | 194 | u32 write_dma; |
194 | u32 read_write_dma; | 195 | u32 read_write_dma; |
196 | u32 link_changes; | ||
197 | u32 msg_enable; | ||
195 | }; | 198 | }; |
196 | 199 | ||
197 | static char *myri10ge_fw_unaligned = "myri10ge_ethp_z8e.dat"; | 200 | static char *myri10ge_fw_unaligned = "myri10ge_ethp_z8e.dat"; |
@@ -257,6 +260,12 @@ module_param(myri10ge_max_irq_loops, int, S_IRUGO); | |||
257 | MODULE_PARM_DESC(myri10ge_max_irq_loops, | 260 | MODULE_PARM_DESC(myri10ge_max_irq_loops, |
258 | "Set stuck legacy IRQ detection threshold\n"); | 261 | "Set stuck legacy IRQ detection threshold\n"); |
259 | 262 | ||
263 | #define MYRI10GE_MSG_DEFAULT NETIF_MSG_LINK | ||
264 | |||
265 | static int myri10ge_debug = -1; /* defaults above */ | ||
266 | module_param(myri10ge_debug, int, 0); | ||
267 | MODULE_PARM_DESC(myri10ge_debug, "Debug level (0=none,...,16=all)"); | ||
268 | |||
260 | #define MYRI10GE_FW_OFFSET 1024*1024 | 269 | #define MYRI10GE_FW_OFFSET 1024*1024 |
261 | #define MYRI10GE_HIGHPART_TO_U32(X) \ | 270 | #define MYRI10GE_HIGHPART_TO_U32(X) \ |
262 | (sizeof (X) == 8) ? ((u32)((u64)(X) >> 32)) : (0) | 271 | (sizeof (X) == 8) ? ((u32)((u64)(X) >> 32)) : (0) |
@@ -271,7 +280,7 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, | |||
271 | struct mcp_cmd *buf; | 280 | struct mcp_cmd *buf; |
272 | char buf_bytes[sizeof(*buf) + 8]; | 281 | char buf_bytes[sizeof(*buf) + 8]; |
273 | struct mcp_cmd_response *response = mgp->cmd; | 282 | struct mcp_cmd_response *response = mgp->cmd; |
274 | char __iomem *cmd_addr = mgp->sram + MXGEFW_CMD_OFFSET; | 283 | char __iomem *cmd_addr = mgp->sram + MXGEFW_ETH_CMD; |
275 | u32 dma_low, dma_high, result, value; | 284 | u32 dma_low, dma_high, result, value; |
276 | int sleep_total = 0; | 285 | int sleep_total = 0; |
277 | 286 | ||
@@ -320,6 +329,8 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, | |||
320 | if (result == 0) { | 329 | if (result == 0) { |
321 | data->data0 = value; | 330 | data->data0 = value; |
322 | return 0; | 331 | return 0; |
332 | } else if (result == MXGEFW_CMD_UNKNOWN) { | ||
333 | return -ENOSYS; | ||
323 | } else { | 334 | } else { |
324 | dev_err(&mgp->pdev->dev, | 335 | dev_err(&mgp->pdev->dev, |
325 | "command %d failed, result = %d\n", | 336 | "command %d failed, result = %d\n", |
@@ -404,7 +415,7 @@ static void myri10ge_dummy_rdma(struct myri10ge_priv *mgp, int enable) | |||
404 | buf[4] = htonl(dma_low); /* dummy addr LSW */ | 415 | buf[4] = htonl(dma_low); /* dummy addr LSW */ |
405 | buf[5] = htonl(enable); /* enable? */ | 416 | buf[5] = htonl(enable); /* enable? */ |
406 | 417 | ||
407 | submit = mgp->sram + 0xfc01c0; | 418 | submit = mgp->sram + MXGEFW_BOOT_DUMMY_RDMA; |
408 | 419 | ||
409 | myri10ge_pio_copy(submit, &buf, sizeof(buf)); | 420 | myri10ge_pio_copy(submit, &buf, sizeof(buf)); |
410 | for (i = 0; mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA && i < 20; i++) | 421 | for (i = 0; mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA && i < 20; i++) |
@@ -600,7 +611,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp) | |||
600 | buf[5] = htonl(8); /* where to copy to */ | 611 | buf[5] = htonl(8); /* where to copy to */ |
601 | buf[6] = htonl(0); /* where to jump to */ | 612 | buf[6] = htonl(0); /* where to jump to */ |
602 | 613 | ||
603 | submit = mgp->sram + 0xfc0000; | 614 | submit = mgp->sram + MXGEFW_BOOT_HANDOFF; |
604 | 615 | ||
605 | myri10ge_pio_copy(submit, &buf, sizeof(buf)); | 616 | myri10ge_pio_copy(submit, &buf, sizeof(buf)); |
606 | mb(); | 617 | mb(); |
@@ -764,6 +775,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) | |||
764 | mgp->rx_small.cnt = 0; | 775 | mgp->rx_small.cnt = 0; |
765 | mgp->rx_done.idx = 0; | 776 | mgp->rx_done.idx = 0; |
766 | mgp->rx_done.cnt = 0; | 777 | mgp->rx_done.cnt = 0; |
778 | mgp->link_changes = 0; | ||
767 | status = myri10ge_update_mac_address(mgp, mgp->dev->dev_addr); | 779 | status = myri10ge_update_mac_address(mgp, mgp->dev->dev_addr); |
768 | myri10ge_change_promisc(mgp, 0, 0); | 780 | myri10ge_change_promisc(mgp, 0, 0); |
769 | myri10ge_change_pause(mgp, mgp->pause); | 781 | myri10ge_change_pause(mgp, mgp->pause); |
@@ -798,12 +810,13 @@ myri10ge_submit_8rx(struct mcp_kreq_ether_recv __iomem * dst, | |||
798 | * pages directly and building a fraglist in the near future. | 810 | * pages directly and building a fraglist in the near future. |
799 | */ | 811 | */ |
800 | 812 | ||
801 | static inline struct sk_buff *myri10ge_alloc_big(int bytes) | 813 | static inline struct sk_buff *myri10ge_alloc_big(struct net_device *dev, |
814 | int bytes) | ||
802 | { | 815 | { |
803 | struct sk_buff *skb; | 816 | struct sk_buff *skb; |
804 | unsigned long data, roundup; | 817 | unsigned long data, roundup; |
805 | 818 | ||
806 | skb = dev_alloc_skb(bytes + 4096 + MXGEFW_PAD); | 819 | skb = netdev_alloc_skb(dev, bytes + 4096 + MXGEFW_PAD); |
807 | if (skb == NULL) | 820 | if (skb == NULL) |
808 | return NULL; | 821 | return NULL; |
809 | 822 | ||
@@ -821,12 +834,13 @@ static inline struct sk_buff *myri10ge_alloc_big(int bytes) | |||
821 | 834 | ||
822 | /* Allocate 2x as much space as required and use whichever portion | 835 | /* Allocate 2x as much space as required and use whichever portion |
823 | * does not cross a 4KB boundary */ | 836 | * does not cross a 4KB boundary */ |
824 | static inline struct sk_buff *myri10ge_alloc_small_safe(unsigned int bytes) | 837 | static inline struct sk_buff *myri10ge_alloc_small_safe(struct net_device *dev, |
838 | unsigned int bytes) | ||
825 | { | 839 | { |
826 | struct sk_buff *skb; | 840 | struct sk_buff *skb; |
827 | unsigned long data, boundary; | 841 | unsigned long data, boundary; |
828 | 842 | ||
829 | skb = dev_alloc_skb(2 * (bytes + MXGEFW_PAD) - 1); | 843 | skb = netdev_alloc_skb(dev, 2 * (bytes + MXGEFW_PAD) - 1); |
830 | if (unlikely(skb == NULL)) | 844 | if (unlikely(skb == NULL)) |
831 | return NULL; | 845 | return NULL; |
832 | 846 | ||
@@ -847,12 +861,13 @@ static inline struct sk_buff *myri10ge_alloc_small_safe(unsigned int bytes) | |||
847 | 861 | ||
848 | /* Allocate just enough space, and verify that the allocated | 862 | /* Allocate just enough space, and verify that the allocated |
849 | * space does not cross a 4KB boundary */ | 863 | * space does not cross a 4KB boundary */ |
850 | static inline struct sk_buff *myri10ge_alloc_small(int bytes) | 864 | static inline struct sk_buff *myri10ge_alloc_small(struct net_device *dev, |
865 | int bytes) | ||
851 | { | 866 | { |
852 | struct sk_buff *skb; | 867 | struct sk_buff *skb; |
853 | unsigned long roundup, data, end; | 868 | unsigned long roundup, data, end; |
854 | 869 | ||
855 | skb = dev_alloc_skb(bytes + 16 + MXGEFW_PAD); | 870 | skb = netdev_alloc_skb(dev, bytes + 16 + MXGEFW_PAD); |
856 | if (unlikely(skb == NULL)) | 871 | if (unlikely(skb == NULL)) |
857 | return NULL; | 872 | return NULL; |
858 | 873 | ||
@@ -868,15 +883,17 @@ static inline struct sk_buff *myri10ge_alloc_small(int bytes) | |||
868 | "myri10ge_alloc_small: small skb crossed 4KB boundary\n"); | 883 | "myri10ge_alloc_small: small skb crossed 4KB boundary\n"); |
869 | myri10ge_skb_cross_4k = 1; | 884 | myri10ge_skb_cross_4k = 1; |
870 | dev_kfree_skb_any(skb); | 885 | dev_kfree_skb_any(skb); |
871 | skb = myri10ge_alloc_small_safe(bytes); | 886 | skb = myri10ge_alloc_small_safe(dev, bytes); |
872 | } | 887 | } |
873 | return skb; | 888 | return skb; |
874 | } | 889 | } |
875 | 890 | ||
876 | static inline int | 891 | static inline int |
877 | myri10ge_getbuf(struct myri10ge_rx_buf *rx, struct pci_dev *pdev, int bytes, | 892 | myri10ge_getbuf(struct myri10ge_rx_buf *rx, struct myri10ge_priv *mgp, |
878 | int idx) | 893 | int bytes, int idx) |
879 | { | 894 | { |
895 | struct net_device *dev = mgp->dev; | ||
896 | struct pci_dev *pdev = mgp->pdev; | ||
880 | struct sk_buff *skb; | 897 | struct sk_buff *skb; |
881 | dma_addr_t bus; | 898 | dma_addr_t bus; |
882 | int len, retval = 0; | 899 | int len, retval = 0; |
@@ -884,11 +901,11 @@ myri10ge_getbuf(struct myri10ge_rx_buf *rx, struct pci_dev *pdev, int bytes, | |||
884 | bytes += VLAN_HLEN; /* account for 802.1q vlan tag */ | 901 | bytes += VLAN_HLEN; /* account for 802.1q vlan tag */ |
885 | 902 | ||
886 | if ((bytes + MXGEFW_PAD) > (4096 - 16) /* linux overhead */ ) | 903 | if ((bytes + MXGEFW_PAD) > (4096 - 16) /* linux overhead */ ) |
887 | skb = myri10ge_alloc_big(bytes); | 904 | skb = myri10ge_alloc_big(dev, bytes); |
888 | else if (myri10ge_skb_cross_4k) | 905 | else if (myri10ge_skb_cross_4k) |
889 | skb = myri10ge_alloc_small_safe(bytes); | 906 | skb = myri10ge_alloc_small_safe(dev, bytes); |
890 | else | 907 | else |
891 | skb = myri10ge_alloc_small(bytes); | 908 | skb = myri10ge_alloc_small(dev, bytes); |
892 | 909 | ||
893 | if (unlikely(skb == NULL)) { | 910 | if (unlikely(skb == NULL)) { |
894 | rx->alloc_fail++; | 911 | rx->alloc_fail++; |
@@ -951,7 +968,7 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, | |||
951 | unmap_len = pci_unmap_len(&rx->info[idx], len); | 968 | unmap_len = pci_unmap_len(&rx->info[idx], len); |
952 | 969 | ||
953 | /* try to replace the received skb */ | 970 | /* try to replace the received skb */ |
954 | if (myri10ge_getbuf(rx, mgp->pdev, bytes, idx)) { | 971 | if (myri10ge_getbuf(rx, mgp, bytes, idx)) { |
955 | /* drop the frame -- the old skbuf is re-cycled */ | 972 | /* drop the frame -- the old skbuf is re-cycled */ |
956 | mgp->stats.rx_dropped += 1; | 973 | mgp->stats.rx_dropped += 1; |
957 | return 0; | 974 | return 0; |
@@ -968,7 +985,6 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, | |||
968 | skb_put(skb, len); | 985 | skb_put(skb, len); |
969 | 986 | ||
970 | skb->protocol = eth_type_trans(skb, mgp->dev); | 987 | skb->protocol = eth_type_trans(skb, mgp->dev); |
971 | skb->dev = mgp->dev; | ||
972 | if (mgp->csum_flag) { | 988 | if (mgp->csum_flag) { |
973 | if ((skb->protocol == ntohs(ETH_P_IP)) || | 989 | if ((skb->protocol == ntohs(ETH_P_IP)) || |
974 | (skb->protocol == ntohs(ETH_P_IPV6))) { | 990 | (skb->protocol == ntohs(ETH_P_IPV6))) { |
@@ -1081,13 +1097,19 @@ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) | |||
1081 | if (mgp->link_state != stats->link_up) { | 1097 | if (mgp->link_state != stats->link_up) { |
1082 | mgp->link_state = stats->link_up; | 1098 | mgp->link_state = stats->link_up; |
1083 | if (mgp->link_state) { | 1099 | if (mgp->link_state) { |
1084 | printk(KERN_INFO "myri10ge: %s: link up\n", | 1100 | if (netif_msg_link(mgp)) |
1085 | mgp->dev->name); | 1101 | printk(KERN_INFO |
1102 | "myri10ge: %s: link up\n", | ||
1103 | mgp->dev->name); | ||
1086 | netif_carrier_on(mgp->dev); | 1104 | netif_carrier_on(mgp->dev); |
1105 | mgp->link_changes++; | ||
1087 | } else { | 1106 | } else { |
1088 | printk(KERN_INFO "myri10ge: %s: link down\n", | 1107 | if (netif_msg_link(mgp)) |
1089 | mgp->dev->name); | 1108 | printk(KERN_INFO |
1109 | "myri10ge: %s: link down\n", | ||
1110 | mgp->dev->name); | ||
1090 | netif_carrier_off(mgp->dev); | 1111 | netif_carrier_off(mgp->dev); |
1112 | mgp->link_changes++; | ||
1091 | } | 1113 | } |
1092 | } | 1114 | } |
1093 | if (mgp->rdma_tags_available != | 1115 | if (mgp->rdma_tags_available != |
@@ -1289,7 +1311,8 @@ static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = { | |||
1289 | "serial_number", "tx_pkt_start", "tx_pkt_done", | 1311 | "serial_number", "tx_pkt_start", "tx_pkt_done", |
1290 | "tx_req", "tx_done", "rx_small_cnt", "rx_big_cnt", | 1312 | "tx_req", "tx_done", "rx_small_cnt", "rx_big_cnt", |
1291 | "wake_queue", "stop_queue", "watchdog_resets", "tx_linearized", | 1313 | "wake_queue", "stop_queue", "watchdog_resets", "tx_linearized", |
1292 | "link_up", "dropped_link_overflow", "dropped_link_error_or_filtered", | 1314 | "link_changes", "link_up", "dropped_link_overflow", |
1315 | "dropped_link_error_or_filtered", "dropped_multicast_filtered", | ||
1293 | "dropped_runt", "dropped_overrun", "dropped_no_small_buffer", | 1316 | "dropped_runt", "dropped_overrun", "dropped_no_small_buffer", |
1294 | "dropped_no_big_buffer" | 1317 | "dropped_no_big_buffer" |
1295 | }; | 1318 | }; |
@@ -1341,17 +1364,32 @@ myri10ge_get_ethtool_stats(struct net_device *netdev, | |||
1341 | data[i++] = (unsigned int)mgp->stop_queue; | 1364 | data[i++] = (unsigned int)mgp->stop_queue; |
1342 | data[i++] = (unsigned int)mgp->watchdog_resets; | 1365 | data[i++] = (unsigned int)mgp->watchdog_resets; |
1343 | data[i++] = (unsigned int)mgp->tx_linearized; | 1366 | data[i++] = (unsigned int)mgp->tx_linearized; |
1367 | data[i++] = (unsigned int)mgp->link_changes; | ||
1344 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->link_up); | 1368 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->link_up); |
1345 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_link_overflow); | 1369 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_link_overflow); |
1346 | data[i++] = | 1370 | data[i++] = |
1347 | (unsigned int)ntohl(mgp->fw_stats->dropped_link_error_or_filtered); | 1371 | (unsigned int)ntohl(mgp->fw_stats->dropped_link_error_or_filtered); |
1372 | data[i++] = | ||
1373 | (unsigned int)ntohl(mgp->fw_stats->dropped_multicast_filtered); | ||
1348 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_runt); | 1374 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_runt); |
1349 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_overrun); | 1375 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_overrun); |
1350 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_small_buffer); | 1376 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_small_buffer); |
1351 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_big_buffer); | 1377 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_big_buffer); |
1352 | } | 1378 | } |
1353 | 1379 | ||
1354 | static struct ethtool_ops myri10ge_ethtool_ops = { | 1380 | static void myri10ge_set_msglevel(struct net_device *netdev, u32 value) |
1381 | { | ||
1382 | struct myri10ge_priv *mgp = netdev_priv(netdev); | ||
1383 | mgp->msg_enable = value; | ||
1384 | } | ||
1385 | |||
1386 | static u32 myri10ge_get_msglevel(struct net_device *netdev) | ||
1387 | { | ||
1388 | struct myri10ge_priv *mgp = netdev_priv(netdev); | ||
1389 | return mgp->msg_enable; | ||
1390 | } | ||
1391 | |||
1392 | static const struct ethtool_ops myri10ge_ethtool_ops = { | ||
1355 | .get_settings = myri10ge_get_settings, | 1393 | .get_settings = myri10ge_get_settings, |
1356 | .get_drvinfo = myri10ge_get_drvinfo, | 1394 | .get_drvinfo = myri10ge_get_drvinfo, |
1357 | .get_coalesce = myri10ge_get_coalesce, | 1395 | .get_coalesce = myri10ge_get_coalesce, |
@@ -1371,7 +1409,9 @@ static struct ethtool_ops myri10ge_ethtool_ops = { | |||
1371 | #endif | 1409 | #endif |
1372 | .get_strings = myri10ge_get_strings, | 1410 | .get_strings = myri10ge_get_strings, |
1373 | .get_stats_count = myri10ge_get_stats_count, | 1411 | .get_stats_count = myri10ge_get_stats_count, |
1374 | .get_ethtool_stats = myri10ge_get_ethtool_stats | 1412 | .get_ethtool_stats = myri10ge_get_ethtool_stats, |
1413 | .set_msglevel = myri10ge_set_msglevel, | ||
1414 | .get_msglevel = myri10ge_get_msglevel | ||
1375 | }; | 1415 | }; |
1376 | 1416 | ||
1377 | static int myri10ge_allocate_rings(struct net_device *dev) | 1417 | static int myri10ge_allocate_rings(struct net_device *dev) |
@@ -1439,7 +1479,7 @@ static int myri10ge_allocate_rings(struct net_device *dev) | |||
1439 | /* Fill the receive rings */ | 1479 | /* Fill the receive rings */ |
1440 | 1480 | ||
1441 | for (i = 0; i <= mgp->rx_small.mask; i++) { | 1481 | for (i = 0; i <= mgp->rx_small.mask; i++) { |
1442 | status = myri10ge_getbuf(&mgp->rx_small, mgp->pdev, | 1482 | status = myri10ge_getbuf(&mgp->rx_small, mgp, |
1443 | mgp->small_bytes, i); | 1483 | mgp->small_bytes, i); |
1444 | if (status) { | 1484 | if (status) { |
1445 | printk(KERN_ERR | 1485 | printk(KERN_ERR |
@@ -1451,8 +1491,7 @@ static int myri10ge_allocate_rings(struct net_device *dev) | |||
1451 | 1491 | ||
1452 | for (i = 0; i <= mgp->rx_big.mask; i++) { | 1492 | for (i = 0; i <= mgp->rx_big.mask; i++) { |
1453 | status = | 1493 | status = |
1454 | myri10ge_getbuf(&mgp->rx_big, mgp->pdev, | 1494 | myri10ge_getbuf(&mgp->rx_big, mgp, dev->mtu + ETH_HLEN, i); |
1455 | dev->mtu + ETH_HLEN, i); | ||
1456 | if (status) { | 1495 | if (status) { |
1457 | printk(KERN_ERR | 1496 | printk(KERN_ERR |
1458 | "myri10ge: %s: alloced only %d big bufs\n", | 1497 | "myri10ge: %s: alloced only %d big bufs\n", |
@@ -1648,9 +1687,11 @@ static int myri10ge_open(struct net_device *dev) | |||
1648 | } | 1687 | } |
1649 | 1688 | ||
1650 | if (mgp->mtrr >= 0) { | 1689 | if (mgp->mtrr >= 0) { |
1651 | mgp->tx.wc_fifo = (u8 __iomem *) mgp->sram + 0x200000; | 1690 | mgp->tx.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_SEND_4; |
1652 | mgp->rx_small.wc_fifo = (u8 __iomem *) mgp->sram + 0x300000; | 1691 | mgp->rx_small.wc_fifo = |
1653 | mgp->rx_big.wc_fifo = (u8 __iomem *) mgp->sram + 0x340000; | 1692 | (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_SMALL; |
1693 | mgp->rx_big.wc_fifo = | ||
1694 | (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_BIG; | ||
1654 | } else { | 1695 | } else { |
1655 | mgp->tx.wc_fifo = NULL; | 1696 | mgp->tx.wc_fifo = NULL; |
1656 | mgp->rx_small.wc_fifo = NULL; | 1697 | mgp->rx_small.wc_fifo = NULL; |
@@ -1686,7 +1727,21 @@ static int myri10ge_open(struct net_device *dev) | |||
1686 | 1727 | ||
1687 | cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->fw_stats_bus); | 1728 | cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->fw_stats_bus); |
1688 | cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->fw_stats_bus); | 1729 | cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->fw_stats_bus); |
1689 | status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_STATS_DMA, &cmd, 0); | 1730 | cmd.data2 = sizeof(struct mcp_irq_data); |
1731 | status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_STATS_DMA_V2, &cmd, 0); | ||
1732 | if (status == -ENOSYS) { | ||
1733 | dma_addr_t bus = mgp->fw_stats_bus; | ||
1734 | bus += offsetof(struct mcp_irq_data, send_done_count); | ||
1735 | cmd.data0 = MYRI10GE_LOWPART_TO_U32(bus); | ||
1736 | cmd.data1 = MYRI10GE_HIGHPART_TO_U32(bus); | ||
1737 | status = myri10ge_send_cmd(mgp, | ||
1738 | MXGEFW_CMD_SET_STATS_DMA_OBSOLETE, | ||
1739 | &cmd, 0); | ||
1740 | /* Firmware cannot support multicast without STATS_DMA_V2 */ | ||
1741 | mgp->fw_multicast_support = 0; | ||
1742 | } else { | ||
1743 | mgp->fw_multicast_support = 1; | ||
1744 | } | ||
1690 | if (status) { | 1745 | if (status) { |
1691 | printk(KERN_ERR "myri10ge: %s: Couldn't set stats DMA\n", | 1746 | printk(KERN_ERR "myri10ge: %s: Couldn't set stats DMA\n", |
1692 | dev->name); | 1747 | dev->name); |
@@ -1841,7 +1896,8 @@ myri10ge_submit_req_wc(struct myri10ge_tx_buf *tx, | |||
1841 | if (cnt > 0) { | 1896 | if (cnt > 0) { |
1842 | /* pad it to 64 bytes. The src is 64 bytes bigger than it | 1897 | /* pad it to 64 bytes. The src is 64 bytes bigger than it |
1843 | * needs to be so that we don't overrun it */ | 1898 | * needs to be so that we don't overrun it */ |
1844 | myri10ge_pio_copy(tx->wc_fifo + (cnt << 18), src, 64); | 1899 | myri10ge_pio_copy(tx->wc_fifo + MXGEFW_ETH_SEND_OFFSET(cnt), |
1900 | src, 64); | ||
1845 | mb(); | 1901 | mb(); |
1846 | } | 1902 | } |
1847 | } | 1903 | } |
@@ -2140,9 +2196,81 @@ static struct net_device_stats *myri10ge_get_stats(struct net_device *dev) | |||
2140 | 2196 | ||
2141 | static void myri10ge_set_multicast_list(struct net_device *dev) | 2197 | static void myri10ge_set_multicast_list(struct net_device *dev) |
2142 | { | 2198 | { |
2199 | struct myri10ge_cmd cmd; | ||
2200 | struct myri10ge_priv *mgp; | ||
2201 | struct dev_mc_list *mc_list; | ||
2202 | int err; | ||
2203 | |||
2204 | mgp = netdev_priv(dev); | ||
2143 | /* can be called from atomic contexts, | 2205 | /* can be called from atomic contexts, |
2144 | * pass 1 to force atomicity in myri10ge_send_cmd() */ | 2206 | * pass 1 to force atomicity in myri10ge_send_cmd() */ |
2145 | myri10ge_change_promisc(netdev_priv(dev), dev->flags & IFF_PROMISC, 1); | 2207 | myri10ge_change_promisc(mgp, dev->flags & IFF_PROMISC, 1); |
2208 | |||
2209 | /* This firmware is known to not support multicast */ | ||
2210 | if (!mgp->fw_multicast_support) | ||
2211 | return; | ||
2212 | |||
2213 | /* Disable multicast filtering */ | ||
2214 | |||
2215 | err = myri10ge_send_cmd(mgp, MXGEFW_ENABLE_ALLMULTI, &cmd, 1); | ||
2216 | if (err != 0) { | ||
2217 | printk(KERN_ERR "myri10ge: %s: Failed MXGEFW_ENABLE_ALLMULTI," | ||
2218 | " error status: %d\n", dev->name, err); | ||
2219 | goto abort; | ||
2220 | } | ||
2221 | |||
2222 | if (dev->flags & IFF_ALLMULTI) { | ||
2223 | /* request to disable multicast filtering, so quit here */ | ||
2224 | return; | ||
2225 | } | ||
2226 | |||
2227 | /* Flush the filters */ | ||
2228 | |||
2229 | err = myri10ge_send_cmd(mgp, MXGEFW_LEAVE_ALL_MULTICAST_GROUPS, | ||
2230 | &cmd, 1); | ||
2231 | if (err != 0) { | ||
2232 | printk(KERN_ERR | ||
2233 | "myri10ge: %s: Failed MXGEFW_LEAVE_ALL_MULTICAST_GROUPS" | ||
2234 | ", error status: %d\n", dev->name, err); | ||
2235 | goto abort; | ||
2236 | } | ||
2237 | |||
2238 | /* Walk the multicast list, and add each address */ | ||
2239 | for (mc_list = dev->mc_list; mc_list != NULL; mc_list = mc_list->next) { | ||
2240 | memcpy(&cmd.data0, &mc_list->dmi_addr, 4); | ||
2241 | memcpy(&cmd.data1, ((char *)&mc_list->dmi_addr) + 4, 2); | ||
2242 | cmd.data0 = htonl(cmd.data0); | ||
2243 | cmd.data1 = htonl(cmd.data1); | ||
2244 | err = myri10ge_send_cmd(mgp, MXGEFW_JOIN_MULTICAST_GROUP, | ||
2245 | &cmd, 1); | ||
2246 | |||
2247 | if (err != 0) { | ||
2248 | printk(KERN_ERR "myri10ge: %s: Failed " | ||
2249 | "MXGEFW_JOIN_MULTICAST_GROUP, error status:" | ||
2250 | "%d\t", dev->name, err); | ||
2251 | printk(KERN_ERR "MAC %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
2252 | ((unsigned char *)&mc_list->dmi_addr)[0], | ||
2253 | ((unsigned char *)&mc_list->dmi_addr)[1], | ||
2254 | ((unsigned char *)&mc_list->dmi_addr)[2], | ||
2255 | ((unsigned char *)&mc_list->dmi_addr)[3], | ||
2256 | ((unsigned char *)&mc_list->dmi_addr)[4], | ||
2257 | ((unsigned char *)&mc_list->dmi_addr)[5] | ||
2258 | ); | ||
2259 | goto abort; | ||
2260 | } | ||
2261 | } | ||
2262 | /* Enable multicast filtering */ | ||
2263 | err = myri10ge_send_cmd(mgp, MXGEFW_DISABLE_ALLMULTI, &cmd, 1); | ||
2264 | if (err != 0) { | ||
2265 | printk(KERN_ERR "myri10ge: %s: Failed MXGEFW_DISABLE_ALLMULTI," | ||
2266 | "error status: %d\n", dev->name, err); | ||
2267 | goto abort; | ||
2268 | } | ||
2269 | |||
2270 | return; | ||
2271 | |||
2272 | abort: | ||
2273 | return; | ||
2146 | } | 2274 | } |
2147 | 2275 | ||
2148 | static int myri10ge_set_mac_address(struct net_device *dev, void *addr) | 2276 | static int myri10ge_set_mac_address(struct net_device *dev, void *addr) |
@@ -2289,6 +2417,8 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) | |||
2289 | */ | 2417 | */ |
2290 | 2418 | ||
2291 | #define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE 0x0132 | 2419 | #define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE 0x0132 |
2420 | #define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7 | ||
2421 | #define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa | ||
2292 | 2422 | ||
2293 | static void myri10ge_select_firmware(struct myri10ge_priv *mgp) | 2423 | static void myri10ge_select_firmware(struct myri10ge_priv *mgp) |
2294 | { | 2424 | { |
@@ -2298,15 +2428,34 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) | |||
2298 | mgp->fw_name = myri10ge_fw_unaligned; | 2428 | mgp->fw_name = myri10ge_fw_unaligned; |
2299 | 2429 | ||
2300 | if (myri10ge_force_firmware == 0) { | 2430 | if (myri10ge_force_firmware == 0) { |
2431 | int link_width, exp_cap; | ||
2432 | u16 lnk; | ||
2433 | |||
2434 | exp_cap = pci_find_capability(mgp->pdev, PCI_CAP_ID_EXP); | ||
2435 | pci_read_config_word(mgp->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk); | ||
2436 | link_width = (lnk >> 4) & 0x3f; | ||
2437 | |||
2301 | myri10ge_enable_ecrc(mgp); | 2438 | myri10ge_enable_ecrc(mgp); |
2302 | 2439 | ||
2303 | /* Check to see if the upstream bridge is known to | 2440 | /* Check to see if Link is less than 8 or if the |
2304 | * provide aligned completions */ | 2441 | * upstream bridge is known to provide aligned |
2305 | if (bridge | 2442 | * completions */ |
2306 | /* ServerWorks HT2000/HT1000 */ | 2443 | if (link_width < 8) { |
2307 | && bridge->vendor == PCI_VENDOR_ID_SERVERWORKS | 2444 | dev_info(&mgp->pdev->dev, "PCIE x%d Link\n", |
2308 | && bridge->device == | 2445 | link_width); |
2309 | PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE) { | 2446 | mgp->tx.boundary = 4096; |
2447 | mgp->fw_name = myri10ge_fw_aligned; | ||
2448 | } else if (bridge && | ||
2449 | /* ServerWorks HT2000/HT1000 */ | ||
2450 | ((bridge->vendor == PCI_VENDOR_ID_SERVERWORKS | ||
2451 | && bridge->device == | ||
2452 | PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE) | ||
2453 | /* All Intel E5000 PCIE ports */ | ||
2454 | || (bridge->vendor == PCI_VENDOR_ID_INTEL | ||
2455 | && bridge->device >= | ||
2456 | PCI_DEVICE_ID_INTEL_E5000_PCIE23 | ||
2457 | && bridge->device <= | ||
2458 | PCI_DEVICE_ID_INTEL_E5000_PCIE47))) { | ||
2310 | dev_info(&mgp->pdev->dev, | 2459 | dev_info(&mgp->pdev->dev, |
2311 | "Assuming aligned completions (0x%x:0x%x)\n", | 2460 | "Assuming aligned completions (0x%x:0x%x)\n", |
2312 | bridge->vendor, bridge->device); | 2461 | bridge->vendor, bridge->device); |
@@ -2581,6 +2730,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2581 | mgp->csum_flag = MXGEFW_FLAGS_CKSUM; | 2730 | mgp->csum_flag = MXGEFW_FLAGS_CKSUM; |
2582 | mgp->pause = myri10ge_flow_control; | 2731 | mgp->pause = myri10ge_flow_control; |
2583 | mgp->intr_coal_delay = myri10ge_intr_coal_delay; | 2732 | mgp->intr_coal_delay = myri10ge_intr_coal_delay; |
2733 | mgp->msg_enable = netif_msg_init(myri10ge_debug, MYRI10GE_MSG_DEFAULT); | ||
2584 | init_waitqueue_head(&mgp->down_wq); | 2734 | init_waitqueue_head(&mgp->down_wq); |
2585 | 2735 | ||
2586 | if (pci_enable_device(pdev)) { | 2736 | if (pci_enable_device(pdev)) { |
diff --git a/drivers/net/myri10ge/myri10ge_mcp.h b/drivers/net/myri10ge/myri10ge_mcp.h index 0a6cae6cb186..9519ae7cd5ec 100644 --- a/drivers/net/myri10ge/myri10ge_mcp.h +++ b/drivers/net/myri10ge/myri10ge_mcp.h | |||
@@ -91,7 +91,19 @@ struct mcp_kreq_ether_recv { | |||
91 | 91 | ||
92 | /* Commands */ | 92 | /* Commands */ |
93 | 93 | ||
94 | #define MXGEFW_CMD_OFFSET 0xf80000 | 94 | #define MXGEFW_BOOT_HANDOFF 0xfc0000 |
95 | #define MXGEFW_BOOT_DUMMY_RDMA 0xfc01c0 | ||
96 | |||
97 | #define MXGEFW_ETH_CMD 0xf80000 | ||
98 | #define MXGEFW_ETH_SEND_4 0x200000 | ||
99 | #define MXGEFW_ETH_SEND_1 0x240000 | ||
100 | #define MXGEFW_ETH_SEND_2 0x280000 | ||
101 | #define MXGEFW_ETH_SEND_3 0x2c0000 | ||
102 | #define MXGEFW_ETH_RECV_SMALL 0x300000 | ||
103 | #define MXGEFW_ETH_RECV_BIG 0x340000 | ||
104 | |||
105 | #define MXGEFW_ETH_SEND(n) (0x200000 + (((n) & 0x03) * 0x40000)) | ||
106 | #define MXGEFW_ETH_SEND_OFFSET(n) (MXGEFW_ETH_SEND(n) - MXGEFW_ETH_SEND_4) | ||
95 | 107 | ||
96 | enum myri10ge_mcp_cmd_type { | 108 | enum myri10ge_mcp_cmd_type { |
97 | MXGEFW_CMD_NONE = 0, | 109 | MXGEFW_CMD_NONE = 0, |
@@ -154,7 +166,7 @@ enum myri10ge_mcp_cmd_type { | |||
154 | MXGEFW_CMD_SET_MTU, | 166 | MXGEFW_CMD_SET_MTU, |
155 | MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, /* in microseconds */ | 167 | MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, /* in microseconds */ |
156 | MXGEFW_CMD_SET_STATS_INTERVAL, /* in microseconds */ | 168 | MXGEFW_CMD_SET_STATS_INTERVAL, /* in microseconds */ |
157 | MXGEFW_CMD_SET_STATS_DMA, | 169 | MXGEFW_CMD_SET_STATS_DMA_OBSOLETE, /* replaced by SET_STATS_DMA_V2 */ |
158 | 170 | ||
159 | MXGEFW_ENABLE_PROMISC, | 171 | MXGEFW_ENABLE_PROMISC, |
160 | MXGEFW_DISABLE_PROMISC, | 172 | MXGEFW_DISABLE_PROMISC, |
@@ -168,7 +180,26 @@ enum myri10ge_mcp_cmd_type { | |||
168 | * data2 = RDMA length (MSH), WDMA length (LSH) | 180 | * data2 = RDMA length (MSH), WDMA length (LSH) |
169 | * command return data = repetitions (MSH), 0.5-ms ticks (LSH) | 181 | * command return data = repetitions (MSH), 0.5-ms ticks (LSH) |
170 | */ | 182 | */ |
171 | MXGEFW_DMA_TEST | 183 | MXGEFW_DMA_TEST, |
184 | |||
185 | MXGEFW_ENABLE_ALLMULTI, | ||
186 | MXGEFW_DISABLE_ALLMULTI, | ||
187 | |||
188 | /* returns MXGEFW_CMD_ERROR_MULTICAST | ||
189 | * if there is no room in the cache | ||
190 | * data0,MSH(data1) = multicast group address */ | ||
191 | MXGEFW_JOIN_MULTICAST_GROUP, | ||
192 | /* returns MXGEFW_CMD_ERROR_MULTICAST | ||
193 | * if the address is not in the cache, | ||
194 | * or is equal to FF-FF-FF-FF-FF-FF | ||
195 | * data0,MSH(data1) = multicast group address */ | ||
196 | MXGEFW_LEAVE_MULTICAST_GROUP, | ||
197 | MXGEFW_LEAVE_ALL_MULTICAST_GROUPS, | ||
198 | |||
199 | MXGEFW_CMD_SET_STATS_DMA_V2, | ||
200 | /* data0, data1 = bus addr, | ||
201 | * data2 = sizeof(struct mcp_irq_data) from driver point of view, allows | ||
202 | * adding new stuff to mcp_irq_data without changing the ABI */ | ||
172 | }; | 203 | }; |
173 | 204 | ||
174 | enum myri10ge_mcp_cmd_status { | 205 | enum myri10ge_mcp_cmd_status { |
@@ -180,11 +211,17 @@ enum myri10ge_mcp_cmd_status { | |||
180 | MXGEFW_CMD_ERROR_CLOSED, | 211 | MXGEFW_CMD_ERROR_CLOSED, |
181 | MXGEFW_CMD_ERROR_HASH_ERROR, | 212 | MXGEFW_CMD_ERROR_HASH_ERROR, |
182 | MXGEFW_CMD_ERROR_BAD_PORT, | 213 | MXGEFW_CMD_ERROR_BAD_PORT, |
183 | MXGEFW_CMD_ERROR_RESOURCES | 214 | MXGEFW_CMD_ERROR_RESOURCES, |
215 | MXGEFW_CMD_ERROR_MULTICAST | ||
184 | }; | 216 | }; |
185 | 217 | ||
186 | /* 40 Bytes */ | 218 | #define MXGEFW_OLD_IRQ_DATA_LEN 40 |
219 | |||
187 | struct mcp_irq_data { | 220 | struct mcp_irq_data { |
221 | /* add new counters at the beginning */ | ||
222 | u32 future_use[5]; | ||
223 | u32 dropped_multicast_filtered; | ||
224 | /* 40 Bytes */ | ||
188 | u32 send_done_count; | 225 | u32 send_done_count; |
189 | 226 | ||
190 | u32 link_up; | 227 | u32 link_up; |