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