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