Linux Audio

Check our new training course

Linux debugging, profiling, tracing and performance analysis training

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