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

netxen_nic_ethtool.c (26060B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright (C) 2003 - 2009 NetXen, Inc.
      4 * Copyright (C) 2009 - QLogic Corporation.
      5 * All rights reserved.
      6 */
      7
      8#include <linux/types.h>
      9#include <linux/delay.h>
     10#include <linux/pci.h>
     11#include <asm/io.h>
     12#include <linux/netdevice.h>
     13#include <linux/ethtool.h>
     14
     15#include "netxen_nic.h"
     16#include "netxen_nic_hw.h"
     17
     18struct netxen_nic_stats {
     19	char stat_string[ETH_GSTRING_LEN];
     20	int sizeof_stat;
     21	int stat_offset;
     22};
     23
     24#define NETXEN_NIC_STAT(m) sizeof(((struct netxen_adapter *)0)->m), \
     25			offsetof(struct netxen_adapter, m)
     26
     27#define NETXEN_NIC_PORT_WINDOW 0x10000
     28#define NETXEN_NIC_INVALID_DATA 0xDEADBEEF
     29
     30static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = {
     31	{"xmit_called", NETXEN_NIC_STAT(stats.xmitcalled)},
     32	{"xmit_finished", NETXEN_NIC_STAT(stats.xmitfinished)},
     33	{"rx_dropped", NETXEN_NIC_STAT(stats.rxdropped)},
     34	{"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)},
     35	{"csummed", NETXEN_NIC_STAT(stats.csummed)},
     36	{"rx_pkts", NETXEN_NIC_STAT(stats.rx_pkts)},
     37	{"lro_pkts", NETXEN_NIC_STAT(stats.lro_pkts)},
     38	{"rx_bytes", NETXEN_NIC_STAT(stats.rxbytes)},
     39	{"tx_bytes", NETXEN_NIC_STAT(stats.txbytes)},
     40};
     41
     42#define NETXEN_NIC_STATS_LEN	ARRAY_SIZE(netxen_nic_gstrings_stats)
     43
     44static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = {
     45	"Register_Test_on_offline",
     46	"Link_Test_on_offline"
     47};
     48
     49#define NETXEN_NIC_TEST_LEN	ARRAY_SIZE(netxen_nic_gstrings_test)
     50
     51#define NETXEN_NIC_REGS_COUNT 30
     52#define NETXEN_NIC_REGS_LEN (NETXEN_NIC_REGS_COUNT * sizeof(__le32))
     53#define NETXEN_MAX_EEPROM_LEN   1024
     54
     55static int netxen_nic_get_eeprom_len(struct net_device *dev)
     56{
     57	return NETXEN_FLASH_TOTAL_SIZE;
     58}
     59
     60static void
     61netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
     62{
     63	struct netxen_adapter *adapter = netdev_priv(dev);
     64	u32 fw_major = 0;
     65	u32 fw_minor = 0;
     66	u32 fw_build = 0;
     67
     68	strlcpy(drvinfo->driver, netxen_nic_driver_name,
     69		sizeof(drvinfo->driver));
     70	strlcpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID,
     71		sizeof(drvinfo->version));
     72	fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
     73	fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
     74	fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
     75	snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
     76		"%d.%d.%d", fw_major, fw_minor, fw_build);
     77
     78	strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
     79		sizeof(drvinfo->bus_info));
     80}
     81
     82static int
     83netxen_nic_get_link_ksettings(struct net_device *dev,
     84			      struct ethtool_link_ksettings *cmd)
     85{
     86	struct netxen_adapter *adapter = netdev_priv(dev);
     87	int check_sfp_module = 0;
     88	u32 supported, advertising;
     89
     90	/* read which mode */
     91	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
     92		supported = (SUPPORTED_10baseT_Half |
     93				   SUPPORTED_10baseT_Full |
     94				   SUPPORTED_100baseT_Half |
     95				   SUPPORTED_100baseT_Full |
     96				   SUPPORTED_1000baseT_Half |
     97				   SUPPORTED_1000baseT_Full);
     98
     99		advertising = (ADVERTISED_100baseT_Half |
    100				     ADVERTISED_100baseT_Full |
    101				     ADVERTISED_1000baseT_Half |
    102				     ADVERTISED_1000baseT_Full);
    103
    104		cmd->base.port = PORT_TP;
    105
    106		cmd->base.speed = adapter->link_speed;
    107		cmd->base.duplex = adapter->link_duplex;
    108		cmd->base.autoneg = adapter->link_autoneg;
    109
    110	} else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
    111		u32 val;
    112
    113		val = NXRD32(adapter, NETXEN_PORT_MODE_ADDR);
    114		if (val == NETXEN_PORT_MODE_802_3_AP) {
    115			supported = SUPPORTED_1000baseT_Full;
    116			advertising = ADVERTISED_1000baseT_Full;
    117		} else {
    118			supported = SUPPORTED_10000baseT_Full;
    119			advertising = ADVERTISED_10000baseT_Full;
    120		}
    121
    122		if (netif_running(dev) && adapter->has_link_events) {
    123			cmd->base.speed = adapter->link_speed;
    124			cmd->base.autoneg = adapter->link_autoneg;
    125			cmd->base.duplex = adapter->link_duplex;
    126			goto skip;
    127		}
    128
    129		cmd->base.port = PORT_TP;
    130
    131		if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
    132			u16 pcifn = adapter->ahw.pci_func;
    133
    134			val = NXRD32(adapter, P3_LINK_SPEED_REG(pcifn));
    135			cmd->base.speed = P3_LINK_SPEED_MHZ *
    136				P3_LINK_SPEED_VAL(pcifn, val);
    137		} else
    138			cmd->base.speed = SPEED_10000;
    139
    140		cmd->base.duplex = DUPLEX_FULL;
    141		cmd->base.autoneg = AUTONEG_DISABLE;
    142	} else
    143		return -EIO;
    144
    145skip:
    146	cmd->base.phy_address = adapter->physical_port;
    147
    148	switch (adapter->ahw.board_type) {
    149	case NETXEN_BRDTYPE_P2_SB35_4G:
    150	case NETXEN_BRDTYPE_P2_SB31_2G:
    151	case NETXEN_BRDTYPE_P3_REF_QG:
    152	case NETXEN_BRDTYPE_P3_4_GB:
    153	case NETXEN_BRDTYPE_P3_4_GB_MM:
    154		supported |= SUPPORTED_Autoneg;
    155		advertising |= ADVERTISED_Autoneg;
    156		fallthrough;
    157	case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
    158	case NETXEN_BRDTYPE_P3_10G_CX4:
    159	case NETXEN_BRDTYPE_P3_10G_CX4_LP:
    160	case NETXEN_BRDTYPE_P3_10000_BASE_T:
    161		supported |= SUPPORTED_TP;
    162		advertising |= ADVERTISED_TP;
    163		cmd->base.port = PORT_TP;
    164		cmd->base.autoneg = (adapter->ahw.board_type ==
    165				 NETXEN_BRDTYPE_P2_SB31_10G_CX4) ?
    166		    (AUTONEG_DISABLE) : (adapter->link_autoneg);
    167		break;
    168	case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
    169	case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
    170	case NETXEN_BRDTYPE_P3_IMEZ:
    171	case NETXEN_BRDTYPE_P3_XG_LOM:
    172	case NETXEN_BRDTYPE_P3_HMEZ:
    173		supported |= SUPPORTED_MII;
    174		advertising |= ADVERTISED_MII;
    175		cmd->base.port = PORT_MII;
    176		cmd->base.autoneg = AUTONEG_DISABLE;
    177		break;
    178	case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
    179	case NETXEN_BRDTYPE_P3_10G_SFP_CT:
    180	case NETXEN_BRDTYPE_P3_10G_SFP_QT:
    181		advertising |= ADVERTISED_TP;
    182		supported |= SUPPORTED_TP;
    183		check_sfp_module = netif_running(dev) &&
    184			adapter->has_link_events;
    185		fallthrough;
    186	case NETXEN_BRDTYPE_P2_SB31_10G:
    187	case NETXEN_BRDTYPE_P3_10G_XFP:
    188		supported |= SUPPORTED_FIBRE;
    189		advertising |= ADVERTISED_FIBRE;
    190		cmd->base.port = PORT_FIBRE;
    191		cmd->base.autoneg = AUTONEG_DISABLE;
    192		break;
    193	case NETXEN_BRDTYPE_P3_10G_TP:
    194		if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
    195			cmd->base.autoneg = AUTONEG_DISABLE;
    196			supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
    197			advertising |=
    198				(ADVERTISED_FIBRE | ADVERTISED_TP);
    199			cmd->base.port = PORT_FIBRE;
    200			check_sfp_module = netif_running(dev) &&
    201				adapter->has_link_events;
    202		} else {
    203			supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
    204			advertising |=
    205				(ADVERTISED_TP | ADVERTISED_Autoneg);
    206			cmd->base.port = PORT_TP;
    207		}
    208		break;
    209	default:
    210		printk(KERN_ERR "netxen-nic: Unsupported board model %d\n",
    211				adapter->ahw.board_type);
    212		return -EIO;
    213	}
    214
    215	if (check_sfp_module) {
    216		switch (adapter->module_type) {
    217		case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
    218		case LINKEVENT_MODULE_OPTICAL_SRLR:
    219		case LINKEVENT_MODULE_OPTICAL_LRM:
    220		case LINKEVENT_MODULE_OPTICAL_SFP_1G:
    221			cmd->base.port = PORT_FIBRE;
    222			break;
    223		case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
    224		case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
    225		case LINKEVENT_MODULE_TWINAX:
    226			cmd->base.port = PORT_TP;
    227			break;
    228		default:
    229			cmd->base.port = -1;
    230		}
    231	}
    232
    233	if (!netif_running(dev) || !adapter->ahw.linkup) {
    234		cmd->base.duplex = DUPLEX_UNKNOWN;
    235		cmd->base.speed = SPEED_UNKNOWN;
    236	}
    237
    238	ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
    239						supported);
    240	ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
    241						advertising);
    242
    243	return 0;
    244}
    245
    246static int
    247netxen_nic_set_link_ksettings(struct net_device *dev,
    248			      const struct ethtool_link_ksettings *cmd)
    249{
    250	struct netxen_adapter *adapter = netdev_priv(dev);
    251	u32 speed = cmd->base.speed;
    252	int ret;
    253
    254	if (adapter->ahw.port_type != NETXEN_NIC_GBE)
    255		return -EOPNOTSUPP;
    256
    257	if (!(adapter->capabilities & NX_FW_CAPABILITY_GBE_LINK_CFG))
    258		return -EOPNOTSUPP;
    259
    260	ret = nx_fw_cmd_set_gbe_port(adapter, speed, cmd->base.duplex,
    261				     cmd->base.autoneg);
    262	if (ret == NX_RCODE_NOT_SUPPORTED)
    263		return -EOPNOTSUPP;
    264	else if (ret)
    265		return -EIO;
    266
    267	adapter->link_speed = speed;
    268	adapter->link_duplex = cmd->base.duplex;
    269	adapter->link_autoneg = cmd->base.autoneg;
    270
    271	if (!netif_running(dev))
    272		return 0;
    273
    274	dev->netdev_ops->ndo_stop(dev);
    275	return dev->netdev_ops->ndo_open(dev);
    276}
    277
    278static int netxen_nic_get_regs_len(struct net_device *dev)
    279{
    280	return NETXEN_NIC_REGS_LEN;
    281}
    282
    283static void
    284netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
    285{
    286	struct netxen_adapter *adapter = netdev_priv(dev);
    287	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
    288	struct nx_host_sds_ring *sds_ring;
    289	u32 *regs_buff = p;
    290	int ring, i = 0;
    291	int port = adapter->physical_port;
    292
    293	memset(p, 0, NETXEN_NIC_REGS_LEN);
    294
    295	regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
    296	    (adapter->pdev)->device;
    297
    298	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
    299		return;
    300
    301	regs_buff[i++] = NXRD32(adapter, CRB_CMDPEG_STATE);
    302	regs_buff[i++] = NXRD32(adapter, CRB_RCVPEG_STATE);
    303	regs_buff[i++] = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
    304	regs_buff[i++] = NXRDIO(adapter, adapter->crb_int_state_reg);
    305	regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
    306	regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_STATE);
    307	regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
    308	regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1);
    309	regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS2);
    310
    311	regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_0+0x3c);
    312	regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_1+0x3c);
    313	regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_2+0x3c);
    314	regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_3+0x3c);
    315
    316	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
    317
    318		regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_4+0x3c);
    319		i += 2;
    320
    321		regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE_P3);
    322		regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
    323
    324	} else {
    325		i++;
    326
    327		regs_buff[i++] = NXRD32(adapter,
    328					NETXEN_NIU_XGE_CONFIG_0+(0x10000*port));
    329		regs_buff[i++] = NXRD32(adapter,
    330					NETXEN_NIU_XGE_CONFIG_1+(0x10000*port));
    331
    332		regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE);
    333		regs_buff[i++] = NXRDIO(adapter,
    334				 adapter->tx_ring->crb_cmd_consumer);
    335	}
    336
    337	regs_buff[i++] = NXRDIO(adapter, adapter->tx_ring->crb_cmd_producer);
    338
    339	regs_buff[i++] = NXRDIO(adapter,
    340			 recv_ctx->rds_rings[0].crb_rcv_producer);
    341	regs_buff[i++] = NXRDIO(adapter,
    342			 recv_ctx->rds_rings[1].crb_rcv_producer);
    343
    344	regs_buff[i++] = adapter->max_sds_rings;
    345
    346	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
    347		sds_ring = &(recv_ctx->sds_rings[ring]);
    348		regs_buff[i++] = NXRDIO(adapter,
    349					sds_ring->crb_sts_consumer);
    350	}
    351}
    352
    353static u32 netxen_nic_test_link(struct net_device *dev)
    354{
    355	struct netxen_adapter *adapter = netdev_priv(dev);
    356	u32 val, port;
    357
    358	port = adapter->physical_port;
    359	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
    360		val = NXRD32(adapter, CRB_XG_STATE_P3);
    361		val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
    362		return (val == XG_LINK_UP_P3) ? 0 : 1;
    363	} else {
    364		val = NXRD32(adapter, CRB_XG_STATE);
    365		val = (val >> port*8) & 0xff;
    366		return (val == XG_LINK_UP) ? 0 : 1;
    367	}
    368}
    369
    370static int
    371netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
    372		      u8 *bytes)
    373{
    374	struct netxen_adapter *adapter = netdev_priv(dev);
    375	int offset;
    376	int ret;
    377
    378	if (eeprom->len == 0)
    379		return -EINVAL;
    380
    381	eeprom->magic = (adapter->pdev)->vendor |
    382			((adapter->pdev)->device << 16);
    383	offset = eeprom->offset;
    384
    385	ret = netxen_rom_fast_read_words(adapter, offset, bytes,
    386						eeprom->len);
    387	if (ret < 0)
    388		return ret;
    389
    390	return 0;
    391}
    392
    393static void
    394netxen_nic_get_ringparam(struct net_device *dev,
    395			 struct ethtool_ringparam *ring,
    396			 struct kernel_ethtool_ringparam *kernel_ring,
    397			 struct netlink_ext_ack *extack)
    398{
    399	struct netxen_adapter *adapter = netdev_priv(dev);
    400
    401	ring->rx_pending = adapter->num_rxd;
    402	ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
    403	ring->rx_jumbo_pending += adapter->num_lro_rxd;
    404	ring->tx_pending = adapter->num_txd;
    405
    406	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
    407		ring->rx_max_pending = MAX_RCV_DESCRIPTORS_1G;
    408		ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_1G;
    409	} else {
    410		ring->rx_max_pending = MAX_RCV_DESCRIPTORS_10G;
    411		ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_10G;
    412	}
    413
    414	ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
    415}
    416
    417static u32
    418netxen_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
    419{
    420	u32 num_desc;
    421	num_desc = max(val, min);
    422	num_desc = min(num_desc, max);
    423	num_desc = roundup_pow_of_two(num_desc);
    424
    425	if (val != num_desc) {
    426		printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
    427		       netxen_nic_driver_name, r_name, num_desc, val);
    428	}
    429
    430	return num_desc;
    431}
    432
    433static int
    434netxen_nic_set_ringparam(struct net_device *dev,
    435			 struct ethtool_ringparam *ring,
    436			 struct kernel_ethtool_ringparam *kernel_ring,
    437			 struct netlink_ext_ack *extack)
    438{
    439	struct netxen_adapter *adapter = netdev_priv(dev);
    440	u16 max_rcv_desc = MAX_RCV_DESCRIPTORS_10G;
    441	u16 max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G;
    442	u16 num_rxd, num_jumbo_rxd, num_txd;
    443
    444	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
    445		return -EOPNOTSUPP;
    446
    447	if (ring->rx_mini_pending)
    448		return -EOPNOTSUPP;
    449
    450	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
    451		max_rcv_desc = MAX_RCV_DESCRIPTORS_1G;
    452		max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G;
    453	}
    454
    455	num_rxd = netxen_validate_ringparam(ring->rx_pending,
    456			MIN_RCV_DESCRIPTORS, max_rcv_desc, "rx");
    457
    458	num_jumbo_rxd = netxen_validate_ringparam(ring->rx_jumbo_pending,
    459			MIN_JUMBO_DESCRIPTORS, max_jumbo_desc, "rx jumbo");
    460
    461	num_txd = netxen_validate_ringparam(ring->tx_pending,
    462			MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
    463
    464	if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
    465			num_jumbo_rxd == adapter->num_jumbo_rxd)
    466		return 0;
    467
    468	adapter->num_rxd = num_rxd;
    469	adapter->num_jumbo_rxd = num_jumbo_rxd;
    470	adapter->num_txd = num_txd;
    471
    472	return netxen_nic_reset_context(adapter);
    473}
    474
    475static void
    476netxen_nic_get_pauseparam(struct net_device *dev,
    477			  struct ethtool_pauseparam *pause)
    478{
    479	struct netxen_adapter *adapter = netdev_priv(dev);
    480	__u32 val;
    481	int port = adapter->physical_port;
    482
    483	pause->autoneg = 0;
    484
    485	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
    486		if ((port < 0) || (port >= NETXEN_NIU_MAX_GBE_PORTS))
    487			return;
    488		/* get flow control settings */
    489		val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
    490		pause->rx_pause = netxen_gb_get_rx_flowctl(val);
    491		val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
    492		switch (port) {
    493		case 0:
    494			pause->tx_pause = !(netxen_gb_get_gb0_mask(val));
    495			break;
    496		case 1:
    497			pause->tx_pause = !(netxen_gb_get_gb1_mask(val));
    498			break;
    499		case 2:
    500			pause->tx_pause = !(netxen_gb_get_gb2_mask(val));
    501			break;
    502		case 3:
    503		default:
    504			pause->tx_pause = !(netxen_gb_get_gb3_mask(val));
    505			break;
    506		}
    507	} else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
    508		if ((port < 0) || (port >= NETXEN_NIU_MAX_XG_PORTS))
    509			return;
    510		pause->rx_pause = 1;
    511		val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
    512		if (port == 0)
    513			pause->tx_pause = !(netxen_xg_get_xg0_mask(val));
    514		else
    515			pause->tx_pause = !(netxen_xg_get_xg1_mask(val));
    516	} else {
    517		printk(KERN_ERR"%s: Unknown board type: %x\n",
    518				netxen_nic_driver_name, adapter->ahw.port_type);
    519	}
    520}
    521
    522static int
    523netxen_nic_set_pauseparam(struct net_device *dev,
    524			  struct ethtool_pauseparam *pause)
    525{
    526	struct netxen_adapter *adapter = netdev_priv(dev);
    527	__u32 val;
    528	int port = adapter->physical_port;
    529
    530	/* not supported */
    531	if (pause->autoneg)
    532		return -EINVAL;
    533
    534	/* read mode */
    535	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
    536		if ((port < 0) || (port >= NETXEN_NIU_MAX_GBE_PORTS))
    537			return -EIO;
    538		/* set flow control */
    539		val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
    540
    541		if (pause->rx_pause)
    542			netxen_gb_rx_flowctl(val);
    543		else
    544			netxen_gb_unset_rx_flowctl(val);
    545
    546		NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
    547				val);
    548		/* set autoneg */
    549		val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
    550		switch (port) {
    551		case 0:
    552			if (pause->tx_pause)
    553				netxen_gb_unset_gb0_mask(val);
    554			else
    555				netxen_gb_set_gb0_mask(val);
    556			break;
    557		case 1:
    558			if (pause->tx_pause)
    559				netxen_gb_unset_gb1_mask(val);
    560			else
    561				netxen_gb_set_gb1_mask(val);
    562			break;
    563		case 2:
    564			if (pause->tx_pause)
    565				netxen_gb_unset_gb2_mask(val);
    566			else
    567				netxen_gb_set_gb2_mask(val);
    568			break;
    569		case 3:
    570		default:
    571			if (pause->tx_pause)
    572				netxen_gb_unset_gb3_mask(val);
    573			else
    574				netxen_gb_set_gb3_mask(val);
    575			break;
    576		}
    577		NXWR32(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
    578	} else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
    579		if ((port < 0) || (port >= NETXEN_NIU_MAX_XG_PORTS))
    580			return -EIO;
    581		val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
    582		if (port == 0) {
    583			if (pause->tx_pause)
    584				netxen_xg_unset_xg0_mask(val);
    585			else
    586				netxen_xg_set_xg0_mask(val);
    587		} else {
    588			if (pause->tx_pause)
    589				netxen_xg_unset_xg1_mask(val);
    590			else
    591				netxen_xg_set_xg1_mask(val);
    592		}
    593		NXWR32(adapter, NETXEN_NIU_XG_PAUSE_CTL, val);
    594	} else {
    595		printk(KERN_ERR "%s: Unknown board type: %x\n",
    596				netxen_nic_driver_name,
    597				adapter->ahw.port_type);
    598	}
    599	return 0;
    600}
    601
    602static int netxen_nic_reg_test(struct net_device *dev)
    603{
    604	struct netxen_adapter *adapter = netdev_priv(dev);
    605	u32 data_read, data_written;
    606
    607	data_read = NXRD32(adapter, NETXEN_PCIX_PH_REG(0));
    608	if ((data_read & 0xffff) != adapter->pdev->vendor)
    609		return 1;
    610
    611	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
    612		return 0;
    613
    614	data_written = (u32)0xa5a5a5a5;
    615
    616	NXWR32(adapter, CRB_SCRATCHPAD_TEST, data_written);
    617	data_read = NXRD32(adapter, CRB_SCRATCHPAD_TEST);
    618	if (data_written != data_read)
    619		return 1;
    620
    621	return 0;
    622}
    623
    624static int netxen_get_sset_count(struct net_device *dev, int sset)
    625{
    626	switch (sset) {
    627	case ETH_SS_TEST:
    628		return NETXEN_NIC_TEST_LEN;
    629	case ETH_SS_STATS:
    630		return NETXEN_NIC_STATS_LEN;
    631	default:
    632		return -EOPNOTSUPP;
    633	}
    634}
    635
    636static void
    637netxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
    638		     u64 *data)
    639{
    640	memset(data, 0, sizeof(uint64_t) * NETXEN_NIC_TEST_LEN);
    641	if ((data[0] = netxen_nic_reg_test(dev)))
    642		eth_test->flags |= ETH_TEST_FL_FAILED;
    643	/* link test */
    644	if ((data[1] = (u64) netxen_nic_test_link(dev)))
    645		eth_test->flags |= ETH_TEST_FL_FAILED;
    646}
    647
    648static void
    649netxen_nic_get_strings(struct net_device *dev, u32 stringset, u8 *data)
    650{
    651	int index;
    652
    653	switch (stringset) {
    654	case ETH_SS_TEST:
    655		memcpy(data, *netxen_nic_gstrings_test,
    656		       NETXEN_NIC_TEST_LEN * ETH_GSTRING_LEN);
    657		break;
    658	case ETH_SS_STATS:
    659		for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) {
    660			memcpy(data + index * ETH_GSTRING_LEN,
    661			       netxen_nic_gstrings_stats[index].stat_string,
    662			       ETH_GSTRING_LEN);
    663		}
    664		break;
    665	}
    666}
    667
    668static void
    669netxen_nic_get_ethtool_stats(struct net_device *dev,
    670			     struct ethtool_stats *stats, u64 *data)
    671{
    672	struct netxen_adapter *adapter = netdev_priv(dev);
    673	int index;
    674
    675	for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) {
    676		char *p =
    677		    (char *)adapter +
    678		    netxen_nic_gstrings_stats[index].stat_offset;
    679		data[index] =
    680		    (netxen_nic_gstrings_stats[index].sizeof_stat ==
    681		     sizeof(u64)) ? *(u64 *) p : *(u32 *) p;
    682	}
    683}
    684
    685static void
    686netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
    687{
    688	struct netxen_adapter *adapter = netdev_priv(dev);
    689	u32 wol_cfg = 0;
    690
    691	wol->supported = 0;
    692	wol->wolopts = 0;
    693
    694	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
    695		return;
    696
    697	wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
    698	if (wol_cfg & (1UL << adapter->portnum))
    699		wol->supported |= WAKE_MAGIC;
    700
    701	wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
    702	if (wol_cfg & (1UL << adapter->portnum))
    703		wol->wolopts |= WAKE_MAGIC;
    704}
    705
    706static int
    707netxen_nic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
    708{
    709	struct netxen_adapter *adapter = netdev_priv(dev);
    710	u32 wol_cfg = 0;
    711
    712	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
    713		return -EOPNOTSUPP;
    714
    715	if (wol->wolopts & ~WAKE_MAGIC)
    716		return -EOPNOTSUPP;
    717
    718	wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
    719	if (!(wol_cfg & (1 << adapter->portnum)))
    720		return -EOPNOTSUPP;
    721
    722	wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
    723	if (wol->wolopts & WAKE_MAGIC)
    724		wol_cfg |= 1UL << adapter->portnum;
    725	else
    726		wol_cfg &= ~(1UL << adapter->portnum);
    727	NXWR32(adapter, NETXEN_WOL_CONFIG, wol_cfg);
    728
    729	return 0;
    730}
    731
    732/*
    733 * Set the coalescing parameters. Currently only normal is supported.
    734 * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
    735 * firmware coalescing to default.
    736 */
    737static int netxen_set_intr_coalesce(struct net_device *netdev,
    738				    struct ethtool_coalesce *ethcoal,
    739				    struct kernel_ethtool_coalesce *kernel_coal,
    740				    struct netlink_ext_ack *extack)
    741{
    742	struct netxen_adapter *adapter = netdev_priv(netdev);
    743
    744	if (!NX_IS_REVISION_P3(adapter->ahw.revision_id))
    745		return -EINVAL;
    746
    747	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
    748		return -EINVAL;
    749
    750	/*
    751	* Return Error if unsupported values or
    752	* unsupported parameters are set.
    753	*/
    754	if (ethcoal->rx_coalesce_usecs > 0xffff ||
    755		ethcoal->rx_max_coalesced_frames > 0xffff ||
    756		ethcoal->tx_coalesce_usecs > 0xffff ||
    757		ethcoal->tx_max_coalesced_frames > 0xffff)
    758		return -EINVAL;
    759
    760	if (!ethcoal->rx_coalesce_usecs ||
    761		!ethcoal->rx_max_coalesced_frames) {
    762		adapter->coal.flags = NETXEN_NIC_INTR_DEFAULT;
    763		adapter->coal.normal.data.rx_time_us =
    764			NETXEN_DEFAULT_INTR_COALESCE_RX_TIME_US;
    765		adapter->coal.normal.data.rx_packets =
    766			NETXEN_DEFAULT_INTR_COALESCE_RX_PACKETS;
    767	} else {
    768		adapter->coal.flags = 0;
    769		adapter->coal.normal.data.rx_time_us =
    770		ethcoal->rx_coalesce_usecs;
    771		adapter->coal.normal.data.rx_packets =
    772		ethcoal->rx_max_coalesced_frames;
    773	}
    774	adapter->coal.normal.data.tx_time_us = ethcoal->tx_coalesce_usecs;
    775	adapter->coal.normal.data.tx_packets =
    776	ethcoal->tx_max_coalesced_frames;
    777
    778	netxen_config_intr_coalesce(adapter);
    779
    780	return 0;
    781}
    782
    783static int netxen_get_intr_coalesce(struct net_device *netdev,
    784				    struct ethtool_coalesce *ethcoal,
    785				    struct kernel_ethtool_coalesce *kernel_coal,
    786				    struct netlink_ext_ack *extack)
    787{
    788	struct netxen_adapter *adapter = netdev_priv(netdev);
    789
    790	if (!NX_IS_REVISION_P3(adapter->ahw.revision_id))
    791		return -EINVAL;
    792
    793	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
    794		return -EINVAL;
    795
    796	ethcoal->rx_coalesce_usecs = adapter->coal.normal.data.rx_time_us;
    797	ethcoal->tx_coalesce_usecs = adapter->coal.normal.data.tx_time_us;
    798	ethcoal->rx_max_coalesced_frames =
    799		adapter->coal.normal.data.rx_packets;
    800	ethcoal->tx_max_coalesced_frames =
    801		adapter->coal.normal.data.tx_packets;
    802
    803	return 0;
    804}
    805
    806static int
    807netxen_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
    808{
    809	struct netxen_adapter *adapter = netdev_priv(netdev);
    810	struct netxen_minidump *mdump = &adapter->mdump;
    811	if (adapter->fw_mdump_rdy)
    812		dump->len = mdump->md_dump_size;
    813	else
    814		dump->len = 0;
    815
    816	if (!mdump->md_enabled)
    817		dump->flag = ETH_FW_DUMP_DISABLE;
    818	else
    819		dump->flag = mdump->md_capture_mask;
    820
    821	dump->version = adapter->fw_version;
    822	return 0;
    823}
    824
    825/* Fw dump levels */
    826static const u32 FW_DUMP_LEVELS[] = { 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff };
    827
    828static int
    829netxen_set_dump(struct net_device *netdev, struct ethtool_dump *val)
    830{
    831	int i;
    832	struct netxen_adapter *adapter = netdev_priv(netdev);
    833	struct netxen_minidump *mdump = &adapter->mdump;
    834
    835	switch (val->flag) {
    836	case NX_FORCE_FW_DUMP_KEY:
    837		if (!mdump->md_enabled) {
    838			netdev_info(netdev, "FW dump not enabled\n");
    839			return 0;
    840		}
    841		if (adapter->fw_mdump_rdy) {
    842			netdev_info(netdev, "Previous dump not cleared, not forcing dump\n");
    843			return 0;
    844		}
    845		netdev_info(netdev, "Forcing a fw dump\n");
    846		nx_dev_request_reset(adapter);
    847		break;
    848	case NX_DISABLE_FW_DUMP:
    849		if (mdump->md_enabled) {
    850			netdev_info(netdev, "Disabling FW Dump\n");
    851			mdump->md_enabled = 0;
    852		}
    853		break;
    854	case NX_ENABLE_FW_DUMP:
    855		if (!mdump->md_enabled) {
    856			netdev_info(netdev, "Enabling FW dump\n");
    857			mdump->md_enabled = 1;
    858		}
    859		break;
    860	case NX_FORCE_FW_RESET:
    861		netdev_info(netdev, "Forcing FW reset\n");
    862		nx_dev_request_reset(adapter);
    863		adapter->flags &= ~NETXEN_FW_RESET_OWNER;
    864		break;
    865	default:
    866		for (i = 0; i < ARRAY_SIZE(FW_DUMP_LEVELS); i++) {
    867			if (val->flag == FW_DUMP_LEVELS[i]) {
    868				mdump->md_capture_mask = val->flag;
    869				netdev_info(netdev,
    870					"Driver mask changed to: 0x%x\n",
    871					mdump->md_capture_mask);
    872				return 0;
    873			}
    874		}
    875		netdev_info(netdev,
    876			"Invalid dump level: 0x%x\n", val->flag);
    877		return -EINVAL;
    878	}
    879
    880	return 0;
    881}
    882
    883static int
    884netxen_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
    885			void *buffer)
    886{
    887	int i, copy_sz;
    888	u32 *hdr_ptr, *data;
    889	struct netxen_adapter *adapter = netdev_priv(netdev);
    890	struct netxen_minidump *mdump = &adapter->mdump;
    891
    892
    893	if (!adapter->fw_mdump_rdy) {
    894		netdev_info(netdev, "Dump not available\n");
    895		return -EINVAL;
    896	}
    897	/* Copy template header first */
    898	copy_sz = mdump->md_template_size;
    899	hdr_ptr = (u32 *) mdump->md_template;
    900	data = buffer;
    901	for (i = 0; i < copy_sz/sizeof(u32); i++)
    902		*data++ = cpu_to_le32(*hdr_ptr++);
    903
    904	/* Copy captured dump data */
    905	memcpy(buffer + copy_sz,
    906		mdump->md_capture_buff + mdump->md_template_size,
    907			mdump->md_capture_size);
    908	dump->len = copy_sz + mdump->md_capture_size;
    909	dump->flag = mdump->md_capture_mask;
    910
    911	/* Free dump area once data has been captured */
    912	vfree(mdump->md_capture_buff);
    913	mdump->md_capture_buff = NULL;
    914	adapter->fw_mdump_rdy = 0;
    915	netdev_info(netdev, "extracted the fw dump Successfully\n");
    916	return 0;
    917}
    918
    919const struct ethtool_ops netxen_nic_ethtool_ops = {
    920	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
    921				     ETHTOOL_COALESCE_MAX_FRAMES,
    922	.get_drvinfo = netxen_nic_get_drvinfo,
    923	.get_regs_len = netxen_nic_get_regs_len,
    924	.get_regs = netxen_nic_get_regs,
    925	.get_link = ethtool_op_get_link,
    926	.get_eeprom_len = netxen_nic_get_eeprom_len,
    927	.get_eeprom = netxen_nic_get_eeprom,
    928	.get_ringparam = netxen_nic_get_ringparam,
    929	.set_ringparam = netxen_nic_set_ringparam,
    930	.get_pauseparam = netxen_nic_get_pauseparam,
    931	.set_pauseparam = netxen_nic_set_pauseparam,
    932	.get_wol = netxen_nic_get_wol,
    933	.set_wol = netxen_nic_set_wol,
    934	.self_test = netxen_nic_diag_test,
    935	.get_strings = netxen_nic_get_strings,
    936	.get_ethtool_stats = netxen_nic_get_ethtool_stats,
    937	.get_sset_count = netxen_get_sset_count,
    938	.get_coalesce = netxen_get_intr_coalesce,
    939	.set_coalesce = netxen_set_intr_coalesce,
    940	.get_dump_flag = netxen_get_dump_flag,
    941	.get_dump_data = netxen_get_dump_data,
    942	.set_dump = netxen_set_dump,
    943	.get_link_ksettings = netxen_nic_get_link_ksettings,
    944	.set_link_ksettings = netxen_nic_set_link_ksettings,
    945};