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