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