diff options
Diffstat (limited to 'drivers/net/e1000e/ethtool.c')
-rw-r--r-- | drivers/net/e1000e/ethtool.c | 438 |
1 files changed, 225 insertions, 213 deletions
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 6355a1b779d3..859d0d3af6c9 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel PRO/1000 Linux driver | 3 | Intel PRO/1000 Linux driver |
4 | Copyright(c) 1999 - 2010 Intel Corporation. | 4 | Copyright(c) 1999 - 2011 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
@@ -45,63 +45,67 @@ struct e1000_stats { | |||
45 | int stat_offset; | 45 | int stat_offset; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | #define E1000_STAT(m) E1000_STATS, \ | 48 | #define E1000_STAT(str, m) { \ |
49 | sizeof(((struct e1000_adapter *)0)->m), \ | 49 | .stat_string = str, \ |
50 | offsetof(struct e1000_adapter, m) | 50 | .type = E1000_STATS, \ |
51 | #define E1000_NETDEV_STAT(m) NETDEV_STATS, \ | 51 | .sizeof_stat = sizeof(((struct e1000_adapter *)0)->m), \ |
52 | sizeof(((struct net_device *)0)->m), \ | 52 | .stat_offset = offsetof(struct e1000_adapter, m) } |
53 | offsetof(struct net_device, m) | 53 | #define E1000_NETDEV_STAT(str, m) { \ |
54 | .stat_string = str, \ | ||
55 | .type = NETDEV_STATS, \ | ||
56 | .sizeof_stat = sizeof(((struct rtnl_link_stats64 *)0)->m), \ | ||
57 | .stat_offset = offsetof(struct rtnl_link_stats64, m) } | ||
54 | 58 | ||
55 | static const struct e1000_stats e1000_gstrings_stats[] = { | 59 | static const struct e1000_stats e1000_gstrings_stats[] = { |
56 | { "rx_packets", E1000_STAT(stats.gprc) }, | 60 | E1000_STAT("rx_packets", stats.gprc), |
57 | { "tx_packets", E1000_STAT(stats.gptc) }, | 61 | E1000_STAT("tx_packets", stats.gptc), |
58 | { "rx_bytes", E1000_STAT(stats.gorc) }, | 62 | E1000_STAT("rx_bytes", stats.gorc), |
59 | { "tx_bytes", E1000_STAT(stats.gotc) }, | 63 | E1000_STAT("tx_bytes", stats.gotc), |
60 | { "rx_broadcast", E1000_STAT(stats.bprc) }, | 64 | E1000_STAT("rx_broadcast", stats.bprc), |
61 | { "tx_broadcast", E1000_STAT(stats.bptc) }, | 65 | E1000_STAT("tx_broadcast", stats.bptc), |
62 | { "rx_multicast", E1000_STAT(stats.mprc) }, | 66 | E1000_STAT("rx_multicast", stats.mprc), |
63 | { "tx_multicast", E1000_STAT(stats.mptc) }, | 67 | E1000_STAT("tx_multicast", stats.mptc), |
64 | { "rx_errors", E1000_NETDEV_STAT(stats.rx_errors) }, | 68 | E1000_NETDEV_STAT("rx_errors", rx_errors), |
65 | { "tx_errors", E1000_NETDEV_STAT(stats.tx_errors) }, | 69 | E1000_NETDEV_STAT("tx_errors", tx_errors), |
66 | { "tx_dropped", E1000_NETDEV_STAT(stats.tx_dropped) }, | 70 | E1000_NETDEV_STAT("tx_dropped", tx_dropped), |
67 | { "multicast", E1000_STAT(stats.mprc) }, | 71 | E1000_STAT("multicast", stats.mprc), |
68 | { "collisions", E1000_STAT(stats.colc) }, | 72 | E1000_STAT("collisions", stats.colc), |
69 | { "rx_length_errors", E1000_NETDEV_STAT(stats.rx_length_errors) }, | 73 | E1000_NETDEV_STAT("rx_length_errors", rx_length_errors), |
70 | { "rx_over_errors", E1000_NETDEV_STAT(stats.rx_over_errors) }, | 74 | E1000_NETDEV_STAT("rx_over_errors", rx_over_errors), |
71 | { "rx_crc_errors", E1000_STAT(stats.crcerrs) }, | 75 | E1000_STAT("rx_crc_errors", stats.crcerrs), |
72 | { "rx_frame_errors", E1000_NETDEV_STAT(stats.rx_frame_errors) }, | 76 | E1000_NETDEV_STAT("rx_frame_errors", rx_frame_errors), |
73 | { "rx_no_buffer_count", E1000_STAT(stats.rnbc) }, | 77 | E1000_STAT("rx_no_buffer_count", stats.rnbc), |
74 | { "rx_missed_errors", E1000_STAT(stats.mpc) }, | 78 | E1000_STAT("rx_missed_errors", stats.mpc), |
75 | { "tx_aborted_errors", E1000_STAT(stats.ecol) }, | 79 | E1000_STAT("tx_aborted_errors", stats.ecol), |
76 | { "tx_carrier_errors", E1000_STAT(stats.tncrs) }, | 80 | E1000_STAT("tx_carrier_errors", stats.tncrs), |
77 | { "tx_fifo_errors", E1000_NETDEV_STAT(stats.tx_fifo_errors) }, | 81 | E1000_NETDEV_STAT("tx_fifo_errors", tx_fifo_errors), |
78 | { "tx_heartbeat_errors", E1000_NETDEV_STAT(stats.tx_heartbeat_errors) }, | 82 | E1000_NETDEV_STAT("tx_heartbeat_errors", tx_heartbeat_errors), |
79 | { "tx_window_errors", E1000_STAT(stats.latecol) }, | 83 | E1000_STAT("tx_window_errors", stats.latecol), |
80 | { "tx_abort_late_coll", E1000_STAT(stats.latecol) }, | 84 | E1000_STAT("tx_abort_late_coll", stats.latecol), |
81 | { "tx_deferred_ok", E1000_STAT(stats.dc) }, | 85 | E1000_STAT("tx_deferred_ok", stats.dc), |
82 | { "tx_single_coll_ok", E1000_STAT(stats.scc) }, | 86 | E1000_STAT("tx_single_coll_ok", stats.scc), |
83 | { "tx_multi_coll_ok", E1000_STAT(stats.mcc) }, | 87 | E1000_STAT("tx_multi_coll_ok", stats.mcc), |
84 | { "tx_timeout_count", E1000_STAT(tx_timeout_count) }, | 88 | E1000_STAT("tx_timeout_count", tx_timeout_count), |
85 | { "tx_restart_queue", E1000_STAT(restart_queue) }, | 89 | E1000_STAT("tx_restart_queue", restart_queue), |
86 | { "rx_long_length_errors", E1000_STAT(stats.roc) }, | 90 | E1000_STAT("rx_long_length_errors", stats.roc), |
87 | { "rx_short_length_errors", E1000_STAT(stats.ruc) }, | 91 | E1000_STAT("rx_short_length_errors", stats.ruc), |
88 | { "rx_align_errors", E1000_STAT(stats.algnerrc) }, | 92 | E1000_STAT("rx_align_errors", stats.algnerrc), |
89 | { "tx_tcp_seg_good", E1000_STAT(stats.tsctc) }, | 93 | E1000_STAT("tx_tcp_seg_good", stats.tsctc), |
90 | { "tx_tcp_seg_failed", E1000_STAT(stats.tsctfc) }, | 94 | E1000_STAT("tx_tcp_seg_failed", stats.tsctfc), |
91 | { "rx_flow_control_xon", E1000_STAT(stats.xonrxc) }, | 95 | E1000_STAT("rx_flow_control_xon", stats.xonrxc), |
92 | { "rx_flow_control_xoff", E1000_STAT(stats.xoffrxc) }, | 96 | E1000_STAT("rx_flow_control_xoff", stats.xoffrxc), |
93 | { "tx_flow_control_xon", E1000_STAT(stats.xontxc) }, | 97 | E1000_STAT("tx_flow_control_xon", stats.xontxc), |
94 | { "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) }, | 98 | E1000_STAT("tx_flow_control_xoff", stats.xofftxc), |
95 | { "rx_long_byte_count", E1000_STAT(stats.gorc) }, | 99 | E1000_STAT("rx_long_byte_count", stats.gorc), |
96 | { "rx_csum_offload_good", E1000_STAT(hw_csum_good) }, | 100 | E1000_STAT("rx_csum_offload_good", hw_csum_good), |
97 | { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) }, | 101 | E1000_STAT("rx_csum_offload_errors", hw_csum_err), |
98 | { "rx_header_split", E1000_STAT(rx_hdr_split) }, | 102 | E1000_STAT("rx_header_split", rx_hdr_split), |
99 | { "alloc_rx_buff_failed", E1000_STAT(alloc_rx_buff_failed) }, | 103 | E1000_STAT("alloc_rx_buff_failed", alloc_rx_buff_failed), |
100 | { "tx_smbus", E1000_STAT(stats.mgptc) }, | 104 | E1000_STAT("tx_smbus", stats.mgptc), |
101 | { "rx_smbus", E1000_STAT(stats.mgprc) }, | 105 | E1000_STAT("rx_smbus", stats.mgprc), |
102 | { "dropped_smbus", E1000_STAT(stats.mgpdc) }, | 106 | E1000_STAT("dropped_smbus", stats.mgpdc), |
103 | { "rx_dma_failed", E1000_STAT(rx_dma_failed) }, | 107 | E1000_STAT("rx_dma_failed", rx_dma_failed), |
104 | { "tx_dma_failed", E1000_STAT(tx_dma_failed) }, | 108 | E1000_STAT("tx_dma_failed", tx_dma_failed), |
105 | }; | 109 | }; |
106 | 110 | ||
107 | #define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats) | 111 | #define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats) |
@@ -118,6 +122,7 @@ static int e1000_get_settings(struct net_device *netdev, | |||
118 | { | 122 | { |
119 | struct e1000_adapter *adapter = netdev_priv(netdev); | 123 | struct e1000_adapter *adapter = netdev_priv(netdev); |
120 | struct e1000_hw *hw = &adapter->hw; | 124 | struct e1000_hw *hw = &adapter->hw; |
125 | u32 speed; | ||
121 | 126 | ||
122 | if (hw->phy.media_type == e1000_media_type_copper) { | 127 | if (hw->phy.media_type == e1000_media_type_copper) { |
123 | 128 | ||
@@ -155,23 +160,23 @@ static int e1000_get_settings(struct net_device *netdev, | |||
155 | ecmd->transceiver = XCVR_EXTERNAL; | 160 | ecmd->transceiver = XCVR_EXTERNAL; |
156 | } | 161 | } |
157 | 162 | ||
158 | ecmd->speed = -1; | 163 | speed = -1; |
159 | ecmd->duplex = -1; | 164 | ecmd->duplex = -1; |
160 | 165 | ||
161 | if (netif_running(netdev)) { | 166 | if (netif_running(netdev)) { |
162 | if (netif_carrier_ok(netdev)) { | 167 | if (netif_carrier_ok(netdev)) { |
163 | ecmd->speed = adapter->link_speed; | 168 | speed = adapter->link_speed; |
164 | ecmd->duplex = adapter->link_duplex - 1; | 169 | ecmd->duplex = adapter->link_duplex - 1; |
165 | } | 170 | } |
166 | } else { | 171 | } else { |
167 | u32 status = er32(STATUS); | 172 | u32 status = er32(STATUS); |
168 | if (status & E1000_STATUS_LU) { | 173 | if (status & E1000_STATUS_LU) { |
169 | if (status & E1000_STATUS_SPEED_1000) | 174 | if (status & E1000_STATUS_SPEED_1000) |
170 | ecmd->speed = 1000; | 175 | speed = SPEED_1000; |
171 | else if (status & E1000_STATUS_SPEED_100) | 176 | else if (status & E1000_STATUS_SPEED_100) |
172 | ecmd->speed = 100; | 177 | speed = SPEED_100; |
173 | else | 178 | else |
174 | ecmd->speed = 10; | 179 | speed = SPEED_10; |
175 | 180 | ||
176 | if (status & E1000_STATUS_FD) | 181 | if (status & E1000_STATUS_FD) |
177 | ecmd->duplex = DUPLEX_FULL; | 182 | ecmd->duplex = DUPLEX_FULL; |
@@ -180,6 +185,7 @@ static int e1000_get_settings(struct net_device *netdev, | |||
180 | } | 185 | } |
181 | } | 186 | } |
182 | 187 | ||
188 | ethtool_cmd_speed_set(ecmd, speed); | ||
183 | ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) || | 189 | ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) || |
184 | hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE; | 190 | hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE; |
185 | 191 | ||
@@ -194,34 +200,25 @@ static int e1000_get_settings(struct net_device *netdev, | |||
194 | return 0; | 200 | return 0; |
195 | } | 201 | } |
196 | 202 | ||
197 | static u32 e1000_get_link(struct net_device *netdev) | 203 | static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx) |
198 | { | ||
199 | struct e1000_adapter *adapter = netdev_priv(netdev); | ||
200 | struct e1000_hw *hw = &adapter->hw; | ||
201 | |||
202 | /* | ||
203 | * Avoid touching hardware registers when possible, otherwise | ||
204 | * link negotiation can get messed up when user-level scripts | ||
205 | * are rapidly polling the driver to see if link is up. | ||
206 | */ | ||
207 | return netif_running(netdev) ? netif_carrier_ok(netdev) : | ||
208 | !!(er32(STATUS) & E1000_STATUS_LU); | ||
209 | } | ||
210 | |||
211 | static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx) | ||
212 | { | 204 | { |
213 | struct e1000_mac_info *mac = &adapter->hw.mac; | 205 | struct e1000_mac_info *mac = &adapter->hw.mac; |
214 | 206 | ||
215 | mac->autoneg = 0; | 207 | mac->autoneg = 0; |
216 | 208 | ||
209 | /* Make sure dplx is at most 1 bit and lsb of speed is not set | ||
210 | * for the switch() below to work */ | ||
211 | if ((spd & 1) || (dplx & ~1)) | ||
212 | goto err_inval; | ||
213 | |||
217 | /* Fiber NICs only allow 1000 gbps Full duplex */ | 214 | /* Fiber NICs only allow 1000 gbps Full duplex */ |
218 | if ((adapter->hw.phy.media_type == e1000_media_type_fiber) && | 215 | if ((adapter->hw.phy.media_type == e1000_media_type_fiber) && |
219 | spddplx != (SPEED_1000 + DUPLEX_FULL)) { | 216 | spd != SPEED_1000 && |
220 | e_err("Unsupported Speed/Duplex configuration\n"); | 217 | dplx != DUPLEX_FULL) { |
221 | return -EINVAL; | 218 | goto err_inval; |
222 | } | 219 | } |
223 | 220 | ||
224 | switch (spddplx) { | 221 | switch (spd + dplx) { |
225 | case SPEED_10 + DUPLEX_HALF: | 222 | case SPEED_10 + DUPLEX_HALF: |
226 | mac->forced_speed_duplex = ADVERTISE_10_HALF; | 223 | mac->forced_speed_duplex = ADVERTISE_10_HALF; |
227 | break; | 224 | break; |
@@ -240,10 +237,13 @@ static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx) | |||
240 | break; | 237 | break; |
241 | case SPEED_1000 + DUPLEX_HALF: /* not supported */ | 238 | case SPEED_1000 + DUPLEX_HALF: /* not supported */ |
242 | default: | 239 | default: |
243 | e_err("Unsupported Speed/Duplex configuration\n"); | 240 | goto err_inval; |
244 | return -EINVAL; | ||
245 | } | 241 | } |
246 | return 0; | 242 | return 0; |
243 | |||
244 | err_inval: | ||
245 | e_err("Unsupported Speed/Duplex configuration\n"); | ||
246 | return -EINVAL; | ||
247 | } | 247 | } |
248 | 248 | ||
249 | static int e1000_set_settings(struct net_device *netdev, | 249 | static int e1000_set_settings(struct net_device *netdev, |
@@ -263,7 +263,7 @@ static int e1000_set_settings(struct net_device *netdev, | |||
263 | } | 263 | } |
264 | 264 | ||
265 | while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) | 265 | while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) |
266 | msleep(1); | 266 | usleep_range(1000, 2000); |
267 | 267 | ||
268 | if (ecmd->autoneg == AUTONEG_ENABLE) { | 268 | if (ecmd->autoneg == AUTONEG_ENABLE) { |
269 | hw->mac.autoneg = 1; | 269 | hw->mac.autoneg = 1; |
@@ -279,7 +279,8 @@ static int e1000_set_settings(struct net_device *netdev, | |||
279 | if (adapter->fc_autoneg) | 279 | if (adapter->fc_autoneg) |
280 | hw->fc.requested_mode = e1000_fc_default; | 280 | hw->fc.requested_mode = e1000_fc_default; |
281 | } else { | 281 | } else { |
282 | if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) { | 282 | u32 speed = ethtool_cmd_speed(ecmd); |
283 | if (e1000_set_spd_dplx(adapter, speed, ecmd->duplex)) { | ||
283 | clear_bit(__E1000_RESETTING, &adapter->state); | 284 | clear_bit(__E1000_RESETTING, &adapter->state); |
284 | return -EINVAL; | 285 | return -EINVAL; |
285 | } | 286 | } |
@@ -327,7 +328,7 @@ static int e1000_set_pauseparam(struct net_device *netdev, | |||
327 | adapter->fc_autoneg = pause->autoneg; | 328 | adapter->fc_autoneg = pause->autoneg; |
328 | 329 | ||
329 | while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) | 330 | while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) |
330 | msleep(1); | 331 | usleep_range(1000, 2000); |
331 | 332 | ||
332 | if (adapter->fc_autoneg == AUTONEG_ENABLE) { | 333 | if (adapter->fc_autoneg == AUTONEG_ENABLE) { |
333 | hw->fc.requested_mode = e1000_fc_default; | 334 | hw->fc.requested_mode = e1000_fc_default; |
@@ -368,7 +369,7 @@ out: | |||
368 | static u32 e1000_get_rx_csum(struct net_device *netdev) | 369 | static u32 e1000_get_rx_csum(struct net_device *netdev) |
369 | { | 370 | { |
370 | struct e1000_adapter *adapter = netdev_priv(netdev); | 371 | struct e1000_adapter *adapter = netdev_priv(netdev); |
371 | return (adapter->flags & FLAG_RX_CSUM_ENABLED); | 372 | return adapter->flags & FLAG_RX_CSUM_ENABLED; |
372 | } | 373 | } |
373 | 374 | ||
374 | static int e1000_set_rx_csum(struct net_device *netdev, u32 data) | 375 | static int e1000_set_rx_csum(struct net_device *netdev, u32 data) |
@@ -389,7 +390,7 @@ static int e1000_set_rx_csum(struct net_device *netdev, u32 data) | |||
389 | 390 | ||
390 | static u32 e1000_get_tx_csum(struct net_device *netdev) | 391 | static u32 e1000_get_tx_csum(struct net_device *netdev) |
391 | { | 392 | { |
392 | return ((netdev->features & NETIF_F_HW_CSUM) != 0); | 393 | return (netdev->features & NETIF_F_HW_CSUM) != 0; |
393 | } | 394 | } |
394 | 395 | ||
395 | static int e1000_set_tx_csum(struct net_device *netdev, u32 data) | 396 | static int e1000_set_tx_csum(struct net_device *netdev, u32 data) |
@@ -443,13 +444,11 @@ static void e1000_get_regs(struct net_device *netdev, | |||
443 | struct e1000_hw *hw = &adapter->hw; | 444 | struct e1000_hw *hw = &adapter->hw; |
444 | u32 *regs_buff = p; | 445 | u32 *regs_buff = p; |
445 | u16 phy_data; | 446 | u16 phy_data; |
446 | u8 revision_id; | ||
447 | 447 | ||
448 | memset(p, 0, E1000_REGS_LEN * sizeof(u32)); | 448 | memset(p, 0, E1000_REGS_LEN * sizeof(u32)); |
449 | 449 | ||
450 | pci_read_config_byte(adapter->pdev, PCI_REVISION_ID, &revision_id); | 450 | regs->version = (1 << 24) | (adapter->pdev->revision << 16) | |
451 | 451 | adapter->pdev->device; | |
452 | regs->version = (1 << 24) | (revision_id << 16) | adapter->pdev->device; | ||
453 | 452 | ||
454 | regs_buff[0] = er32(CTRL); | 453 | regs_buff[0] = er32(CTRL); |
455 | regs_buff[1] = er32(STATUS); | 454 | regs_buff[1] = er32(STATUS); |
@@ -634,20 +633,24 @@ static void e1000_get_drvinfo(struct net_device *netdev, | |||
634 | struct e1000_adapter *adapter = netdev_priv(netdev); | 633 | struct e1000_adapter *adapter = netdev_priv(netdev); |
635 | char firmware_version[32]; | 634 | char firmware_version[32]; |
636 | 635 | ||
637 | strncpy(drvinfo->driver, e1000e_driver_name, 32); | 636 | strncpy(drvinfo->driver, e1000e_driver_name, |
638 | strncpy(drvinfo->version, e1000e_driver_version, 32); | 637 | sizeof(drvinfo->driver) - 1); |
638 | strncpy(drvinfo->version, e1000e_driver_version, | ||
639 | sizeof(drvinfo->version) - 1); | ||
639 | 640 | ||
640 | /* | 641 | /* |
641 | * EEPROM image version # is reported as firmware version # for | 642 | * EEPROM image version # is reported as firmware version # for |
642 | * PCI-E controllers | 643 | * PCI-E controllers |
643 | */ | 644 | */ |
644 | sprintf(firmware_version, "%d.%d-%d", | 645 | snprintf(firmware_version, sizeof(firmware_version), "%d.%d-%d", |
645 | (adapter->eeprom_vers & 0xF000) >> 12, | 646 | (adapter->eeprom_vers & 0xF000) >> 12, |
646 | (adapter->eeprom_vers & 0x0FF0) >> 4, | 647 | (adapter->eeprom_vers & 0x0FF0) >> 4, |
647 | (adapter->eeprom_vers & 0x000F)); | 648 | (adapter->eeprom_vers & 0x000F)); |
648 | 649 | ||
649 | strncpy(drvinfo->fw_version, firmware_version, 32); | 650 | strncpy(drvinfo->fw_version, firmware_version, |
650 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); | 651 | sizeof(drvinfo->fw_version) - 1); |
652 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), | ||
653 | sizeof(drvinfo->bus_info) - 1); | ||
651 | drvinfo->regdump_len = e1000_get_regs_len(netdev); | 654 | drvinfo->regdump_len = e1000_get_regs_len(netdev); |
652 | drvinfo->eedump_len = e1000_get_eeprom_len(netdev); | 655 | drvinfo->eedump_len = e1000_get_eeprom_len(netdev); |
653 | } | 656 | } |
@@ -681,7 +684,7 @@ static int e1000_set_ringparam(struct net_device *netdev, | |||
681 | return -EINVAL; | 684 | return -EINVAL; |
682 | 685 | ||
683 | while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) | 686 | while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) |
684 | msleep(1); | 687 | usleep_range(1000, 2000); |
685 | 688 | ||
686 | if (netif_running(adapter->netdev)) | 689 | if (netif_running(adapter->netdev)) |
687 | e1000e_down(adapter); | 690 | e1000e_down(adapter); |
@@ -690,20 +693,13 @@ static int e1000_set_ringparam(struct net_device *netdev, | |||
690 | rx_old = adapter->rx_ring; | 693 | rx_old = adapter->rx_ring; |
691 | 694 | ||
692 | err = -ENOMEM; | 695 | err = -ENOMEM; |
693 | tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); | 696 | tx_ring = kmemdup(tx_old, sizeof(struct e1000_ring), GFP_KERNEL); |
694 | if (!tx_ring) | 697 | if (!tx_ring) |
695 | goto err_alloc_tx; | 698 | goto err_alloc_tx; |
696 | /* | ||
697 | * use a memcpy to save any previously configured | ||
698 | * items like napi structs from having to be | ||
699 | * reinitialized | ||
700 | */ | ||
701 | memcpy(tx_ring, tx_old, sizeof(struct e1000_ring)); | ||
702 | 699 | ||
703 | rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); | 700 | rx_ring = kmemdup(rx_old, sizeof(struct e1000_ring), GFP_KERNEL); |
704 | if (!rx_ring) | 701 | if (!rx_ring) |
705 | goto err_alloc_rx; | 702 | goto err_alloc_rx; |
706 | memcpy(rx_ring, rx_old, sizeof(struct e1000_ring)); | ||
707 | 703 | ||
708 | adapter->tx_ring = tx_ring; | 704 | adapter->tx_ring = tx_ring; |
709 | adapter->rx_ring = rx_ring; | 705 | adapter->rx_ring = rx_ring; |
@@ -763,8 +759,8 @@ static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data, | |||
763 | int reg, int offset, u32 mask, u32 write) | 759 | int reg, int offset, u32 mask, u32 write) |
764 | { | 760 | { |
765 | u32 pat, val; | 761 | u32 pat, val; |
766 | static const u32 test[] = | 762 | static const u32 test[] = { |
767 | {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; | 763 | 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; |
768 | for (pat = 0; pat < ARRAY_SIZE(test); pat++) { | 764 | for (pat = 0; pat < ARRAY_SIZE(test); pat++) { |
769 | E1000_WRITE_REG_ARRAY(&adapter->hw, reg, offset, | 765 | E1000_WRITE_REG_ARRAY(&adapter->hw, reg, offset, |
770 | (test[pat] & write)); | 766 | (test[pat] & write)); |
@@ -967,7 +963,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) | |||
967 | 963 | ||
968 | /* Disable all the interrupts */ | 964 | /* Disable all the interrupts */ |
969 | ew32(IMC, 0xFFFFFFFF); | 965 | ew32(IMC, 0xFFFFFFFF); |
970 | msleep(10); | 966 | usleep_range(10000, 20000); |
971 | 967 | ||
972 | /* Test each interrupt */ | 968 | /* Test each interrupt */ |
973 | for (i = 0; i < 10; i++) { | 969 | for (i = 0; i < 10; i++) { |
@@ -999,7 +995,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) | |||
999 | adapter->test_icr = 0; | 995 | adapter->test_icr = 0; |
1000 | ew32(IMC, mask); | 996 | ew32(IMC, mask); |
1001 | ew32(ICS, mask); | 997 | ew32(ICS, mask); |
1002 | msleep(10); | 998 | usleep_range(10000, 20000); |
1003 | 999 | ||
1004 | if (adapter->test_icr & mask) { | 1000 | if (adapter->test_icr & mask) { |
1005 | *data = 3; | 1001 | *data = 3; |
@@ -1017,7 +1013,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) | |||
1017 | adapter->test_icr = 0; | 1013 | adapter->test_icr = 0; |
1018 | ew32(IMS, mask); | 1014 | ew32(IMS, mask); |
1019 | ew32(ICS, mask); | 1015 | ew32(ICS, mask); |
1020 | msleep(10); | 1016 | usleep_range(10000, 20000); |
1021 | 1017 | ||
1022 | if (!(adapter->test_icr & mask)) { | 1018 | if (!(adapter->test_icr & mask)) { |
1023 | *data = 4; | 1019 | *data = 4; |
@@ -1035,7 +1031,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) | |||
1035 | adapter->test_icr = 0; | 1031 | adapter->test_icr = 0; |
1036 | ew32(IMC, ~mask & 0x00007FFF); | 1032 | ew32(IMC, ~mask & 0x00007FFF); |
1037 | ew32(ICS, ~mask & 0x00007FFF); | 1033 | ew32(ICS, ~mask & 0x00007FFF); |
1038 | msleep(10); | 1034 | usleep_range(10000, 20000); |
1039 | 1035 | ||
1040 | if (adapter->test_icr) { | 1036 | if (adapter->test_icr) { |
1041 | *data = 5; | 1037 | *data = 5; |
@@ -1046,7 +1042,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) | |||
1046 | 1042 | ||
1047 | /* Disable all the interrupts */ | 1043 | /* Disable all the interrupts */ |
1048 | ew32(IMC, 0xFFFFFFFF); | 1044 | ew32(IMC, 0xFFFFFFFF); |
1049 | msleep(10); | 1045 | usleep_range(10000, 20000); |
1050 | 1046 | ||
1051 | /* Unhook test interrupt handler */ | 1047 | /* Unhook test interrupt handler */ |
1052 | free_irq(irq, netdev); | 1048 | free_irq(irq, netdev); |
@@ -1261,8 +1257,8 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) | |||
1261 | { | 1257 | { |
1262 | struct e1000_hw *hw = &adapter->hw; | 1258 | struct e1000_hw *hw = &adapter->hw; |
1263 | u32 ctrl_reg = 0; | 1259 | u32 ctrl_reg = 0; |
1264 | u32 stat_reg = 0; | ||
1265 | u16 phy_reg = 0; | 1260 | u16 phy_reg = 0; |
1261 | s32 ret_val = 0; | ||
1266 | 1262 | ||
1267 | hw->mac.autoneg = 0; | 1263 | hw->mac.autoneg = 0; |
1268 | 1264 | ||
@@ -1322,7 +1318,13 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) | |||
1322 | case e1000_phy_82577: | 1318 | case e1000_phy_82577: |
1323 | case e1000_phy_82578: | 1319 | case e1000_phy_82578: |
1324 | /* Workaround: K1 must be disabled for stable 1Gbps operation */ | 1320 | /* Workaround: K1 must be disabled for stable 1Gbps operation */ |
1321 | ret_val = hw->phy.ops.acquire(hw); | ||
1322 | if (ret_val) { | ||
1323 | e_err("Cannot setup 1Gbps loopback.\n"); | ||
1324 | return ret_val; | ||
1325 | } | ||
1325 | e1000_configure_k1_ich8lan(hw, false); | 1326 | e1000_configure_k1_ich8lan(hw, false); |
1327 | hw->phy.ops.release(hw); | ||
1326 | break; | 1328 | break; |
1327 | case e1000_phy_82579: | 1329 | case e1000_phy_82579: |
1328 | /* Disable PHY energy detect power down */ | 1330 | /* Disable PHY energy detect power down */ |
@@ -1362,8 +1364,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) | |||
1362 | * Set the ILOS bit on the fiber Nic if half duplex link is | 1364 | * Set the ILOS bit on the fiber Nic if half duplex link is |
1363 | * detected. | 1365 | * detected. |
1364 | */ | 1366 | */ |
1365 | stat_reg = er32(STATUS); | 1367 | if ((er32(STATUS) & E1000_STATUS_FD) == 0) |
1366 | if ((stat_reg & E1000_STATUS_FD) == 0) | ||
1367 | ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU); | 1368 | ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU); |
1368 | } | 1369 | } |
1369 | 1370 | ||
@@ -1416,7 +1417,7 @@ static int e1000_set_82571_fiber_loopback(struct e1000_adapter *adapter) | |||
1416 | */ | 1417 | */ |
1417 | #define E1000_SERDES_LB_ON 0x410 | 1418 | #define E1000_SERDES_LB_ON 0x410 |
1418 | ew32(SCTL, E1000_SERDES_LB_ON); | 1419 | ew32(SCTL, E1000_SERDES_LB_ON); |
1419 | msleep(10); | 1420 | usleep_range(10000, 20000); |
1420 | 1421 | ||
1421 | return 0; | 1422 | return 0; |
1422 | } | 1423 | } |
@@ -1511,7 +1512,7 @@ static void e1000_loopback_cleanup(struct e1000_adapter *adapter) | |||
1511 | hw->phy.media_type == e1000_media_type_internal_serdes) { | 1512 | hw->phy.media_type == e1000_media_type_internal_serdes) { |
1512 | #define E1000_SERDES_LB_OFF 0x400 | 1513 | #define E1000_SERDES_LB_OFF 0x400 |
1513 | ew32(SCTL, E1000_SERDES_LB_OFF); | 1514 | ew32(SCTL, E1000_SERDES_LB_OFF); |
1514 | msleep(10); | 1515 | usleep_range(10000, 20000); |
1515 | break; | 1516 | break; |
1516 | } | 1517 | } |
1517 | /* Fall Through */ | 1518 | /* Fall Through */ |
@@ -1676,10 +1677,13 @@ static int e1000_link_test(struct e1000_adapter *adapter, u64 *data) | |||
1676 | } else { | 1677 | } else { |
1677 | hw->mac.ops.check_for_link(hw); | 1678 | hw->mac.ops.check_for_link(hw); |
1678 | if (hw->mac.autoneg) | 1679 | if (hw->mac.autoneg) |
1679 | msleep(4000); | 1680 | /* |
1681 | * On some Phy/switch combinations, link establishment | ||
1682 | * can take a few seconds more than expected. | ||
1683 | */ | ||
1684 | msleep(5000); | ||
1680 | 1685 | ||
1681 | if (!(er32(STATUS) & | 1686 | if (!(er32(STATUS) & E1000_STATUS_LU)) |
1682 | E1000_STATUS_LU)) | ||
1683 | *data = 1; | 1687 | *data = 1; |
1684 | } | 1688 | } |
1685 | return *data; | 1689 | return *data; |
@@ -1707,6 +1711,19 @@ static void e1000_diag_test(struct net_device *netdev, | |||
1707 | bool if_running = netif_running(netdev); | 1711 | bool if_running = netif_running(netdev); |
1708 | 1712 | ||
1709 | set_bit(__E1000_TESTING, &adapter->state); | 1713 | set_bit(__E1000_TESTING, &adapter->state); |
1714 | |||
1715 | if (!if_running) { | ||
1716 | /* Get control of and reset hardware */ | ||
1717 | if (adapter->flags & FLAG_HAS_AMT) | ||
1718 | e1000e_get_hw_control(adapter); | ||
1719 | |||
1720 | e1000e_power_up_phy(adapter); | ||
1721 | |||
1722 | adapter->hw.phy.autoneg_wait_to_complete = 1; | ||
1723 | e1000e_reset(adapter); | ||
1724 | adapter->hw.phy.autoneg_wait_to_complete = 0; | ||
1725 | } | ||
1726 | |||
1710 | if (eth_test->flags == ETH_TEST_FL_OFFLINE) { | 1727 | if (eth_test->flags == ETH_TEST_FL_OFFLINE) { |
1711 | /* Offline tests */ | 1728 | /* Offline tests */ |
1712 | 1729 | ||
@@ -1717,18 +1734,9 @@ static void e1000_diag_test(struct net_device *netdev, | |||
1717 | 1734 | ||
1718 | e_info("offline testing starting\n"); | 1735 | e_info("offline testing starting\n"); |
1719 | 1736 | ||
1720 | /* | ||
1721 | * Link test performed before hardware reset so autoneg doesn't | ||
1722 | * interfere with test result | ||
1723 | */ | ||
1724 | if (e1000_link_test(adapter, &data[4])) | ||
1725 | eth_test->flags |= ETH_TEST_FL_FAILED; | ||
1726 | |||
1727 | if (if_running) | 1737 | if (if_running) |
1728 | /* indicate we're in test mode */ | 1738 | /* indicate we're in test mode */ |
1729 | dev_close(netdev); | 1739 | dev_close(netdev); |
1730 | else | ||
1731 | e1000e_reset(adapter); | ||
1732 | 1740 | ||
1733 | if (e1000_reg_test(adapter, &data[0])) | 1741 | if (e1000_reg_test(adapter, &data[0])) |
1734 | eth_test->flags |= ETH_TEST_FL_FAILED; | 1742 | eth_test->flags |= ETH_TEST_FL_FAILED; |
@@ -1742,47 +1750,50 @@ static void e1000_diag_test(struct net_device *netdev, | |||
1742 | eth_test->flags |= ETH_TEST_FL_FAILED; | 1750 | eth_test->flags |= ETH_TEST_FL_FAILED; |
1743 | 1751 | ||
1744 | e1000e_reset(adapter); | 1752 | e1000e_reset(adapter); |
1745 | /* make sure the phy is powered up */ | ||
1746 | e1000e_power_up_phy(adapter); | ||
1747 | if (e1000_loopback_test(adapter, &data[3])) | 1753 | if (e1000_loopback_test(adapter, &data[3])) |
1748 | eth_test->flags |= ETH_TEST_FL_FAILED; | 1754 | eth_test->flags |= ETH_TEST_FL_FAILED; |
1749 | 1755 | ||
1756 | /* force this routine to wait until autoneg complete/timeout */ | ||
1757 | adapter->hw.phy.autoneg_wait_to_complete = 1; | ||
1758 | e1000e_reset(adapter); | ||
1759 | adapter->hw.phy.autoneg_wait_to_complete = 0; | ||
1760 | |||
1761 | if (e1000_link_test(adapter, &data[4])) | ||
1762 | eth_test->flags |= ETH_TEST_FL_FAILED; | ||
1763 | |||
1750 | /* restore speed, duplex, autoneg settings */ | 1764 | /* restore speed, duplex, autoneg settings */ |
1751 | adapter->hw.phy.autoneg_advertised = autoneg_advertised; | 1765 | adapter->hw.phy.autoneg_advertised = autoneg_advertised; |
1752 | adapter->hw.mac.forced_speed_duplex = forced_speed_duplex; | 1766 | adapter->hw.mac.forced_speed_duplex = forced_speed_duplex; |
1753 | adapter->hw.mac.autoneg = autoneg; | 1767 | adapter->hw.mac.autoneg = autoneg; |
1754 | |||
1755 | /* force this routine to wait until autoneg complete/timeout */ | ||
1756 | adapter->hw.phy.autoneg_wait_to_complete = 1; | ||
1757 | e1000e_reset(adapter); | 1768 | e1000e_reset(adapter); |
1758 | adapter->hw.phy.autoneg_wait_to_complete = 0; | ||
1759 | 1769 | ||
1760 | clear_bit(__E1000_TESTING, &adapter->state); | 1770 | clear_bit(__E1000_TESTING, &adapter->state); |
1761 | if (if_running) | 1771 | if (if_running) |
1762 | dev_open(netdev); | 1772 | dev_open(netdev); |
1763 | } else { | 1773 | } else { |
1764 | if (!if_running && (adapter->flags & FLAG_HAS_AMT)) { | 1774 | /* Online tests */ |
1765 | clear_bit(__E1000_TESTING, &adapter->state); | ||
1766 | dev_open(netdev); | ||
1767 | set_bit(__E1000_TESTING, &adapter->state); | ||
1768 | } | ||
1769 | 1775 | ||
1770 | e_info("online testing starting\n"); | 1776 | e_info("online testing starting\n"); |
1771 | /* Online tests */ | ||
1772 | if (e1000_link_test(adapter, &data[4])) | ||
1773 | eth_test->flags |= ETH_TEST_FL_FAILED; | ||
1774 | 1777 | ||
1775 | /* Online tests aren't run; pass by default */ | 1778 | /* register, eeprom, intr and loopback tests not run online */ |
1776 | data[0] = 0; | 1779 | data[0] = 0; |
1777 | data[1] = 0; | 1780 | data[1] = 0; |
1778 | data[2] = 0; | 1781 | data[2] = 0; |
1779 | data[3] = 0; | 1782 | data[3] = 0; |
1780 | 1783 | ||
1781 | if (!if_running && (adapter->flags & FLAG_HAS_AMT)) | 1784 | if (e1000_link_test(adapter, &data[4])) |
1782 | dev_close(netdev); | 1785 | eth_test->flags |= ETH_TEST_FL_FAILED; |
1783 | 1786 | ||
1784 | clear_bit(__E1000_TESTING, &adapter->state); | 1787 | clear_bit(__E1000_TESTING, &adapter->state); |
1785 | } | 1788 | } |
1789 | |||
1790 | if (!if_running) { | ||
1791 | e1000e_reset(adapter); | ||
1792 | |||
1793 | if (adapter->flags & FLAG_HAS_AMT) | ||
1794 | e1000e_release_hw_control(adapter); | ||
1795 | } | ||
1796 | |||
1786 | msleep_interruptible(4 * 1000); | 1797 | msleep_interruptible(4 * 1000); |
1787 | } | 1798 | } |
1788 | 1799 | ||
@@ -1799,8 +1810,7 @@ static void e1000_get_wol(struct net_device *netdev, | |||
1799 | return; | 1810 | return; |
1800 | 1811 | ||
1801 | wol->supported = WAKE_UCAST | WAKE_MCAST | | 1812 | wol->supported = WAKE_UCAST | WAKE_MCAST | |
1802 | WAKE_BCAST | WAKE_MAGIC | | 1813 | WAKE_BCAST | WAKE_MAGIC | WAKE_PHY; |
1803 | WAKE_PHY | WAKE_ARP; | ||
1804 | 1814 | ||
1805 | /* apply any specific unsupported masks here */ | 1815 | /* apply any specific unsupported masks here */ |
1806 | if (adapter->flags & FLAG_NO_WAKE_UCAST) { | 1816 | if (adapter->flags & FLAG_NO_WAKE_UCAST) { |
@@ -1821,19 +1831,16 @@ static void e1000_get_wol(struct net_device *netdev, | |||
1821 | wol->wolopts |= WAKE_MAGIC; | 1831 | wol->wolopts |= WAKE_MAGIC; |
1822 | if (adapter->wol & E1000_WUFC_LNKC) | 1832 | if (adapter->wol & E1000_WUFC_LNKC) |
1823 | wol->wolopts |= WAKE_PHY; | 1833 | wol->wolopts |= WAKE_PHY; |
1824 | if (adapter->wol & E1000_WUFC_ARP) | ||
1825 | wol->wolopts |= WAKE_ARP; | ||
1826 | } | 1834 | } |
1827 | 1835 | ||
1828 | static int e1000_set_wol(struct net_device *netdev, | 1836 | static int e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) |
1829 | struct ethtool_wolinfo *wol) | ||
1830 | { | 1837 | { |
1831 | struct e1000_adapter *adapter = netdev_priv(netdev); | 1838 | struct e1000_adapter *adapter = netdev_priv(netdev); |
1832 | 1839 | ||
1833 | if (!(adapter->flags & FLAG_HAS_WOL) || | 1840 | if (!(adapter->flags & FLAG_HAS_WOL) || |
1834 | !device_can_wakeup(&adapter->pdev->dev) || | 1841 | !device_can_wakeup(&adapter->pdev->dev) || |
1835 | (wol->wolopts & ~(WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | | 1842 | (wol->wolopts & ~(WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | |
1836 | WAKE_MAGIC | WAKE_PHY | WAKE_ARP))) | 1843 | WAKE_MAGIC | WAKE_PHY))) |
1837 | return -EOPNOTSUPP; | 1844 | return -EOPNOTSUPP; |
1838 | 1845 | ||
1839 | /* these settings will always override what we currently have */ | 1846 | /* these settings will always override what we currently have */ |
@@ -1849,73 +1856,41 @@ static int e1000_set_wol(struct net_device *netdev, | |||
1849 | adapter->wol |= E1000_WUFC_MAG; | 1856 | adapter->wol |= E1000_WUFC_MAG; |
1850 | if (wol->wolopts & WAKE_PHY) | 1857 | if (wol->wolopts & WAKE_PHY) |
1851 | adapter->wol |= E1000_WUFC_LNKC; | 1858 | adapter->wol |= E1000_WUFC_LNKC; |
1852 | if (wol->wolopts & WAKE_ARP) | ||
1853 | adapter->wol |= E1000_WUFC_ARP; | ||
1854 | 1859 | ||
1855 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); | 1860 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); |
1856 | 1861 | ||
1857 | return 0; | 1862 | return 0; |
1858 | } | 1863 | } |
1859 | 1864 | ||
1860 | /* toggle LED 4 times per second = 2 "blinks" per second */ | 1865 | static int e1000_set_phys_id(struct net_device *netdev, |
1861 | #define E1000_ID_INTERVAL (HZ/4) | 1866 | enum ethtool_phys_id_state state) |
1862 | |||
1863 | /* bit defines for adapter->led_status */ | ||
1864 | #define E1000_LED_ON 0 | ||
1865 | |||
1866 | static void e1000e_led_blink_task(struct work_struct *work) | ||
1867 | { | ||
1868 | struct e1000_adapter *adapter = container_of(work, | ||
1869 | struct e1000_adapter, led_blink_task); | ||
1870 | |||
1871 | if (test_and_change_bit(E1000_LED_ON, &adapter->led_status)) | ||
1872 | adapter->hw.mac.ops.led_off(&adapter->hw); | ||
1873 | else | ||
1874 | adapter->hw.mac.ops.led_on(&adapter->hw); | ||
1875 | } | ||
1876 | |||
1877 | static void e1000_led_blink_callback(unsigned long data) | ||
1878 | { | ||
1879 | struct e1000_adapter *adapter = (struct e1000_adapter *) data; | ||
1880 | |||
1881 | schedule_work(&adapter->led_blink_task); | ||
1882 | mod_timer(&adapter->blink_timer, jiffies + E1000_ID_INTERVAL); | ||
1883 | } | ||
1884 | |||
1885 | static int e1000_phys_id(struct net_device *netdev, u32 data) | ||
1886 | { | 1867 | { |
1887 | struct e1000_adapter *adapter = netdev_priv(netdev); | 1868 | struct e1000_adapter *adapter = netdev_priv(netdev); |
1888 | struct e1000_hw *hw = &adapter->hw; | 1869 | struct e1000_hw *hw = &adapter->hw; |
1889 | 1870 | ||
1890 | if (!data) | 1871 | switch (state) { |
1891 | data = INT_MAX; | 1872 | case ETHTOOL_ID_ACTIVE: |
1873 | if (!hw->mac.ops.blink_led) | ||
1874 | return 2; /* cycle on/off twice per second */ | ||
1892 | 1875 | ||
1893 | if ((hw->phy.type == e1000_phy_ife) || | 1876 | hw->mac.ops.blink_led(hw); |
1894 | (hw->mac.type == e1000_pchlan) || | 1877 | break; |
1895 | (hw->mac.type == e1000_pch2lan) || | 1878 | |
1896 | (hw->mac.type == e1000_82583) || | 1879 | case ETHTOOL_ID_INACTIVE: |
1897 | (hw->mac.type == e1000_82574)) { | ||
1898 | INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task); | ||
1899 | if (!adapter->blink_timer.function) { | ||
1900 | init_timer(&adapter->blink_timer); | ||
1901 | adapter->blink_timer.function = | ||
1902 | e1000_led_blink_callback; | ||
1903 | adapter->blink_timer.data = (unsigned long) adapter; | ||
1904 | } | ||
1905 | mod_timer(&adapter->blink_timer, jiffies); | ||
1906 | msleep_interruptible(data * 1000); | ||
1907 | del_timer_sync(&adapter->blink_timer); | ||
1908 | if (hw->phy.type == e1000_phy_ife) | 1880 | if (hw->phy.type == e1000_phy_ife) |
1909 | e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED, 0); | 1881 | e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED, 0); |
1910 | } else { | 1882 | hw->mac.ops.led_off(hw); |
1911 | e1000e_blink_led(hw); | 1883 | hw->mac.ops.cleanup_led(hw); |
1912 | msleep_interruptible(data * 1000); | 1884 | break; |
1913 | } | ||
1914 | 1885 | ||
1915 | hw->mac.ops.led_off(hw); | 1886 | case ETHTOOL_ID_ON: |
1916 | clear_bit(E1000_LED_ON, &adapter->led_status); | 1887 | adapter->hw.mac.ops.led_on(&adapter->hw); |
1917 | hw->mac.ops.cleanup_led(hw); | 1888 | break; |
1918 | 1889 | ||
1890 | case ETHTOOL_ID_OFF: | ||
1891 | adapter->hw.mac.ops.led_off(&adapter->hw); | ||
1892 | break; | ||
1893 | } | ||
1919 | return 0; | 1894 | return 0; |
1920 | } | 1895 | } |
1921 | 1896 | ||
@@ -1965,8 +1940,15 @@ static int e1000_set_coalesce(struct net_device *netdev, | |||
1965 | static int e1000_nway_reset(struct net_device *netdev) | 1940 | static int e1000_nway_reset(struct net_device *netdev) |
1966 | { | 1941 | { |
1967 | struct e1000_adapter *adapter = netdev_priv(netdev); | 1942 | struct e1000_adapter *adapter = netdev_priv(netdev); |
1968 | if (netif_running(netdev)) | 1943 | |
1969 | e1000e_reinit_locked(adapter); | 1944 | if (!netif_running(netdev)) |
1945 | return -EAGAIN; | ||
1946 | |||
1947 | if (!adapter->hw.mac.autoneg) | ||
1948 | return -EINVAL; | ||
1949 | |||
1950 | e1000e_reinit_locked(adapter); | ||
1951 | |||
1970 | return 0; | 1952 | return 0; |
1971 | } | 1953 | } |
1972 | 1954 | ||
@@ -1975,20 +1957,24 @@ static void e1000_get_ethtool_stats(struct net_device *netdev, | |||
1975 | u64 *data) | 1957 | u64 *data) |
1976 | { | 1958 | { |
1977 | struct e1000_adapter *adapter = netdev_priv(netdev); | 1959 | struct e1000_adapter *adapter = netdev_priv(netdev); |
1960 | struct rtnl_link_stats64 net_stats; | ||
1978 | int i; | 1961 | int i; |
1979 | char *p = NULL; | 1962 | char *p = NULL; |
1980 | 1963 | ||
1981 | e1000e_update_stats(adapter); | 1964 | e1000e_get_stats64(netdev, &net_stats); |
1982 | for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { | 1965 | for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { |
1983 | switch (e1000_gstrings_stats[i].type) { | 1966 | switch (e1000_gstrings_stats[i].type) { |
1984 | case NETDEV_STATS: | 1967 | case NETDEV_STATS: |
1985 | p = (char *) netdev + | 1968 | p = (char *) &net_stats + |
1986 | e1000_gstrings_stats[i].stat_offset; | 1969 | e1000_gstrings_stats[i].stat_offset; |
1987 | break; | 1970 | break; |
1988 | case E1000_STATS: | 1971 | case E1000_STATS: |
1989 | p = (char *) adapter + | 1972 | p = (char *) adapter + |
1990 | e1000_gstrings_stats[i].stat_offset; | 1973 | e1000_gstrings_stats[i].stat_offset; |
1991 | break; | 1974 | break; |
1975 | default: | ||
1976 | data[i] = 0; | ||
1977 | continue; | ||
1992 | } | 1978 | } |
1993 | 1979 | ||
1994 | data[i] = (e1000_gstrings_stats[i].sizeof_stat == | 1980 | data[i] = (e1000_gstrings_stats[i].sizeof_stat == |
@@ -2004,7 +1990,7 @@ static void e1000_get_strings(struct net_device *netdev, u32 stringset, | |||
2004 | 1990 | ||
2005 | switch (stringset) { | 1991 | switch (stringset) { |
2006 | case ETH_SS_TEST: | 1992 | case ETH_SS_TEST: |
2007 | memcpy(data, *e1000_gstrings_test, sizeof(e1000_gstrings_test)); | 1993 | memcpy(data, e1000_gstrings_test, sizeof(e1000_gstrings_test)); |
2008 | break; | 1994 | break; |
2009 | case ETH_SS_STATS: | 1995 | case ETH_SS_STATS: |
2010 | for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { | 1996 | for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { |
@@ -2016,6 +2002,31 @@ static void e1000_get_strings(struct net_device *netdev, u32 stringset, | |||
2016 | } | 2002 | } |
2017 | } | 2003 | } |
2018 | 2004 | ||
2005 | static int e1000e_set_flags(struct net_device *netdev, u32 data) | ||
2006 | { | ||
2007 | struct e1000_adapter *adapter = netdev_priv(netdev); | ||
2008 | bool need_reset = false; | ||
2009 | int rc; | ||
2010 | |||
2011 | need_reset = (data & ETH_FLAG_RXVLAN) != | ||
2012 | (netdev->features & NETIF_F_HW_VLAN_RX); | ||
2013 | |||
2014 | rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_RXVLAN | | ||
2015 | ETH_FLAG_TXVLAN); | ||
2016 | |||
2017 | if (rc) | ||
2018 | return rc; | ||
2019 | |||
2020 | if (need_reset) { | ||
2021 | if (netif_running(netdev)) | ||
2022 | e1000e_reinit_locked(adapter); | ||
2023 | else | ||
2024 | e1000e_reset(adapter); | ||
2025 | } | ||
2026 | |||
2027 | return 0; | ||
2028 | } | ||
2029 | |||
2019 | static const struct ethtool_ops e1000_ethtool_ops = { | 2030 | static const struct ethtool_ops e1000_ethtool_ops = { |
2020 | .get_settings = e1000_get_settings, | 2031 | .get_settings = e1000_get_settings, |
2021 | .set_settings = e1000_set_settings, | 2032 | .set_settings = e1000_set_settings, |
@@ -2027,7 +2038,7 @@ static const struct ethtool_ops e1000_ethtool_ops = { | |||
2027 | .get_msglevel = e1000_get_msglevel, | 2038 | .get_msglevel = e1000_get_msglevel, |
2028 | .set_msglevel = e1000_set_msglevel, | 2039 | .set_msglevel = e1000_set_msglevel, |
2029 | .nway_reset = e1000_nway_reset, | 2040 | .nway_reset = e1000_nway_reset, |
2030 | .get_link = e1000_get_link, | 2041 | .get_link = ethtool_op_get_link, |
2031 | .get_eeprom_len = e1000_get_eeprom_len, | 2042 | .get_eeprom_len = e1000_get_eeprom_len, |
2032 | .get_eeprom = e1000_get_eeprom, | 2043 | .get_eeprom = e1000_get_eeprom, |
2033 | .set_eeprom = e1000_set_eeprom, | 2044 | .set_eeprom = e1000_set_eeprom, |
@@ -2045,12 +2056,13 @@ static const struct ethtool_ops e1000_ethtool_ops = { | |||
2045 | .set_tso = e1000_set_tso, | 2056 | .set_tso = e1000_set_tso, |
2046 | .self_test = e1000_diag_test, | 2057 | .self_test = e1000_diag_test, |
2047 | .get_strings = e1000_get_strings, | 2058 | .get_strings = e1000_get_strings, |
2048 | .phys_id = e1000_phys_id, | 2059 | .set_phys_id = e1000_set_phys_id, |
2049 | .get_ethtool_stats = e1000_get_ethtool_stats, | 2060 | .get_ethtool_stats = e1000_get_ethtool_stats, |
2050 | .get_sset_count = e1000e_get_sset_count, | 2061 | .get_sset_count = e1000e_get_sset_count, |
2051 | .get_coalesce = e1000_get_coalesce, | 2062 | .get_coalesce = e1000_get_coalesce, |
2052 | .set_coalesce = e1000_set_coalesce, | 2063 | .set_coalesce = e1000_set_coalesce, |
2053 | .get_flags = ethtool_op_get_flags, | 2064 | .get_flags = ethtool_op_get_flags, |
2065 | .set_flags = e1000e_set_flags, | ||
2054 | }; | 2066 | }; |
2055 | 2067 | ||
2056 | void e1000e_set_ethtool_ops(struct net_device *netdev) | 2068 | void e1000e_set_ethtool_ops(struct net_device *netdev) |