File Index
Files and directories
Sign in
FILE

qlcnic_ethtool.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * QLogic qlcnic NIC Driver
   4 * Copyright (c) 2009-2013 QLogic Corporation
   5 */
   6
   7#include <linux/types.h>
   8#include <linux/delay.h>
   9#include <linux/pci.h>
  10#include <linux/io.h>
  11#include <linux/netdevice.h>
  12#include <linux/ethtool.h>
  13
  14#include "qlcnic.h"
  15
  16struct qlcnic_stats {
  17	char stat_string[ETH_GSTRING_LEN];
  18	int sizeof_stat;
  19	int stat_offset;
  20};
  21
  22#define QLC_SIZEOF(m) sizeof_field(struct qlcnic_adapter, m)
  23#define QLC_OFF(m) offsetof(struct qlcnic_adapter, m)
  24static const u32 qlcnic_fw_dump_level[] = {
  25	0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff
  26};
  27
  28static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
  29	{"xmit_on", QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)},
  30	{"xmit_off", QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)},
  31	{"xmit_called", QLC_SIZEOF(stats.xmitcalled),
  32	 QLC_OFF(stats.xmitcalled)},
  33	{"xmit_finished", QLC_SIZEOF(stats.xmitfinished),
  34	 QLC_OFF(stats.xmitfinished)},
  35	{"tx dma map error", QLC_SIZEOF(stats.tx_dma_map_error),
  36	 QLC_OFF(stats.tx_dma_map_error)},
  37	{"tx_bytes", QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)},
  38	{"tx_dropped", QLC_SIZEOF(stats.txdropped), QLC_OFF(stats.txdropped)},
  39	{"rx dma map error", QLC_SIZEOF(stats.rx_dma_map_error),
  40	 QLC_OFF(stats.rx_dma_map_error)},
  41	{"rx_pkts", QLC_SIZEOF(stats.rx_pkts), QLC_OFF(stats.rx_pkts)},
  42	{"rx_bytes", QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)},
  43	{"rx_dropped", QLC_SIZEOF(stats.rxdropped), QLC_OFF(stats.rxdropped)},
  44	{"null rxbuf", QLC_SIZEOF(stats.null_rxbuf), QLC_OFF(stats.null_rxbuf)},
  45	{"csummed", QLC_SIZEOF(stats.csummed), QLC_OFF(stats.csummed)},
  46	{"lro_pkts", QLC_SIZEOF(stats.lro_pkts), QLC_OFF(stats.lro_pkts)},
  47	{"lrobytes", QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)},
  48	{"lso_frames", QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)},
  49	{"encap_lso_frames", QLC_SIZEOF(stats.encap_lso_frames),
  50	 QLC_OFF(stats.encap_lso_frames)},
  51	{"encap_tx_csummed", QLC_SIZEOF(stats.encap_tx_csummed),
  52	 QLC_OFF(stats.encap_tx_csummed)},
  53	{"encap_rx_csummed", QLC_SIZEOF(stats.encap_rx_csummed),
  54	 QLC_OFF(stats.encap_rx_csummed)},
  55	{"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
  56	 QLC_OFF(stats.skb_alloc_failure)},
  57	{"mac_filter_limit_overrun", QLC_SIZEOF(stats.mac_filter_limit_overrun),
  58	 QLC_OFF(stats.mac_filter_limit_overrun)},
  59	{"spurious intr", QLC_SIZEOF(stats.spurious_intr),
  60	 QLC_OFF(stats.spurious_intr)},
  61	{"mbx spurious intr", QLC_SIZEOF(stats.mbx_spurious_intr),
  62	 QLC_OFF(stats.mbx_spurious_intr)},
  63};
  64
  65static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
  66	"tx unicast frames",
  67	"tx multicast frames",
  68	"tx broadcast frames",
  69	"tx dropped frames",
  70	"tx errors",
  71	"tx local frames",
  72	"tx numbytes",
  73	"rx unicast frames",
  74	"rx multicast frames",
  75	"rx broadcast frames",
  76	"rx dropped frames",
  77	"rx errors",
  78	"rx local frames",
  79	"rx numbytes",
  80};
  81
  82static const char qlcnic_83xx_tx_stats_strings[][ETH_GSTRING_LEN] = {
  83	"ctx_tx_bytes",
  84	"ctx_tx_pkts",
  85	"ctx_tx_errors",
  86	"ctx_tx_dropped_pkts",
  87	"ctx_tx_num_buffers",
  88};
  89
  90static const char qlcnic_83xx_mac_stats_strings[][ETH_GSTRING_LEN] = {
  91	"mac_tx_frames",
  92	"mac_tx_bytes",
  93	"mac_tx_mcast_pkts",
  94	"mac_tx_bcast_pkts",
  95	"mac_tx_pause_cnt",
  96	"mac_tx_ctrl_pkt",
  97	"mac_tx_lt_64b_pkts",
  98	"mac_tx_lt_127b_pkts",
  99	"mac_tx_lt_255b_pkts",
 100	"mac_tx_lt_511b_pkts",
 101	"mac_tx_lt_1023b_pkts",
 102	"mac_tx_lt_1518b_pkts",
 103	"mac_tx_gt_1518b_pkts",
 104	"mac_rx_frames",
 105	"mac_rx_bytes",
 106	"mac_rx_mcast_pkts",
 107	"mac_rx_bcast_pkts",
 108	"mac_rx_pause_cnt",
 109	"mac_rx_ctrl_pkt",
 110	"mac_rx_lt_64b_pkts",
 111	"mac_rx_lt_127b_pkts",
 112	"mac_rx_lt_255b_pkts",
 113	"mac_rx_lt_511b_pkts",
 114	"mac_rx_lt_1023b_pkts",
 115	"mac_rx_lt_1518b_pkts",
 116	"mac_rx_gt_1518b_pkts",
 117	"mac_rx_length_error",
 118	"mac_rx_length_small",
 119	"mac_rx_length_large",
 120	"mac_rx_jabber",
 121	"mac_rx_dropped",
 122	"mac_crc_error",
 123	"mac_align_error",
 124	"eswitch_frames",
 125	"eswitch_bytes",
 126	"eswitch_multicast_frames",
 127	"eswitch_broadcast_frames",
 128	"eswitch_unicast_frames",
 129	"eswitch_error_free_frames",
 130	"eswitch_error_free_bytes",
 131};
 132
 133#define QLCNIC_STATS_LEN	ARRAY_SIZE(qlcnic_gstrings_stats)
 134
 135static const char qlcnic_tx_queue_stats_strings[][ETH_GSTRING_LEN] = {
 136	"xmit_on",
 137	"xmit_off",
 138	"xmit_called",
 139	"xmit_finished",
 140	"tx_bytes",
 141};
 142
 143#define QLCNIC_TX_STATS_LEN	ARRAY_SIZE(qlcnic_tx_queue_stats_strings)
 144
 145static const char qlcnic_83xx_rx_stats_strings[][ETH_GSTRING_LEN] = {
 146	"ctx_rx_bytes",
 147	"ctx_rx_pkts",
 148	"ctx_lro_pkt_cnt",
 149	"ctx_ip_csum_error",
 150	"ctx_rx_pkts_wo_ctx",
 151	"ctx_rx_pkts_drop_wo_sds_on_card",
 152	"ctx_rx_pkts_drop_wo_sds_on_host",
 153	"ctx_rx_osized_pkts",
 154	"ctx_rx_pkts_dropped_wo_rds",
 155	"ctx_rx_unexpected_mcast_pkts",
 156	"ctx_invalid_mac_address",
 157	"ctx_rx_rds_ring_prim_attempted",
 158	"ctx_rx_rds_ring_prim_success",
 159	"ctx_num_lro_flows_added",
 160	"ctx_num_lro_flows_removed",
 161	"ctx_num_lro_flows_active",
 162	"ctx_pkts_dropped_unknown",
 163};
 164
 165static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
 166	"Register_Test_on_offline",
 167	"Link_Test_on_offline",
 168	"Interrupt_Test_offline",
 169	"Internal_Loopback_offline",
 170	"External_Loopback_offline",
 171	"EEPROM_Test_offline"
 172};
 173
 174#define QLCNIC_TEST_LEN	ARRAY_SIZE(qlcnic_gstrings_test)
 175
 176static inline int qlcnic_82xx_statistics(struct qlcnic_adapter *adapter)
 177{
 178	return ARRAY_SIZE(qlcnic_gstrings_stats) +
 179	       ARRAY_SIZE(qlcnic_83xx_mac_stats_strings) +
 180	       QLCNIC_TX_STATS_LEN * adapter->drv_tx_rings;
 181}
 182
 183static inline int qlcnic_83xx_statistics(struct qlcnic_adapter *adapter)
 184{
 185	return ARRAY_SIZE(qlcnic_gstrings_stats) +
 186	       ARRAY_SIZE(qlcnic_83xx_tx_stats_strings) +
 187	       ARRAY_SIZE(qlcnic_83xx_mac_stats_strings) +
 188	       ARRAY_SIZE(qlcnic_83xx_rx_stats_strings) +
 189	       QLCNIC_TX_STATS_LEN * adapter->drv_tx_rings;
 190}
 191
 192static int qlcnic_dev_statistics_len(struct qlcnic_adapter *adapter)
 193{
 194	int len = -1;
 195
 196	if (qlcnic_82xx_check(adapter)) {
 197		len = qlcnic_82xx_statistics(adapter);
 198		if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
 199			len += ARRAY_SIZE(qlcnic_device_gstrings_stats);
 200	} else if (qlcnic_83xx_check(adapter)) {
 201		len = qlcnic_83xx_statistics(adapter);
 202	}
 203
 204	return len;
 205}
 206
 207#define	QLCNIC_TX_INTR_NOT_CONFIGURED	0X78563412
 208
 209#define QLCNIC_MAX_EEPROM_LEN   1024
 210
 211static const u32 diag_registers[] = {
 212	QLCNIC_CMDPEG_STATE,
 213	QLCNIC_RCVPEG_STATE,
 214	QLCNIC_FW_CAPABILITIES,
 215	QLCNIC_CRB_DRV_ACTIVE,
 216	QLCNIC_CRB_DEV_STATE,
 217	QLCNIC_CRB_DRV_STATE,
 218	QLCNIC_CRB_DRV_SCRATCH,
 219	QLCNIC_CRB_DEV_PARTITION_INFO,
 220	QLCNIC_CRB_DRV_IDC_VER,
 221	QLCNIC_PEG_ALIVE_COUNTER,
 222	QLCNIC_PEG_HALT_STATUS1,
 223	QLCNIC_PEG_HALT_STATUS2,
 224	-1
 225};
 226
 227
 228static const u32 ext_diag_registers[] = {
 229	CRB_XG_STATE_P3P,
 230	ISR_INT_STATE_REG,
 231	QLCNIC_CRB_PEG_NET_0+0x3c,
 232	QLCNIC_CRB_PEG_NET_1+0x3c,
 233	QLCNIC_CRB_PEG_NET_2+0x3c,
 234	QLCNIC_CRB_PEG_NET_4+0x3c,
 235	-1
 236};
 237
 238#define QLCNIC_MGMT_API_VERSION	3
 239#define QLCNIC_ETHTOOL_REGS_VER	4
 240
 241static inline int qlcnic_get_ring_regs_len(struct qlcnic_adapter *adapter)
 242{
 243	int ring_regs_cnt = (adapter->drv_tx_rings * 5) +
 244			    (adapter->max_rds_rings * 2) +
 245			    (adapter->drv_sds_rings * 3) + 5;
 246	return ring_regs_cnt * sizeof(u32);
 247}
 248
 249static int qlcnic_get_regs_len(struct net_device *dev)
 250{
 251	struct qlcnic_adapter *adapter = netdev_priv(dev);
 252	u32 len;
 253
 254	if (qlcnic_83xx_check(adapter))
 255		len = qlcnic_83xx_get_regs_len(adapter);
 256	else
 257		len = sizeof(ext_diag_registers) + sizeof(diag_registers);
 258
 259	len += ((QLCNIC_DEV_INFO_SIZE + 2) * sizeof(u32));
 260	len += qlcnic_get_ring_regs_len(adapter);
 261	return len;
 262}
 263
 264static int qlcnic_get_eeprom_len(struct net_device *dev)
 265{
 266	return QLCNIC_FLASH_TOTAL_SIZE;
 267}
 268
 269static void
 270qlcnic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
 271{
 272	struct qlcnic_adapter *adapter = netdev_priv(dev);
 273	u32 fw_major, fw_minor, fw_build;
 274	fw_major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
 275	fw_minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
 276	fw_build = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
 277	snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
 278		"%d.%d.%d", fw_major, fw_minor, fw_build);
 279
 280	strscpy(drvinfo->bus_info, pci_name(adapter->pdev),
 281		sizeof(drvinfo->bus_info));
 282	strscpy(drvinfo->driver, qlcnic_driver_name, sizeof(drvinfo->driver));
 283	strscpy(drvinfo->version, QLCNIC_LINUX_VERSIONID,
 284		sizeof(drvinfo->version));
 285}
 286
 287static int qlcnic_82xx_get_link_ksettings(struct qlcnic_adapter *adapter,
 288					  struct ethtool_link_ksettings *ecmd)
 289{
 290	struct qlcnic_hardware_context *ahw = adapter->ahw;
 291	u32 speed, reg;
 292	int check_sfp_module = 0, err = 0;
 293	u16 pcifn = ahw->pci_func;
 294	u32 supported, advertising;
 295
 296	/* read which mode */
 297	if (adapter->ahw->port_type == QLCNIC_GBE) {
 298		supported = (SUPPORTED_10baseT_Half |
 299				   SUPPORTED_10baseT_Full |
 300				   SUPPORTED_100baseT_Half |
 301				   SUPPORTED_100baseT_Full |
 302				   SUPPORTED_1000baseT_Half |
 303				   SUPPORTED_1000baseT_Full);
 304
 305		advertising = (ADVERTISED_100baseT_Half |
 306				     ADVERTISED_100baseT_Full |
 307				     ADVERTISED_1000baseT_Half |
 308				     ADVERTISED_1000baseT_Full);
 309
 310		ecmd->base.speed = adapter->ahw->link_speed;
 311		ecmd->base.duplex = adapter->ahw->link_duplex;
 312		ecmd->base.autoneg = adapter->ahw->link_autoneg;
 313
 314	} else if (adapter->ahw->port_type == QLCNIC_XGBE) {
 315		u32 val = 0;
 316		val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR, &err);
 317
 318		if (val == QLCNIC_PORT_MODE_802_3_AP) {
 319			supported = SUPPORTED_1000baseT_Full;
 320			advertising = ADVERTISED_1000baseT_Full;
 321		} else {
 322			supported = SUPPORTED_10000baseT_Full;
 323			advertising = ADVERTISED_10000baseT_Full;
 324		}
 325
 326		if (netif_running(adapter->netdev) && ahw->has_link_events) {
 327			if (ahw->linkup) {
 328				reg = QLCRD32(adapter,
 329					      P3P_LINK_SPEED_REG(pcifn), &err);
 330				speed = P3P_LINK_SPEED_VAL(pcifn, reg);
 331				ahw->link_speed = speed * P3P_LINK_SPEED_MHZ;
 332			}
 333
 334			ecmd->base.speed = ahw->link_speed;
 335			ecmd->base.autoneg = ahw->link_autoneg;
 336			ecmd->base.duplex = ahw->link_duplex;
 337			goto skip;
 338		}
 339
 340		ecmd->base.speed = SPEED_UNKNOWN;
 341		ecmd->base.duplex = DUPLEX_UNKNOWN;
 342		ecmd->base.autoneg = AUTONEG_DISABLE;
 343	} else
 344		return -EIO;
 345
 346skip:
 347	ecmd->base.phy_address = adapter->ahw->physical_port;
 348
 349	switch (adapter->ahw->board_type) {
 350	case QLCNIC_BRDTYPE_P3P_REF_QG:
 351	case QLCNIC_BRDTYPE_P3P_4_GB:
 352	case QLCNIC_BRDTYPE_P3P_4_GB_MM:
 353		supported |= SUPPORTED_Autoneg;
 354		advertising |= ADVERTISED_Autoneg;
 355		fallthrough;
 356	case QLCNIC_BRDTYPE_P3P_10G_CX4:
 357	case QLCNIC_BRDTYPE_P3P_10G_CX4_LP:
 358	case QLCNIC_BRDTYPE_P3P_10000_BASE_T:
 359		supported |= SUPPORTED_TP;
 360		advertising |= ADVERTISED_TP;
 361		ecmd->base.port = PORT_TP;
 362		ecmd->base.autoneg =  adapter->ahw->link_autoneg;
 363		break;
 364	case QLCNIC_BRDTYPE_P3P_IMEZ:
 365	case QLCNIC_BRDTYPE_P3P_XG_LOM:
 366	case QLCNIC_BRDTYPE_P3P_HMEZ:
 367		supported |= SUPPORTED_MII;
 368		advertising |= ADVERTISED_MII;
 369		ecmd->base.port = PORT_MII;
 370		ecmd->base.autoneg = AUTONEG_DISABLE;
 371		break;
 372	case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS:
 373	case QLCNIC_BRDTYPE_P3P_10G_SFP_CT:
 374	case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
 375		advertising |= ADVERTISED_TP;
 376		supported |= SUPPORTED_TP;
 377		check_sfp_module = netif_running(adapter->netdev) &&
 378				   ahw->has_link_events;
 379		fallthrough;
 380	case QLCNIC_BRDTYPE_P3P_10G_XFP:
 381		supported |= SUPPORTED_FIBRE;
 382		advertising |= ADVERTISED_FIBRE;
 383		ecmd->base.port = PORT_FIBRE;
 384		ecmd->base.autoneg = AUTONEG_DISABLE;
 385		break;
 386	case QLCNIC_BRDTYPE_P3P_10G_TP:
 387		if (adapter->ahw->port_type == QLCNIC_XGBE) {
 388			ecmd->base.autoneg = AUTONEG_DISABLE;
 389			supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
 390			advertising |=
 391				(ADVERTISED_FIBRE | ADVERTISED_TP);
 392			ecmd->base.port = PORT_FIBRE;
 393			check_sfp_module = netif_running(adapter->netdev) &&
 394					   ahw->has_link_events;
 395		} else {
 396			ecmd->base.autoneg = AUTONEG_ENABLE;
 397			supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
 398			advertising |=
 399				(ADVERTISED_TP | ADVERTISED_Autoneg);
 400			ecmd->base.port = PORT_TP;
 401		}
 402		break;
 403	default:
 404		dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
 405			adapter->ahw->board_type);
 406		return -EIO;
 407	}
 408
 409	if (check_sfp_module) {
 410		switch (adapter->ahw->module_type) {
 411		case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
 412		case LINKEVENT_MODULE_OPTICAL_SRLR:
 413		case LINKEVENT_MODULE_OPTICAL_LRM:
 414		case LINKEVENT_MODULE_OPTICAL_SFP_1G:
 415			ecmd->base.port = PORT_FIBRE;
 416			break;
 417		case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
 418		case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
 419		case LINKEVENT_MODULE_TWINAX:
 420			ecmd->base.port = PORT_TP;
 421			break;
 422		default:
 423			ecmd->base.port = PORT_OTHER;
 424		}
 425	}
 426
 427	ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.supported,
 428						supported);
 429	ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.advertising,
 430						advertising);
 431
 432	return 0;
 433}
 434
 435static int qlcnic_get_link_ksettings(struct net_device *dev,
 436				     struct ethtool_link_ksettings *ecmd)
 437{
 438	struct qlcnic_adapter *adapter = netdev_priv(dev);
 439
 440	if (qlcnic_82xx_check(adapter))
 441		return qlcnic_82xx_get_link_ksettings(adapter, ecmd);
 442	else if (qlcnic_83xx_check(adapter))
 443		return qlcnic_83xx_get_link_ksettings(adapter, ecmd);
 444
 445	return -EIO;
 446}
 447
 448
 449static int qlcnic_set_port_config(struct qlcnic_adapter *adapter,
 450				  const struct ethtool_link_ksettings *ecmd)
 451{
 452	u32 ret = 0, config = 0;
 453	/* read which mode */
 454	if (ecmd->base.duplex)
 455		config |= 0x1;
 456
 457	if (ecmd->base.autoneg)
 458		config |= 0x2;
 459
 460	switch (ecmd->base.speed) {
 461	case SPEED_10:
 462		config |= (0 << 8);
 463		break;
 464	case SPEED_100:
 465		config |= (1 << 8);
 466		break;
 467	case SPEED_1000:
 468		config |= (10 << 8);
 469		break;
 470	default:
 471		return -EIO;
 472	}
 473
 474	ret = qlcnic_fw_cmd_set_port(adapter, config);
 475
 476	if (ret == QLCNIC_RCODE_NOT_SUPPORTED)
 477		return -EOPNOTSUPP;
 478	else if (ret)
 479		return -EIO;
 480	return ret;
 481}
 482
 483static int qlcnic_set_link_ksettings(struct net_device *dev,
 484				     const struct ethtool_link_ksettings *ecmd)
 485{
 486	u32 ret = 0;
 487	struct qlcnic_adapter *adapter = netdev_priv(dev);
 488
 489	if (qlcnic_83xx_check(adapter))
 490		qlcnic_83xx_get_port_type(adapter);
 491
 492	if (adapter->ahw->port_type != QLCNIC_GBE)
 493		return -EOPNOTSUPP;
 494
 495	if (qlcnic_83xx_check(adapter))
 496		ret = qlcnic_83xx_set_link_ksettings(adapter, ecmd);
 497	else
 498		ret = qlcnic_set_port_config(adapter, ecmd);
 499
 500	if (!ret)
 501		return ret;
 502
 503	adapter->ahw->link_speed = ecmd->base.speed;
 504	adapter->ahw->link_duplex = ecmd->base.duplex;
 505	adapter->ahw->link_autoneg = ecmd->base.autoneg;
 506
 507	if (!netif_running(dev))
 508		return 0;
 509
 510	dev->netdev_ops->ndo_stop(dev);
 511	return dev->netdev_ops->ndo_open(dev);
 512}
 513
 514static int qlcnic_82xx_get_registers(struct qlcnic_adapter *adapter,
 515				     u32 *regs_buff)
 516{
 517	int i, j = 0, err = 0;
 518
 519	for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++)
 520		regs_buff[i] = QLC_SHARED_REG_RD32(adapter, diag_registers[j]);
 521	j = 0;
 522	while (ext_diag_registers[j] != -1)
 523		regs_buff[i++] = QLCRD32(adapter, ext_diag_registers[j++],
 524					 &err);
 525	return i;
 526}
 527
 528static void
 529qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
 530{
 531	struct qlcnic_adapter *adapter = netdev_priv(dev);
 532	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
 533	struct qlcnic_host_sds_ring *sds_ring;
 534	struct qlcnic_host_rds_ring *rds_rings;
 535	struct qlcnic_host_tx_ring *tx_ring;
 536	u32 *regs_buff = p;
 537	int ring, i = 0;
 538
 539	memset(p, 0, qlcnic_get_regs_len(dev));
 540
 541	regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
 542		(adapter->ahw->revision_id << 16) | (adapter->pdev)->device;
 543
 544	regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
 545	regs_buff[1] = QLCNIC_MGMT_API_VERSION;
 546
 547	if (adapter->ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY)
 548		regs_buff[2] = adapter->ahw->max_vnic_func;
 549
 550	if (qlcnic_82xx_check(adapter))
 551		i = qlcnic_82xx_get_registers(adapter, regs_buff);
 552	else
 553		i = qlcnic_83xx_get_registers(adapter, regs_buff);
 554
 555	if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
 556		return;
 557
 558	/* Marker btw regs and TX ring count */
 559	regs_buff[i++] = 0xFFEFCDAB;
 560
 561	regs_buff[i++] = adapter->drv_tx_rings; /* No. of TX ring */
 562	for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
 563		tx_ring = &adapter->tx_ring[ring];
 564		regs_buff[i++] = le32_to_cpu(*(tx_ring->hw_consumer));
 565		regs_buff[i++] = tx_ring->sw_consumer;
 566		regs_buff[i++] = readl(tx_ring->crb_cmd_producer);
 567		regs_buff[i++] = tx_ring->producer;
 568		if (tx_ring->crb_intr_mask)
 569			regs_buff[i++] = readl(tx_ring->crb_intr_mask);
 570		else
 571			regs_buff[i++] = QLCNIC_TX_INTR_NOT_CONFIGURED;
 572	}
 573
 574	regs_buff[i++] = adapter->max_rds_rings; /* No. of RX ring */
 575	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
 576		rds_rings = &recv_ctx->rds_rings[ring];
 577		regs_buff[i++] = readl(rds_rings->crb_rcv_producer);
 578		regs_buff[i++] = rds_rings->producer;
 579	}
 580
 581	regs_buff[i++] = adapter->drv_sds_rings; /* No. of SDS ring */
 582	for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
 583		sds_ring = &(recv_ctx->sds_rings[ring]);
 584		regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
 585		regs_buff[i++] = sds_ring->consumer;
 586		regs_buff[i++] = readl(sds_ring->crb_intr_mask);
 587	}
 588}
 589
 590static u32 qlcnic_test_link(struct net_device *dev)
 591{
 592	struct qlcnic_adapter *adapter = netdev_priv(dev);
 593	int err = 0;
 594	u32 val;
 595
 596	if (qlcnic_83xx_check(adapter)) {
 597		val = qlcnic_83xx_test_link(adapter);
 598		return (val & 1) ? 0 : 1;
 599	}
 600	val = QLCRD32(adapter, CRB_XG_STATE_P3P, &err);
 601	if (err == -EIO)
 602		return err;
 603	val = XG_LINK_STATE_P3P(adapter->ahw->pci_func, val);
 604	return (val == XG_LINK_UP_P3P) ? 0 : 1;
 605}
 606
 607static int
 608qlcnic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
 609		      u8 *bytes)
 610{
 611	struct qlcnic_adapter *adapter = netdev_priv(dev);
 612	int offset;
 613	int ret = -1;
 614
 615	if (qlcnic_83xx_check(adapter))
 616		return 0;
 617	if (eeprom->len == 0)
 618		return -EINVAL;
 619
 620	eeprom->magic = (adapter->pdev)->vendor |
 621			((adapter->pdev)->device << 16);
 622	offset = eeprom->offset;
 623
 624	if (qlcnic_82xx_check(adapter))
 625		ret = qlcnic_rom_fast_read_words(adapter, offset, bytes,
 626						 eeprom->len);
 627	if (ret < 0)
 628		return ret;
 629
 630	return 0;
 631}
 632
 633static void
 634qlcnic_get_ringparam(struct net_device *dev,
 635		     struct ethtool_ringparam *ring,
 636		     struct kernel_ethtool_ringparam *kernel_ring,
 637		     struct netlink_ext_ack *extack)
 638{
 639	struct qlcnic_adapter *adapter = netdev_priv(dev);
 640
 641	ring->rx_pending = adapter->num_rxd;
 642	ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
 643	ring->tx_pending = adapter->num_txd;
 644
 645	ring->rx_max_pending = adapter->max_rxd;
 646	ring->rx_jumbo_max_pending = adapter->max_jumbo_rxd;
 647	ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
 648}
 649
 650static u32
 651qlcnic_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
 652{
 653	u32 num_desc;
 654	num_desc = max(val, min);
 655	num_desc = min(num_desc, max);
 656	num_desc = roundup_pow_of_two(num_desc);
 657
 658	if (val != num_desc) {
 659		printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
 660		       qlcnic_driver_name, r_name, num_desc, val);
 661	}
 662
 663	return num_desc;
 664}
 665
 666static int
 667qlcnic_set_ringparam(struct net_device *dev,
 668		     struct ethtool_ringparam *ring,
 669		     struct kernel_ethtool_ringparam *kernel_ring,
 670		     struct netlink_ext_ack *extack)
 671{
 672	struct qlcnic_adapter *adapter = netdev_priv(dev);
 673	u16 num_rxd, num_jumbo_rxd, num_txd;
 674
 675	if (ring->rx_mini_pending)
 676		return -EOPNOTSUPP;
 677
 678	num_rxd = qlcnic_validate_ringparam(ring->rx_pending,
 679			MIN_RCV_DESCRIPTORS, adapter->max_rxd, "rx");
 680
 681	num_jumbo_rxd = qlcnic_validate_ringparam(ring->rx_jumbo_pending,
 682			MIN_JUMBO_DESCRIPTORS, adapter->max_jumbo_rxd,
 683						"rx jumbo");
 684
 685	num_txd = qlcnic_validate_ringparam(ring->tx_pending,
 686			MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
 687
 688	if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
 689			num_jumbo_rxd == adapter->num_jumbo_rxd)
 690		return 0;
 691
 692	adapter->num_rxd = num_rxd;
 693	adapter->num_jumbo_rxd = num_jumbo_rxd;
 694	adapter->num_txd = num_txd;
 695
 696	return qlcnic_reset_context(adapter);
 697}
 698
 699static int qlcnic_validate_ring_count(struct qlcnic_adapter *adapter,
 700				      u8 rx_ring, u8 tx_ring)
 701{
 702	if (rx_ring == 0 || tx_ring == 0)
 703		return -EINVAL;
 704
 705	if (rx_ring != 0) {
 706		if (rx_ring > adapter->max_sds_rings) {
 707			netdev_err(adapter->netdev,
 708				   "Invalid ring count, SDS ring count %d should not be greater than max %d driver sds rings.\n",
 709				   rx_ring, adapter->max_sds_rings);
 710			return -EINVAL;
 711		}
 712	}
 713
 714	if (tx_ring != 0) {
 715		if (tx_ring > adapter->max_tx_rings) {
 716			netdev_err(adapter->netdev,
 717				   "Invalid ring count, Tx ring count %d should not be greater than max %d driver Tx rings.\n",
 718				   tx_ring, adapter->max_tx_rings);
 719			return -EINVAL;
 720		}
 721	}
 722
 723	return 0;
 724}
 725
 726static void qlcnic_get_channels(struct net_device *dev,
 727		struct ethtool_channels *channel)
 728{
 729	struct qlcnic_adapter *adapter = netdev_priv(dev);
 730
 731	channel->max_rx = adapter->max_sds_rings;
 732	channel->max_tx = adapter->max_tx_rings;
 733	channel->rx_count = adapter->drv_sds_rings;
 734	channel->tx_count = adapter->drv_tx_rings;
 735}
 736
 737static int qlcnic_set_channels(struct net_device *dev,
 738			       struct ethtool_channels *channel)
 739{
 740	struct qlcnic_adapter *adapter = netdev_priv(dev);
 741	int err;
 742
 743	if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
 744		netdev_err(dev, "No RSS/TSS support in non MSI-X mode\n");
 745		return -EINVAL;
 746	}
 747
 748	if (channel->other_count || channel->combined_count)
 749		return -EINVAL;
 750
 751	err = qlcnic_validate_ring_count(adapter, channel->rx_count,
 752					 channel->tx_count);
 753	if (err)
 754		return err;
 755
 756	if (adapter->drv_sds_rings != channel->rx_count) {
 757		err = qlcnic_validate_rings(adapter, channel->rx_count,
 758					    QLCNIC_RX_QUEUE);
 759		if (err) {
 760			netdev_err(dev, "Unable to configure %u SDS rings\n",
 761				   channel->rx_count);
 762			return err;
 763		}
 764		adapter->drv_rss_rings = channel->rx_count;
 765	}
 766
 767	if (adapter->drv_tx_rings != channel->tx_count) {
 768		err = qlcnic_validate_rings(adapter, channel->tx_count,
 769					    QLCNIC_TX_QUEUE);
 770		if (err) {
 771			netdev_err(dev, "Unable to configure %u Tx rings\n",
 772				   channel->tx_count);
 773			return err;
 774		}
 775		adapter->drv_tss_rings = channel->tx_count;
 776	}
 777
 778	adapter->flags |= QLCNIC_TSS_RSS;
 779
 780	err = qlcnic_setup_rings(adapter);
 781	netdev_info(dev, "Allocated %d SDS rings and %d Tx rings\n",
 782		    adapter->drv_sds_rings, adapter->drv_tx_rings);
 783
 784	return err;
 785}
 786
 787static void
 788qlcnic_get_pauseparam(struct net_device *netdev,
 789			  struct ethtool_pauseparam *pause)
 790{
 791	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 792	int port = adapter->ahw->physical_port;
 793	int err = 0;
 794	__u32 val;
 795
 796	if (qlcnic_83xx_check(adapter)) {
 797		qlcnic_83xx_get_pauseparam(adapter, pause);
 798		return;
 799	}
 800	if (adapter->ahw->port_type == QLCNIC_GBE) {
 801		if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
 802			return;
 803		/* get flow control settings */
 804		val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), &err);
 805		if (err == -EIO)
 806			return;
 807		pause->rx_pause = qlcnic_gb_get_rx_flowctl(val);
 808		val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, &err);
 809		if (err == -EIO)
 810			return;
 811		switch (port) {
 812		case 0:
 813			pause->tx_pause = !(qlcnic_gb_get_gb0_mask(val));
 814			break;
 815		case 1:
 816			pause->tx_pause = !(qlcnic_gb_get_gb1_mask(val));
 817			break;
 818		case 2:
 819			pause->tx_pause = !(qlcnic_gb_get_gb2_mask(val));
 820			break;
 821		case 3:
 822		default:
 823			pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val));
 824			break;
 825		}
 826	} else if (adapter->ahw->port_type == QLCNIC_XGBE) {
 827		if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
 828			return;
 829		pause->rx_pause = 1;
 830		val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, &err);
 831		if (err == -EIO)
 832			return;
 833		if (port == 0)
 834			pause->tx_pause = !(qlcnic_xg_get_xg0_mask(val));
 835		else
 836			pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val));
 837	} else {
 838		dev_err(&netdev->dev, "Unknown board type: %x\n",
 839					adapter->ahw->port_type);
 840	}
 841}
 842
 843static int
 844qlcnic_set_pauseparam(struct net_device *netdev,
 845			  struct ethtool_pauseparam *pause)
 846{
 847	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 848	int port = adapter->ahw->physical_port;
 849	int err = 0;
 850	__u32 val;
 851
 852	if (qlcnic_83xx_check(adapter))
 853		return qlcnic_83xx_set_pauseparam(adapter, pause);
 854
 855	/* read mode */
 856	if (adapter->ahw->port_type == QLCNIC_GBE) {
 857		if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
 858			return -EIO;
 859		/* set flow control */
 860		val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), &err);
 861		if (err == -EIO)
 862			return err;
 863
 864		if (pause->rx_pause)
 865			qlcnic_gb_rx_flowctl(val);
 866		else
 867			qlcnic_gb_unset_rx_flowctl(val);
 868
 869		QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port),
 870				val);
 871		QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), val);
 872		/* set autoneg */
 873		val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, &err);
 874		if (err == -EIO)
 875			return err;
 876		switch (port) {
 877		case 0:
 878			if (pause->tx_pause)
 879				qlcnic_gb_unset_gb0_mask(val);
 880			else
 881				qlcnic_gb_set_gb0_mask(val);
 882			break;
 883		case 1:
 884			if (pause->tx_pause)
 885				qlcnic_gb_unset_gb1_mask(val);
 886			else
 887				qlcnic_gb_set_gb1_mask(val);
 888			break;
 889		case 2:
 890			if (pause->tx_pause)
 891				qlcnic_gb_unset_gb2_mask(val);
 892			else
 893				qlcnic_gb_set_gb2_mask(val);
 894			break;
 895		case 3:
 896		default:
 897			if (pause->tx_pause)
 898				qlcnic_gb_unset_gb3_mask(val);
 899			else
 900				qlcnic_gb_set_gb3_mask(val);
 901			break;
 902		}
 903		QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val);
 904	} else if (adapter->ahw->port_type == QLCNIC_XGBE) {
 905		if (!pause->rx_pause || pause->autoneg)
 906			return -EOPNOTSUPP;
 907
 908		if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
 909			return -EIO;
 910
 911		val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, &err);
 912		if (err == -EIO)
 913			return err;
 914		if (port == 0) {
 915			if (pause->tx_pause)
 916				qlcnic_xg_unset_xg0_mask(val);
 917			else
 918				qlcnic_xg_set_xg0_mask(val);
 919		} else {
 920			if (pause->tx_pause)
 921				qlcnic_xg_unset_xg1_mask(val);
 922			else
 923				qlcnic_xg_set_xg1_mask(val);
 924		}
 925		QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val);
 926	} else {
 927		dev_err(&netdev->dev, "Unknown board type: %x\n",
 928				adapter->ahw->port_type);
 929	}
 930	return 0;
 931}
 932
 933static int qlcnic_reg_test(struct net_device *dev)
 934{
 935	struct qlcnic_adapter *adapter = netdev_priv(dev);
 936	u32 data_read;
 937	int err = 0;
 938
 939	if (qlcnic_83xx_check(adapter))
 940		return qlcnic_83xx_reg_test(adapter);
 941
 942	data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0), &err);
 943	if (err == -EIO)
 944		return err;
 945	if ((data_read & 0xffff) != adapter->pdev->vendor)
 946		return 1;
 947
 948	return 0;
 949}
 950
 951static int qlcnic_eeprom_test(struct net_device *dev)
 952{
 953	struct qlcnic_adapter *adapter = netdev_priv(dev);
 954
 955	if (qlcnic_82xx_check(adapter))
 956		return 0;
 957
 958	return qlcnic_83xx_flash_test(adapter);
 959}
 960
 961static int qlcnic_get_sset_count(struct net_device *dev, int sset)
 962{
 963
 964	struct qlcnic_adapter *adapter = netdev_priv(dev);
 965	switch (sset) {
 966	case ETH_SS_TEST:
 967		return QLCNIC_TEST_LEN;
 968	case ETH_SS_STATS:
 969		return qlcnic_dev_statistics_len(adapter);
 970	default:
 971		return -EOPNOTSUPP;
 972	}
 973}
 974
 975static int qlcnic_irq_test(struct net_device *netdev)
 976{
 977	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 978	struct qlcnic_hardware_context *ahw = adapter->ahw;
 979	struct qlcnic_cmd_args cmd;
 980	int ret, drv_sds_rings = adapter->drv_sds_rings;
 981	int drv_tx_rings = adapter->drv_tx_rings;
 982
 983	if (qlcnic_83xx_check(adapter))
 984		return qlcnic_83xx_interrupt_test(netdev);
 985
 986	if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
 987		return -EIO;
 988
 989	ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST);
 990	if (ret)
 991		goto clear_diag_irq;
 992
 993	ahw->diag_cnt = 0;
 994	ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
 995	if (ret)
 996		goto free_diag_res;
 997
 998	cmd.req.arg[1] = ahw->pci_func;
 999	ret = qlcnic_issue_cmd(adapter, &cmd);
1000	if (ret)
1001		goto done;
1002
1003	usleep_range(1000, 12000);
1004	ret = !ahw->diag_cnt;
1005
1006done:
1007	qlcnic_free_mbx_args(&cmd);
1008
1009free_diag_res:
1010	qlcnic_diag_free_res(netdev, drv_sds_rings);
1011
1012clear_diag_irq:
1013	adapter->drv_sds_rings = drv_sds_rings;
1014	adapter->drv_tx_rings = drv_tx_rings;
1015	clear_bit(__QLCNIC_RESETTING, &adapter->state);
1016
1017	return ret;
1018}
1019
1020#define QLCNIC_ILB_PKT_SIZE		64
1021#define QLCNIC_NUM_ILB_PKT		16
1022#define QLCNIC_ILB_MAX_RCV_LOOP		10
1023#define QLCNIC_LB_PKT_POLL_DELAY_MSEC	1
1024#define QLCNIC_LB_PKT_POLL_COUNT	20
1025
1026static void qlcnic_create_loopback_buff(unsigned char *data, u8 mac[])
1027{
1028	static const unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00};
1029
1030	memset(data, 0x4e, QLCNIC_ILB_PKT_SIZE);
1031
1032	memcpy(data, mac, ETH_ALEN);
1033	memcpy(data + ETH_ALEN, mac, ETH_ALEN);
1034
1035	memcpy(data + 2 * ETH_ALEN, random_data, sizeof(random_data));
1036}
1037
1038int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[])
1039{
1040	unsigned char buff[QLCNIC_ILB_PKT_SIZE];
1041	qlcnic_create_loopback_buff(buff, mac);
1042	return memcmp(data, buff, QLCNIC_ILB_PKT_SIZE);
1043}
1044
1045int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
1046{
1047	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1048	struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0];
1049	struct sk_buff *skb;
1050	int i, loop, cnt = 0;
1051
1052	for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) {
1053		skb = netdev_alloc_skb(adapter->netdev, QLCNIC_ILB_PKT_SIZE);
1054		if (!skb)
1055			goto error;
1056		qlcnic_create_loopback_buff(skb->data, adapter->mac_addr);
1057		skb_put(skb, QLCNIC_ILB_PKT_SIZE);
1058		adapter->ahw->diag_cnt = 0;
1059		qlcnic_xmit_frame(skb, adapter->netdev);
1060		loop = 0;
1061
1062		do {
1063			msleep(QLCNIC_LB_PKT_POLL_DELAY_MSEC);
1064			qlcnic_process_rcv_ring_diag(sds_ring);
1065			if (loop++ > QLCNIC_LB_PKT_POLL_COUNT)
1066				break;
1067		} while (!adapter->ahw->diag_cnt);
1068
1069		dev_kfree_skb_any(skb);
1070
1071		if (!adapter->ahw->diag_cnt)
1072			dev_warn(&adapter->pdev->dev,
1073				 "LB Test: packet #%d was not received\n",
1074				 i + 1);
1075		else
1076			cnt++;
1077	}
1078	if (cnt != i) {
1079error:
1080		dev_err(&adapter->pdev->dev,
1081			"LB Test: failed, TX[%d], RX[%d]\n", i, cnt);
1082		if (mode != QLCNIC_ILB_MODE)
1083			dev_warn(&adapter->pdev->dev,
1084				 "WARNING: Please check loopback cable\n");
1085		return -1;
1086	}
1087	return 0;
1088}
1089
1090static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
1091{
1092	struct qlcnic_adapter *adapter = netdev_priv(netdev);
1093	int drv_tx_rings = adapter->drv_tx_rings;
1094	int drv_sds_rings = adapter->drv_sds_rings;
1095	struct qlcnic_host_sds_ring *sds_ring;
1096	struct qlcnic_hardware_context *ahw = adapter->ahw;
1097	int loop = 0;
1098	int ret;
1099
1100	if (qlcnic_83xx_check(adapter))
1101		return qlcnic_83xx_loopback_test(netdev, mode);
1102
1103	if (!(ahw->capabilities & QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK)) {
1104		dev_info(&adapter->pdev->dev,
1105			 "Firmware do not support loopback test\n");
1106		return -EOPNOTSUPP;
1107	}
1108
1109	dev_warn(&adapter->pdev->dev, "%s loopback test in progress\n",
1110		 mode == QLCNIC_ILB_MODE ? "internal" : "external");
1111	if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1112		dev_warn(&adapter->pdev->dev,
1113			 "Loopback test not supported in nonprivileged mode\n");
1114		return 0;
1115	}
1116
1117	if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
1118		return -EBUSY;
1119
1120	ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
1121	if (ret)
1122		goto clear_it;
1123
1124	sds_ring = &adapter->recv_ctx->sds_rings[0];
1125	ret = qlcnic_set_lb_mode(adapter, mode);
1126	if (ret)
1127		goto free_res;
1128
1129	ahw->diag_cnt = 0;
1130	do {
1131		msleep(500);
1132		qlcnic_process_rcv_ring_diag(sds_ring);
1133		if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
1134			netdev_info(netdev,
1135				    "Firmware didn't sent link up event to loopback request\n");
1136			ret = -ETIMEDOUT;
1137			goto free_res;
1138		} else if (adapter->ahw->diag_cnt) {
1139			ret = adapter->ahw->diag_cnt;
1140			goto free_res;
1141		}
1142	} while (!QLCNIC_IS_LB_CONFIGURED(ahw->loopback_state));
1143
1144	ret = qlcnic_do_lb_test(adapter, mode);
1145
1146	qlcnic_clear_lb_mode(adapter, mode);
1147
1148 free_res:
1149	qlcnic_diag_free_res(netdev, drv_sds_rings);
1150
1151 clear_it:
1152	adapter->drv_sds_rings = drv_sds_rings;
1153	adapter->drv_tx_rings = drv_tx_rings;
1154	clear_bit(__QLCNIC_RESETTING, &adapter->state);
1155	return ret;
1156}
1157
1158static void
1159qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
1160		     u64 *data)
1161{
1162	memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
1163
1164	data[0] = qlcnic_reg_test(dev);
1165	if (data[0])
1166		eth_test->flags |= ETH_TEST_FL_FAILED;
1167
1168	data[1] = (u64) qlcnic_test_link(dev);
1169	if (data[1])
1170		eth_test->flags |= ETH_TEST_FL_FAILED;
1171
1172	if (eth_test->flags & ETH_TEST_FL_OFFLINE) {
1173		data[2] = qlcnic_irq_test(dev);
1174		if (data[2])
1175			eth_test->flags |= ETH_TEST_FL_FAILED;
1176
1177		data[3] = qlcnic_loopback_test(dev, QLCNIC_ILB_MODE);
1178		if (data[3])
1179			eth_test->flags |= ETH_TEST_FL_FAILED;
1180
1181		if (eth_test->flags & ETH_TEST_FL_EXTERNAL_LB) {
1182			data[4] = qlcnic_loopback_test(dev, QLCNIC_ELB_MODE);
1183			if (data[4])
1184				eth_test->flags |= ETH_TEST_FL_FAILED;
1185			eth_test->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE;
1186		}
1187
1188		data[5] = qlcnic_eeprom_test(dev);
1189		if (data[5])
1190			eth_test->flags |= ETH_TEST_FL_FAILED;
1191	}
1192}
1193
1194static void
1195qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 *data)
1196{
1197	struct qlcnic_adapter *adapter = netdev_priv(dev);
1198	int index, i, num_stats;
1199	const char *str;
1200
1201	switch (stringset) {
1202	case ETH_SS_TEST:
1203		for (i = 0; i < QLCNIC_TEST_LEN; i++)
1204			ethtool_puts(&data, qlcnic_gstrings_test[i]);
1205		break;
1206	case ETH_SS_STATS:
1207		num_stats = ARRAY_SIZE(qlcnic_tx_queue_stats_strings);
1208		for (i = 0; i < adapter->drv_tx_rings; i++)
1209			for (index = 0; index < num_stats; index++) {
1210				str = qlcnic_tx_queue_stats_strings[index];
1211				ethtool_sprintf(&data, "tx_queue_%d %s", i,
1212						str);
1213			}
1214
1215		for (i = 0; i < QLCNIC_STATS_LEN; i++) {
1216			str = qlcnic_gstrings_stats[i].stat_string;
1217			ethtool_puts(&data, str);
1218		}
1219
1220		if (qlcnic_83xx_check(adapter)) {
1221			num_stats = ARRAY_SIZE(qlcnic_83xx_tx_stats_strings);
1222			for (i = 0; i < num_stats; i++) {
1223				str = qlcnic_83xx_tx_stats_strings[i];
1224				ethtool_puts(&data, str);
1225			}
1226			num_stats = ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
1227			for (i = 0; i < num_stats; i++) {
1228				str = qlcnic_83xx_mac_stats_strings[i];
1229				ethtool_puts(&data, str);
1230			}
1231			num_stats = ARRAY_SIZE(qlcnic_83xx_rx_stats_strings);
1232			for (i = 0; i < num_stats; i++) {
1233				str = qlcnic_83xx_rx_stats_strings[i];
1234				ethtool_puts(&data, str);
1235			}
1236			return;
1237		} else {
1238			num_stats = ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
1239			for (i = 0; i < num_stats; i++) {
1240				str = qlcnic_83xx_mac_stats_strings[i];
1241				ethtool_puts(&data, str);
1242			}
1243		}
1244		if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1245			return;
1246		num_stats = ARRAY_SIZE(qlcnic_device_gstrings_stats);
1247		for (i = 0; i < num_stats; i++)
1248			ethtool_puts(&data, qlcnic_device_gstrings_stats[i]);
1249	}
1250}
1251
1252static u64 *qlcnic_fill_stats(u64 *data, void *stats, int type)
1253{
1254	if (type == QLCNIC_MAC_STATS) {
1255		struct qlcnic_mac_statistics *mac_stats =
1256					(struct qlcnic_mac_statistics *)stats;
1257		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_frames);
1258		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_bytes);
1259		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_mcast_pkts);
1260		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_bcast_pkts);
1261		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_pause_cnt);
1262		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_ctrl_pkt);
1263		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_64b_pkts);
1264		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_127b_pkts);
1265		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_255b_pkts);
1266		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_511b_pkts);
1267		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1023b_pkts);
1268		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1518b_pkts);
1269		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_gt_1518b_pkts);
1270		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_frames);
1271		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_bytes);
1272		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_mcast_pkts);
1273		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_bcast_pkts);
1274		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_pause_cnt);
1275		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_ctrl_pkt);
1276		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_64b_pkts);
1277		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_127b_pkts);
1278		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_255b_pkts);
1279		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_511b_pkts);
1280		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1023b_pkts);
1281		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1518b_pkts);
1282		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_gt_1518b_pkts);
1283		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_error);
1284		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_small);
1285		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_large);
1286		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_jabber);
1287		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_dropped);
1288		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_crc_error);
1289		*data++ = QLCNIC_FILL_STATS(mac_stats->mac_align_error);
1290	} else if (type == QLCNIC_ESW_STATS) {
1291		struct __qlcnic_esw_statistics *esw_stats =
1292				(struct __qlcnic_esw_statistics *)stats;
1293		*data++ = QLCNIC_FILL_STATS(esw_stats->unicast_frames);
1294		*data++ = QLCNIC_FILL_STATS(esw_stats->multicast_frames);
1295		*data++ = QLCNIC_FILL_STATS(esw_stats->broadcast_frames);
1296		*data++ = QLCNIC_FILL_STATS(esw_stats->dropped_frames);
1297		*data++ = QLCNIC_FILL_STATS(esw_stats->errors);
1298		*data++ = QLCNIC_FILL_STATS(esw_stats->local_frames);
1299		*data++ = QLCNIC_FILL_STATS(esw_stats->numbytes);
1300	}
1301	return data;
1302}
1303
1304void qlcnic_update_stats(struct qlcnic_adapter *adapter)
1305{
1306	struct qlcnic_tx_queue_stats tx_stats;
1307	struct qlcnic_host_tx_ring *tx_ring;
1308	int ring;
1309
1310	memset(&tx_stats, 0, sizeof(tx_stats));
1311	for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
1312		tx_ring = &adapter->tx_ring[ring];
1313		tx_stats.xmit_on += tx_ring->tx_stats.xmit_on;
1314		tx_stats.xmit_off += tx_ring->tx_stats.xmit_off;
1315		tx_stats.xmit_called += tx_ring->tx_stats.xmit_called;
1316		tx_stats.xmit_finished += tx_ring->tx_stats.xmit_finished;
1317		tx_stats.tx_bytes += tx_ring->tx_stats.tx_bytes;
1318	}
1319
1320	adapter->stats.xmit_on = tx_stats.xmit_on;
1321	adapter->stats.xmit_off = tx_stats.xmit_off;
1322	adapter->stats.xmitcalled = tx_stats.xmit_called;
1323	adapter->stats.xmitfinished = tx_stats.xmit_finished;
1324	adapter->stats.txbytes = tx_stats.tx_bytes;
1325}
1326
1327static u64 *qlcnic_fill_tx_queue_stats(u64 *data, void *stats)
1328{
1329	struct qlcnic_host_tx_ring *tx_ring;
1330
1331	tx_ring = (struct qlcnic_host_tx_ring *)stats;
1332
1333	*data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_on);
1334	*data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_off);
1335	*data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_called);
1336	*data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_finished);
1337	*data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.tx_bytes);
1338
1339	return data;
1340}
1341
1342static void qlcnic_get_ethtool_stats(struct net_device *dev,
1343				     struct ethtool_stats *stats, u64 *data)
1344{
1345	struct qlcnic_adapter *adapter = netdev_priv(dev);
1346	struct qlcnic_host_tx_ring *tx_ring;
1347	struct qlcnic_esw_statistics port_stats;
1348	struct qlcnic_mac_statistics mac_stats;
1349	int index, ret, length, size, ring;
1350	char *p;
1351
1352	memset(data, 0, stats->n_stats * sizeof(u64));
1353
1354	for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
1355		if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) {
1356			tx_ring = &adapter->tx_ring[ring];
1357			data = qlcnic_fill_tx_queue_stats(data, tx_ring);
1358			qlcnic_update_stats(adapter);
1359		} else {
1360			data += QLCNIC_TX_STATS_LEN;
1361		}
1362	}
1363
1364	length = QLCNIC_STATS_LEN;
1365	for (index = 0; index < length; index++) {
1366		p = (char *)adapter + qlcnic_gstrings_stats[index].stat_offset;
1367		size = qlcnic_gstrings_stats[index].sizeof_stat;
1368		*data++ = (size == sizeof(u64)) ? (*(u64 *)p) : ((*(u32 *)p));
1369	}
1370
1371	if (qlcnic_83xx_check(adapter)) {
1372		if (adapter->ahw->linkup)
1373			qlcnic_83xx_get_stats(adapter, data);
1374		return;
1375	} else {
1376		/* Retrieve MAC statistics from firmware */
1377		memset(&mac_stats, 0, sizeof(struct qlcnic_mac_statistics));
1378		qlcnic_get_mac_stats(adapter, &mac_stats);
1379		data = qlcnic_fill_stats(data, &mac_stats, QLCNIC_MAC_STATS);
1380	}
1381
1382	if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1383		return;
1384
1385	memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics));
1386	ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
1387			QLCNIC_QUERY_RX_COUNTER, &port_stats.rx);
1388	if (ret)
1389		return;
1390
1391	data = qlcnic_fill_stats(data, &port_stats.rx, QLCNIC_ESW_STATS);
1392	ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
1393			QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
1394	if (ret)
1395		return;
1396
1397	qlcnic_fill_stats(data, &port_stats.tx, QLCNIC_ESW_STATS);
1398}
1399
1400static int qlcnic_set_led(struct net_device *dev,
1401			  enum ethtool_phys_id_state state)
1402{
1403	struct qlcnic_adapter *adapter = netdev_priv(dev);
1404	int drv_sds_rings = adapter->drv_sds_rings;
1405	int err = -EIO, active = 1;
1406
1407	if (qlcnic_83xx_check(adapter))
1408		return qlcnic_83xx_set_led(dev, state);
1409
1410	if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1411		netdev_warn(dev, "LED test not supported for non "
1412				"privilege function\n");
1413		return -EOPNOTSUPP;
1414	}
1415
1416	switch (state) {
1417	case ETHTOOL_ID_ACTIVE:
1418		if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
1419			return -EBUSY;
1420
1421		if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1422			break;
1423
1424		if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
1425			if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
1426				break;
1427			set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
1428		}
1429
1430		if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) {
1431			err = 0;
1432			break;
1433		}
1434
1435		dev_err(&adapter->pdev->dev,
1436			"Failed to set LED blink state.\n");
1437		break;
1438
1439	case ETHTOOL_ID_INACTIVE:
1440		active = 0;
1441
1442		if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1443			break;
1444
1445		if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
1446			if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
1447				break;
1448			set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
1449		}
1450
1451		if (adapter->nic_ops->config_led(adapter, 0, 0xf))
1452			dev_err(&adapter->pdev->dev,
1453				"Failed to reset LED blink state.\n");
1454
1455		break;
1456
1457	default:
1458		return -EINVAL;
1459	}
1460
1461	if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
1462		qlcnic_diag_free_res(dev, drv_sds_rings);
1463
1464	if (!active || err)
1465		clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
1466
1467	return err;
1468}
1469
1470static void
1471qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1472{
1473	struct qlcnic_adapter *adapter = netdev_priv(dev);
1474	u32 wol_cfg;
1475	int err = 0;
1476
1477	if (qlcnic_83xx_check(adapter))
1478		return;
1479	wol->supported = 0;
1480	wol->wolopts = 0;
1481
1482	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV, &err);
1483	if (err == -EIO)
1484		return;
1485	if (wol_cfg & (1UL << adapter->portnum))
1486		wol->supported |= WAKE_MAGIC;
1487
1488	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG, &err);
1489	if (wol_cfg & (1UL << adapter->portnum))
1490		wol->wolopts |= WAKE_MAGIC;
1491}
1492
1493static int
1494qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1495{
1496	struct qlcnic_adapter *adapter = netdev_priv(dev);
1497	u32 wol_cfg;
1498	int err = 0;
1499
1500	if (qlcnic_83xx_check(adapter))
1501		return -EOPNOTSUPP;
1502	if (wol->wolopts & ~WAKE_MAGIC)
1503		return -EINVAL;
1504
1505	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV, &err);
1506	if (err == -EIO)
1507		return err;
1508	if (!(wol_cfg & (1 << adapter->portnum)))
1509		return -EOPNOTSUPP;
1510
1511	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG, &err);
1512	if (err == -EIO)
1513		return err;
1514	if (wol->wolopts & WAKE_MAGIC)
1515		wol_cfg |= 1UL << adapter->portnum;
1516	else
1517		wol_cfg &= ~(1UL << adapter->portnum);
1518
1519	QLCWR32(adapter, QLCNIC_WOL_CONFIG, wol_cfg);
1520
1521	return 0;
1522}
1523
1524/*
1525 * Set the coalescing parameters. Currently only normal is supported.
1526 * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
1527 * firmware coalescing to default.
1528 */
1529static int qlcnic_set_intr_coalesce(struct net_device *netdev,
1530				    struct ethtool_coalesce *ethcoal,
1531				    struct kernel_ethtool_coalesce *kernel_coal,
1532				    struct netlink_ext_ack *extack)
1533{
1534	struct qlcnic_adapter *adapter = netdev_priv(netdev);
1535	int err;
1536
1537	if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
1538		return -EINVAL;
1539
1540	/*
1541	* Return Error if unsupported values or
1542	* unsupported parameters are set.
1543	*/
1544	if (ethcoal->rx_coalesce_usecs > 0xffff ||
1545	    ethcoal->rx_max_coalesced_frames > 0xffff ||
1546	    ethcoal->tx_coalesce_usecs > 0xffff ||
1547	    ethcoal->tx_max_coalesced_frames > 0xffff)
1548		return -EINVAL;
1549
1550	err = qlcnic_config_intr_coalesce(adapter, ethcoal);
1551
1552	return err;
1553}
1554
1555static int qlcnic_get_intr_coalesce(struct net_device *netdev,
1556				    struct ethtool_coalesce *ethcoal,
1557				    struct kernel_ethtool_coalesce *kernel_coal,
1558				    struct netlink_ext_ack *extack)
1559{
1560	struct qlcnic_adapter *adapter = netdev_priv(netdev);
1561
1562	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
1563		return -EINVAL;
1564
1565	ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us;
1566	ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets;
1567	ethcoal->tx_coalesce_usecs = adapter->ahw->coal.tx_time_us;
1568	ethcoal->tx_max_coalesced_frames = adapter->ahw->coal.tx_packets;
1569
1570	return 0;
1571}
1572
1573static u32 qlcnic_get_msglevel(struct net_device *netdev)
1574{
1575	struct qlcnic_adapter *adapter = netdev_priv(netdev);
1576
1577	return adapter->ahw->msg_enable;
1578}
1579
1580static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
1581{
1582	struct qlcnic_adapter *adapter = netdev_priv(netdev);
1583
1584	adapter->ahw->msg_enable = msglvl;
1585}
1586
1587int qlcnic_enable_fw_dump_state(struct qlcnic_adapter *adapter)
1588{
1589	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1590	u32 val;
1591
1592	if (qlcnic_84xx_check(adapter)) {
1593		if (qlcnic_83xx_lock_driver(adapter))
1594			return -EBUSY;
1595
1596		val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
1597		val &= ~QLC_83XX_IDC_DISABLE_FW_DUMP;
1598		QLCWRX(adapter->ahw, QLC_83XX_IDC_CTRL, val);
1599
1600		qlcnic_83xx_unlock_driver(adapter);
1601	} else {
1602		fw_dump->enable = true;
1603	}
1604
1605	dev_info(&adapter->pdev->dev, "FW dump enabled\n");
1606
1607	return 0;
1608}
1609
1610static int qlcnic_disable_fw_dump_state(struct qlcnic_adapter *adapter)
1611{
1612	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1613	u32 val;
1614
1615	if (qlcnic_84xx_check(adapter)) {
1616		if (qlcnic_83xx_lock_driver(adapter))
1617			return -EBUSY;
1618
1619		val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
1620		val |= QLC_83XX_IDC_DISABLE_FW_DUMP;
1621		QLCWRX(adapter->ahw, QLC_83XX_IDC_CTRL, val);
1622
1623		qlcnic_83xx_unlock_driver(adapter);
1624	} else {
1625		fw_dump->enable = false;
1626	}
1627
1628	dev_info(&adapter->pdev->dev, "FW dump disabled\n");
1629
1630	return 0;
1631}
1632
1633bool qlcnic_check_fw_dump_state(struct qlcnic_adapter *adapter)
1634{
1635	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1636	bool state;
1637	u32 val;
1638
1639	if (qlcnic_84xx_check(adapter)) {
1640		val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
1641		state = (val & QLC_83XX_IDC_DISABLE_FW_DUMP) ? false : true;
1642	} else {
1643		state = fw_dump->enable;
1644	}
1645
1646	return state;
1647}
1648
1649static int
1650qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
1651{
1652	struct qlcnic_adapter *adapter = netdev_priv(netdev);
1653	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1654
1655	if (!fw_dump->tmpl_hdr) {
1656		netdev_err(adapter->netdev, "FW Dump not supported\n");
1657		return -ENOTSUPP;
1658	}
1659
1660	if (fw_dump->clr)
1661		dump->len = fw_dump->tmpl_hdr_size + fw_dump->size;
1662	else
1663		dump->len = 0;
1664
1665	if (!qlcnic_check_fw_dump_state(adapter))
1666		dump->flag = ETH_FW_DUMP_DISABLE;
1667	else
1668		dump->flag = fw_dump->cap_mask;
1669
1670	dump->version = adapter->fw_version;
1671	return 0;
1672}
1673
1674static int
1675qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
1676			void *buffer)
1677{
1678	int i, copy_sz;
1679	u32 *hdr_ptr;
1680	__le32 *data;
1681	struct qlcnic_adapter *adapter = netdev_priv(netdev);
1682	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1683
1684	if (!fw_dump->tmpl_hdr) {
1685		netdev_err(netdev, "FW Dump not supported\n");
1686		return -ENOTSUPP;
1687	}
1688
1689	if (!fw_dump->clr) {
1690		netdev_info(netdev, "Dump not available\n");
1691		return -EINVAL;
1692	}
1693
1694	/* Copy template header first */
1695	copy_sz = fw_dump->tmpl_hdr_size;
1696	hdr_ptr = (u32 *)fw_dump->tmpl_hdr;
1697	data = buffer;
1698	for (i = 0; i < copy_sz/sizeof(u32); i++)
1699		*data++ = cpu_to_le32(*hdr_ptr++);
1700
1701	/* Copy captured dump data */
1702	memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size);
1703	dump->len = copy_sz + fw_dump->size;
1704	dump->flag = fw_dump->cap_mask;
1705
1706	/* Free dump area once data has been captured */
1707	vfree(fw_dump->data);
1708	fw_dump->data = NULL;
1709	fw_dump->clr = 0;
1710	netdev_info(netdev, "extracted the FW dump Successfully\n");
1711	return 0;
1712}
1713
1714static int qlcnic_set_dump_mask(struct qlcnic_adapter *adapter, u32 mask)
1715{
1716	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1717	struct net_device *netdev = adapter->netdev;
1718
1719	if (!qlcnic_check_fw_dump_state(adapter)) {
1720		netdev_info(netdev,
1721			    "Can not change driver mask to 0x%x. FW dump not enabled\n",
1722			    mask);
1723		return -EOPNOTSUPP;
1724	}
1725
1726	fw_dump->cap_mask = mask;
1727
1728	/* Store new capture mask in template header as well*/
1729	qlcnic_store_cap_mask(adapter, fw_dump->tmpl_hdr, mask);
1730
1731	netdev_info(netdev, "Driver mask changed to: 0x%x\n", mask);
1732	return 0;
1733}
1734
1735static int
1736qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
1737{
1738	struct qlcnic_adapter *adapter = netdev_priv(netdev);
1739	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1740	bool valid_mask = false;
1741	int i, ret = 0;
1742
1743	switch (val->flag) {
1744	case QLCNIC_FORCE_FW_DUMP_KEY:
1745		if (!fw_dump->tmpl_hdr) {
1746			netdev_err(netdev, "FW dump not supported\n");
1747			ret = -EOPNOTSUPP;
1748			break;
1749		}
1750
1751		if (!qlcnic_check_fw_dump_state(adapter)) {
1752			netdev_info(netdev, "FW dump not enabled\n");
1753			ret = -EOPNOTSUPP;
1754			break;
1755		}
1756
1757		if (fw_dump->clr) {
1758			netdev_info(netdev,
1759				    "Previous dump not cleared, not forcing dump\n");
1760			break;
1761		}
1762
1763		netdev_info(netdev, "Forcing a FW dump\n");
1764		qlcnic_dev_request_reset(adapter, val->flag);
1765		break;
1766	case QLCNIC_DISABLE_FW_DUMP:
1767		if (!fw_dump->tmpl_hdr) {
1768			netdev_err(netdev, "FW dump not supported\n");
1769			ret = -EOPNOTSUPP;
1770			break;
1771		}
1772
1773		ret = qlcnic_disable_fw_dump_state(adapter);
1774		break;
1775
1776	case QLCNIC_ENABLE_FW_DUMP:
1777		if (!fw_dump->tmpl_hdr) {
1778			netdev_err(netdev, "FW dump not supported\n");
1779			ret = -EOPNOTSUPP;
1780			break;
1781		}
1782
1783		ret = qlcnic_enable_fw_dump_state(adapter);
1784		break;
1785
1786	case QLCNIC_FORCE_FW_RESET:
1787		netdev_info(netdev, "Forcing a FW reset\n");
1788		qlcnic_dev_request_reset(adapter, val->flag);
1789		adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
1790		break;
1791
1792	case QLCNIC_SET_QUIESCENT:
1793	case QLCNIC_RESET_QUIESCENT:
1794		if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state))
1795			netdev_info(netdev, "Device is in non-operational state\n");
1796		break;
1797
1798	default:
1799		if (!fw_dump->tmpl_hdr) {
1800			netdev_err(netdev, "FW dump not supported\n");
1801			ret = -EOPNOTSUPP;
1802			break;
1803		}
1804
1805		for (i = 0; i < ARRAY_SIZE(qlcnic_fw_dump_level); i++) {
1806			if (val->flag == qlcnic_fw_dump_level[i]) {
1807				valid_mask = true;
1808				break;
1809			}
1810		}
1811
1812		if (valid_mask) {
1813			ret = qlcnic_set_dump_mask(adapter, val->flag);
1814		} else {
1815			netdev_info(netdev, "Invalid dump level: 0x%x\n",
1816				    val->flag);
1817			ret = -EINVAL;
1818		}
1819	}
1820	return ret;
1821}
1822
1823const struct ethtool_ops qlcnic_ethtool_ops = {
1824	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
1825				     ETHTOOL_COALESCE_MAX_FRAMES,
1826	.get_drvinfo = qlcnic_get_drvinfo,
1827	.get_regs_len = qlcnic_get_regs_len,
1828	.get_regs = qlcnic_get_regs,
1829	.get_link = ethtool_op_get_link,
1830	.get_eeprom_len = qlcnic_get_eeprom_len,
1831	.get_eeprom = qlcnic_get_eeprom,
1832	.get_ringparam = qlcnic_get_ringparam,
1833	.set_ringparam = qlcnic_set_ringparam,
1834	.get_channels = qlcnic_get_channels,
1835	.set_channels = qlcnic_set_channels,
1836	.get_pauseparam = qlcnic_get_pauseparam,
1837	.set_pauseparam = qlcnic_set_pauseparam,
1838	.get_wol = qlcnic_get_wol,
1839	.set_wol = qlcnic_set_wol,
1840	.self_test = qlcnic_diag_test,
1841	.get_strings = qlcnic_get_strings,
1842	.get_ethtool_stats = qlcnic_get_ethtool_stats,
1843	.get_sset_count = qlcnic_get_sset_count,
1844	.get_coalesce = qlcnic_get_intr_coalesce,
1845	.set_coalesce = qlcnic_set_intr_coalesce,
1846	.set_phys_id = qlcnic_set_led,
1847	.set_msglevel = qlcnic_set_msglevel,
1848	.get_msglevel = qlcnic_get_msglevel,
1849	.get_dump_flag = qlcnic_get_dump_flag,
1850	.get_dump_data = qlcnic_get_dump_data,
1851	.set_dump = qlcnic_set_dump,
1852	.get_link_ksettings = qlcnic_get_link_ksettings,
1853	.set_link_ksettings = qlcnic_set_link_ksettings,
1854};
1855
1856const struct ethtool_ops qlcnic_sriov_vf_ethtool_ops = {
1857	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
1858				     ETHTOOL_COALESCE_MAX_FRAMES,
1859	.get_drvinfo		= qlcnic_get_drvinfo,
1860	.get_regs_len		= qlcnic_get_regs_len,
1861	.get_regs		= qlcnic_get_regs,
1862	.get_link		= ethtool_op_get_link,
1863	.get_eeprom_len		= qlcnic_get_eeprom_len,
1864	.get_eeprom		= qlcnic_get_eeprom,
1865	.get_ringparam		= qlcnic_get_ringparam,
1866	.set_ringparam		= qlcnic_set_ringparam,
1867	.get_channels		= qlcnic_get_channels,
1868	.get_pauseparam		= qlcnic_get_pauseparam,
1869	.get_wol		= qlcnic_get_wol,
1870	.get_strings		= qlcnic_get_strings,
1871	.get_ethtool_stats	= qlcnic_get_ethtool_stats,
1872	.get_sset_count		= qlcnic_get_sset_count,
1873	.get_coalesce		= qlcnic_get_intr_coalesce,
1874	.set_coalesce		= qlcnic_set_intr_coalesce,
1875	.set_msglevel		= qlcnic_set_msglevel,
1876	.get_msglevel		= qlcnic_get_msglevel,
1877	.get_link_ksettings	= qlcnic_get_link_ksettings,
1878};
1879
1880const struct ethtool_ops qlcnic_ethtool_failed_ops = {
1881	.get_drvinfo		= qlcnic_get_drvinfo,
1882	.set_msglevel		= qlcnic_set_msglevel,
1883	.get_msglevel		= qlcnic_get_msglevel,
1884	.set_dump		= qlcnic_set_dump,
1885	.get_link_ksettings	= qlcnic_get_link_ksettings,
1886};
~/ Read-only file preview.