diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-15 12:40:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-15 12:40:05 -0400 |
commit | 2ed0e21b30b53d3a94e204196e523e6c8f732b56 (patch) | |
tree | de2635426477d86338a9469ce09ba0626052288f /drivers/net/ixgbe/ixgbe_ethtool.c | |
parent | 0fa213310cd8fa7a51071cdcf130e26fa56e9549 (diff) | |
parent | 9cbc1cb8cd46ce1f7645b9de249b2ce8460129bb (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1244 commits)
pkt_sched: Rename PSCHED_US2NS and PSCHED_NS2US
ipv4: Fix fib_trie rebalancing
Bluetooth: Fix issue with uninitialized nsh.type in DTL-1 driver
Bluetooth: Fix Kconfig issue with RFKILL integration
PIM-SM: namespace changes
ipv4: update ARPD help text
net: use a deferred timer in rt_check_expire
ieee802154: fix kconfig bool/tristate muckup
bonding: initialization rework
bonding: use is_zero_ether_addr
bonding: network device names are case sensative
bonding: elminate bad refcount code
bonding: fix style issues
bonding: fix destructor
bonding: remove bonding read/write semaphore
bonding: initialize before registration
bonding: bond_create always called with default parameters
x_tables: Convert printk to pr_err
netfilter: conntrack: optional reliable conntrack event delivery
list_nulls: add hlist_nulls_add_head and hlist_nulls_del
...
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_ethtool.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_ethtool.c | 961 |
1 files changed, 928 insertions, 33 deletions
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index f0a20facc650..86f4f3e36f27 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c | |||
@@ -67,6 +67,9 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = { | |||
67 | {"rx_over_errors", IXGBE_STAT(net_stats.rx_over_errors)}, | 67 | {"rx_over_errors", IXGBE_STAT(net_stats.rx_over_errors)}, |
68 | {"rx_crc_errors", IXGBE_STAT(net_stats.rx_crc_errors)}, | 68 | {"rx_crc_errors", IXGBE_STAT(net_stats.rx_crc_errors)}, |
69 | {"rx_frame_errors", IXGBE_STAT(net_stats.rx_frame_errors)}, | 69 | {"rx_frame_errors", IXGBE_STAT(net_stats.rx_frame_errors)}, |
70 | {"hw_rsc_count", IXGBE_STAT(rsc_count)}, | ||
71 | {"fdir_match", IXGBE_STAT(stats.fdirmatch)}, | ||
72 | {"fdir_miss", IXGBE_STAT(stats.fdirmiss)}, | ||
70 | {"rx_fifo_errors", IXGBE_STAT(net_stats.rx_fifo_errors)}, | 73 | {"rx_fifo_errors", IXGBE_STAT(net_stats.rx_fifo_errors)}, |
71 | {"rx_missed_errors", IXGBE_STAT(net_stats.rx_missed_errors)}, | 74 | {"rx_missed_errors", IXGBE_STAT(net_stats.rx_missed_errors)}, |
72 | {"tx_aborted_errors", IXGBE_STAT(net_stats.tx_aborted_errors)}, | 75 | {"tx_aborted_errors", IXGBE_STAT(net_stats.tx_aborted_errors)}, |
@@ -90,6 +93,14 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = { | |||
90 | {"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)}, | 93 | {"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)}, |
91 | {"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)}, | 94 | {"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)}, |
92 | {"rx_no_dma_resources", IXGBE_STAT(hw_rx_no_dma_resources)}, | 95 | {"rx_no_dma_resources", IXGBE_STAT(hw_rx_no_dma_resources)}, |
96 | #ifdef IXGBE_FCOE | ||
97 | {"fcoe_bad_fccrc", IXGBE_STAT(stats.fccrc)}, | ||
98 | {"rx_fcoe_dropped", IXGBE_STAT(stats.fcoerpdc)}, | ||
99 | {"rx_fcoe_packets", IXGBE_STAT(stats.fcoeprc)}, | ||
100 | {"rx_fcoe_dwords", IXGBE_STAT(stats.fcoedwrc)}, | ||
101 | {"tx_fcoe_packets", IXGBE_STAT(stats.fcoeptc)}, | ||
102 | {"tx_fcoe_dwords", IXGBE_STAT(stats.fcoedwtc)}, | ||
103 | #endif /* IXGBE_FCOE */ | ||
93 | }; | 104 | }; |
94 | 105 | ||
95 | #define IXGBE_QUEUE_STATS_LEN \ | 106 | #define IXGBE_QUEUE_STATS_LEN \ |
@@ -109,6 +120,13 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = { | |||
109 | IXGBE_PB_STATS_LEN + \ | 120 | IXGBE_PB_STATS_LEN + \ |
110 | IXGBE_QUEUE_STATS_LEN) | 121 | IXGBE_QUEUE_STATS_LEN) |
111 | 122 | ||
123 | static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = { | ||
124 | "Register test (offline)", "Eeprom test (offline)", | ||
125 | "Interrupt test (offline)", "Loopback test (offline)", | ||
126 | "Link test (on/offline)" | ||
127 | }; | ||
128 | #define IXGBE_TEST_LEN sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN | ||
129 | |||
112 | static int ixgbe_get_settings(struct net_device *netdev, | 130 | static int ixgbe_get_settings(struct net_device *netdev, |
113 | struct ethtool_cmd *ecmd) | 131 | struct ethtool_cmd *ecmd) |
114 | { | 132 | { |
@@ -120,11 +138,12 @@ static int ixgbe_get_settings(struct net_device *netdev, | |||
120 | ecmd->supported = SUPPORTED_10000baseT_Full; | 138 | ecmd->supported = SUPPORTED_10000baseT_Full; |
121 | ecmd->autoneg = AUTONEG_ENABLE; | 139 | ecmd->autoneg = AUTONEG_ENABLE; |
122 | ecmd->transceiver = XCVR_EXTERNAL; | 140 | ecmd->transceiver = XCVR_EXTERNAL; |
123 | if (hw->phy.media_type == ixgbe_media_type_copper) { | 141 | if ((hw->phy.media_type == ixgbe_media_type_copper) || |
142 | (hw->mac.type == ixgbe_mac_82599EB)) { | ||
124 | ecmd->supported |= (SUPPORTED_1000baseT_Full | | 143 | ecmd->supported |= (SUPPORTED_1000baseT_Full | |
125 | SUPPORTED_TP | SUPPORTED_Autoneg); | 144 | SUPPORTED_Autoneg); |
126 | 145 | ||
127 | ecmd->advertising = (ADVERTISED_TP | ADVERTISED_Autoneg); | 146 | ecmd->advertising = ADVERTISED_Autoneg; |
128 | if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) | 147 | if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) |
129 | ecmd->advertising |= ADVERTISED_10000baseT_Full; | 148 | ecmd->advertising |= ADVERTISED_10000baseT_Full; |
130 | if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) | 149 | if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) |
@@ -139,7 +158,15 @@ static int ixgbe_get_settings(struct net_device *netdev, | |||
139 | ecmd->advertising |= (ADVERTISED_10000baseT_Full | | 158 | ecmd->advertising |= (ADVERTISED_10000baseT_Full | |
140 | ADVERTISED_1000baseT_Full); | 159 | ADVERTISED_1000baseT_Full); |
141 | 160 | ||
142 | ecmd->port = PORT_TP; | 161 | if (hw->phy.media_type == ixgbe_media_type_copper) { |
162 | ecmd->supported |= SUPPORTED_TP; | ||
163 | ecmd->advertising |= ADVERTISED_TP; | ||
164 | ecmd->port = PORT_TP; | ||
165 | } else { | ||
166 | ecmd->supported |= SUPPORTED_FIBRE; | ||
167 | ecmd->advertising |= ADVERTISED_FIBRE; | ||
168 | ecmd->port = PORT_FIBRE; | ||
169 | } | ||
143 | } else if (hw->phy.media_type == ixgbe_media_type_backplane) { | 170 | } else if (hw->phy.media_type == ixgbe_media_type_backplane) { |
144 | /* Set as FIBRE until SERDES defined in kernel */ | 171 | /* Set as FIBRE until SERDES defined in kernel */ |
145 | switch (hw->device_id) { | 172 | switch (hw->device_id) { |
@@ -187,16 +214,10 @@ static int ixgbe_set_settings(struct net_device *netdev, | |||
187 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 214 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
188 | struct ixgbe_hw *hw = &adapter->hw; | 215 | struct ixgbe_hw *hw = &adapter->hw; |
189 | u32 advertised, old; | 216 | u32 advertised, old; |
190 | s32 err; | 217 | s32 err = 0; |
191 | 218 | ||
192 | switch (hw->phy.media_type) { | 219 | if ((hw->phy.media_type == ixgbe_media_type_copper) || |
193 | case ixgbe_media_type_fiber: | 220 | (hw->mac.type == ixgbe_mac_82599EB)) { |
194 | if ((ecmd->autoneg == AUTONEG_ENABLE) || | ||
195 | (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)) | ||
196 | return -EINVAL; | ||
197 | /* in this case we currently only support 10Gb/FULL */ | ||
198 | break; | ||
199 | case ixgbe_media_type_copper: | ||
200 | /* 10000/copper and 1000/copper must autoneg | 221 | /* 10000/copper and 1000/copper must autoneg |
201 | * this function does not support any duplex forcing, but can | 222 | * this function does not support any duplex forcing, but can |
202 | * limit the advertising of the adapter to only 10000 or 1000 */ | 223 | * limit the advertising of the adapter to only 10000 or 1000 */ |
@@ -212,20 +233,23 @@ static int ixgbe_set_settings(struct net_device *netdev, | |||
212 | advertised |= IXGBE_LINK_SPEED_1GB_FULL; | 233 | advertised |= IXGBE_LINK_SPEED_1GB_FULL; |
213 | 234 | ||
214 | if (old == advertised) | 235 | if (old == advertised) |
215 | break; | 236 | return err; |
216 | /* this sets the link speed and restarts auto-neg */ | 237 | /* this sets the link speed and restarts auto-neg */ |
238 | hw->mac.autotry_restart = true; | ||
217 | err = hw->mac.ops.setup_link_speed(hw, advertised, true, true); | 239 | err = hw->mac.ops.setup_link_speed(hw, advertised, true, true); |
218 | if (err) { | 240 | if (err) { |
219 | DPRINTK(PROBE, INFO, | 241 | DPRINTK(PROBE, INFO, |
220 | "setup link failed with code %d\n", err); | 242 | "setup link failed with code %d\n", err); |
221 | hw->mac.ops.setup_link_speed(hw, old, true, true); | 243 | hw->mac.ops.setup_link_speed(hw, old, true, true); |
222 | } | 244 | } |
223 | break; | 245 | } else { |
224 | default: | 246 | /* in this case we currently only support 10Gb/FULL */ |
225 | break; | 247 | if ((ecmd->autoneg == AUTONEG_ENABLE) || |
248 | (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)) | ||
249 | return -EINVAL; | ||
226 | } | 250 | } |
227 | 251 | ||
228 | return 0; | 252 | return err; |
229 | } | 253 | } |
230 | 254 | ||
231 | static void ixgbe_get_pauseparam(struct net_device *netdev, | 255 | static void ixgbe_get_pauseparam(struct net_device *netdev, |
@@ -245,6 +269,13 @@ static void ixgbe_get_pauseparam(struct net_device *netdev, | |||
245 | else | 269 | else |
246 | pause->autoneg = 1; | 270 | pause->autoneg = 1; |
247 | 271 | ||
272 | #ifdef CONFIG_DCB | ||
273 | if (hw->fc.current_mode == ixgbe_fc_pfc) { | ||
274 | pause->rx_pause = 0; | ||
275 | pause->tx_pause = 0; | ||
276 | } | ||
277 | |||
278 | #endif | ||
248 | if (hw->fc.current_mode == ixgbe_fc_rx_pause) { | 279 | if (hw->fc.current_mode == ixgbe_fc_rx_pause) { |
249 | pause->rx_pause = 1; | 280 | pause->rx_pause = 1; |
250 | } else if (hw->fc.current_mode == ixgbe_fc_tx_pause) { | 281 | } else if (hw->fc.current_mode == ixgbe_fc_tx_pause) { |
@@ -260,24 +291,46 @@ static int ixgbe_set_pauseparam(struct net_device *netdev, | |||
260 | { | 291 | { |
261 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 292 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
262 | struct ixgbe_hw *hw = &adapter->hw; | 293 | struct ixgbe_hw *hw = &adapter->hw; |
294 | struct ixgbe_fc_info fc; | ||
295 | |||
296 | #ifdef CONFIG_DCB | ||
297 | if (adapter->dcb_cfg.pfc_mode_enable || | ||
298 | ((hw->mac.type == ixgbe_mac_82598EB) && | ||
299 | (adapter->flags & IXGBE_FLAG_DCB_ENABLED))) | ||
300 | return -EINVAL; | ||
301 | |||
302 | #endif | ||
303 | |||
304 | fc = hw->fc; | ||
263 | 305 | ||
264 | if (pause->autoneg != AUTONEG_ENABLE) | 306 | if (pause->autoneg != AUTONEG_ENABLE) |
265 | hw->fc.disable_fc_autoneg = true; | 307 | fc.disable_fc_autoneg = true; |
266 | else | 308 | else |
267 | hw->fc.disable_fc_autoneg = false; | 309 | fc.disable_fc_autoneg = false; |
268 | 310 | ||
269 | if (pause->rx_pause && pause->tx_pause) | 311 | if (pause->rx_pause && pause->tx_pause) |
270 | hw->fc.requested_mode = ixgbe_fc_full; | 312 | fc.requested_mode = ixgbe_fc_full; |
271 | else if (pause->rx_pause && !pause->tx_pause) | 313 | else if (pause->rx_pause && !pause->tx_pause) |
272 | hw->fc.requested_mode = ixgbe_fc_rx_pause; | 314 | fc.requested_mode = ixgbe_fc_rx_pause; |
273 | else if (!pause->rx_pause && pause->tx_pause) | 315 | else if (!pause->rx_pause && pause->tx_pause) |
274 | hw->fc.requested_mode = ixgbe_fc_tx_pause; | 316 | fc.requested_mode = ixgbe_fc_tx_pause; |
275 | else if (!pause->rx_pause && !pause->tx_pause) | 317 | else if (!pause->rx_pause && !pause->tx_pause) |
276 | hw->fc.requested_mode = ixgbe_fc_none; | 318 | fc.requested_mode = ixgbe_fc_none; |
277 | else | 319 | else |
278 | return -EINVAL; | 320 | return -EINVAL; |
279 | 321 | ||
280 | hw->mac.ops.setup_fc(hw, 0); | 322 | #ifdef CONFIG_DCB |
323 | adapter->last_lfc_mode = fc.requested_mode; | ||
324 | #endif | ||
325 | |||
326 | /* if the thing changed then we'll update and use new autoneg */ | ||
327 | if (memcmp(&fc, &hw->fc, sizeof(struct ixgbe_fc_info))) { | ||
328 | hw->fc = fc; | ||
329 | if (netif_running(netdev)) | ||
330 | ixgbe_reinit_locked(adapter); | ||
331 | else | ||
332 | ixgbe_reset(adapter); | ||
333 | } | ||
281 | 334 | ||
282 | return 0; | 335 | return 0; |
283 | } | 336 | } |
@@ -311,10 +364,17 @@ static u32 ixgbe_get_tx_csum(struct net_device *netdev) | |||
311 | 364 | ||
312 | static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data) | 365 | static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data) |
313 | { | 366 | { |
314 | if (data) | 367 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
368 | |||
369 | if (data) { | ||
315 | netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); | 370 | netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); |
316 | else | 371 | if (adapter->hw.mac.type == ixgbe_mac_82599EB) |
372 | netdev->features |= NETIF_F_SCTP_CSUM; | ||
373 | } else { | ||
317 | netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); | 374 | netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); |
375 | if (adapter->hw.mac.type == ixgbe_mac_82599EB) | ||
376 | netdev->features &= ~NETIF_F_SCTP_CSUM; | ||
377 | } | ||
318 | 378 | ||
319 | return 0; | 379 | return 0; |
320 | } | 380 | } |
@@ -710,6 +770,7 @@ static void ixgbe_get_drvinfo(struct net_device *netdev, | |||
710 | strncpy(drvinfo->fw_version, firmware_version, 32); | 770 | strncpy(drvinfo->fw_version, firmware_version, 32); |
711 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); | 771 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); |
712 | drvinfo->n_stats = IXGBE_STATS_LEN; | 772 | drvinfo->n_stats = IXGBE_STATS_LEN; |
773 | drvinfo->testinfo_len = IXGBE_TEST_LEN; | ||
713 | drvinfo->regdump_len = ixgbe_get_regs_len(netdev); | 774 | drvinfo->regdump_len = ixgbe_get_regs_len(netdev); |
714 | } | 775 | } |
715 | 776 | ||
@@ -781,7 +842,6 @@ static int ixgbe_set_ringparam(struct net_device *netdev, | |||
781 | } | 842 | } |
782 | goto err_setup; | 843 | goto err_setup; |
783 | } | 844 | } |
784 | temp_tx_ring[i].v_idx = adapter->tx_ring[i].v_idx; | ||
785 | } | 845 | } |
786 | need_update = true; | 846 | need_update = true; |
787 | } | 847 | } |
@@ -811,7 +871,6 @@ static int ixgbe_set_ringparam(struct net_device *netdev, | |||
811 | } | 871 | } |
812 | goto err_setup; | 872 | goto err_setup; |
813 | } | 873 | } |
814 | temp_rx_ring[i].v_idx = adapter->rx_ring[i].v_idx; | ||
815 | } | 874 | } |
816 | need_update = true; | 875 | need_update = true; |
817 | } | 876 | } |
@@ -851,6 +910,8 @@ err_setup: | |||
851 | static int ixgbe_get_sset_count(struct net_device *netdev, int sset) | 910 | static int ixgbe_get_sset_count(struct net_device *netdev, int sset) |
852 | { | 911 | { |
853 | switch (sset) { | 912 | switch (sset) { |
913 | case ETH_SS_TEST: | ||
914 | return IXGBE_TEST_LEN; | ||
854 | case ETH_SS_STATS: | 915 | case ETH_SS_STATS: |
855 | return IXGBE_STATS_LEN; | 916 | return IXGBE_STATS_LEN; |
856 | default: | 917 | default: |
@@ -905,6 +966,10 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset, | |||
905 | int i; | 966 | int i; |
906 | 967 | ||
907 | switch (stringset) { | 968 | switch (stringset) { |
969 | case ETH_SS_TEST: | ||
970 | memcpy(data, *ixgbe_gstrings_test, | ||
971 | IXGBE_TEST_LEN * ETH_GSTRING_LEN); | ||
972 | break; | ||
908 | case ETH_SS_STATS: | 973 | case ETH_SS_STATS: |
909 | for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) { | 974 | for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) { |
910 | memcpy(p, ixgbe_gstrings_stats[i].stat_string, | 975 | memcpy(p, ixgbe_gstrings_stats[i].stat_string, |
@@ -942,6 +1007,815 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset, | |||
942 | } | 1007 | } |
943 | } | 1008 | } |
944 | 1009 | ||
1010 | static int ixgbe_link_test(struct ixgbe_adapter *adapter, u64 *data) | ||
1011 | { | ||
1012 | struct ixgbe_hw *hw = &adapter->hw; | ||
1013 | bool link_up; | ||
1014 | u32 link_speed = 0; | ||
1015 | *data = 0; | ||
1016 | |||
1017 | hw->mac.ops.check_link(hw, &link_speed, &link_up, true); | ||
1018 | if (link_up) | ||
1019 | return *data; | ||
1020 | else | ||
1021 | *data = 1; | ||
1022 | return *data; | ||
1023 | } | ||
1024 | |||
1025 | /* ethtool register test data */ | ||
1026 | struct ixgbe_reg_test { | ||
1027 | u16 reg; | ||
1028 | u8 array_len; | ||
1029 | u8 test_type; | ||
1030 | u32 mask; | ||
1031 | u32 write; | ||
1032 | }; | ||
1033 | |||
1034 | /* In the hardware, registers are laid out either singly, in arrays | ||
1035 | * spaced 0x40 bytes apart, or in contiguous tables. We assume | ||
1036 | * most tests take place on arrays or single registers (handled | ||
1037 | * as a single-element array) and special-case the tables. | ||
1038 | * Table tests are always pattern tests. | ||
1039 | * | ||
1040 | * We also make provision for some required setup steps by specifying | ||
1041 | * registers to be written without any read-back testing. | ||
1042 | */ | ||
1043 | |||
1044 | #define PATTERN_TEST 1 | ||
1045 | #define SET_READ_TEST 2 | ||
1046 | #define WRITE_NO_TEST 3 | ||
1047 | #define TABLE32_TEST 4 | ||
1048 | #define TABLE64_TEST_LO 5 | ||
1049 | #define TABLE64_TEST_HI 6 | ||
1050 | |||
1051 | /* default 82599 register test */ | ||
1052 | static struct ixgbe_reg_test reg_test_82599[] = { | ||
1053 | { IXGBE_FCRTL_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, | ||
1054 | { IXGBE_FCRTH_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, | ||
1055 | { IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, | ||
1056 | { IXGBE_VLNCTRL, 1, PATTERN_TEST, 0x00000000, 0x00000000 }, | ||
1057 | { IXGBE_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 }, | ||
1058 | { IXGBE_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, | ||
1059 | { IXGBE_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, | ||
1060 | { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE }, | ||
1061 | { IXGBE_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, | ||
1062 | { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, 0 }, | ||
1063 | { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, | ||
1064 | { IXGBE_FCTTV(0), 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, | ||
1065 | { IXGBE_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, | ||
1066 | { IXGBE_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, | ||
1067 | { IXGBE_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFF80 }, | ||
1068 | { IXGBE_RXCTRL, 1, SET_READ_TEST, 0x00000001, 0x00000001 }, | ||
1069 | { IXGBE_RAL(0), 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF }, | ||
1070 | { IXGBE_RAL(0), 16, TABLE64_TEST_HI, 0x8001FFFF, 0x800CFFFF }, | ||
1071 | { IXGBE_MTA(0), 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, | ||
1072 | { 0, 0, 0, 0 } | ||
1073 | }; | ||
1074 | |||
1075 | /* default 82598 register test */ | ||
1076 | static struct ixgbe_reg_test reg_test_82598[] = { | ||
1077 | { IXGBE_FCRTL(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, | ||
1078 | { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, | ||
1079 | { IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, | ||
1080 | { IXGBE_VLNCTRL, 1, PATTERN_TEST, 0x00000000, 0x00000000 }, | ||
1081 | { IXGBE_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, | ||
1082 | { IXGBE_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, | ||
1083 | { IXGBE_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, | ||
1084 | /* Enable all four RX queues before testing. */ | ||
1085 | { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE }, | ||
1086 | /* RDH is read-only for 82598, only test RDT. */ | ||
1087 | { IXGBE_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, | ||
1088 | { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, 0 }, | ||
1089 | { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, | ||
1090 | { IXGBE_FCTTV(0), 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, | ||
1091 | { IXGBE_TIPG, 1, PATTERN_TEST, 0x000000FF, 0x000000FF }, | ||
1092 | { IXGBE_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, | ||
1093 | { IXGBE_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, | ||
1094 | { IXGBE_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, | ||
1095 | { IXGBE_RXCTRL, 1, SET_READ_TEST, 0x00000003, 0x00000003 }, | ||
1096 | { IXGBE_DTXCTL, 1, SET_READ_TEST, 0x00000005, 0x00000005 }, | ||
1097 | { IXGBE_RAL(0), 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF }, | ||
1098 | { IXGBE_RAL(0), 16, TABLE64_TEST_HI, 0x800CFFFF, 0x800CFFFF }, | ||
1099 | { IXGBE_MTA(0), 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, | ||
1100 | { 0, 0, 0, 0 } | ||
1101 | }; | ||
1102 | |||
1103 | #define REG_PATTERN_TEST(R, M, W) \ | ||
1104 | { \ | ||
1105 | u32 pat, val, before; \ | ||
1106 | const u32 _test[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \ | ||
1107 | for (pat = 0; pat < ARRAY_SIZE(_test); pat++) { \ | ||
1108 | before = readl(adapter->hw.hw_addr + R); \ | ||
1109 | writel((_test[pat] & W), (adapter->hw.hw_addr + R)); \ | ||
1110 | val = readl(adapter->hw.hw_addr + R); \ | ||
1111 | if (val != (_test[pat] & W & M)) { \ | ||
1112 | DPRINTK(DRV, ERR, "pattern test reg %04X failed: got "\ | ||
1113 | "0x%08X expected 0x%08X\n", \ | ||
1114 | R, val, (_test[pat] & W & M)); \ | ||
1115 | *data = R; \ | ||
1116 | writel(before, adapter->hw.hw_addr + R); \ | ||
1117 | return 1; \ | ||
1118 | } \ | ||
1119 | writel(before, adapter->hw.hw_addr + R); \ | ||
1120 | } \ | ||
1121 | } | ||
1122 | |||
1123 | #define REG_SET_AND_CHECK(R, M, W) \ | ||
1124 | { \ | ||
1125 | u32 val, before; \ | ||
1126 | before = readl(adapter->hw.hw_addr + R); \ | ||
1127 | writel((W & M), (adapter->hw.hw_addr + R)); \ | ||
1128 | val = readl(adapter->hw.hw_addr + R); \ | ||
1129 | if ((W & M) != (val & M)) { \ | ||
1130 | DPRINTK(DRV, ERR, "set/check reg %04X test failed: got 0x%08X "\ | ||
1131 | "expected 0x%08X\n", R, (val & M), (W & M)); \ | ||
1132 | *data = R; \ | ||
1133 | writel(before, (adapter->hw.hw_addr + R)); \ | ||
1134 | return 1; \ | ||
1135 | } \ | ||
1136 | writel(before, (adapter->hw.hw_addr + R)); \ | ||
1137 | } | ||
1138 | |||
1139 | static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data) | ||
1140 | { | ||
1141 | struct ixgbe_reg_test *test; | ||
1142 | u32 value, before, after; | ||
1143 | u32 i, toggle; | ||
1144 | |||
1145 | if (adapter->hw.mac.type == ixgbe_mac_82599EB) { | ||
1146 | toggle = 0x7FFFF30F; | ||
1147 | test = reg_test_82599; | ||
1148 | } else { | ||
1149 | toggle = 0x7FFFF3FF; | ||
1150 | test = reg_test_82598; | ||
1151 | } | ||
1152 | |||
1153 | /* | ||
1154 | * Because the status register is such a special case, | ||
1155 | * we handle it separately from the rest of the register | ||
1156 | * tests. Some bits are read-only, some toggle, and some | ||
1157 | * are writeable on newer MACs. | ||
1158 | */ | ||
1159 | before = IXGBE_READ_REG(&adapter->hw, IXGBE_STATUS); | ||
1160 | value = (IXGBE_READ_REG(&adapter->hw, IXGBE_STATUS) & toggle); | ||
1161 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_STATUS, toggle); | ||
1162 | after = IXGBE_READ_REG(&adapter->hw, IXGBE_STATUS) & toggle; | ||
1163 | if (value != after) { | ||
1164 | DPRINTK(DRV, ERR, "failed STATUS register test got: " | ||
1165 | "0x%08X expected: 0x%08X\n", after, value); | ||
1166 | *data = 1; | ||
1167 | return 1; | ||
1168 | } | ||
1169 | /* restore previous status */ | ||
1170 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_STATUS, before); | ||
1171 | |||
1172 | /* | ||
1173 | * Perform the remainder of the register test, looping through | ||
1174 | * the test table until we either fail or reach the null entry. | ||
1175 | */ | ||
1176 | while (test->reg) { | ||
1177 | for (i = 0; i < test->array_len; i++) { | ||
1178 | switch (test->test_type) { | ||
1179 | case PATTERN_TEST: | ||
1180 | REG_PATTERN_TEST(test->reg + (i * 0x40), | ||
1181 | test->mask, | ||
1182 | test->write); | ||
1183 | break; | ||
1184 | case SET_READ_TEST: | ||
1185 | REG_SET_AND_CHECK(test->reg + (i * 0x40), | ||
1186 | test->mask, | ||
1187 | test->write); | ||
1188 | break; | ||
1189 | case WRITE_NO_TEST: | ||
1190 | writel(test->write, | ||
1191 | (adapter->hw.hw_addr + test->reg) | ||
1192 | + (i * 0x40)); | ||
1193 | break; | ||
1194 | case TABLE32_TEST: | ||
1195 | REG_PATTERN_TEST(test->reg + (i * 4), | ||
1196 | test->mask, | ||
1197 | test->write); | ||
1198 | break; | ||
1199 | case TABLE64_TEST_LO: | ||
1200 | REG_PATTERN_TEST(test->reg + (i * 8), | ||
1201 | test->mask, | ||
1202 | test->write); | ||
1203 | break; | ||
1204 | case TABLE64_TEST_HI: | ||
1205 | REG_PATTERN_TEST((test->reg + 4) + (i * 8), | ||
1206 | test->mask, | ||
1207 | test->write); | ||
1208 | break; | ||
1209 | } | ||
1210 | } | ||
1211 | test++; | ||
1212 | } | ||
1213 | |||
1214 | *data = 0; | ||
1215 | return 0; | ||
1216 | } | ||
1217 | |||
1218 | static int ixgbe_eeprom_test(struct ixgbe_adapter *adapter, u64 *data) | ||
1219 | { | ||
1220 | struct ixgbe_hw *hw = &adapter->hw; | ||
1221 | if (hw->eeprom.ops.validate_checksum(hw, NULL)) | ||
1222 | *data = 1; | ||
1223 | else | ||
1224 | *data = 0; | ||
1225 | return *data; | ||
1226 | } | ||
1227 | |||
1228 | static irqreturn_t ixgbe_test_intr(int irq, void *data) | ||
1229 | { | ||
1230 | struct net_device *netdev = (struct net_device *) data; | ||
1231 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||
1232 | |||
1233 | adapter->test_icr |= IXGBE_READ_REG(&adapter->hw, IXGBE_EICR); | ||
1234 | |||
1235 | return IRQ_HANDLED; | ||
1236 | } | ||
1237 | |||
1238 | static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data) | ||
1239 | { | ||
1240 | struct net_device *netdev = adapter->netdev; | ||
1241 | u32 mask, i = 0, shared_int = true; | ||
1242 | u32 irq = adapter->pdev->irq; | ||
1243 | |||
1244 | *data = 0; | ||
1245 | |||
1246 | /* Hook up test interrupt handler just for this test */ | ||
1247 | if (adapter->msix_entries) { | ||
1248 | /* NOTE: we don't test MSI-X interrupts here, yet */ | ||
1249 | return 0; | ||
1250 | } else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) { | ||
1251 | shared_int = false; | ||
1252 | if (request_irq(irq, &ixgbe_test_intr, 0, netdev->name, | ||
1253 | netdev)) { | ||
1254 | *data = 1; | ||
1255 | return -1; | ||
1256 | } | ||
1257 | } else if (!request_irq(irq, &ixgbe_test_intr, IRQF_PROBE_SHARED, | ||
1258 | netdev->name, netdev)) { | ||
1259 | shared_int = false; | ||
1260 | } else if (request_irq(irq, &ixgbe_test_intr, IRQF_SHARED, | ||
1261 | netdev->name, netdev)) { | ||
1262 | *data = 1; | ||
1263 | return -1; | ||
1264 | } | ||
1265 | DPRINTK(HW, INFO, "testing %s interrupt\n", | ||
1266 | (shared_int ? "shared" : "unshared")); | ||
1267 | |||
1268 | /* Disable all the interrupts */ | ||
1269 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF); | ||
1270 | msleep(10); | ||
1271 | |||
1272 | /* Test each interrupt */ | ||
1273 | for (; i < 10; i++) { | ||
1274 | /* Interrupt to test */ | ||
1275 | mask = 1 << i; | ||
1276 | |||
1277 | if (!shared_int) { | ||
1278 | /* | ||
1279 | * Disable the interrupts to be reported in | ||
1280 | * the cause register and then force the same | ||
1281 | * interrupt and see if one gets posted. If | ||
1282 | * an interrupt was posted to the bus, the | ||
1283 | * test failed. | ||
1284 | */ | ||
1285 | adapter->test_icr = 0; | ||
1286 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, | ||
1287 | ~mask & 0x00007FFF); | ||
1288 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, | ||
1289 | ~mask & 0x00007FFF); | ||
1290 | msleep(10); | ||
1291 | |||
1292 | if (adapter->test_icr & mask) { | ||
1293 | *data = 3; | ||
1294 | break; | ||
1295 | } | ||
1296 | } | ||
1297 | |||
1298 | /* | ||
1299 | * Enable the interrupt to be reported in the cause | ||
1300 | * register and then force the same interrupt and see | ||
1301 | * if one gets posted. If an interrupt was not posted | ||
1302 | * to the bus, the test failed. | ||
1303 | */ | ||
1304 | adapter->test_icr = 0; | ||
1305 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); | ||
1306 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask); | ||
1307 | msleep(10); | ||
1308 | |||
1309 | if (!(adapter->test_icr &mask)) { | ||
1310 | *data = 4; | ||
1311 | break; | ||
1312 | } | ||
1313 | |||
1314 | if (!shared_int) { | ||
1315 | /* | ||
1316 | * Disable the other interrupts to be reported in | ||
1317 | * the cause register and then force the other | ||
1318 | * interrupts and see if any get posted. If | ||
1319 | * an interrupt was posted to the bus, the | ||
1320 | * test failed. | ||
1321 | */ | ||
1322 | adapter->test_icr = 0; | ||
1323 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, | ||
1324 | ~mask & 0x00007FFF); | ||
1325 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, | ||
1326 | ~mask & 0x00007FFF); | ||
1327 | msleep(10); | ||
1328 | |||
1329 | if (adapter->test_icr) { | ||
1330 | *data = 5; | ||
1331 | break; | ||
1332 | } | ||
1333 | } | ||
1334 | } | ||
1335 | |||
1336 | /* Disable all the interrupts */ | ||
1337 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF); | ||
1338 | msleep(10); | ||
1339 | |||
1340 | /* Unhook test interrupt handler */ | ||
1341 | free_irq(irq, netdev); | ||
1342 | |||
1343 | return *data; | ||
1344 | } | ||
1345 | |||
1346 | static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter) | ||
1347 | { | ||
1348 | struct ixgbe_ring *tx_ring = &adapter->test_tx_ring; | ||
1349 | struct ixgbe_ring *rx_ring = &adapter->test_rx_ring; | ||
1350 | struct ixgbe_hw *hw = &adapter->hw; | ||
1351 | struct pci_dev *pdev = adapter->pdev; | ||
1352 | u32 reg_ctl; | ||
1353 | int i; | ||
1354 | |||
1355 | /* shut down the DMA engines now so they can be reinitialized later */ | ||
1356 | |||
1357 | /* first Rx */ | ||
1358 | reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); | ||
1359 | reg_ctl &= ~IXGBE_RXCTRL_RXEN; | ||
1360 | IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_ctl); | ||
1361 | reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(0)); | ||
1362 | reg_ctl &= ~IXGBE_RXDCTL_ENABLE; | ||
1363 | IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(0), reg_ctl); | ||
1364 | |||
1365 | /* now Tx */ | ||
1366 | reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(0)); | ||
1367 | reg_ctl &= ~IXGBE_TXDCTL_ENABLE; | ||
1368 | IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(0), reg_ctl); | ||
1369 | if (hw->mac.type == ixgbe_mac_82599EB) { | ||
1370 | reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); | ||
1371 | reg_ctl &= ~IXGBE_DMATXCTL_TE; | ||
1372 | IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_ctl); | ||
1373 | } | ||
1374 | |||
1375 | ixgbe_reset(adapter); | ||
1376 | |||
1377 | if (tx_ring->desc && tx_ring->tx_buffer_info) { | ||
1378 | for (i = 0; i < tx_ring->count; i++) { | ||
1379 | struct ixgbe_tx_buffer *buf = | ||
1380 | &(tx_ring->tx_buffer_info[i]); | ||
1381 | if (buf->dma) | ||
1382 | pci_unmap_single(pdev, buf->dma, buf->length, | ||
1383 | PCI_DMA_TODEVICE); | ||
1384 | if (buf->skb) | ||
1385 | dev_kfree_skb(buf->skb); | ||
1386 | } | ||
1387 | } | ||
1388 | |||
1389 | if (rx_ring->desc && rx_ring->rx_buffer_info) { | ||
1390 | for (i = 0; i < rx_ring->count; i++) { | ||
1391 | struct ixgbe_rx_buffer *buf = | ||
1392 | &(rx_ring->rx_buffer_info[i]); | ||
1393 | if (buf->dma) | ||
1394 | pci_unmap_single(pdev, buf->dma, | ||
1395 | IXGBE_RXBUFFER_2048, | ||
1396 | PCI_DMA_FROMDEVICE); | ||
1397 | if (buf->skb) | ||
1398 | dev_kfree_skb(buf->skb); | ||
1399 | } | ||
1400 | } | ||
1401 | |||
1402 | if (tx_ring->desc) { | ||
1403 | pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, | ||
1404 | tx_ring->dma); | ||
1405 | tx_ring->desc = NULL; | ||
1406 | } | ||
1407 | if (rx_ring->desc) { | ||
1408 | pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, | ||
1409 | rx_ring->dma); | ||
1410 | rx_ring->desc = NULL; | ||
1411 | } | ||
1412 | |||
1413 | kfree(tx_ring->tx_buffer_info); | ||
1414 | tx_ring->tx_buffer_info = NULL; | ||
1415 | kfree(rx_ring->rx_buffer_info); | ||
1416 | rx_ring->rx_buffer_info = NULL; | ||
1417 | |||
1418 | return; | ||
1419 | } | ||
1420 | |||
1421 | static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) | ||
1422 | { | ||
1423 | struct ixgbe_ring *tx_ring = &adapter->test_tx_ring; | ||
1424 | struct ixgbe_ring *rx_ring = &adapter->test_rx_ring; | ||
1425 | struct pci_dev *pdev = adapter->pdev; | ||
1426 | u32 rctl, reg_data; | ||
1427 | int i, ret_val; | ||
1428 | |||
1429 | /* Setup Tx descriptor ring and Tx buffers */ | ||
1430 | |||
1431 | if (!tx_ring->count) | ||
1432 | tx_ring->count = IXGBE_DEFAULT_TXD; | ||
1433 | |||
1434 | tx_ring->tx_buffer_info = kcalloc(tx_ring->count, | ||
1435 | sizeof(struct ixgbe_tx_buffer), | ||
1436 | GFP_KERNEL); | ||
1437 | if (!(tx_ring->tx_buffer_info)) { | ||
1438 | ret_val = 1; | ||
1439 | goto err_nomem; | ||
1440 | } | ||
1441 | |||
1442 | tx_ring->size = tx_ring->count * sizeof(struct ixgbe_legacy_tx_desc); | ||
1443 | tx_ring->size = ALIGN(tx_ring->size, 4096); | ||
1444 | if (!(tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size, | ||
1445 | &tx_ring->dma))) { | ||
1446 | ret_val = 2; | ||
1447 | goto err_nomem; | ||
1448 | } | ||
1449 | tx_ring->next_to_use = tx_ring->next_to_clean = 0; | ||
1450 | |||
1451 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDBAL(0), | ||
1452 | ((u64) tx_ring->dma & 0x00000000FFFFFFFF)); | ||
1453 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDBAH(0), | ||
1454 | ((u64) tx_ring->dma >> 32)); | ||
1455 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDLEN(0), | ||
1456 | tx_ring->count * sizeof(struct ixgbe_legacy_tx_desc)); | ||
1457 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDH(0), 0); | ||
1458 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(0), 0); | ||
1459 | |||
1460 | reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0); | ||
1461 | reg_data |= IXGBE_HLREG0_TXPADEN; | ||
1462 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data); | ||
1463 | |||
1464 | if (adapter->hw.mac.type == ixgbe_mac_82599EB) { | ||
1465 | reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL); | ||
1466 | reg_data |= IXGBE_DMATXCTL_TE; | ||
1467 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data); | ||
1468 | } | ||
1469 | reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_TXDCTL(0)); | ||
1470 | reg_data |= IXGBE_TXDCTL_ENABLE; | ||
1471 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_TXDCTL(0), reg_data); | ||
1472 | |||
1473 | for (i = 0; i < tx_ring->count; i++) { | ||
1474 | struct ixgbe_legacy_tx_desc *desc = IXGBE_TX_DESC(*tx_ring, i); | ||
1475 | struct sk_buff *skb; | ||
1476 | unsigned int size = 1024; | ||
1477 | |||
1478 | skb = alloc_skb(size, GFP_KERNEL); | ||
1479 | if (!skb) { | ||
1480 | ret_val = 3; | ||
1481 | goto err_nomem; | ||
1482 | } | ||
1483 | skb_put(skb, size); | ||
1484 | tx_ring->tx_buffer_info[i].skb = skb; | ||
1485 | tx_ring->tx_buffer_info[i].length = skb->len; | ||
1486 | tx_ring->tx_buffer_info[i].dma = | ||
1487 | pci_map_single(pdev, skb->data, skb->len, | ||
1488 | PCI_DMA_TODEVICE); | ||
1489 | desc->buffer_addr = cpu_to_le64(tx_ring->tx_buffer_info[i].dma); | ||
1490 | desc->lower.data = cpu_to_le32(skb->len); | ||
1491 | desc->lower.data |= cpu_to_le32(IXGBE_TXD_CMD_EOP | | ||
1492 | IXGBE_TXD_CMD_IFCS | | ||
1493 | IXGBE_TXD_CMD_RS); | ||
1494 | desc->upper.data = 0; | ||
1495 | } | ||
1496 | |||
1497 | /* Setup Rx Descriptor ring and Rx buffers */ | ||
1498 | |||
1499 | if (!rx_ring->count) | ||
1500 | rx_ring->count = IXGBE_DEFAULT_RXD; | ||
1501 | |||
1502 | rx_ring->rx_buffer_info = kcalloc(rx_ring->count, | ||
1503 | sizeof(struct ixgbe_rx_buffer), | ||
1504 | GFP_KERNEL); | ||
1505 | if (!(rx_ring->rx_buffer_info)) { | ||
1506 | ret_val = 4; | ||
1507 | goto err_nomem; | ||
1508 | } | ||
1509 | |||
1510 | rx_ring->size = rx_ring->count * sizeof(struct ixgbe_legacy_rx_desc); | ||
1511 | rx_ring->size = ALIGN(rx_ring->size, 4096); | ||
1512 | if (!(rx_ring->desc = pci_alloc_consistent(pdev, rx_ring->size, | ||
1513 | &rx_ring->dma))) { | ||
1514 | ret_val = 5; | ||
1515 | goto err_nomem; | ||
1516 | } | ||
1517 | rx_ring->next_to_use = rx_ring->next_to_clean = 0; | ||
1518 | |||
1519 | rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXCTRL); | ||
1520 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl & ~IXGBE_RXCTRL_RXEN); | ||
1521 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDBAL(0), | ||
1522 | ((u64)rx_ring->dma & 0xFFFFFFFF)); | ||
1523 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDBAH(0), | ||
1524 | ((u64) rx_ring->dma >> 32)); | ||
1525 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDLEN(0), rx_ring->size); | ||
1526 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDH(0), 0); | ||
1527 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(0), 0); | ||
1528 | |||
1529 | reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL); | ||
1530 | reg_data |= IXGBE_FCTRL_BAM | IXGBE_FCTRL_SBP | IXGBE_FCTRL_MPE; | ||
1531 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_data); | ||
1532 | |||
1533 | reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0); | ||
1534 | reg_data &= ~IXGBE_HLREG0_LPBK; | ||
1535 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data); | ||
1536 | |||
1537 | reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_RDRXCTL); | ||
1538 | #define IXGBE_RDRXCTL_RDMTS_MASK 0x00000003 /* Receive Descriptor Minimum | ||
1539 | Threshold Size mask */ | ||
1540 | reg_data &= ~IXGBE_RDRXCTL_RDMTS_MASK; | ||
1541 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDRXCTL, reg_data); | ||
1542 | |||
1543 | reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_MCSTCTRL); | ||
1544 | #define IXGBE_MCSTCTRL_MO_MASK 0x00000003 /* Multicast Offset mask */ | ||
1545 | reg_data &= ~IXGBE_MCSTCTRL_MO_MASK; | ||
1546 | reg_data |= adapter->hw.mac.mc_filter_type; | ||
1547 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_MCSTCTRL, reg_data); | ||
1548 | |||
1549 | reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_RXDCTL(0)); | ||
1550 | reg_data |= IXGBE_RXDCTL_ENABLE; | ||
1551 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(0), reg_data); | ||
1552 | if (adapter->hw.mac.type == ixgbe_mac_82599EB) { | ||
1553 | int j = adapter->rx_ring[0].reg_idx; | ||
1554 | u32 k; | ||
1555 | for (k = 0; k < 10; k++) { | ||
1556 | if (IXGBE_READ_REG(&adapter->hw, | ||
1557 | IXGBE_RXDCTL(j)) & IXGBE_RXDCTL_ENABLE) | ||
1558 | break; | ||
1559 | else | ||
1560 | msleep(1); | ||
1561 | } | ||
1562 | } | ||
1563 | |||
1564 | rctl |= IXGBE_RXCTRL_RXEN | IXGBE_RXCTRL_DMBYPS; | ||
1565 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl); | ||
1566 | |||
1567 | for (i = 0; i < rx_ring->count; i++) { | ||
1568 | struct ixgbe_legacy_rx_desc *rx_desc = | ||
1569 | IXGBE_RX_DESC(*rx_ring, i); | ||
1570 | struct sk_buff *skb; | ||
1571 | |||
1572 | skb = alloc_skb(IXGBE_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL); | ||
1573 | if (!skb) { | ||
1574 | ret_val = 6; | ||
1575 | goto err_nomem; | ||
1576 | } | ||
1577 | skb_reserve(skb, NET_IP_ALIGN); | ||
1578 | rx_ring->rx_buffer_info[i].skb = skb; | ||
1579 | rx_ring->rx_buffer_info[i].dma = | ||
1580 | pci_map_single(pdev, skb->data, IXGBE_RXBUFFER_2048, | ||
1581 | PCI_DMA_FROMDEVICE); | ||
1582 | rx_desc->buffer_addr = | ||
1583 | cpu_to_le64(rx_ring->rx_buffer_info[i].dma); | ||
1584 | memset(skb->data, 0x00, skb->len); | ||
1585 | } | ||
1586 | |||
1587 | return 0; | ||
1588 | |||
1589 | err_nomem: | ||
1590 | ixgbe_free_desc_rings(adapter); | ||
1591 | return ret_val; | ||
1592 | } | ||
1593 | |||
1594 | static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter) | ||
1595 | { | ||
1596 | struct ixgbe_hw *hw = &adapter->hw; | ||
1597 | u32 reg_data; | ||
1598 | |||
1599 | /* right now we only support MAC loopback in the driver */ | ||
1600 | |||
1601 | /* Setup MAC loopback */ | ||
1602 | reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0); | ||
1603 | reg_data |= IXGBE_HLREG0_LPBK; | ||
1604 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data); | ||
1605 | |||
1606 | reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_AUTOC); | ||
1607 | reg_data &= ~IXGBE_AUTOC_LMS_MASK; | ||
1608 | reg_data |= IXGBE_AUTOC_LMS_10G_LINK_NO_AN | IXGBE_AUTOC_FLU; | ||
1609 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_AUTOC, reg_data); | ||
1610 | |||
1611 | /* Disable Atlas Tx lanes; re-enabled in reset path */ | ||
1612 | if (hw->mac.type == ixgbe_mac_82598EB) { | ||
1613 | u8 atlas; | ||
1614 | |||
1615 | hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &atlas); | ||
1616 | atlas |= IXGBE_ATLAS_PDN_TX_REG_EN; | ||
1617 | hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, atlas); | ||
1618 | |||
1619 | hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, &atlas); | ||
1620 | atlas |= IXGBE_ATLAS_PDN_TX_10G_QL_ALL; | ||
1621 | hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, atlas); | ||
1622 | |||
1623 | hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, &atlas); | ||
1624 | atlas |= IXGBE_ATLAS_PDN_TX_1G_QL_ALL; | ||
1625 | hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, atlas); | ||
1626 | |||
1627 | hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, &atlas); | ||
1628 | atlas |= IXGBE_ATLAS_PDN_TX_AN_QL_ALL; | ||
1629 | hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, atlas); | ||
1630 | } | ||
1631 | |||
1632 | return 0; | ||
1633 | } | ||
1634 | |||
1635 | static void ixgbe_loopback_cleanup(struct ixgbe_adapter *adapter) | ||
1636 | { | ||
1637 | u32 reg_data; | ||
1638 | |||
1639 | reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0); | ||
1640 | reg_data &= ~IXGBE_HLREG0_LPBK; | ||
1641 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data); | ||
1642 | } | ||
1643 | |||
1644 | static void ixgbe_create_lbtest_frame(struct sk_buff *skb, | ||
1645 | unsigned int frame_size) | ||
1646 | { | ||
1647 | memset(skb->data, 0xFF, frame_size); | ||
1648 | frame_size &= ~1; | ||
1649 | memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1); | ||
1650 | memset(&skb->data[frame_size / 2 + 10], 0xBE, 1); | ||
1651 | memset(&skb->data[frame_size / 2 + 12], 0xAF, 1); | ||
1652 | } | ||
1653 | |||
1654 | static int ixgbe_check_lbtest_frame(struct sk_buff *skb, | ||
1655 | unsigned int frame_size) | ||
1656 | { | ||
1657 | frame_size &= ~1; | ||
1658 | if (*(skb->data + 3) == 0xFF) { | ||
1659 | if ((*(skb->data + frame_size / 2 + 10) == 0xBE) && | ||
1660 | (*(skb->data + frame_size / 2 + 12) == 0xAF)) { | ||
1661 | return 0; | ||
1662 | } | ||
1663 | } | ||
1664 | return 13; | ||
1665 | } | ||
1666 | |||
1667 | static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter) | ||
1668 | { | ||
1669 | struct ixgbe_ring *tx_ring = &adapter->test_tx_ring; | ||
1670 | struct ixgbe_ring *rx_ring = &adapter->test_rx_ring; | ||
1671 | struct pci_dev *pdev = adapter->pdev; | ||
1672 | int i, j, k, l, lc, good_cnt, ret_val = 0; | ||
1673 | unsigned long time; | ||
1674 | |||
1675 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(0), rx_ring->count - 1); | ||
1676 | |||
1677 | /* | ||
1678 | * Calculate the loop count based on the largest descriptor ring | ||
1679 | * The idea is to wrap the largest ring a number of times using 64 | ||
1680 | * send/receive pairs during each loop | ||
1681 | */ | ||
1682 | |||
1683 | if (rx_ring->count <= tx_ring->count) | ||
1684 | lc = ((tx_ring->count / 64) * 2) + 1; | ||
1685 | else | ||
1686 | lc = ((rx_ring->count / 64) * 2) + 1; | ||
1687 | |||
1688 | k = l = 0; | ||
1689 | for (j = 0; j <= lc; j++) { | ||
1690 | for (i = 0; i < 64; i++) { | ||
1691 | ixgbe_create_lbtest_frame( | ||
1692 | tx_ring->tx_buffer_info[k].skb, | ||
1693 | 1024); | ||
1694 | pci_dma_sync_single_for_device(pdev, | ||
1695 | tx_ring->tx_buffer_info[k].dma, | ||
1696 | tx_ring->tx_buffer_info[k].length, | ||
1697 | PCI_DMA_TODEVICE); | ||
1698 | if (unlikely(++k == tx_ring->count)) | ||
1699 | k = 0; | ||
1700 | } | ||
1701 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(0), k); | ||
1702 | msleep(200); | ||
1703 | /* set the start time for the receive */ | ||
1704 | time = jiffies; | ||
1705 | good_cnt = 0; | ||
1706 | do { | ||
1707 | /* receive the sent packets */ | ||
1708 | pci_dma_sync_single_for_cpu(pdev, | ||
1709 | rx_ring->rx_buffer_info[l].dma, | ||
1710 | IXGBE_RXBUFFER_2048, | ||
1711 | PCI_DMA_FROMDEVICE); | ||
1712 | ret_val = ixgbe_check_lbtest_frame( | ||
1713 | rx_ring->rx_buffer_info[l].skb, 1024); | ||
1714 | if (!ret_val) | ||
1715 | good_cnt++; | ||
1716 | if (++l == rx_ring->count) | ||
1717 | l = 0; | ||
1718 | /* | ||
1719 | * time + 20 msecs (200 msecs on 2.4) is more than | ||
1720 | * enough time to complete the receives, if it's | ||
1721 | * exceeded, break and error off | ||
1722 | */ | ||
1723 | } while (good_cnt < 64 && jiffies < (time + 20)); | ||
1724 | if (good_cnt != 64) { | ||
1725 | /* ret_val is the same as mis-compare */ | ||
1726 | ret_val = 13; | ||
1727 | break; | ||
1728 | } | ||
1729 | if (jiffies >= (time + 20)) { | ||
1730 | /* Error code for time out error */ | ||
1731 | ret_val = 14; | ||
1732 | break; | ||
1733 | } | ||
1734 | } | ||
1735 | |||
1736 | return ret_val; | ||
1737 | } | ||
1738 | |||
1739 | static int ixgbe_loopback_test(struct ixgbe_adapter *adapter, u64 *data) | ||
1740 | { | ||
1741 | *data = ixgbe_setup_desc_rings(adapter); | ||
1742 | if (*data) | ||
1743 | goto out; | ||
1744 | *data = ixgbe_setup_loopback_test(adapter); | ||
1745 | if (*data) | ||
1746 | goto err_loopback; | ||
1747 | *data = ixgbe_run_loopback_test(adapter); | ||
1748 | ixgbe_loopback_cleanup(adapter); | ||
1749 | |||
1750 | err_loopback: | ||
1751 | ixgbe_free_desc_rings(adapter); | ||
1752 | out: | ||
1753 | return *data; | ||
1754 | } | ||
1755 | |||
1756 | static void ixgbe_diag_test(struct net_device *netdev, | ||
1757 | struct ethtool_test *eth_test, u64 *data) | ||
1758 | { | ||
1759 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||
1760 | bool if_running = netif_running(netdev); | ||
1761 | |||
1762 | set_bit(__IXGBE_TESTING, &adapter->state); | ||
1763 | if (eth_test->flags == ETH_TEST_FL_OFFLINE) { | ||
1764 | /* Offline tests */ | ||
1765 | |||
1766 | DPRINTK(HW, INFO, "offline testing starting\n"); | ||
1767 | |||
1768 | /* Link test performed before hardware reset so autoneg doesn't | ||
1769 | * interfere with test result */ | ||
1770 | if (ixgbe_link_test(adapter, &data[4])) | ||
1771 | eth_test->flags |= ETH_TEST_FL_FAILED; | ||
1772 | |||
1773 | if (if_running) | ||
1774 | /* indicate we're in test mode */ | ||
1775 | dev_close(netdev); | ||
1776 | else | ||
1777 | ixgbe_reset(adapter); | ||
1778 | |||
1779 | DPRINTK(HW, INFO, "register testing starting\n"); | ||
1780 | if (ixgbe_reg_test(adapter, &data[0])) | ||
1781 | eth_test->flags |= ETH_TEST_FL_FAILED; | ||
1782 | |||
1783 | ixgbe_reset(adapter); | ||
1784 | DPRINTK(HW, INFO, "eeprom testing starting\n"); | ||
1785 | if (ixgbe_eeprom_test(adapter, &data[1])) | ||
1786 | eth_test->flags |= ETH_TEST_FL_FAILED; | ||
1787 | |||
1788 | ixgbe_reset(adapter); | ||
1789 | DPRINTK(HW, INFO, "interrupt testing starting\n"); | ||
1790 | if (ixgbe_intr_test(adapter, &data[2])) | ||
1791 | eth_test->flags |= ETH_TEST_FL_FAILED; | ||
1792 | |||
1793 | ixgbe_reset(adapter); | ||
1794 | DPRINTK(HW, INFO, "loopback testing starting\n"); | ||
1795 | if (ixgbe_loopback_test(adapter, &data[3])) | ||
1796 | eth_test->flags |= ETH_TEST_FL_FAILED; | ||
1797 | |||
1798 | ixgbe_reset(adapter); | ||
1799 | |||
1800 | clear_bit(__IXGBE_TESTING, &adapter->state); | ||
1801 | if (if_running) | ||
1802 | dev_open(netdev); | ||
1803 | } else { | ||
1804 | DPRINTK(HW, INFO, "online testing starting\n"); | ||
1805 | /* Online tests */ | ||
1806 | if (ixgbe_link_test(adapter, &data[4])) | ||
1807 | eth_test->flags |= ETH_TEST_FL_FAILED; | ||
1808 | |||
1809 | /* Online tests aren't run; pass by default */ | ||
1810 | data[0] = 0; | ||
1811 | data[1] = 0; | ||
1812 | data[2] = 0; | ||
1813 | data[3] = 0; | ||
1814 | |||
1815 | clear_bit(__IXGBE_TESTING, &adapter->state); | ||
1816 | } | ||
1817 | msleep_interruptible(4 * 1000); | ||
1818 | } | ||
945 | 1819 | ||
946 | static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter, | 1820 | static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter, |
947 | struct ethtool_wolinfo *wol) | 1821 | struct ethtool_wolinfo *wol) |
@@ -1106,20 +1980,40 @@ static int ixgbe_set_coalesce(struct net_device *netdev, | |||
1106 | } | 1980 | } |
1107 | 1981 | ||
1108 | for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) { | 1982 | for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) { |
1109 | struct ixgbe_q_vector *q_vector = &adapter->q_vector[i]; | 1983 | struct ixgbe_q_vector *q_vector = adapter->q_vector[i]; |
1110 | if (q_vector->txr_count && !q_vector->rxr_count) | 1984 | if (q_vector->txr_count && !q_vector->rxr_count) |
1111 | /* tx vector gets half the rate */ | 1985 | /* tx vector gets half the rate */ |
1112 | q_vector->eitr = (adapter->eitr_param >> 1); | 1986 | q_vector->eitr = (adapter->eitr_param >> 1); |
1113 | else | 1987 | else |
1114 | /* rx only or mixed */ | 1988 | /* rx only or mixed */ |
1115 | q_vector->eitr = adapter->eitr_param; | 1989 | q_vector->eitr = adapter->eitr_param; |
1116 | ixgbe_write_eitr(adapter, i, | 1990 | ixgbe_write_eitr(q_vector); |
1117 | EITR_INTS_PER_SEC_TO_REG(q_vector->eitr)); | ||
1118 | } | 1991 | } |
1119 | 1992 | ||
1120 | return 0; | 1993 | return 0; |
1121 | } | 1994 | } |
1122 | 1995 | ||
1996 | static int ixgbe_set_flags(struct net_device *netdev, u32 data) | ||
1997 | { | ||
1998 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||
1999 | |||
2000 | ethtool_op_set_flags(netdev, data); | ||
2001 | |||
2002 | if (!(adapter->flags & IXGBE_FLAG2_RSC_CAPABLE)) | ||
2003 | return 0; | ||
2004 | |||
2005 | /* if state changes we need to update adapter->flags and reset */ | ||
2006 | if ((!!(data & ETH_FLAG_LRO)) != | ||
2007 | (!!(adapter->flags & IXGBE_FLAG2_RSC_ENABLED))) { | ||
2008 | adapter->flags ^= IXGBE_FLAG2_RSC_ENABLED; | ||
2009 | if (netif_running(netdev)) | ||
2010 | ixgbe_reinit_locked(adapter); | ||
2011 | else | ||
2012 | ixgbe_reset(adapter); | ||
2013 | } | ||
2014 | return 0; | ||
2015 | |||
2016 | } | ||
1123 | 2017 | ||
1124 | static const struct ethtool_ops ixgbe_ethtool_ops = { | 2018 | static const struct ethtool_ops ixgbe_ethtool_ops = { |
1125 | .get_settings = ixgbe_get_settings, | 2019 | .get_settings = ixgbe_get_settings, |
@@ -1147,6 +2041,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = { | |||
1147 | .set_msglevel = ixgbe_set_msglevel, | 2041 | .set_msglevel = ixgbe_set_msglevel, |
1148 | .get_tso = ethtool_op_get_tso, | 2042 | .get_tso = ethtool_op_get_tso, |
1149 | .set_tso = ixgbe_set_tso, | 2043 | .set_tso = ixgbe_set_tso, |
2044 | .self_test = ixgbe_diag_test, | ||
1150 | .get_strings = ixgbe_get_strings, | 2045 | .get_strings = ixgbe_get_strings, |
1151 | .phys_id = ixgbe_phys_id, | 2046 | .phys_id = ixgbe_phys_id, |
1152 | .get_sset_count = ixgbe_get_sset_count, | 2047 | .get_sset_count = ixgbe_get_sset_count, |
@@ -1154,7 +2049,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = { | |||
1154 | .get_coalesce = ixgbe_get_coalesce, | 2049 | .get_coalesce = ixgbe_get_coalesce, |
1155 | .set_coalesce = ixgbe_set_coalesce, | 2050 | .set_coalesce = ixgbe_set_coalesce, |
1156 | .get_flags = ethtool_op_get_flags, | 2051 | .get_flags = ethtool_op_get_flags, |
1157 | .set_flags = ethtool_op_set_flags, | 2052 | .set_flags = ixgbe_set_flags, |
1158 | }; | 2053 | }; |
1159 | 2054 | ||
1160 | void ixgbe_set_ethtool_ops(struct net_device *netdev) | 2055 | void ixgbe_set_ethtool_ops(struct net_device *netdev) |