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