Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.17.
  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, -1);
111		ecmd->duplex = -1;
112	}
113
114	ecmd->autoneg = AUTONEG_DISABLE;
115	return 0;
116}
117
118static void 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_rx_csum(struct net_device *netdev)
199{
200	struct ixgb_adapter *adapter = netdev_priv(netdev);
201
202	return adapter->rx_csum;
203}
204
205static int
206ixgb_set_rx_csum(struct net_device *netdev, u32 data)
207{
208	struct ixgb_adapter *adapter = netdev_priv(netdev);
209
210	adapter->rx_csum = data;
211
212	if (netif_running(netdev)) {
213		ixgb_down(adapter, true);
214		ixgb_up(adapter);
215		ixgb_set_speed_duplex(netdev);
216	} else
217		ixgb_reset(adapter);
218	return 0;
219}
220
221static u32
222ixgb_get_tx_csum(struct net_device *netdev)
223{
224	return (netdev->features & NETIF_F_HW_CSUM) != 0;
225}
226
227static int
228ixgb_set_tx_csum(struct net_device *netdev, u32 data)
229{
230	if (data)
231		netdev->features |= NETIF_F_HW_CSUM;
232	else
233		netdev->features &= ~NETIF_F_HW_CSUM;
234
235	return 0;
236}
237
238static int
239ixgb_set_tso(struct net_device *netdev, u32 data)
240{
241	if (data)
242		netdev->features |= NETIF_F_TSO;
243	else
244		netdev->features &= ~NETIF_F_TSO;
245	return 0;
246}
247
248static u32
249ixgb_get_msglevel(struct net_device *netdev)
250{
251	struct ixgb_adapter *adapter = netdev_priv(netdev);
252	return adapter->msg_enable;
253}
254
255static void
256ixgb_set_msglevel(struct net_device *netdev, u32 data)
257{
258	struct ixgb_adapter *adapter = netdev_priv(netdev);
259	adapter->msg_enable = data;
260}
261#define IXGB_GET_STAT(_A_, _R_) _A_->stats._R_
262
263static int
264ixgb_get_regs_len(struct net_device *netdev)
265{
266#define IXGB_REG_DUMP_LEN  136*sizeof(u32)
267	return IXGB_REG_DUMP_LEN;
268}
269
270static void
271ixgb_get_regs(struct net_device *netdev,
272		   struct ethtool_regs *regs, void *p)
273{
274	struct ixgb_adapter *adapter = netdev_priv(netdev);
275	struct ixgb_hw *hw = &adapter->hw;
276	u32 *reg = p;
277	u32 *reg_start = reg;
278	u8 i;
279
280	/* the 1 (one) below indicates an attempt at versioning, if the
281	 * interface in ethtool or the driver changes, this 1 should be
282	 * incremented */
283	regs->version = (1<<24) | hw->revision_id << 16 | hw->device_id;
284
285	/* General Registers */
286	*reg++ = IXGB_READ_REG(hw, CTRL0);	/*   0 */
287	*reg++ = IXGB_READ_REG(hw, CTRL1);	/*   1 */
288	*reg++ = IXGB_READ_REG(hw, STATUS);	/*   2 */
289	*reg++ = IXGB_READ_REG(hw, EECD);	/*   3 */
290	*reg++ = IXGB_READ_REG(hw, MFS);	/*   4 */
291
292	/* Interrupt */
293	*reg++ = IXGB_READ_REG(hw, ICR);	/*   5 */
294	*reg++ = IXGB_READ_REG(hw, ICS);	/*   6 */
295	*reg++ = IXGB_READ_REG(hw, IMS);	/*   7 */
296	*reg++ = IXGB_READ_REG(hw, IMC);	/*   8 */
297
298	/* Receive */
299	*reg++ = IXGB_READ_REG(hw, RCTL);	/*   9 */
300	*reg++ = IXGB_READ_REG(hw, FCRTL);	/*  10 */
301	*reg++ = IXGB_READ_REG(hw, FCRTH);	/*  11 */
302	*reg++ = IXGB_READ_REG(hw, RDBAL);	/*  12 */
303	*reg++ = IXGB_READ_REG(hw, RDBAH);	/*  13 */
304	*reg++ = IXGB_READ_REG(hw, RDLEN);	/*  14 */
305	*reg++ = IXGB_READ_REG(hw, RDH);	/*  15 */
306	*reg++ = IXGB_READ_REG(hw, RDT);	/*  16 */
307	*reg++ = IXGB_READ_REG(hw, RDTR);	/*  17 */
308	*reg++ = IXGB_READ_REG(hw, RXDCTL);	/*  18 */
309	*reg++ = IXGB_READ_REG(hw, RAIDC);	/*  19 */
310	*reg++ = IXGB_READ_REG(hw, RXCSUM);	/*  20 */
311
312	/* there are 16 RAR entries in hardware, we only use 3 */
313	for (i = 0; i < IXGB_ALL_RAR_ENTRIES; i++) {
314		*reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */
315		*reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */
316	}
317
318	/* Transmit */
319	*reg++ = IXGB_READ_REG(hw, TCTL);	/*  53 */
320	*reg++ = IXGB_READ_REG(hw, TDBAL);	/*  54 */
321	*reg++ = IXGB_READ_REG(hw, TDBAH);	/*  55 */
322	*reg++ = IXGB_READ_REG(hw, TDLEN);	/*  56 */
323	*reg++ = IXGB_READ_REG(hw, TDH);	/*  57 */
324	*reg++ = IXGB_READ_REG(hw, TDT);	/*  58 */
325	*reg++ = IXGB_READ_REG(hw, TIDV);	/*  59 */
326	*reg++ = IXGB_READ_REG(hw, TXDCTL);	/*  60 */
327	*reg++ = IXGB_READ_REG(hw, TSPMT);	/*  61 */
328	*reg++ = IXGB_READ_REG(hw, PAP);	/*  62 */
329
330	/* Physical */
331	*reg++ = IXGB_READ_REG(hw, PCSC1);	/*  63 */
332	*reg++ = IXGB_READ_REG(hw, PCSC2);	/*  64 */
333	*reg++ = IXGB_READ_REG(hw, PCSS1);	/*  65 */
334	*reg++ = IXGB_READ_REG(hw, PCSS2);	/*  66 */
335	*reg++ = IXGB_READ_REG(hw, XPCSS);	/*  67 */
336	*reg++ = IXGB_READ_REG(hw, UCCR);	/*  68 */
337	*reg++ = IXGB_READ_REG(hw, XPCSTC);	/*  69 */
338	*reg++ = IXGB_READ_REG(hw, MACA);	/*  70 */
339	*reg++ = IXGB_READ_REG(hw, APAE);	/*  71 */
340	*reg++ = IXGB_READ_REG(hw, ARD);	/*  72 */
341	*reg++ = IXGB_READ_REG(hw, AIS);	/*  73 */
342	*reg++ = IXGB_READ_REG(hw, MSCA);	/*  74 */
343	*reg++ = IXGB_READ_REG(hw, MSRWD);	/*  75 */
344
345	/* Statistics */
346	*reg++ = IXGB_GET_STAT(adapter, tprl);	/*  76 */
347	*reg++ = IXGB_GET_STAT(adapter, tprh);	/*  77 */
348	*reg++ = IXGB_GET_STAT(adapter, gprcl);	/*  78 */
349	*reg++ = IXGB_GET_STAT(adapter, gprch);	/*  79 */
350	*reg++ = IXGB_GET_STAT(adapter, bprcl);	/*  80 */
351	*reg++ = IXGB_GET_STAT(adapter, bprch);	/*  81 */
352	*reg++ = IXGB_GET_STAT(adapter, mprcl);	/*  82 */
353	*reg++ = IXGB_GET_STAT(adapter, mprch);	/*  83 */
354	*reg++ = IXGB_GET_STAT(adapter, uprcl);	/*  84 */
355	*reg++ = IXGB_GET_STAT(adapter, uprch);	/*  85 */
356	*reg++ = IXGB_GET_STAT(adapter, vprcl);	/*  86 */
357	*reg++ = IXGB_GET_STAT(adapter, vprch);	/*  87 */
358	*reg++ = IXGB_GET_STAT(adapter, jprcl);	/*  88 */
359	*reg++ = IXGB_GET_STAT(adapter, jprch);	/*  89 */
360	*reg++ = IXGB_GET_STAT(adapter, gorcl);	/*  90 */
361	*reg++ = IXGB_GET_STAT(adapter, gorch);	/*  91 */
362	*reg++ = IXGB_GET_STAT(adapter, torl);	/*  92 */
363	*reg++ = IXGB_GET_STAT(adapter, torh);	/*  93 */
364	*reg++ = IXGB_GET_STAT(adapter, rnbc);	/*  94 */
365	*reg++ = IXGB_GET_STAT(adapter, ruc);	/*  95 */
366	*reg++ = IXGB_GET_STAT(adapter, roc);	/*  96 */
367	*reg++ = IXGB_GET_STAT(adapter, rlec);	/*  97 */
368	*reg++ = IXGB_GET_STAT(adapter, crcerrs);	/*  98 */
369	*reg++ = IXGB_GET_STAT(adapter, icbc);	/*  99 */
370	*reg++ = IXGB_GET_STAT(adapter, ecbc);	/* 100 */
371	*reg++ = IXGB_GET_STAT(adapter, mpc);	/* 101 */
372	*reg++ = IXGB_GET_STAT(adapter, tptl);	/* 102 */
373	*reg++ = IXGB_GET_STAT(adapter, tpth);	/* 103 */
374	*reg++ = IXGB_GET_STAT(adapter, gptcl);	/* 104 */
375	*reg++ = IXGB_GET_STAT(adapter, gptch);	/* 105 */
376	*reg++ = IXGB_GET_STAT(adapter, bptcl);	/* 106 */
377	*reg++ = IXGB_GET_STAT(adapter, bptch);	/* 107 */
378	*reg++ = IXGB_GET_STAT(adapter, mptcl);	/* 108 */
379	*reg++ = IXGB_GET_STAT(adapter, mptch);	/* 109 */
380	*reg++ = IXGB_GET_STAT(adapter, uptcl);	/* 110 */
381	*reg++ = IXGB_GET_STAT(adapter, uptch);	/* 111 */
382	*reg++ = IXGB_GET_STAT(adapter, vptcl);	/* 112 */
383	*reg++ = IXGB_GET_STAT(adapter, vptch);	/* 113 */
384	*reg++ = IXGB_GET_STAT(adapter, jptcl);	/* 114 */
385	*reg++ = IXGB_GET_STAT(adapter, jptch);	/* 115 */
386	*reg++ = IXGB_GET_STAT(adapter, gotcl);	/* 116 */
387	*reg++ = IXGB_GET_STAT(adapter, gotch);	/* 117 */
388	*reg++ = IXGB_GET_STAT(adapter, totl);	/* 118 */
389	*reg++ = IXGB_GET_STAT(adapter, toth);	/* 119 */
390	*reg++ = IXGB_GET_STAT(adapter, dc);	/* 120 */
391	*reg++ = IXGB_GET_STAT(adapter, plt64c);	/* 121 */
392	*reg++ = IXGB_GET_STAT(adapter, tsctc);	/* 122 */
393	*reg++ = IXGB_GET_STAT(adapter, tsctfc);	/* 123 */
394	*reg++ = IXGB_GET_STAT(adapter, ibic);	/* 124 */
395	*reg++ = IXGB_GET_STAT(adapter, rfc);	/* 125 */
396	*reg++ = IXGB_GET_STAT(adapter, lfc);	/* 126 */
397	*reg++ = IXGB_GET_STAT(adapter, pfrc);	/* 127 */
398	*reg++ = IXGB_GET_STAT(adapter, pftc);	/* 128 */
399	*reg++ = IXGB_GET_STAT(adapter, mcfrc);	/* 129 */
400	*reg++ = IXGB_GET_STAT(adapter, mcftc);	/* 130 */
401	*reg++ = IXGB_GET_STAT(adapter, xonrxc);	/* 131 */
402	*reg++ = IXGB_GET_STAT(adapter, xontxc);	/* 132 */
403	*reg++ = IXGB_GET_STAT(adapter, xoffrxc);	/* 133 */
404	*reg++ = IXGB_GET_STAT(adapter, xofftxc);	/* 134 */
405	*reg++ = IXGB_GET_STAT(adapter, rjc);	/* 135 */
406
407	regs->len = (reg - reg_start) * sizeof(u32);
408}
409
410static int
411ixgb_get_eeprom_len(struct net_device *netdev)
412{
413	/* return size in bytes */
414	return IXGB_EEPROM_SIZE << 1;
415}
416
417static int
418ixgb_get_eeprom(struct net_device *netdev,
419		  struct ethtool_eeprom *eeprom, u8 *bytes)
420{
421	struct ixgb_adapter *adapter = netdev_priv(netdev);
422	struct ixgb_hw *hw = &adapter->hw;
423	__le16 *eeprom_buff;
424	int i, max_len, first_word, last_word;
425	int ret_val = 0;
426
427	if (eeprom->len == 0) {
428		ret_val = -EINVAL;
429		goto geeprom_error;
430	}
431
432	eeprom->magic = hw->vendor_id | (hw->device_id << 16);
433
434	max_len = ixgb_get_eeprom_len(netdev);
435
436	if (eeprom->offset > eeprom->offset + eeprom->len) {
437		ret_val = -EINVAL;
438		goto geeprom_error;
439	}
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
447	eeprom_buff = kmalloc(sizeof(__le16) *
448			(last_word - first_word + 1), GFP_KERNEL);
449	if (!eeprom_buff)
450		return -ENOMEM;
451
452	/* note the eeprom was good because the driver loaded */
453	for (i = 0; i <= (last_word - first_word); i++)
454		eeprom_buff[i] = ixgb_get_eeprom_word(hw, (first_word + i));
455
456	memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
457	kfree(eeprom_buff);
458
459geeprom_error:
460	return ret_val;
461}
462
463static int
464ixgb_set_eeprom(struct net_device *netdev,
465		  struct ethtool_eeprom *eeprom, u8 *bytes)
466{
467	struct ixgb_adapter *adapter = netdev_priv(netdev);
468	struct ixgb_hw *hw = &adapter->hw;
469	u16 *eeprom_buff;
470	void *ptr;
471	int max_len, first_word, last_word;
472	u16 i;
473
474	if (eeprom->len == 0)
475		return -EINVAL;
476
477	if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
478		return -EFAULT;
479
480	max_len = ixgb_get_eeprom_len(netdev);
481
482	if (eeprom->offset > eeprom->offset + eeprom->len)
483		return -EINVAL;
484
485	if ((eeprom->offset + eeprom->len) > max_len)
486		eeprom->len = (max_len - eeprom->offset);
487
488	first_word = eeprom->offset >> 1;
489	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
490	eeprom_buff = kmalloc(max_len, GFP_KERNEL);
491	if (!eeprom_buff)
492		return -ENOMEM;
493
494	ptr = (void *)eeprom_buff;
495
496	if (eeprom->offset & 1) {
497		/* need read/modify/write of first changed EEPROM word */
498		/* only the second byte of the word is being modified */
499		eeprom_buff[0] = ixgb_read_eeprom(hw, first_word);
500		ptr++;
501	}
502	if ((eeprom->offset + eeprom->len) & 1) {
503		/* need read/modify/write of last changed EEPROM word */
504		/* only the first byte of the word is being modified */
505		eeprom_buff[last_word - first_word]
506			= ixgb_read_eeprom(hw, last_word);
507	}
508
509	memcpy(ptr, bytes, eeprom->len);
510	for (i = 0; i <= (last_word - first_word); i++)
511		ixgb_write_eeprom(hw, first_word + i, eeprom_buff[i]);
512
513	/* Update the checksum over the first part of the EEPROM if needed */
514	if (first_word <= EEPROM_CHECKSUM_REG)
515		ixgb_update_eeprom_checksum(hw);
516
517	kfree(eeprom_buff);
518	return 0;
519}
520
521static void
522ixgb_get_drvinfo(struct net_device *netdev,
523		   struct ethtool_drvinfo *drvinfo)
524{
525	struct ixgb_adapter *adapter = netdev_priv(netdev);
526
527	strncpy(drvinfo->driver,  ixgb_driver_name, 32);
528	strncpy(drvinfo->version, ixgb_driver_version, 32);
529	strncpy(drvinfo->fw_version, "N/A", 32);
530	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
531	drvinfo->n_stats = IXGB_STATS_LEN;
532	drvinfo->regdump_len = ixgb_get_regs_len(netdev);
533	drvinfo->eedump_len = ixgb_get_eeprom_len(netdev);
534}
535
536static void
537ixgb_get_ringparam(struct net_device *netdev,
538		struct ethtool_ringparam *ring)
539{
540	struct ixgb_adapter *adapter = netdev_priv(netdev);
541	struct ixgb_desc_ring *txdr = &adapter->tx_ring;
542	struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
543
544	ring->rx_max_pending = MAX_RXD;
545	ring->tx_max_pending = MAX_TXD;
546	ring->rx_mini_max_pending = 0;
547	ring->rx_jumbo_max_pending = 0;
548	ring->rx_pending = rxdr->count;
549	ring->tx_pending = txdr->count;
550	ring->rx_mini_pending = 0;
551	ring->rx_jumbo_pending = 0;
552}
553
554static int
555ixgb_set_ringparam(struct net_device *netdev,
556		struct ethtool_ringparam *ring)
557{
558	struct ixgb_adapter *adapter = netdev_priv(netdev);
559	struct ixgb_desc_ring *txdr = &adapter->tx_ring;
560	struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
561	struct ixgb_desc_ring tx_old, tx_new, rx_old, rx_new;
562	int err;
563
564	tx_old = adapter->tx_ring;
565	rx_old = adapter->rx_ring;
566
567	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
568		return -EINVAL;
569
570	if (netif_running(adapter->netdev))
571		ixgb_down(adapter, true);
572
573	rxdr->count = max(ring->rx_pending,(u32)MIN_RXD);
574	rxdr->count = min(rxdr->count,(u32)MAX_RXD);
575	rxdr->count = ALIGN(rxdr->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE);
576
577	txdr->count = max(ring->tx_pending,(u32)MIN_TXD);
578	txdr->count = min(txdr->count,(u32)MAX_TXD);
579	txdr->count = ALIGN(txdr->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
580
581	if (netif_running(adapter->netdev)) {
582		/* Try to get new resources before deleting old */
583		if ((err = ixgb_setup_rx_resources(adapter)))
584			goto err_setup_rx;
585		if ((err = ixgb_setup_tx_resources(adapter)))
586			goto err_setup_tx;
587
588		/* save the new, restore the old in order to free it,
589		 * then restore the new back again */
590
591		rx_new = adapter->rx_ring;
592		tx_new = adapter->tx_ring;
593		adapter->rx_ring = rx_old;
594		adapter->tx_ring = tx_old;
595		ixgb_free_rx_resources(adapter);
596		ixgb_free_tx_resources(adapter);
597		adapter->rx_ring = rx_new;
598		adapter->tx_ring = tx_new;
599		if ((err = ixgb_up(adapter)))
600			return err;
601		ixgb_set_speed_duplex(netdev);
602	}
603
604	return 0;
605err_setup_tx:
606	ixgb_free_rx_resources(adapter);
607err_setup_rx:
608	adapter->rx_ring = rx_old;
609	adapter->tx_ring = tx_old;
610	ixgb_up(adapter);
611	return err;
612}
613
614static int
615ixgb_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
616{
617	struct ixgb_adapter *adapter = netdev_priv(netdev);
618
619	switch (state) {
620	case ETHTOOL_ID_ACTIVE:
621		return 2;
622
623	case ETHTOOL_ID_ON:
624		ixgb_led_on(&adapter->hw);
625		break;
626
627	case ETHTOOL_ID_OFF:
628	case ETHTOOL_ID_INACTIVE:
629		ixgb_led_off(&adapter->hw);
630	}
631
632	return 0;
633}
634
635static int
636ixgb_get_sset_count(struct net_device *netdev, int sset)
637{
638	switch (sset) {
639	case ETH_SS_STATS:
640		return IXGB_STATS_LEN;
641	default:
642		return -EOPNOTSUPP;
643	}
644}
645
646static void
647ixgb_get_ethtool_stats(struct net_device *netdev,
648		struct ethtool_stats *stats, u64 *data)
649{
650	struct ixgb_adapter *adapter = netdev_priv(netdev);
651	int i;
652	char *p = NULL;
653
654	ixgb_update_stats(adapter);
655	for (i = 0; i < IXGB_STATS_LEN; i++) {
656		switch (ixgb_gstrings_stats[i].type) {
657		case NETDEV_STATS:
658			p = (char *) netdev +
659					ixgb_gstrings_stats[i].stat_offset;
660			break;
661		case IXGB_STATS:
662			p = (char *) adapter +
663					ixgb_gstrings_stats[i].stat_offset;
664			break;
665		}
666
667		data[i] = (ixgb_gstrings_stats[i].sizeof_stat ==
668			sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
669	}
670}
671
672static void
673ixgb_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
674{
675	int i;
676
677	switch(stringset) {
678	case ETH_SS_STATS:
679		for (i = 0; i < IXGB_STATS_LEN; i++) {
680			memcpy(data + i * ETH_GSTRING_LEN,
681			ixgb_gstrings_stats[i].stat_string,
682			ETH_GSTRING_LEN);
683		}
684		break;
685	}
686}
687
688static int ixgb_set_flags(struct net_device *netdev, u32 data)
689{
690	struct ixgb_adapter *adapter = netdev_priv(netdev);
691	bool need_reset;
692	int rc;
693
694	/*
695	 * Tx VLAN insertion does not work per HW design when Rx stripping is
696	 * disabled.  Disable txvlan when rxvlan is turned off, and enable
697	 * rxvlan when txvlan is turned on.
698	 */
699	if (!(data & ETH_FLAG_RXVLAN) &&
700	    (netdev->features & NETIF_F_HW_VLAN_TX))
701		data &= ~ETH_FLAG_TXVLAN;
702	else if (data & ETH_FLAG_TXVLAN)
703		data |= ETH_FLAG_RXVLAN;
704
705	need_reset = (data & ETH_FLAG_RXVLAN) !=
706		     (netdev->features & NETIF_F_HW_VLAN_RX);
707
708	rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_RXVLAN |
709						ETH_FLAG_TXVLAN);
710	if (rc)
711		return rc;
712
713	if (need_reset) {
714		if (netif_running(netdev)) {
715			ixgb_down(adapter, true);
716			ixgb_up(adapter);
717			ixgb_set_speed_duplex(netdev);
718		} else
719			ixgb_reset(adapter);
720	}
721
722	return 0;
723}
724
725static const struct ethtool_ops ixgb_ethtool_ops = {
726	.get_settings = ixgb_get_settings,
727	.set_settings = ixgb_set_settings,
728	.get_drvinfo = ixgb_get_drvinfo,
729	.get_regs_len = ixgb_get_regs_len,
730	.get_regs = ixgb_get_regs,
731	.get_link = ethtool_op_get_link,
732	.get_eeprom_len = ixgb_get_eeprom_len,
733	.get_eeprom = ixgb_get_eeprom,
734	.set_eeprom = ixgb_set_eeprom,
735	.get_ringparam = ixgb_get_ringparam,
736	.set_ringparam = ixgb_set_ringparam,
737	.get_pauseparam	= ixgb_get_pauseparam,
738	.set_pauseparam	= ixgb_set_pauseparam,
739	.get_rx_csum = ixgb_get_rx_csum,
740	.set_rx_csum = ixgb_set_rx_csum,
741	.get_tx_csum = ixgb_get_tx_csum,
742	.set_tx_csum = ixgb_set_tx_csum,
743	.set_sg	= ethtool_op_set_sg,
744	.get_msglevel = ixgb_get_msglevel,
745	.set_msglevel = ixgb_set_msglevel,
746	.set_tso = ixgb_set_tso,
747	.get_strings = ixgb_get_strings,
748	.set_phys_id = ixgb_set_phys_id,
749	.get_sset_count = ixgb_get_sset_count,
750	.get_ethtool_stats = ixgb_get_ethtool_stats,
751	.get_flags = ethtool_op_get_flags,
752	.set_flags = ixgb_set_flags,
753};
754
755void ixgb_set_ethtool_ops(struct net_device *netdev)
756{
757	SET_ETHTOOL_OPS(netdev, &ixgb_ethtool_ops);
758}