cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ixgb_ethtool.c (19572B)


      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
     12enum {NETDEV_STATS, IXGB_STATS};
     13
     14struct 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
     28static 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
     71static int
     72ixgb_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
     99void 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
    109static int
    110ixgb_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
    131static void
    132ixgb_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
    150static int
    151ixgb_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
    179static u32
    180ixgb_get_msglevel(struct net_device *netdev)
    181{
    182	struct ixgb_adapter *adapter = netdev_priv(netdev);
    183	return adapter->msg_enable;
    184}
    185
    186static void
    187ixgb_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
    194static int
    195ixgb_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
    201static void
    202ixgb_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
    341static int
    342ixgb_get_eeprom_len(struct net_device *netdev)
    343{
    344	/* return size in bytes */
    345	return IXGB_EEPROM_SIZE << 1;
    346}
    347
    348static int
    349ixgb_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
    391geeprom_error:
    392	return ret_val;
    393}
    394
    395static int
    396ixgb_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
    453static void
    454ixgb_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
    465static void
    466ixgb_get_ringparam(struct net_device *netdev,
    467		   struct ethtool_ringparam *ring,
    468		   struct kernel_ethtool_ringparam *kernel_ring,
    469		   struct netlink_ext_ack *extack)
    470{
    471	struct ixgb_adapter *adapter = netdev_priv(netdev);
    472	struct ixgb_desc_ring *txdr = &adapter->tx_ring;
    473	struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
    474
    475	ring->rx_max_pending = MAX_RXD;
    476	ring->tx_max_pending = MAX_TXD;
    477	ring->rx_pending = rxdr->count;
    478	ring->tx_pending = txdr->count;
    479}
    480
    481static int
    482ixgb_set_ringparam(struct net_device *netdev,
    483		   struct ethtool_ringparam *ring,
    484		   struct kernel_ethtool_ringparam *kernel_ring,
    485		   struct netlink_ext_ack *extack)
    486{
    487	struct ixgb_adapter *adapter = netdev_priv(netdev);
    488	struct ixgb_desc_ring *txdr = &adapter->tx_ring;
    489	struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
    490	struct ixgb_desc_ring tx_old, tx_new, rx_old, rx_new;
    491	int err;
    492
    493	tx_old = adapter->tx_ring;
    494	rx_old = adapter->rx_ring;
    495
    496	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
    497		return -EINVAL;
    498
    499	if (netif_running(adapter->netdev))
    500		ixgb_down(adapter, true);
    501
    502	rxdr->count = max(ring->rx_pending,(u32)MIN_RXD);
    503	rxdr->count = min(rxdr->count,(u32)MAX_RXD);
    504	rxdr->count = ALIGN(rxdr->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE);
    505
    506	txdr->count = max(ring->tx_pending,(u32)MIN_TXD);
    507	txdr->count = min(txdr->count,(u32)MAX_TXD);
    508	txdr->count = ALIGN(txdr->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
    509
    510	if (netif_running(adapter->netdev)) {
    511		/* Try to get new resources before deleting old */
    512		if ((err = ixgb_setup_rx_resources(adapter)))
    513			goto err_setup_rx;
    514		if ((err = ixgb_setup_tx_resources(adapter)))
    515			goto err_setup_tx;
    516
    517		/* save the new, restore the old in order to free it,
    518		 * then restore the new back again */
    519
    520		rx_new = adapter->rx_ring;
    521		tx_new = adapter->tx_ring;
    522		adapter->rx_ring = rx_old;
    523		adapter->tx_ring = tx_old;
    524		ixgb_free_rx_resources(adapter);
    525		ixgb_free_tx_resources(adapter);
    526		adapter->rx_ring = rx_new;
    527		adapter->tx_ring = tx_new;
    528		if ((err = ixgb_up(adapter)))
    529			return err;
    530		ixgb_set_speed_duplex(netdev);
    531	}
    532
    533	return 0;
    534err_setup_tx:
    535	ixgb_free_rx_resources(adapter);
    536err_setup_rx:
    537	adapter->rx_ring = rx_old;
    538	adapter->tx_ring = tx_old;
    539	ixgb_up(adapter);
    540	return err;
    541}
    542
    543static int
    544ixgb_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
    545{
    546	struct ixgb_adapter *adapter = netdev_priv(netdev);
    547
    548	switch (state) {
    549	case ETHTOOL_ID_ACTIVE:
    550		return 2;
    551
    552	case ETHTOOL_ID_ON:
    553		ixgb_led_on(&adapter->hw);
    554		break;
    555
    556	case ETHTOOL_ID_OFF:
    557	case ETHTOOL_ID_INACTIVE:
    558		ixgb_led_off(&adapter->hw);
    559	}
    560
    561	return 0;
    562}
    563
    564static int
    565ixgb_get_sset_count(struct net_device *netdev, int sset)
    566{
    567	switch (sset) {
    568	case ETH_SS_STATS:
    569		return IXGB_STATS_LEN;
    570	default:
    571		return -EOPNOTSUPP;
    572	}
    573}
    574
    575static void
    576ixgb_get_ethtool_stats(struct net_device *netdev,
    577		struct ethtool_stats *stats, u64 *data)
    578{
    579	struct ixgb_adapter *adapter = netdev_priv(netdev);
    580	int i;
    581	char *p = NULL;
    582
    583	ixgb_update_stats(adapter);
    584	for (i = 0; i < IXGB_STATS_LEN; i++) {
    585		switch (ixgb_gstrings_stats[i].type) {
    586		case NETDEV_STATS:
    587			p = (char *) netdev +
    588					ixgb_gstrings_stats[i].stat_offset;
    589			break;
    590		case IXGB_STATS:
    591			p = (char *) adapter +
    592					ixgb_gstrings_stats[i].stat_offset;
    593			break;
    594		}
    595
    596		data[i] = (ixgb_gstrings_stats[i].sizeof_stat ==
    597			sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
    598	}
    599}
    600
    601static void
    602ixgb_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
    603{
    604	int i;
    605
    606	switch(stringset) {
    607	case ETH_SS_STATS:
    608		for (i = 0; i < IXGB_STATS_LEN; i++) {
    609			memcpy(data + i * ETH_GSTRING_LEN,
    610			ixgb_gstrings_stats[i].stat_string,
    611			ETH_GSTRING_LEN);
    612		}
    613		break;
    614	}
    615}
    616
    617static const struct ethtool_ops ixgb_ethtool_ops = {
    618	.get_drvinfo = ixgb_get_drvinfo,
    619	.get_regs_len = ixgb_get_regs_len,
    620	.get_regs = ixgb_get_regs,
    621	.get_link = ethtool_op_get_link,
    622	.get_eeprom_len = ixgb_get_eeprom_len,
    623	.get_eeprom = ixgb_get_eeprom,
    624	.set_eeprom = ixgb_set_eeprom,
    625	.get_ringparam = ixgb_get_ringparam,
    626	.set_ringparam = ixgb_set_ringparam,
    627	.get_pauseparam	= ixgb_get_pauseparam,
    628	.set_pauseparam	= ixgb_set_pauseparam,
    629	.get_msglevel = ixgb_get_msglevel,
    630	.set_msglevel = ixgb_set_msglevel,
    631	.get_strings = ixgb_get_strings,
    632	.set_phys_id = ixgb_set_phys_id,
    633	.get_sset_count = ixgb_get_sset_count,
    634	.get_ethtool_stats = ixgb_get_ethtool_stats,
    635	.get_link_ksettings = ixgb_get_link_ksettings,
    636	.set_link_ksettings = ixgb_set_link_ksettings,
    637};
    638
    639void ixgb_set_ethtool_ops(struct net_device *netdev)
    640{
    641	netdev->ethtool_ops = &ixgb_ethtool_ops;
    642}