diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2009-10-27 19:46:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-28 06:25:34 -0400 |
commit | 317f66bdadc31f0c037b91ae7857f5c3d2a4e3e5 (patch) | |
tree | 00819b07f6498a087814bf9d8877ae49f002f2bf /drivers | |
parent | c5b9bd5e4f7caea10d113f610b85cc2093cc3179 (diff) |
igb: misc cleanups within igb_ethtool.c
This patch just goes thorugh and does several cleanups on igb_ethtool.c.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/igb/igb_ethtool.c | 105 |
1 files changed, 60 insertions, 45 deletions
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index 84fe25ad1b7c..d24b902ba7de 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c | |||
@@ -101,24 +101,25 @@ static const struct igb_stats igb_gstrings_stats[] = { | |||
101 | }; | 101 | }; |
102 | 102 | ||
103 | #define IGB_QUEUE_STATS_LEN \ | 103 | #define IGB_QUEUE_STATS_LEN \ |
104 | (((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues)* \ | 104 | ((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues * \ |
105 | (sizeof(struct igb_rx_queue_stats) / sizeof(u64))) + \ | 105 | (sizeof(struct igb_rx_queue_stats) / sizeof(u64))) + \ |
106 | ((((struct igb_adapter *)netdev_priv(netdev))->num_tx_queues) * \ | 106 | (((struct igb_adapter *)netdev_priv(netdev))->num_tx_queues * \ |
107 | (sizeof(struct igb_tx_queue_stats) / sizeof(u64)))) | 107 | (sizeof(struct igb_tx_queue_stats) / sizeof(u64)))) |
108 | #define IGB_GLOBAL_STATS_LEN \ | 108 | #define IGB_GLOBAL_STATS_LEN \ |
109 | sizeof(igb_gstrings_stats) / sizeof(struct igb_stats) | 109 | (sizeof(igb_gstrings_stats) / sizeof(struct igb_stats)) |
110 | #define IGB_STATS_LEN (IGB_GLOBAL_STATS_LEN + IGB_QUEUE_STATS_LEN) | 110 | #define IGB_STATS_LEN (IGB_GLOBAL_STATS_LEN + IGB_QUEUE_STATS_LEN) |
111 | static const char igb_gstrings_test[][ETH_GSTRING_LEN] = { | 111 | static const char igb_gstrings_test[][ETH_GSTRING_LEN] = { |
112 | "Register test (offline)", "Eeprom test (offline)", | 112 | "Register test (offline)", "Eeprom test (offline)", |
113 | "Interrupt test (offline)", "Loopback test (offline)", | 113 | "Interrupt test (offline)", "Loopback test (offline)", |
114 | "Link test (on/offline)" | 114 | "Link test (on/offline)" |
115 | }; | 115 | }; |
116 | #define IGB_TEST_LEN sizeof(igb_gstrings_test) / ETH_GSTRING_LEN | 116 | #define IGB_TEST_LEN (sizeof(igb_gstrings_test) / ETH_GSTRING_LEN) |
117 | 117 | ||
118 | static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | 118 | static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) |
119 | { | 119 | { |
120 | struct igb_adapter *adapter = netdev_priv(netdev); | 120 | struct igb_adapter *adapter = netdev_priv(netdev); |
121 | struct e1000_hw *hw = &adapter->hw; | 121 | struct e1000_hw *hw = &adapter->hw; |
122 | u32 status; | ||
122 | 123 | ||
123 | if (hw->phy.media_type == e1000_media_type_copper) { | 124 | if (hw->phy.media_type == e1000_media_type_copper) { |
124 | 125 | ||
@@ -153,17 +154,20 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
153 | 154 | ||
154 | ecmd->transceiver = XCVR_INTERNAL; | 155 | ecmd->transceiver = XCVR_INTERNAL; |
155 | 156 | ||
156 | if (rd32(E1000_STATUS) & E1000_STATUS_LU) { | 157 | status = rd32(E1000_STATUS); |
157 | 158 | ||
158 | adapter->hw.mac.ops.get_speed_and_duplex(hw, | 159 | if (status & E1000_STATUS_LU) { |
159 | &adapter->link_speed, | ||
160 | &adapter->link_duplex); | ||
161 | ecmd->speed = adapter->link_speed; | ||
162 | 160 | ||
163 | /* unfortunately FULL_DUPLEX != DUPLEX_FULL | 161 | if ((status & E1000_STATUS_SPEED_1000) || |
164 | * and HALF_DUPLEX != DUPLEX_HALF */ | 162 | hw->phy.media_type != e1000_media_type_copper) |
163 | ecmd->speed = SPEED_1000; | ||
164 | else if (status & E1000_STATUS_SPEED_100) | ||
165 | ecmd->speed = SPEED_100; | ||
166 | else | ||
167 | ecmd->speed = SPEED_10; | ||
165 | 168 | ||
166 | if (adapter->link_duplex == FULL_DUPLEX) | 169 | if ((status & E1000_STATUS_FD) || |
170 | hw->phy.media_type != e1000_media_type_copper) | ||
167 | ecmd->duplex = DUPLEX_FULL; | 171 | ecmd->duplex = DUPLEX_FULL; |
168 | else | 172 | else |
169 | ecmd->duplex = DUPLEX_HALF; | 173 | ecmd->duplex = DUPLEX_HALF; |
@@ -254,8 +258,9 @@ static int igb_set_pauseparam(struct net_device *netdev, | |||
254 | if (netif_running(adapter->netdev)) { | 258 | if (netif_running(adapter->netdev)) { |
255 | igb_down(adapter); | 259 | igb_down(adapter); |
256 | igb_up(adapter); | 260 | igb_up(adapter); |
257 | } else | 261 | } else { |
258 | igb_reset(adapter); | 262 | igb_reset(adapter); |
263 | } | ||
259 | } else { | 264 | } else { |
260 | if (pause->rx_pause && pause->tx_pause) | 265 | if (pause->rx_pause && pause->tx_pause) |
261 | hw->fc.requested_mode = e1000_fc_full; | 266 | hw->fc.requested_mode = e1000_fc_full; |
@@ -308,7 +313,7 @@ static int igb_set_tx_csum(struct net_device *netdev, u32 data) | |||
308 | 313 | ||
309 | if (data) { | 314 | if (data) { |
310 | netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); | 315 | netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); |
311 | if (adapter->hw.mac.type == e1000_82576) | 316 | if (adapter->hw.mac.type >= e1000_82576) |
312 | netdev->features |= NETIF_F_SCTP_CSUM; | 317 | netdev->features |= NETIF_F_SCTP_CSUM; |
313 | } else { | 318 | } else { |
314 | netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 319 | netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
@@ -735,12 +740,12 @@ static int igb_set_ringparam(struct net_device *netdev, | |||
735 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) | 740 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) |
736 | return -EINVAL; | 741 | return -EINVAL; |
737 | 742 | ||
738 | new_rx_count = max(ring->rx_pending, (u32)IGB_MIN_RXD); | 743 | new_rx_count = min(ring->rx_pending, (u32)IGB_MAX_RXD); |
739 | new_rx_count = min(new_rx_count, (u32)IGB_MAX_RXD); | 744 | new_rx_count = max(new_rx_count, (u16)IGB_MIN_RXD); |
740 | new_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE); | 745 | new_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE); |
741 | 746 | ||
742 | new_tx_count = max(ring->tx_pending, (u32)IGB_MIN_TXD); | 747 | new_tx_count = min(ring->tx_pending, (u32)IGB_MAX_TXD); |
743 | new_tx_count = min(new_tx_count, (u32)IGB_MAX_TXD); | 748 | new_tx_count = max(new_tx_count, (u16)IGB_MIN_TXD); |
744 | new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE); | 749 | new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE); |
745 | 750 | ||
746 | if ((new_tx_count == adapter->tx_ring_count) && | 751 | if ((new_tx_count == adapter->tx_ring_count) && |
@@ -941,7 +946,7 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data, | |||
941 | { | 946 | { |
942 | struct e1000_hw *hw = &adapter->hw; | 947 | struct e1000_hw *hw = &adapter->hw; |
943 | u32 pat, val; | 948 | u32 pat, val; |
944 | u32 _test[] = | 949 | static const u32 _test[] = |
945 | {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; | 950 | {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; |
946 | for (pat = 0; pat < ARRAY_SIZE(_test); pat++) { | 951 | for (pat = 0; pat < ARRAY_SIZE(_test); pat++) { |
947 | wr32(reg, (_test[pat] & write)); | 952 | wr32(reg, (_test[pat] & write)); |
@@ -954,6 +959,7 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data, | |||
954 | return 1; | 959 | return 1; |
955 | } | 960 | } |
956 | } | 961 | } |
962 | |||
957 | return 0; | 963 | return 0; |
958 | } | 964 | } |
959 | 965 | ||
@@ -971,6 +977,7 @@ static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data, | |||
971 | *data = reg; | 977 | *data = reg; |
972 | return 1; | 978 | return 1; |
973 | } | 979 | } |
980 | |||
974 | return 0; | 981 | return 0; |
975 | } | 982 | } |
976 | 983 | ||
@@ -993,14 +1000,14 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data) | |||
993 | u32 value, before, after; | 1000 | u32 value, before, after; |
994 | u32 i, toggle; | 1001 | u32 i, toggle; |
995 | 1002 | ||
996 | toggle = 0x7FFFF3FF; | ||
997 | |||
998 | switch (adapter->hw.mac.type) { | 1003 | switch (adapter->hw.mac.type) { |
999 | case e1000_82576: | 1004 | case e1000_82576: |
1000 | test = reg_test_82576; | 1005 | test = reg_test_82576; |
1006 | toggle = 0x7FFFF3FF; | ||
1001 | break; | 1007 | break; |
1002 | default: | 1008 | default: |
1003 | test = reg_test_82575; | 1009 | test = reg_test_82575; |
1010 | toggle = 0x7FFFF3FF; | ||
1004 | break; | 1011 | break; |
1005 | } | 1012 | } |
1006 | 1013 | ||
@@ -1078,8 +1085,7 @@ static int igb_eeprom_test(struct igb_adapter *adapter, u64 *data) | |||
1078 | *data = 0; | 1085 | *data = 0; |
1079 | /* Read and add up the contents of the EEPROM */ | 1086 | /* Read and add up the contents of the EEPROM */ |
1080 | for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { | 1087 | for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { |
1081 | if ((adapter->hw.nvm.ops.read(&adapter->hw, i, 1, &temp)) | 1088 | if ((adapter->hw.nvm.ops.read(&adapter->hw, i, 1, &temp)) < 0) { |
1082 | < 0) { | ||
1083 | *data = 1; | 1089 | *data = 1; |
1084 | break; | 1090 | break; |
1085 | } | 1091 | } |
@@ -1095,8 +1101,7 @@ static int igb_eeprom_test(struct igb_adapter *adapter, u64 *data) | |||
1095 | 1101 | ||
1096 | static irqreturn_t igb_test_intr(int irq, void *data) | 1102 | static irqreturn_t igb_test_intr(int irq, void *data) |
1097 | { | 1103 | { |
1098 | struct net_device *netdev = (struct net_device *) data; | 1104 | struct igb_adapter *adapter = (struct igb_adapter *) data; |
1099 | struct igb_adapter *adapter = netdev_priv(netdev); | ||
1100 | struct e1000_hw *hw = &adapter->hw; | 1105 | struct e1000_hw *hw = &adapter->hw; |
1101 | 1106 | ||
1102 | adapter->test_icr |= rd32(E1000_ICR); | 1107 | adapter->test_icr |= rd32(E1000_ICR); |
@@ -1120,7 +1125,6 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) | |||
1120 | *data = 1; | 1125 | *data = 1; |
1121 | return -1; | 1126 | return -1; |
1122 | } | 1127 | } |
1123 | |||
1124 | } else if (adapter->flags & IGB_FLAG_HAS_MSI) { | 1128 | } else if (adapter->flags & IGB_FLAG_HAS_MSI) { |
1125 | shared_int = false; | 1129 | shared_int = false; |
1126 | if (request_irq(irq, | 1130 | if (request_irq(irq, |
@@ -1138,6 +1142,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) | |||
1138 | } | 1142 | } |
1139 | dev_info(&adapter->pdev->dev, "testing %s interrupt\n", | 1143 | dev_info(&adapter->pdev->dev, "testing %s interrupt\n", |
1140 | (shared_int ? "shared" : "unshared")); | 1144 | (shared_int ? "shared" : "unshared")); |
1145 | |||
1141 | /* Disable all the interrupts */ | 1146 | /* Disable all the interrupts */ |
1142 | wr32(E1000_IMC, ~0); | 1147 | wr32(E1000_IMC, ~0); |
1143 | msleep(10); | 1148 | msleep(10); |
@@ -1363,7 +1368,10 @@ static int igb_setup_loopback_test(struct igb_adapter *adapter) | |||
1363 | struct e1000_hw *hw = &adapter->hw; | 1368 | struct e1000_hw *hw = &adapter->hw; |
1364 | u32 reg; | 1369 | u32 reg; |
1365 | 1370 | ||
1366 | if (hw->phy.media_type == e1000_media_type_internal_serdes) { | 1371 | reg = rd32(E1000_CTRL_EXT); |
1372 | |||
1373 | /* use CTRL_EXT to identify link type as SGMII can appear as copper */ | ||
1374 | if (reg & E1000_CTRL_EXT_LINK_MODE_MASK) { | ||
1367 | reg = rd32(E1000_RCTL); | 1375 | reg = rd32(E1000_RCTL); |
1368 | reg |= E1000_RCTL_LBM_TCVR; | 1376 | reg |= E1000_RCTL_LBM_TCVR; |
1369 | wr32(E1000_RCTL, reg); | 1377 | wr32(E1000_RCTL, reg); |
@@ -1394,11 +1402,9 @@ static int igb_setup_loopback_test(struct igb_adapter *adapter) | |||
1394 | wr32(E1000_PCS_LCTL, reg); | 1402 | wr32(E1000_PCS_LCTL, reg); |
1395 | 1403 | ||
1396 | return 0; | 1404 | return 0; |
1397 | } else if (hw->phy.media_type == e1000_media_type_copper) { | ||
1398 | return igb_set_phy_loopback(adapter); | ||
1399 | } | 1405 | } |
1400 | 1406 | ||
1401 | return 7; | 1407 | return igb_set_phy_loopback(adapter); |
1402 | } | 1408 | } |
1403 | 1409 | ||
1404 | static void igb_loopback_cleanup(struct igb_adapter *adapter) | 1410 | static void igb_loopback_cleanup(struct igb_adapter *adapter) |
@@ -1424,19 +1430,21 @@ static void igb_create_lbtest_frame(struct sk_buff *skb, | |||
1424 | unsigned int frame_size) | 1430 | unsigned int frame_size) |
1425 | { | 1431 | { |
1426 | memset(skb->data, 0xFF, frame_size); | 1432 | memset(skb->data, 0xFF, frame_size); |
1427 | frame_size &= ~1; | 1433 | frame_size /= 2; |
1428 | memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1); | 1434 | memset(&skb->data[frame_size], 0xAA, frame_size - 1); |
1429 | memset(&skb->data[frame_size / 2 + 10], 0xBE, 1); | 1435 | memset(&skb->data[frame_size + 10], 0xBE, 1); |
1430 | memset(&skb->data[frame_size / 2 + 12], 0xAF, 1); | 1436 | memset(&skb->data[frame_size + 12], 0xAF, 1); |
1431 | } | 1437 | } |
1432 | 1438 | ||
1433 | static int igb_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size) | 1439 | static int igb_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size) |
1434 | { | 1440 | { |
1435 | frame_size &= ~1; | 1441 | frame_size /= 2; |
1436 | if (*(skb->data + 3) == 0xFF) | 1442 | if (*(skb->data + 3) == 0xFF) { |
1437 | if ((*(skb->data + frame_size / 2 + 10) == 0xBE) && | 1443 | if ((*(skb->data + frame_size + 10) == 0xBE) && |
1438 | (*(skb->data + frame_size / 2 + 12) == 0xAF)) | 1444 | (*(skb->data + frame_size + 12) == 0xAF)) { |
1439 | return 0; | 1445 | return 0; |
1446 | } | ||
1447 | } | ||
1440 | return 13; | 1448 | return 13; |
1441 | } | 1449 | } |
1442 | 1450 | ||
@@ -1513,7 +1521,8 @@ static int igb_run_loopback_test(struct igb_adapter *adapter) | |||
1513 | igb_create_lbtest_frame(skb, size); | 1521 | igb_create_lbtest_frame(skb, size); |
1514 | skb_put(skb, size); | 1522 | skb_put(skb, size); |
1515 | 1523 | ||
1516 | /* Calculate the loop count based on the largest descriptor ring | 1524 | /* |
1525 | * Calculate the loop count based on the largest descriptor ring | ||
1517 | * The idea is to wrap the largest ring a number of times using 64 | 1526 | * The idea is to wrap the largest ring a number of times using 64 |
1518 | * send/receive pairs during each loop | 1527 | * send/receive pairs during each loop |
1519 | */ | 1528 | */ |
@@ -1605,8 +1614,7 @@ static int igb_link_test(struct igb_adapter *adapter, u64 *data) | |||
1605 | if (hw->mac.autoneg) | 1614 | if (hw->mac.autoneg) |
1606 | msleep(4000); | 1615 | msleep(4000); |
1607 | 1616 | ||
1608 | if (!(rd32(E1000_STATUS) & | 1617 | if (!(rd32(E1000_STATUS) & E1000_STATUS_LU)) |
1609 | E1000_STATUS_LU)) | ||
1610 | *data = 1; | 1618 | *data = 1; |
1611 | } | 1619 | } |
1612 | return *data; | 1620 | return *data; |
@@ -1788,7 +1796,6 @@ static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
1788 | adapter->wol |= E1000_WUFC_BC; | 1796 | adapter->wol |= E1000_WUFC_BC; |
1789 | if (wol->wolopts & WAKE_MAGIC) | 1797 | if (wol->wolopts & WAKE_MAGIC) |
1790 | adapter->wol |= E1000_WUFC_MAG; | 1798 | adapter->wol |= E1000_WUFC_MAG; |
1791 | |||
1792 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); | 1799 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); |
1793 | 1800 | ||
1794 | return 0; | 1801 | return 0; |
@@ -1801,12 +1808,19 @@ static int igb_phys_id(struct net_device *netdev, u32 data) | |||
1801 | { | 1808 | { |
1802 | struct igb_adapter *adapter = netdev_priv(netdev); | 1809 | struct igb_adapter *adapter = netdev_priv(netdev); |
1803 | struct e1000_hw *hw = &adapter->hw; | 1810 | struct e1000_hw *hw = &adapter->hw; |
1811 | unsigned long timeout; | ||
1804 | 1812 | ||
1805 | if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) | 1813 | timeout = data * 1000; |
1806 | data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ); | 1814 | |
1815 | /* | ||
1816 | * msleep_interruptable only accepts unsigned int so we are limited | ||
1817 | * in how long a duration we can wait | ||
1818 | */ | ||
1819 | if (!timeout || timeout > UINT_MAX) | ||
1820 | timeout = UINT_MAX; | ||
1807 | 1821 | ||
1808 | igb_blink_led(hw); | 1822 | igb_blink_led(hw); |
1809 | msleep_interruptible(data * 1000); | 1823 | msleep_interruptible(timeout); |
1810 | 1824 | ||
1811 | igb_led_off(hw); | 1825 | igb_led_off(hw); |
1812 | clear_bit(IGB_LED_ON, &adapter->led_status); | 1826 | clear_bit(IGB_LED_ON, &adapter->led_status); |
@@ -1916,6 +1930,7 @@ static void igb_get_ethtool_stats(struct net_device *netdev, | |||
1916 | char *p = NULL; | 1930 | char *p = NULL; |
1917 | 1931 | ||
1918 | igb_update_stats(adapter); | 1932 | igb_update_stats(adapter); |
1933 | |||
1919 | for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) { | 1934 | for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) { |
1920 | switch (igb_gstrings_stats[i].type) { | 1935 | switch (igb_gstrings_stats[i].type) { |
1921 | case NETDEV_STATS: | 1936 | case NETDEV_STATS: |