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