Linux Audio

Check our new training course

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