1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /* Copyright(c) 1999 - 2008 Intel Corporation. */
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun /* ethtool support for ixgb */
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun #include "ixgb.h"
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <linux/uaccess.h>
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #define IXGB_ALL_RAR_ENTRIES 16
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun enum {NETDEV_STATS, IXGB_STATS};
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun struct ixgb_stats {
15*4882a593Smuzhiyun char stat_string[ETH_GSTRING_LEN];
16*4882a593Smuzhiyun int type;
17*4882a593Smuzhiyun int sizeof_stat;
18*4882a593Smuzhiyun int stat_offset;
19*4882a593Smuzhiyun };
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun #define IXGB_STAT(m) IXGB_STATS, \
22*4882a593Smuzhiyun sizeof_field(struct ixgb_adapter, m), \
23*4882a593Smuzhiyun offsetof(struct ixgb_adapter, m)
24*4882a593Smuzhiyun #define IXGB_NETDEV_STAT(m) NETDEV_STATS, \
25*4882a593Smuzhiyun sizeof_field(struct net_device, m), \
26*4882a593Smuzhiyun offsetof(struct net_device, m)
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun static struct ixgb_stats ixgb_gstrings_stats[] = {
29*4882a593Smuzhiyun {"rx_packets", IXGB_NETDEV_STAT(stats.rx_packets)},
30*4882a593Smuzhiyun {"tx_packets", IXGB_NETDEV_STAT(stats.tx_packets)},
31*4882a593Smuzhiyun {"rx_bytes", IXGB_NETDEV_STAT(stats.rx_bytes)},
32*4882a593Smuzhiyun {"tx_bytes", IXGB_NETDEV_STAT(stats.tx_bytes)},
33*4882a593Smuzhiyun {"rx_errors", IXGB_NETDEV_STAT(stats.rx_errors)},
34*4882a593Smuzhiyun {"tx_errors", IXGB_NETDEV_STAT(stats.tx_errors)},
35*4882a593Smuzhiyun {"rx_dropped", IXGB_NETDEV_STAT(stats.rx_dropped)},
36*4882a593Smuzhiyun {"tx_dropped", IXGB_NETDEV_STAT(stats.tx_dropped)},
37*4882a593Smuzhiyun {"multicast", IXGB_NETDEV_STAT(stats.multicast)},
38*4882a593Smuzhiyun {"collisions", IXGB_NETDEV_STAT(stats.collisions)},
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun /* { "rx_length_errors", IXGB_NETDEV_STAT(stats.rx_length_errors) }, */
41*4882a593Smuzhiyun {"rx_over_errors", IXGB_NETDEV_STAT(stats.rx_over_errors)},
42*4882a593Smuzhiyun {"rx_crc_errors", IXGB_NETDEV_STAT(stats.rx_crc_errors)},
43*4882a593Smuzhiyun {"rx_frame_errors", IXGB_NETDEV_STAT(stats.rx_frame_errors)},
44*4882a593Smuzhiyun {"rx_no_buffer_count", IXGB_STAT(stats.rnbc)},
45*4882a593Smuzhiyun {"rx_fifo_errors", IXGB_NETDEV_STAT(stats.rx_fifo_errors)},
46*4882a593Smuzhiyun {"rx_missed_errors", IXGB_NETDEV_STAT(stats.rx_missed_errors)},
47*4882a593Smuzhiyun {"tx_aborted_errors", IXGB_NETDEV_STAT(stats.tx_aborted_errors)},
48*4882a593Smuzhiyun {"tx_carrier_errors", IXGB_NETDEV_STAT(stats.tx_carrier_errors)},
49*4882a593Smuzhiyun {"tx_fifo_errors", IXGB_NETDEV_STAT(stats.tx_fifo_errors)},
50*4882a593Smuzhiyun {"tx_heartbeat_errors", IXGB_NETDEV_STAT(stats.tx_heartbeat_errors)},
51*4882a593Smuzhiyun {"tx_window_errors", IXGB_NETDEV_STAT(stats.tx_window_errors)},
52*4882a593Smuzhiyun {"tx_deferred_ok", IXGB_STAT(stats.dc)},
53*4882a593Smuzhiyun {"tx_timeout_count", IXGB_STAT(tx_timeout_count) },
54*4882a593Smuzhiyun {"tx_restart_queue", IXGB_STAT(restart_queue) },
55*4882a593Smuzhiyun {"rx_long_length_errors", IXGB_STAT(stats.roc)},
56*4882a593Smuzhiyun {"rx_short_length_errors", IXGB_STAT(stats.ruc)},
57*4882a593Smuzhiyun {"tx_tcp_seg_good", IXGB_STAT(stats.tsctc)},
58*4882a593Smuzhiyun {"tx_tcp_seg_failed", IXGB_STAT(stats.tsctfc)},
59*4882a593Smuzhiyun {"rx_flow_control_xon", IXGB_STAT(stats.xonrxc)},
60*4882a593Smuzhiyun {"rx_flow_control_xoff", IXGB_STAT(stats.xoffrxc)},
61*4882a593Smuzhiyun {"tx_flow_control_xon", IXGB_STAT(stats.xontxc)},
62*4882a593Smuzhiyun {"tx_flow_control_xoff", IXGB_STAT(stats.xofftxc)},
63*4882a593Smuzhiyun {"rx_csum_offload_good", IXGB_STAT(hw_csum_rx_good)},
64*4882a593Smuzhiyun {"rx_csum_offload_errors", IXGB_STAT(hw_csum_rx_error)},
65*4882a593Smuzhiyun {"tx_csum_offload_good", IXGB_STAT(hw_csum_tx_good)},
66*4882a593Smuzhiyun {"tx_csum_offload_errors", IXGB_STAT(hw_csum_tx_error)}
67*4882a593Smuzhiyun };
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun #define IXGB_STATS_LEN ARRAY_SIZE(ixgb_gstrings_stats)
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun static int
ixgb_get_link_ksettings(struct net_device * netdev,struct ethtool_link_ksettings * cmd)72*4882a593Smuzhiyun ixgb_get_link_ksettings(struct net_device *netdev,
73*4882a593Smuzhiyun struct ethtool_link_ksettings *cmd)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun struct ixgb_adapter *adapter = netdev_priv(netdev);
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun ethtool_link_ksettings_zero_link_mode(cmd, supported);
78*4882a593Smuzhiyun ethtool_link_ksettings_add_link_mode(cmd, supported, 10000baseT_Full);
79*4882a593Smuzhiyun ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun ethtool_link_ksettings_zero_link_mode(cmd, advertising);
82*4882a593Smuzhiyun ethtool_link_ksettings_add_link_mode(cmd, advertising, 10000baseT_Full);
83*4882a593Smuzhiyun ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE);
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun cmd->base.port = PORT_FIBRE;
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun if (netif_carrier_ok(adapter->netdev)) {
88*4882a593Smuzhiyun cmd->base.speed = SPEED_10000;
89*4882a593Smuzhiyun cmd->base.duplex = DUPLEX_FULL;
90*4882a593Smuzhiyun } else {
91*4882a593Smuzhiyun cmd->base.speed = SPEED_UNKNOWN;
92*4882a593Smuzhiyun cmd->base.duplex = DUPLEX_UNKNOWN;
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun cmd->base.autoneg = AUTONEG_DISABLE;
96*4882a593Smuzhiyun return 0;
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun
ixgb_set_speed_duplex(struct net_device * netdev)99*4882a593Smuzhiyun void ixgb_set_speed_duplex(struct net_device *netdev)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun struct ixgb_adapter *adapter = netdev_priv(netdev);
102*4882a593Smuzhiyun /* be optimistic about our link, since we were up before */
103*4882a593Smuzhiyun adapter->link_speed = 10000;
104*4882a593Smuzhiyun adapter->link_duplex = FULL_DUPLEX;
105*4882a593Smuzhiyun netif_carrier_on(netdev);
106*4882a593Smuzhiyun netif_wake_queue(netdev);
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun static int
ixgb_set_link_ksettings(struct net_device * netdev,const struct ethtool_link_ksettings * cmd)110*4882a593Smuzhiyun ixgb_set_link_ksettings(struct net_device *netdev,
111*4882a593Smuzhiyun const struct ethtool_link_ksettings *cmd)
112*4882a593Smuzhiyun {
113*4882a593Smuzhiyun struct ixgb_adapter *adapter = netdev_priv(netdev);
114*4882a593Smuzhiyun u32 speed = cmd->base.speed;
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun if (cmd->base.autoneg == AUTONEG_ENABLE ||
117*4882a593Smuzhiyun (speed + cmd->base.duplex != SPEED_10000 + DUPLEX_FULL))
118*4882a593Smuzhiyun return -EINVAL;
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun if (netif_running(adapter->netdev)) {
121*4882a593Smuzhiyun ixgb_down(adapter, true);
122*4882a593Smuzhiyun ixgb_reset(adapter);
123*4882a593Smuzhiyun ixgb_up(adapter);
124*4882a593Smuzhiyun ixgb_set_speed_duplex(netdev);
125*4882a593Smuzhiyun } else
126*4882a593Smuzhiyun ixgb_reset(adapter);
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun return 0;
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun static void
ixgb_get_pauseparam(struct net_device * netdev,struct ethtool_pauseparam * pause)132*4882a593Smuzhiyun ixgb_get_pauseparam(struct net_device *netdev,
133*4882a593Smuzhiyun struct ethtool_pauseparam *pause)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun struct ixgb_adapter *adapter = netdev_priv(netdev);
136*4882a593Smuzhiyun struct ixgb_hw *hw = &adapter->hw;
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun pause->autoneg = AUTONEG_DISABLE;
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun if (hw->fc.type == ixgb_fc_rx_pause)
141*4882a593Smuzhiyun pause->rx_pause = 1;
142*4882a593Smuzhiyun else if (hw->fc.type == ixgb_fc_tx_pause)
143*4882a593Smuzhiyun pause->tx_pause = 1;
144*4882a593Smuzhiyun else if (hw->fc.type == ixgb_fc_full) {
145*4882a593Smuzhiyun pause->rx_pause = 1;
146*4882a593Smuzhiyun pause->tx_pause = 1;
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun static int
ixgb_set_pauseparam(struct net_device * netdev,struct ethtool_pauseparam * pause)151*4882a593Smuzhiyun ixgb_set_pauseparam(struct net_device *netdev,
152*4882a593Smuzhiyun struct ethtool_pauseparam *pause)
153*4882a593Smuzhiyun {
154*4882a593Smuzhiyun struct ixgb_adapter *adapter = netdev_priv(netdev);
155*4882a593Smuzhiyun struct ixgb_hw *hw = &adapter->hw;
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun if (pause->autoneg == AUTONEG_ENABLE)
158*4882a593Smuzhiyun return -EINVAL;
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun if (pause->rx_pause && pause->tx_pause)
161*4882a593Smuzhiyun hw->fc.type = ixgb_fc_full;
162*4882a593Smuzhiyun else if (pause->rx_pause && !pause->tx_pause)
163*4882a593Smuzhiyun hw->fc.type = ixgb_fc_rx_pause;
164*4882a593Smuzhiyun else if (!pause->rx_pause && pause->tx_pause)
165*4882a593Smuzhiyun hw->fc.type = ixgb_fc_tx_pause;
166*4882a593Smuzhiyun else if (!pause->rx_pause && !pause->tx_pause)
167*4882a593Smuzhiyun hw->fc.type = ixgb_fc_none;
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun if (netif_running(adapter->netdev)) {
170*4882a593Smuzhiyun ixgb_down(adapter, true);
171*4882a593Smuzhiyun ixgb_up(adapter);
172*4882a593Smuzhiyun ixgb_set_speed_duplex(netdev);
173*4882a593Smuzhiyun } else
174*4882a593Smuzhiyun ixgb_reset(adapter);
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun return 0;
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun static u32
ixgb_get_msglevel(struct net_device * netdev)180*4882a593Smuzhiyun ixgb_get_msglevel(struct net_device *netdev)
181*4882a593Smuzhiyun {
182*4882a593Smuzhiyun struct ixgb_adapter *adapter = netdev_priv(netdev);
183*4882a593Smuzhiyun return adapter->msg_enable;
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun static void
ixgb_set_msglevel(struct net_device * netdev,u32 data)187*4882a593Smuzhiyun ixgb_set_msglevel(struct net_device *netdev, u32 data)
188*4882a593Smuzhiyun {
189*4882a593Smuzhiyun struct ixgb_adapter *adapter = netdev_priv(netdev);
190*4882a593Smuzhiyun adapter->msg_enable = data;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun #define IXGB_GET_STAT(_A_, _R_) _A_->stats._R_
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun static int
ixgb_get_regs_len(struct net_device * netdev)195*4882a593Smuzhiyun ixgb_get_regs_len(struct net_device *netdev)
196*4882a593Smuzhiyun {
197*4882a593Smuzhiyun #define IXGB_REG_DUMP_LEN 136*sizeof(u32)
198*4882a593Smuzhiyun return IXGB_REG_DUMP_LEN;
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun static void
ixgb_get_regs(struct net_device * netdev,struct ethtool_regs * regs,void * p)202*4882a593Smuzhiyun ixgb_get_regs(struct net_device *netdev,
203*4882a593Smuzhiyun struct ethtool_regs *regs, void *p)
204*4882a593Smuzhiyun {
205*4882a593Smuzhiyun struct ixgb_adapter *adapter = netdev_priv(netdev);
206*4882a593Smuzhiyun struct ixgb_hw *hw = &adapter->hw;
207*4882a593Smuzhiyun u32 *reg = p;
208*4882a593Smuzhiyun u32 *reg_start = reg;
209*4882a593Smuzhiyun u8 i;
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun /* the 1 (one) below indicates an attempt at versioning, if the
212*4882a593Smuzhiyun * interface in ethtool or the driver changes, this 1 should be
213*4882a593Smuzhiyun * incremented */
214*4882a593Smuzhiyun regs->version = (1<<24) | hw->revision_id << 16 | hw->device_id;
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun /* General Registers */
217*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, CTRL0); /* 0 */
218*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, CTRL1); /* 1 */
219*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, STATUS); /* 2 */
220*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, EECD); /* 3 */
221*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, MFS); /* 4 */
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun /* Interrupt */
224*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, ICR); /* 5 */
225*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, ICS); /* 6 */
226*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, IMS); /* 7 */
227*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, IMC); /* 8 */
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun /* Receive */
230*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, RCTL); /* 9 */
231*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, FCRTL); /* 10 */
232*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, FCRTH); /* 11 */
233*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, RDBAL); /* 12 */
234*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, RDBAH); /* 13 */
235*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, RDLEN); /* 14 */
236*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, RDH); /* 15 */
237*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, RDT); /* 16 */
238*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, RDTR); /* 17 */
239*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, RXDCTL); /* 18 */
240*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, RAIDC); /* 19 */
241*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, RXCSUM); /* 20 */
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun /* there are 16 RAR entries in hardware, we only use 3 */
244*4882a593Smuzhiyun for (i = 0; i < IXGB_ALL_RAR_ENTRIES; i++) {
245*4882a593Smuzhiyun *reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */
246*4882a593Smuzhiyun *reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun /* Transmit */
250*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, TCTL); /* 53 */
251*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, TDBAL); /* 54 */
252*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, TDBAH); /* 55 */
253*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, TDLEN); /* 56 */
254*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, TDH); /* 57 */
255*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, TDT); /* 58 */
256*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, TIDV); /* 59 */
257*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, TXDCTL); /* 60 */
258*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, TSPMT); /* 61 */
259*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, PAP); /* 62 */
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun /* Physical */
262*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, PCSC1); /* 63 */
263*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, PCSC2); /* 64 */
264*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, PCSS1); /* 65 */
265*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, PCSS2); /* 66 */
266*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, XPCSS); /* 67 */
267*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, UCCR); /* 68 */
268*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, XPCSTC); /* 69 */
269*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, MACA); /* 70 */
270*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, APAE); /* 71 */
271*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, ARD); /* 72 */
272*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, AIS); /* 73 */
273*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, MSCA); /* 74 */
274*4882a593Smuzhiyun *reg++ = IXGB_READ_REG(hw, MSRWD); /* 75 */
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun /* Statistics */
277*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, tprl); /* 76 */
278*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, tprh); /* 77 */
279*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, gprcl); /* 78 */
280*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, gprch); /* 79 */
281*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, bprcl); /* 80 */
282*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, bprch); /* 81 */
283*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, mprcl); /* 82 */
284*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, mprch); /* 83 */
285*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, uprcl); /* 84 */
286*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, uprch); /* 85 */
287*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, vprcl); /* 86 */
288*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, vprch); /* 87 */
289*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, jprcl); /* 88 */
290*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, jprch); /* 89 */
291*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, gorcl); /* 90 */
292*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, gorch); /* 91 */
293*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, torl); /* 92 */
294*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, torh); /* 93 */
295*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, rnbc); /* 94 */
296*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, ruc); /* 95 */
297*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, roc); /* 96 */
298*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, rlec); /* 97 */
299*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, crcerrs); /* 98 */
300*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, icbc); /* 99 */
301*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, ecbc); /* 100 */
302*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, mpc); /* 101 */
303*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, tptl); /* 102 */
304*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, tpth); /* 103 */
305*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, gptcl); /* 104 */
306*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, gptch); /* 105 */
307*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, bptcl); /* 106 */
308*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, bptch); /* 107 */
309*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, mptcl); /* 108 */
310*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, mptch); /* 109 */
311*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, uptcl); /* 110 */
312*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, uptch); /* 111 */
313*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, vptcl); /* 112 */
314*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, vptch); /* 113 */
315*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, jptcl); /* 114 */
316*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, jptch); /* 115 */
317*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, gotcl); /* 116 */
318*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, gotch); /* 117 */
319*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, totl); /* 118 */
320*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, toth); /* 119 */
321*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, dc); /* 120 */
322*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, plt64c); /* 121 */
323*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, tsctc); /* 122 */
324*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, tsctfc); /* 123 */
325*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, ibic); /* 124 */
326*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, rfc); /* 125 */
327*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, lfc); /* 126 */
328*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, pfrc); /* 127 */
329*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, pftc); /* 128 */
330*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, mcfrc); /* 129 */
331*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, mcftc); /* 130 */
332*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, xonrxc); /* 131 */
333*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, xontxc); /* 132 */
334*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, xoffrxc); /* 133 */
335*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, xofftxc); /* 134 */
336*4882a593Smuzhiyun *reg++ = IXGB_GET_STAT(adapter, rjc); /* 135 */
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun regs->len = (reg - reg_start) * sizeof(u32);
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun static int
ixgb_get_eeprom_len(struct net_device * netdev)342*4882a593Smuzhiyun ixgb_get_eeprom_len(struct net_device *netdev)
343*4882a593Smuzhiyun {
344*4882a593Smuzhiyun /* return size in bytes */
345*4882a593Smuzhiyun return IXGB_EEPROM_SIZE << 1;
346*4882a593Smuzhiyun }
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun static int
ixgb_get_eeprom(struct net_device * netdev,struct ethtool_eeprom * eeprom,u8 * bytes)349*4882a593Smuzhiyun ixgb_get_eeprom(struct net_device *netdev,
350*4882a593Smuzhiyun struct ethtool_eeprom *eeprom, u8 *bytes)
351*4882a593Smuzhiyun {
352*4882a593Smuzhiyun struct ixgb_adapter *adapter = netdev_priv(netdev);
353*4882a593Smuzhiyun struct ixgb_hw *hw = &adapter->hw;
354*4882a593Smuzhiyun __le16 *eeprom_buff;
355*4882a593Smuzhiyun int i, max_len, first_word, last_word;
356*4882a593Smuzhiyun int ret_val = 0;
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun if (eeprom->len == 0) {
359*4882a593Smuzhiyun ret_val = -EINVAL;
360*4882a593Smuzhiyun goto geeprom_error;
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun eeprom->magic = hw->vendor_id | (hw->device_id << 16);
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun max_len = ixgb_get_eeprom_len(netdev);
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun if (eeprom->offset > eeprom->offset + eeprom->len) {
368*4882a593Smuzhiyun ret_val = -EINVAL;
369*4882a593Smuzhiyun goto geeprom_error;
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun if ((eeprom->offset + eeprom->len) > max_len)
373*4882a593Smuzhiyun eeprom->len = (max_len - eeprom->offset);
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun first_word = eeprom->offset >> 1;
376*4882a593Smuzhiyun last_word = (eeprom->offset + eeprom->len - 1) >> 1;
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun eeprom_buff = kmalloc_array(last_word - first_word + 1,
379*4882a593Smuzhiyun sizeof(__le16),
380*4882a593Smuzhiyun GFP_KERNEL);
381*4882a593Smuzhiyun if (!eeprom_buff)
382*4882a593Smuzhiyun return -ENOMEM;
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun /* note the eeprom was good because the driver loaded */
385*4882a593Smuzhiyun for (i = 0; i <= (last_word - first_word); i++)
386*4882a593Smuzhiyun eeprom_buff[i] = ixgb_get_eeprom_word(hw, (first_word + i));
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
389*4882a593Smuzhiyun kfree(eeprom_buff);
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun geeprom_error:
392*4882a593Smuzhiyun return ret_val;
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun static int
ixgb_set_eeprom(struct net_device * netdev,struct ethtool_eeprom * eeprom,u8 * bytes)396*4882a593Smuzhiyun ixgb_set_eeprom(struct net_device *netdev,
397*4882a593Smuzhiyun struct ethtool_eeprom *eeprom, u8 *bytes)
398*4882a593Smuzhiyun {
399*4882a593Smuzhiyun struct ixgb_adapter *adapter = netdev_priv(netdev);
400*4882a593Smuzhiyun struct ixgb_hw *hw = &adapter->hw;
401*4882a593Smuzhiyun u16 *eeprom_buff;
402*4882a593Smuzhiyun void *ptr;
403*4882a593Smuzhiyun int max_len, first_word, last_word;
404*4882a593Smuzhiyun u16 i;
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun if (eeprom->len == 0)
407*4882a593Smuzhiyun return -EINVAL;
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
410*4882a593Smuzhiyun return -EFAULT;
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun max_len = ixgb_get_eeprom_len(netdev);
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun if (eeprom->offset > eeprom->offset + eeprom->len)
415*4882a593Smuzhiyun return -EINVAL;
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun if ((eeprom->offset + eeprom->len) > max_len)
418*4882a593Smuzhiyun eeprom->len = (max_len - eeprom->offset);
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun first_word = eeprom->offset >> 1;
421*4882a593Smuzhiyun last_word = (eeprom->offset + eeprom->len - 1) >> 1;
422*4882a593Smuzhiyun eeprom_buff = kmalloc(max_len, GFP_KERNEL);
423*4882a593Smuzhiyun if (!eeprom_buff)
424*4882a593Smuzhiyun return -ENOMEM;
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun ptr = (void *)eeprom_buff;
427*4882a593Smuzhiyun
428*4882a593Smuzhiyun if (eeprom->offset & 1) {
429*4882a593Smuzhiyun /* need read/modify/write of first changed EEPROM word */
430*4882a593Smuzhiyun /* only the second byte of the word is being modified */
431*4882a593Smuzhiyun eeprom_buff[0] = ixgb_read_eeprom(hw, first_word);
432*4882a593Smuzhiyun ptr++;
433*4882a593Smuzhiyun }
434*4882a593Smuzhiyun if ((eeprom->offset + eeprom->len) & 1) {
435*4882a593Smuzhiyun /* need read/modify/write of last changed EEPROM word */
436*4882a593Smuzhiyun /* only the first byte of the word is being modified */
437*4882a593Smuzhiyun eeprom_buff[last_word - first_word]
438*4882a593Smuzhiyun = ixgb_read_eeprom(hw, last_word);
439*4882a593Smuzhiyun }
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun memcpy(ptr, bytes, eeprom->len);
442*4882a593Smuzhiyun for (i = 0; i <= (last_word - first_word); i++)
443*4882a593Smuzhiyun ixgb_write_eeprom(hw, first_word + i, eeprom_buff[i]);
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun /* Update the checksum over the first part of the EEPROM if needed */
446*4882a593Smuzhiyun if (first_word <= EEPROM_CHECKSUM_REG)
447*4882a593Smuzhiyun ixgb_update_eeprom_checksum(hw);
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun kfree(eeprom_buff);
450*4882a593Smuzhiyun return 0;
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun static void
ixgb_get_drvinfo(struct net_device * netdev,struct ethtool_drvinfo * drvinfo)454*4882a593Smuzhiyun ixgb_get_drvinfo(struct net_device *netdev,
455*4882a593Smuzhiyun struct ethtool_drvinfo *drvinfo)
456*4882a593Smuzhiyun {
457*4882a593Smuzhiyun struct ixgb_adapter *adapter = netdev_priv(netdev);
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun strlcpy(drvinfo->driver, ixgb_driver_name,
460*4882a593Smuzhiyun sizeof(drvinfo->driver));
461*4882a593Smuzhiyun strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
462*4882a593Smuzhiyun sizeof(drvinfo->bus_info));
463*4882a593Smuzhiyun }
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun static void
ixgb_get_ringparam(struct net_device * netdev,struct ethtool_ringparam * ring)466*4882a593Smuzhiyun ixgb_get_ringparam(struct net_device *netdev,
467*4882a593Smuzhiyun struct ethtool_ringparam *ring)
468*4882a593Smuzhiyun {
469*4882a593Smuzhiyun struct ixgb_adapter *adapter = netdev_priv(netdev);
470*4882a593Smuzhiyun struct ixgb_desc_ring *txdr = &adapter->tx_ring;
471*4882a593Smuzhiyun struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun ring->rx_max_pending = MAX_RXD;
474*4882a593Smuzhiyun ring->tx_max_pending = MAX_TXD;
475*4882a593Smuzhiyun ring->rx_pending = rxdr->count;
476*4882a593Smuzhiyun ring->tx_pending = txdr->count;
477*4882a593Smuzhiyun }
478*4882a593Smuzhiyun
479*4882a593Smuzhiyun static int
ixgb_set_ringparam(struct net_device * netdev,struct ethtool_ringparam * ring)480*4882a593Smuzhiyun ixgb_set_ringparam(struct net_device *netdev,
481*4882a593Smuzhiyun struct ethtool_ringparam *ring)
482*4882a593Smuzhiyun {
483*4882a593Smuzhiyun struct ixgb_adapter *adapter = netdev_priv(netdev);
484*4882a593Smuzhiyun struct ixgb_desc_ring *txdr = &adapter->tx_ring;
485*4882a593Smuzhiyun struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
486*4882a593Smuzhiyun struct ixgb_desc_ring tx_old, tx_new, rx_old, rx_new;
487*4882a593Smuzhiyun int err;
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun tx_old = adapter->tx_ring;
490*4882a593Smuzhiyun rx_old = adapter->rx_ring;
491*4882a593Smuzhiyun
492*4882a593Smuzhiyun if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
493*4882a593Smuzhiyun return -EINVAL;
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun if (netif_running(adapter->netdev))
496*4882a593Smuzhiyun ixgb_down(adapter, true);
497*4882a593Smuzhiyun
498*4882a593Smuzhiyun rxdr->count = max(ring->rx_pending,(u32)MIN_RXD);
499*4882a593Smuzhiyun rxdr->count = min(rxdr->count,(u32)MAX_RXD);
500*4882a593Smuzhiyun rxdr->count = ALIGN(rxdr->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE);
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun txdr->count = max(ring->tx_pending,(u32)MIN_TXD);
503*4882a593Smuzhiyun txdr->count = min(txdr->count,(u32)MAX_TXD);
504*4882a593Smuzhiyun txdr->count = ALIGN(txdr->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
505*4882a593Smuzhiyun
506*4882a593Smuzhiyun if (netif_running(adapter->netdev)) {
507*4882a593Smuzhiyun /* Try to get new resources before deleting old */
508*4882a593Smuzhiyun if ((err = ixgb_setup_rx_resources(adapter)))
509*4882a593Smuzhiyun goto err_setup_rx;
510*4882a593Smuzhiyun if ((err = ixgb_setup_tx_resources(adapter)))
511*4882a593Smuzhiyun goto err_setup_tx;
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun /* save the new, restore the old in order to free it,
514*4882a593Smuzhiyun * then restore the new back again */
515*4882a593Smuzhiyun
516*4882a593Smuzhiyun rx_new = adapter->rx_ring;
517*4882a593Smuzhiyun tx_new = adapter->tx_ring;
518*4882a593Smuzhiyun adapter->rx_ring = rx_old;
519*4882a593Smuzhiyun adapter->tx_ring = tx_old;
520*4882a593Smuzhiyun ixgb_free_rx_resources(adapter);
521*4882a593Smuzhiyun ixgb_free_tx_resources(adapter);
522*4882a593Smuzhiyun adapter->rx_ring = rx_new;
523*4882a593Smuzhiyun adapter->tx_ring = tx_new;
524*4882a593Smuzhiyun if ((err = ixgb_up(adapter)))
525*4882a593Smuzhiyun return err;
526*4882a593Smuzhiyun ixgb_set_speed_duplex(netdev);
527*4882a593Smuzhiyun }
528*4882a593Smuzhiyun
529*4882a593Smuzhiyun return 0;
530*4882a593Smuzhiyun err_setup_tx:
531*4882a593Smuzhiyun ixgb_free_rx_resources(adapter);
532*4882a593Smuzhiyun err_setup_rx:
533*4882a593Smuzhiyun adapter->rx_ring = rx_old;
534*4882a593Smuzhiyun adapter->tx_ring = tx_old;
535*4882a593Smuzhiyun ixgb_up(adapter);
536*4882a593Smuzhiyun return err;
537*4882a593Smuzhiyun }
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun static int
ixgb_set_phys_id(struct net_device * netdev,enum ethtool_phys_id_state state)540*4882a593Smuzhiyun ixgb_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
541*4882a593Smuzhiyun {
542*4882a593Smuzhiyun struct ixgb_adapter *adapter = netdev_priv(netdev);
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun switch (state) {
545*4882a593Smuzhiyun case ETHTOOL_ID_ACTIVE:
546*4882a593Smuzhiyun return 2;
547*4882a593Smuzhiyun
548*4882a593Smuzhiyun case ETHTOOL_ID_ON:
549*4882a593Smuzhiyun ixgb_led_on(&adapter->hw);
550*4882a593Smuzhiyun break;
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun case ETHTOOL_ID_OFF:
553*4882a593Smuzhiyun case ETHTOOL_ID_INACTIVE:
554*4882a593Smuzhiyun ixgb_led_off(&adapter->hw);
555*4882a593Smuzhiyun }
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun return 0;
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun static int
ixgb_get_sset_count(struct net_device * netdev,int sset)561*4882a593Smuzhiyun ixgb_get_sset_count(struct net_device *netdev, int sset)
562*4882a593Smuzhiyun {
563*4882a593Smuzhiyun switch (sset) {
564*4882a593Smuzhiyun case ETH_SS_STATS:
565*4882a593Smuzhiyun return IXGB_STATS_LEN;
566*4882a593Smuzhiyun default:
567*4882a593Smuzhiyun return -EOPNOTSUPP;
568*4882a593Smuzhiyun }
569*4882a593Smuzhiyun }
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun static void
ixgb_get_ethtool_stats(struct net_device * netdev,struct ethtool_stats * stats,u64 * data)572*4882a593Smuzhiyun ixgb_get_ethtool_stats(struct net_device *netdev,
573*4882a593Smuzhiyun struct ethtool_stats *stats, u64 *data)
574*4882a593Smuzhiyun {
575*4882a593Smuzhiyun struct ixgb_adapter *adapter = netdev_priv(netdev);
576*4882a593Smuzhiyun int i;
577*4882a593Smuzhiyun char *p = NULL;
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun ixgb_update_stats(adapter);
580*4882a593Smuzhiyun for (i = 0; i < IXGB_STATS_LEN; i++) {
581*4882a593Smuzhiyun switch (ixgb_gstrings_stats[i].type) {
582*4882a593Smuzhiyun case NETDEV_STATS:
583*4882a593Smuzhiyun p = (char *) netdev +
584*4882a593Smuzhiyun ixgb_gstrings_stats[i].stat_offset;
585*4882a593Smuzhiyun break;
586*4882a593Smuzhiyun case IXGB_STATS:
587*4882a593Smuzhiyun p = (char *) adapter +
588*4882a593Smuzhiyun ixgb_gstrings_stats[i].stat_offset;
589*4882a593Smuzhiyun break;
590*4882a593Smuzhiyun }
591*4882a593Smuzhiyun
592*4882a593Smuzhiyun data[i] = (ixgb_gstrings_stats[i].sizeof_stat ==
593*4882a593Smuzhiyun sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
594*4882a593Smuzhiyun }
595*4882a593Smuzhiyun }
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun static void
ixgb_get_strings(struct net_device * netdev,u32 stringset,u8 * data)598*4882a593Smuzhiyun ixgb_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
599*4882a593Smuzhiyun {
600*4882a593Smuzhiyun int i;
601*4882a593Smuzhiyun
602*4882a593Smuzhiyun switch(stringset) {
603*4882a593Smuzhiyun case ETH_SS_STATS:
604*4882a593Smuzhiyun for (i = 0; i < IXGB_STATS_LEN; i++) {
605*4882a593Smuzhiyun memcpy(data + i * ETH_GSTRING_LEN,
606*4882a593Smuzhiyun ixgb_gstrings_stats[i].stat_string,
607*4882a593Smuzhiyun ETH_GSTRING_LEN);
608*4882a593Smuzhiyun }
609*4882a593Smuzhiyun break;
610*4882a593Smuzhiyun }
611*4882a593Smuzhiyun }
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun static const struct ethtool_ops ixgb_ethtool_ops = {
614*4882a593Smuzhiyun .get_drvinfo = ixgb_get_drvinfo,
615*4882a593Smuzhiyun .get_regs_len = ixgb_get_regs_len,
616*4882a593Smuzhiyun .get_regs = ixgb_get_regs,
617*4882a593Smuzhiyun .get_link = ethtool_op_get_link,
618*4882a593Smuzhiyun .get_eeprom_len = ixgb_get_eeprom_len,
619*4882a593Smuzhiyun .get_eeprom = ixgb_get_eeprom,
620*4882a593Smuzhiyun .set_eeprom = ixgb_set_eeprom,
621*4882a593Smuzhiyun .get_ringparam = ixgb_get_ringparam,
622*4882a593Smuzhiyun .set_ringparam = ixgb_set_ringparam,
623*4882a593Smuzhiyun .get_pauseparam = ixgb_get_pauseparam,
624*4882a593Smuzhiyun .set_pauseparam = ixgb_set_pauseparam,
625*4882a593Smuzhiyun .get_msglevel = ixgb_get_msglevel,
626*4882a593Smuzhiyun .set_msglevel = ixgb_set_msglevel,
627*4882a593Smuzhiyun .get_strings = ixgb_get_strings,
628*4882a593Smuzhiyun .set_phys_id = ixgb_set_phys_id,
629*4882a593Smuzhiyun .get_sset_count = ixgb_get_sset_count,
630*4882a593Smuzhiyun .get_ethtool_stats = ixgb_get_ethtool_stats,
631*4882a593Smuzhiyun .get_link_ksettings = ixgb_get_link_ksettings,
632*4882a593Smuzhiyun .set_link_ksettings = ixgb_set_link_ksettings,
633*4882a593Smuzhiyun };
634*4882a593Smuzhiyun
ixgb_set_ethtool_ops(struct net_device * netdev)635*4882a593Smuzhiyun void ixgb_set_ethtool_ops(struct net_device *netdev)
636*4882a593Smuzhiyun {
637*4882a593Smuzhiyun netdev->ethtool_ops = &ixgb_ethtool_ops;
638*4882a593Smuzhiyun }
639