treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / net / ethernet / qlogic / qlcnic / qlcnic_ethtool.c
blob75d83c3cbf27f2dbf867c69888137f6b17a973c3
1 /*
2 * QLogic qlcnic NIC Driver
3 * Copyright (c) 2009-2013 QLogic Corporation
5 * See LICENSE.qlcnic for copyright and licensing details.
6 */
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>
15 #include "qlcnic.h"
17 struct qlcnic_stats {
18 char stat_string[ETH_GSTRING_LEN];
19 int sizeof_stat;
20 int stat_offset;
23 #define QLC_SIZEOF(m) sizeof_field(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
29 static 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)},
66 static 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",
83 static 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",
91 static 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",
134 #define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats)
136 static 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",
144 #define QLCNIC_TX_STATS_LEN ARRAY_SIZE(qlcnic_tx_queue_stats_strings)
146 static 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",
166 static 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"
175 #define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test)
177 static inline int qlcnic_82xx_statistics(struct qlcnic_adapter *adapter)
179 return ARRAY_SIZE(qlcnic_gstrings_stats) +
180 ARRAY_SIZE(qlcnic_83xx_mac_stats_strings) +
181 QLCNIC_TX_STATS_LEN * adapter->drv_tx_rings;
184 static inline int qlcnic_83xx_statistics(struct qlcnic_adapter *adapter)
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;
193 static int qlcnic_dev_statistics_len(struct qlcnic_adapter *adapter)
195 int len = -1;
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);
205 return len;
208 #define QLCNIC_TX_INTR_NOT_CONFIGURED 0X78563412
210 #define QLCNIC_MAX_EEPROM_LEN 1024
212 static 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,
229 static 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,
239 #define QLCNIC_MGMT_API_VERSION 3
240 #define QLCNIC_ETHTOOL_REGS_VER 4
242 static inline int qlcnic_get_ring_regs_len(struct qlcnic_adapter *adapter)
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);
250 static int qlcnic_get_regs_len(struct net_device *dev)
252 struct qlcnic_adapter *adapter = netdev_priv(dev);
253 u32 len;
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);
260 len += ((QLCNIC_DEV_INFO_SIZE + 2) * sizeof(u32));
261 len += qlcnic_get_ring_regs_len(adapter);
262 return len;
265 static int qlcnic_get_eeprom_len(struct net_device *dev)
267 return QLCNIC_FLASH_TOTAL_SIZE;
270 static void
271 qlcnic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
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);
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));
288 static int qlcnic_82xx_get_link_ksettings(struct qlcnic_adapter *adapter,
289 struct ethtool_link_ksettings *ecmd)
291 struct qlcnic_hardware_context *ahw = adapter->ahw;
292 u32 speed, reg;
293 int check_sfp_module = 0, err = 0;
294 u16 pcifn = ahw->pci_func;
295 u32 supported, advertising;
297 /* read which mode */
298 if (adapter->ahw->port_type == QLCNIC_GBE) {
299 supported = (SUPPORTED_10baseT_Half |
300 SUPPORTED_10baseT_Full |
301 SUPPORTED_100baseT_Half |
302 SUPPORTED_100baseT_Full |
303 SUPPORTED_1000baseT_Half |
304 SUPPORTED_1000baseT_Full);
306 advertising = (ADVERTISED_100baseT_Half |
307 ADVERTISED_100baseT_Full |
308 ADVERTISED_1000baseT_Half |
309 ADVERTISED_1000baseT_Full);
311 ecmd->base.speed = adapter->ahw->link_speed;
312 ecmd->base.duplex = adapter->ahw->link_duplex;
313 ecmd->base.autoneg = adapter->ahw->link_autoneg;
315 } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
316 u32 val = 0;
317 val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR, &err);
319 if (val == QLCNIC_PORT_MODE_802_3_AP) {
320 supported = SUPPORTED_1000baseT_Full;
321 advertising = ADVERTISED_1000baseT_Full;
322 } else {
323 supported = SUPPORTED_10000baseT_Full;
324 advertising = ADVERTISED_10000baseT_Full;
327 if (netif_running(adapter->netdev) && ahw->has_link_events) {
328 if (ahw->linkup) {
329 reg = QLCRD32(adapter,
330 P3P_LINK_SPEED_REG(pcifn), &err);
331 speed = P3P_LINK_SPEED_VAL(pcifn, reg);
332 ahw->link_speed = speed * P3P_LINK_SPEED_MHZ;
335 ecmd->base.speed = ahw->link_speed;
336 ecmd->base.autoneg = ahw->link_autoneg;
337 ecmd->base.duplex = ahw->link_duplex;
338 goto skip;
341 ecmd->base.speed = SPEED_UNKNOWN;
342 ecmd->base.duplex = DUPLEX_UNKNOWN;
343 ecmd->base.autoneg = AUTONEG_DISABLE;
344 } else
345 return -EIO;
347 skip:
348 ecmd->base.phy_address = adapter->ahw->physical_port;
350 switch (adapter->ahw->board_type) {
351 case QLCNIC_BRDTYPE_P3P_REF_QG:
352 case QLCNIC_BRDTYPE_P3P_4_GB:
353 case QLCNIC_BRDTYPE_P3P_4_GB_MM:
354 supported |= SUPPORTED_Autoneg;
355 advertising |= ADVERTISED_Autoneg;
356 /* fall through */
357 case QLCNIC_BRDTYPE_P3P_10G_CX4:
358 case QLCNIC_BRDTYPE_P3P_10G_CX4_LP:
359 case QLCNIC_BRDTYPE_P3P_10000_BASE_T:
360 supported |= SUPPORTED_TP;
361 advertising |= ADVERTISED_TP;
362 ecmd->base.port = PORT_TP;
363 ecmd->base.autoneg = adapter->ahw->link_autoneg;
364 break;
365 case QLCNIC_BRDTYPE_P3P_IMEZ:
366 case QLCNIC_BRDTYPE_P3P_XG_LOM:
367 case QLCNIC_BRDTYPE_P3P_HMEZ:
368 supported |= SUPPORTED_MII;
369 advertising |= ADVERTISED_MII;
370 ecmd->base.port = PORT_MII;
371 ecmd->base.autoneg = AUTONEG_DISABLE;
372 break;
373 case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS:
374 case QLCNIC_BRDTYPE_P3P_10G_SFP_CT:
375 case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
376 advertising |= ADVERTISED_TP;
377 supported |= SUPPORTED_TP;
378 check_sfp_module = netif_running(adapter->netdev) &&
379 ahw->has_link_events;
380 /* fall through */
381 case QLCNIC_BRDTYPE_P3P_10G_XFP:
382 supported |= SUPPORTED_FIBRE;
383 advertising |= ADVERTISED_FIBRE;
384 ecmd->base.port = PORT_FIBRE;
385 ecmd->base.autoneg = AUTONEG_DISABLE;
386 break;
387 case QLCNIC_BRDTYPE_P3P_10G_TP:
388 if (adapter->ahw->port_type == QLCNIC_XGBE) {
389 ecmd->base.autoneg = AUTONEG_DISABLE;
390 supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
391 advertising |=
392 (ADVERTISED_FIBRE | ADVERTISED_TP);
393 ecmd->base.port = PORT_FIBRE;
394 check_sfp_module = netif_running(adapter->netdev) &&
395 ahw->has_link_events;
396 } else {
397 ecmd->base.autoneg = AUTONEG_ENABLE;
398 supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
399 advertising |=
400 (ADVERTISED_TP | ADVERTISED_Autoneg);
401 ecmd->base.port = PORT_TP;
403 break;
404 default:
405 dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
406 adapter->ahw->board_type);
407 return -EIO;
410 if (check_sfp_module) {
411 switch (adapter->ahw->module_type) {
412 case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
413 case LINKEVENT_MODULE_OPTICAL_SRLR:
414 case LINKEVENT_MODULE_OPTICAL_LRM:
415 case LINKEVENT_MODULE_OPTICAL_SFP_1G:
416 ecmd->base.port = PORT_FIBRE;
417 break;
418 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
419 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
420 case LINKEVENT_MODULE_TWINAX:
421 ecmd->base.port = PORT_TP;
422 break;
423 default:
424 ecmd->base.port = PORT_OTHER;
428 ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.supported,
429 supported);
430 ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.advertising,
431 advertising);
433 return 0;
436 static int qlcnic_get_link_ksettings(struct net_device *dev,
437 struct ethtool_link_ksettings *ecmd)
439 struct qlcnic_adapter *adapter = netdev_priv(dev);
441 if (qlcnic_82xx_check(adapter))
442 return qlcnic_82xx_get_link_ksettings(adapter, ecmd);
443 else if (qlcnic_83xx_check(adapter))
444 return qlcnic_83xx_get_link_ksettings(adapter, ecmd);
446 return -EIO;
450 static int qlcnic_set_port_config(struct qlcnic_adapter *adapter,
451 const struct ethtool_link_ksettings *ecmd)
453 u32 ret = 0, config = 0;
454 /* read which mode */
455 if (ecmd->base.duplex)
456 config |= 0x1;
458 if (ecmd->base.autoneg)
459 config |= 0x2;
461 switch (ecmd->base.speed) {
462 case SPEED_10:
463 config |= (0 << 8);
464 break;
465 case SPEED_100:
466 config |= (1 << 8);
467 break;
468 case SPEED_1000:
469 config |= (10 << 8);
470 break;
471 default:
472 return -EIO;
475 ret = qlcnic_fw_cmd_set_port(adapter, config);
477 if (ret == QLCNIC_RCODE_NOT_SUPPORTED)
478 return -EOPNOTSUPP;
479 else if (ret)
480 return -EIO;
481 return ret;
484 static int qlcnic_set_link_ksettings(struct net_device *dev,
485 const struct ethtool_link_ksettings *ecmd)
487 u32 ret = 0;
488 struct qlcnic_adapter *adapter = netdev_priv(dev);
490 if (qlcnic_83xx_check(adapter))
491 qlcnic_83xx_get_port_type(adapter);
493 if (adapter->ahw->port_type != QLCNIC_GBE)
494 return -EOPNOTSUPP;
496 if (qlcnic_83xx_check(adapter))
497 ret = qlcnic_83xx_set_link_ksettings(adapter, ecmd);
498 else
499 ret = qlcnic_set_port_config(adapter, ecmd);
501 if (!ret)
502 return ret;
504 adapter->ahw->link_speed = ecmd->base.speed;
505 adapter->ahw->link_duplex = ecmd->base.duplex;
506 adapter->ahw->link_autoneg = ecmd->base.autoneg;
508 if (!netif_running(dev))
509 return 0;
511 dev->netdev_ops->ndo_stop(dev);
512 return dev->netdev_ops->ndo_open(dev);
515 static int qlcnic_82xx_get_registers(struct qlcnic_adapter *adapter,
516 u32 *regs_buff)
518 int i, j = 0, err = 0;
520 for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++)
521 regs_buff[i] = QLC_SHARED_REG_RD32(adapter, diag_registers[j]);
522 j = 0;
523 while (ext_diag_registers[j] != -1)
524 regs_buff[i++] = QLCRD32(adapter, ext_diag_registers[j++],
525 &err);
526 return i;
529 static void
530 qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
532 struct qlcnic_adapter *adapter = netdev_priv(dev);
533 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
534 struct qlcnic_host_sds_ring *sds_ring;
535 struct qlcnic_host_rds_ring *rds_rings;
536 struct qlcnic_host_tx_ring *tx_ring;
537 u32 *regs_buff = p;
538 int ring, i = 0;
540 memset(p, 0, qlcnic_get_regs_len(dev));
542 regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
543 (adapter->ahw->revision_id << 16) | (adapter->pdev)->device;
545 regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
546 regs_buff[1] = QLCNIC_MGMT_API_VERSION;
548 if (adapter->ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY)
549 regs_buff[2] = adapter->ahw->max_vnic_func;
551 if (qlcnic_82xx_check(adapter))
552 i = qlcnic_82xx_get_registers(adapter, regs_buff);
553 else
554 i = qlcnic_83xx_get_registers(adapter, regs_buff);
556 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
557 return;
559 /* Marker btw regs and TX ring count */
560 regs_buff[i++] = 0xFFEFCDAB;
562 regs_buff[i++] = adapter->drv_tx_rings; /* No. of TX ring */
563 for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
564 tx_ring = &adapter->tx_ring[ring];
565 regs_buff[i++] = le32_to_cpu(*(tx_ring->hw_consumer));
566 regs_buff[i++] = tx_ring->sw_consumer;
567 regs_buff[i++] = readl(tx_ring->crb_cmd_producer);
568 regs_buff[i++] = tx_ring->producer;
569 if (tx_ring->crb_intr_mask)
570 regs_buff[i++] = readl(tx_ring->crb_intr_mask);
571 else
572 regs_buff[i++] = QLCNIC_TX_INTR_NOT_CONFIGURED;
575 regs_buff[i++] = adapter->max_rds_rings; /* No. of RX ring */
576 for (ring = 0; ring < adapter->max_rds_rings; ring++) {
577 rds_rings = &recv_ctx->rds_rings[ring];
578 regs_buff[i++] = readl(rds_rings->crb_rcv_producer);
579 regs_buff[i++] = rds_rings->producer;
582 regs_buff[i++] = adapter->drv_sds_rings; /* No. of SDS ring */
583 for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
584 sds_ring = &(recv_ctx->sds_rings[ring]);
585 regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
586 regs_buff[i++] = sds_ring->consumer;
587 regs_buff[i++] = readl(sds_ring->crb_intr_mask);
591 static u32 qlcnic_test_link(struct net_device *dev)
593 struct qlcnic_adapter *adapter = netdev_priv(dev);
594 int err = 0;
595 u32 val;
597 if (qlcnic_83xx_check(adapter)) {
598 val = qlcnic_83xx_test_link(adapter);
599 return (val & 1) ? 0 : 1;
601 val = QLCRD32(adapter, CRB_XG_STATE_P3P, &err);
602 if (err == -EIO)
603 return err;
604 val = XG_LINK_STATE_P3P(adapter->ahw->pci_func, val);
605 return (val == XG_LINK_UP_P3P) ? 0 : 1;
608 static int
609 qlcnic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
610 u8 *bytes)
612 struct qlcnic_adapter *adapter = netdev_priv(dev);
613 int offset;
614 int ret = -1;
616 if (qlcnic_83xx_check(adapter))
617 return 0;
618 if (eeprom->len == 0)
619 return -EINVAL;
621 eeprom->magic = (adapter->pdev)->vendor |
622 ((adapter->pdev)->device << 16);
623 offset = eeprom->offset;
625 if (qlcnic_82xx_check(adapter))
626 ret = qlcnic_rom_fast_read_words(adapter, offset, bytes,
627 eeprom->len);
628 if (ret < 0)
629 return ret;
631 return 0;
634 static void
635 qlcnic_get_ringparam(struct net_device *dev,
636 struct ethtool_ringparam *ring)
638 struct qlcnic_adapter *adapter = netdev_priv(dev);
640 ring->rx_pending = adapter->num_rxd;
641 ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
642 ring->tx_pending = adapter->num_txd;
644 ring->rx_max_pending = adapter->max_rxd;
645 ring->rx_jumbo_max_pending = adapter->max_jumbo_rxd;
646 ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
649 static u32
650 qlcnic_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
652 u32 num_desc;
653 num_desc = max(val, min);
654 num_desc = min(num_desc, max);
655 num_desc = roundup_pow_of_two(num_desc);
657 if (val != num_desc) {
658 printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
659 qlcnic_driver_name, r_name, num_desc, val);
662 return num_desc;
665 static int
666 qlcnic_set_ringparam(struct net_device *dev,
667 struct ethtool_ringparam *ring)
669 struct qlcnic_adapter *adapter = netdev_priv(dev);
670 u16 num_rxd, num_jumbo_rxd, num_txd;
672 if (ring->rx_mini_pending)
673 return -EOPNOTSUPP;
675 num_rxd = qlcnic_validate_ringparam(ring->rx_pending,
676 MIN_RCV_DESCRIPTORS, adapter->max_rxd, "rx");
678 num_jumbo_rxd = qlcnic_validate_ringparam(ring->rx_jumbo_pending,
679 MIN_JUMBO_DESCRIPTORS, adapter->max_jumbo_rxd,
680 "rx jumbo");
682 num_txd = qlcnic_validate_ringparam(ring->tx_pending,
683 MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
685 if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
686 num_jumbo_rxd == adapter->num_jumbo_rxd)
687 return 0;
689 adapter->num_rxd = num_rxd;
690 adapter->num_jumbo_rxd = num_jumbo_rxd;
691 adapter->num_txd = num_txd;
693 return qlcnic_reset_context(adapter);
696 static int qlcnic_validate_ring_count(struct qlcnic_adapter *adapter,
697 u8 rx_ring, u8 tx_ring)
699 if (rx_ring == 0 || tx_ring == 0)
700 return -EINVAL;
702 if (rx_ring != 0) {
703 if (rx_ring > adapter->max_sds_rings) {
704 netdev_err(adapter->netdev,
705 "Invalid ring count, SDS ring count %d should not be greater than max %d driver sds rings.\n",
706 rx_ring, adapter->max_sds_rings);
707 return -EINVAL;
711 if (tx_ring != 0) {
712 if (tx_ring > adapter->max_tx_rings) {
713 netdev_err(adapter->netdev,
714 "Invalid ring count, Tx ring count %d should not be greater than max %d driver Tx rings.\n",
715 tx_ring, adapter->max_tx_rings);
716 return -EINVAL;
720 return 0;
723 static void qlcnic_get_channels(struct net_device *dev,
724 struct ethtool_channels *channel)
726 struct qlcnic_adapter *adapter = netdev_priv(dev);
728 channel->max_rx = adapter->max_sds_rings;
729 channel->max_tx = adapter->max_tx_rings;
730 channel->rx_count = adapter->drv_sds_rings;
731 channel->tx_count = adapter->drv_tx_rings;
734 static int qlcnic_set_channels(struct net_device *dev,
735 struct ethtool_channels *channel)
737 struct qlcnic_adapter *adapter = netdev_priv(dev);
738 int err;
740 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
741 netdev_err(dev, "No RSS/TSS support in non MSI-X mode\n");
742 return -EINVAL;
745 if (channel->other_count || channel->combined_count)
746 return -EINVAL;
748 err = qlcnic_validate_ring_count(adapter, channel->rx_count,
749 channel->tx_count);
750 if (err)
751 return err;
753 if (adapter->drv_sds_rings != channel->rx_count) {
754 err = qlcnic_validate_rings(adapter, channel->rx_count,
755 QLCNIC_RX_QUEUE);
756 if (err) {
757 netdev_err(dev, "Unable to configure %u SDS rings\n",
758 channel->rx_count);
759 return err;
761 adapter->drv_rss_rings = channel->rx_count;
764 if (adapter->drv_tx_rings != channel->tx_count) {
765 err = qlcnic_validate_rings(adapter, channel->tx_count,
766 QLCNIC_TX_QUEUE);
767 if (err) {
768 netdev_err(dev, "Unable to configure %u Tx rings\n",
769 channel->tx_count);
770 return err;
772 adapter->drv_tss_rings = channel->tx_count;
775 adapter->flags |= QLCNIC_TSS_RSS;
777 err = qlcnic_setup_rings(adapter);
778 netdev_info(dev, "Allocated %d SDS rings and %d Tx rings\n",
779 adapter->drv_sds_rings, adapter->drv_tx_rings);
781 return err;
784 static void
785 qlcnic_get_pauseparam(struct net_device *netdev,
786 struct ethtool_pauseparam *pause)
788 struct qlcnic_adapter *adapter = netdev_priv(netdev);
789 int port = adapter->ahw->physical_port;
790 int err = 0;
791 __u32 val;
793 if (qlcnic_83xx_check(adapter)) {
794 qlcnic_83xx_get_pauseparam(adapter, pause);
795 return;
797 if (adapter->ahw->port_type == QLCNIC_GBE) {
798 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
799 return;
800 /* get flow control settings */
801 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), &err);
802 if (err == -EIO)
803 return;
804 pause->rx_pause = qlcnic_gb_get_rx_flowctl(val);
805 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, &err);
806 if (err == -EIO)
807 return;
808 switch (port) {
809 case 0:
810 pause->tx_pause = !(qlcnic_gb_get_gb0_mask(val));
811 break;
812 case 1:
813 pause->tx_pause = !(qlcnic_gb_get_gb1_mask(val));
814 break;
815 case 2:
816 pause->tx_pause = !(qlcnic_gb_get_gb2_mask(val));
817 break;
818 case 3:
819 default:
820 pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val));
821 break;
823 } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
824 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
825 return;
826 pause->rx_pause = 1;
827 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, &err);
828 if (err == -EIO)
829 return;
830 if (port == 0)
831 pause->tx_pause = !(qlcnic_xg_get_xg0_mask(val));
832 else
833 pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val));
834 } else {
835 dev_err(&netdev->dev, "Unknown board type: %x\n",
836 adapter->ahw->port_type);
840 static int
841 qlcnic_set_pauseparam(struct net_device *netdev,
842 struct ethtool_pauseparam *pause)
844 struct qlcnic_adapter *adapter = netdev_priv(netdev);
845 int port = adapter->ahw->physical_port;
846 int err = 0;
847 __u32 val;
849 if (qlcnic_83xx_check(adapter))
850 return qlcnic_83xx_set_pauseparam(adapter, pause);
852 /* read mode */
853 if (adapter->ahw->port_type == QLCNIC_GBE) {
854 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
855 return -EIO;
856 /* set flow control */
857 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), &err);
858 if (err == -EIO)
859 return err;
861 if (pause->rx_pause)
862 qlcnic_gb_rx_flowctl(val);
863 else
864 qlcnic_gb_unset_rx_flowctl(val);
866 QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port),
867 val);
868 QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), val);
869 /* set autoneg */
870 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, &err);
871 if (err == -EIO)
872 return err;
873 switch (port) {
874 case 0:
875 if (pause->tx_pause)
876 qlcnic_gb_unset_gb0_mask(val);
877 else
878 qlcnic_gb_set_gb0_mask(val);
879 break;
880 case 1:
881 if (pause->tx_pause)
882 qlcnic_gb_unset_gb1_mask(val);
883 else
884 qlcnic_gb_set_gb1_mask(val);
885 break;
886 case 2:
887 if (pause->tx_pause)
888 qlcnic_gb_unset_gb2_mask(val);
889 else
890 qlcnic_gb_set_gb2_mask(val);
891 break;
892 case 3:
893 default:
894 if (pause->tx_pause)
895 qlcnic_gb_unset_gb3_mask(val);
896 else
897 qlcnic_gb_set_gb3_mask(val);
898 break;
900 QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val);
901 } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
902 if (!pause->rx_pause || pause->autoneg)
903 return -EOPNOTSUPP;
905 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
906 return -EIO;
908 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, &err);
909 if (err == -EIO)
910 return err;
911 if (port == 0) {
912 if (pause->tx_pause)
913 qlcnic_xg_unset_xg0_mask(val);
914 else
915 qlcnic_xg_set_xg0_mask(val);
916 } else {
917 if (pause->tx_pause)
918 qlcnic_xg_unset_xg1_mask(val);
919 else
920 qlcnic_xg_set_xg1_mask(val);
922 QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val);
923 } else {
924 dev_err(&netdev->dev, "Unknown board type: %x\n",
925 adapter->ahw->port_type);
927 return 0;
930 static int qlcnic_reg_test(struct net_device *dev)
932 struct qlcnic_adapter *adapter = netdev_priv(dev);
933 u32 data_read;
934 int err = 0;
936 if (qlcnic_83xx_check(adapter))
937 return qlcnic_83xx_reg_test(adapter);
939 data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0), &err);
940 if (err == -EIO)
941 return err;
942 if ((data_read & 0xffff) != adapter->pdev->vendor)
943 return 1;
945 return 0;
948 static int qlcnic_eeprom_test(struct net_device *dev)
950 struct qlcnic_adapter *adapter = netdev_priv(dev);
952 if (qlcnic_82xx_check(adapter))
953 return 0;
955 return qlcnic_83xx_flash_test(adapter);
958 static int qlcnic_get_sset_count(struct net_device *dev, int sset)
961 struct qlcnic_adapter *adapter = netdev_priv(dev);
962 switch (sset) {
963 case ETH_SS_TEST:
964 return QLCNIC_TEST_LEN;
965 case ETH_SS_STATS:
966 return qlcnic_dev_statistics_len(adapter);
967 default:
968 return -EOPNOTSUPP;
972 static int qlcnic_irq_test(struct net_device *netdev)
974 struct qlcnic_adapter *adapter = netdev_priv(netdev);
975 struct qlcnic_hardware_context *ahw = adapter->ahw;
976 struct qlcnic_cmd_args cmd;
977 int ret, drv_sds_rings = adapter->drv_sds_rings;
978 int drv_tx_rings = adapter->drv_tx_rings;
980 if (qlcnic_83xx_check(adapter))
981 return qlcnic_83xx_interrupt_test(netdev);
983 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
984 return -EIO;
986 ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST);
987 if (ret)
988 goto clear_diag_irq;
990 ahw->diag_cnt = 0;
991 ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
992 if (ret)
993 goto free_diag_res;
995 cmd.req.arg[1] = ahw->pci_func;
996 ret = qlcnic_issue_cmd(adapter, &cmd);
997 if (ret)
998 goto done;
1000 usleep_range(1000, 12000);
1001 ret = !ahw->diag_cnt;
1003 done:
1004 qlcnic_free_mbx_args(&cmd);
1006 free_diag_res:
1007 qlcnic_diag_free_res(netdev, drv_sds_rings);
1009 clear_diag_irq:
1010 adapter->drv_sds_rings = drv_sds_rings;
1011 adapter->drv_tx_rings = drv_tx_rings;
1012 clear_bit(__QLCNIC_RESETTING, &adapter->state);
1014 return ret;
1017 #define QLCNIC_ILB_PKT_SIZE 64
1018 #define QLCNIC_NUM_ILB_PKT 16
1019 #define QLCNIC_ILB_MAX_RCV_LOOP 10
1020 #define QLCNIC_LB_PKT_POLL_DELAY_MSEC 1
1021 #define QLCNIC_LB_PKT_POLL_COUNT 20
1023 static void qlcnic_create_loopback_buff(unsigned char *data, u8 mac[])
1025 unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00};
1027 memset(data, 0x4e, QLCNIC_ILB_PKT_SIZE);
1029 memcpy(data, mac, ETH_ALEN);
1030 memcpy(data + ETH_ALEN, mac, ETH_ALEN);
1032 memcpy(data + 2 * ETH_ALEN, random_data, sizeof(random_data));
1035 int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[])
1037 unsigned char buff[QLCNIC_ILB_PKT_SIZE];
1038 qlcnic_create_loopback_buff(buff, mac);
1039 return memcmp(data, buff, QLCNIC_ILB_PKT_SIZE);
1042 int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
1044 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1045 struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0];
1046 struct sk_buff *skb;
1047 int i, loop, cnt = 0;
1049 for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) {
1050 skb = netdev_alloc_skb(adapter->netdev, QLCNIC_ILB_PKT_SIZE);
1051 if (!skb)
1052 break;
1053 qlcnic_create_loopback_buff(skb->data, adapter->mac_addr);
1054 skb_put(skb, QLCNIC_ILB_PKT_SIZE);
1055 adapter->ahw->diag_cnt = 0;
1056 qlcnic_xmit_frame(skb, adapter->netdev);
1057 loop = 0;
1059 do {
1060 msleep(QLCNIC_LB_PKT_POLL_DELAY_MSEC);
1061 qlcnic_process_rcv_ring_diag(sds_ring);
1062 if (loop++ > QLCNIC_LB_PKT_POLL_COUNT)
1063 break;
1064 } while (!adapter->ahw->diag_cnt);
1066 dev_kfree_skb_any(skb);
1068 if (!adapter->ahw->diag_cnt)
1069 dev_warn(&adapter->pdev->dev,
1070 "LB Test: packet #%d was not received\n",
1071 i + 1);
1072 else
1073 cnt++;
1075 if (cnt != i) {
1076 dev_err(&adapter->pdev->dev,
1077 "LB Test: failed, TX[%d], RX[%d]\n", i, cnt);
1078 if (mode != QLCNIC_ILB_MODE)
1079 dev_warn(&adapter->pdev->dev,
1080 "WARNING: Please check loopback cable\n");
1081 return -1;
1083 return 0;
1086 static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
1088 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1089 int drv_tx_rings = adapter->drv_tx_rings;
1090 int drv_sds_rings = adapter->drv_sds_rings;
1091 struct qlcnic_host_sds_ring *sds_ring;
1092 struct qlcnic_hardware_context *ahw = adapter->ahw;
1093 int loop = 0;
1094 int ret;
1096 if (qlcnic_83xx_check(adapter))
1097 return qlcnic_83xx_loopback_test(netdev, mode);
1099 if (!(ahw->capabilities & QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK)) {
1100 dev_info(&adapter->pdev->dev,
1101 "Firmware do not support loopback test\n");
1102 return -EOPNOTSUPP;
1105 dev_warn(&adapter->pdev->dev, "%s loopback test in progress\n",
1106 mode == QLCNIC_ILB_MODE ? "internal" : "external");
1107 if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1108 dev_warn(&adapter->pdev->dev,
1109 "Loopback test not supported in nonprivileged mode\n");
1110 return 0;
1113 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
1114 return -EBUSY;
1116 ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
1117 if (ret)
1118 goto clear_it;
1120 sds_ring = &adapter->recv_ctx->sds_rings[0];
1121 ret = qlcnic_set_lb_mode(adapter, mode);
1122 if (ret)
1123 goto free_res;
1125 ahw->diag_cnt = 0;
1126 do {
1127 msleep(500);
1128 qlcnic_process_rcv_ring_diag(sds_ring);
1129 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
1130 netdev_info(netdev,
1131 "Firmware didn't sent link up event to loopback request\n");
1132 ret = -ETIMEDOUT;
1133 goto free_res;
1134 } else if (adapter->ahw->diag_cnt) {
1135 ret = adapter->ahw->diag_cnt;
1136 goto free_res;
1138 } while (!QLCNIC_IS_LB_CONFIGURED(ahw->loopback_state));
1140 ret = qlcnic_do_lb_test(adapter, mode);
1142 qlcnic_clear_lb_mode(adapter, mode);
1144 free_res:
1145 qlcnic_diag_free_res(netdev, drv_sds_rings);
1147 clear_it:
1148 adapter->drv_sds_rings = drv_sds_rings;
1149 adapter->drv_tx_rings = drv_tx_rings;
1150 clear_bit(__QLCNIC_RESETTING, &adapter->state);
1151 return ret;
1154 static void
1155 qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
1156 u64 *data)
1158 memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
1160 data[0] = qlcnic_reg_test(dev);
1161 if (data[0])
1162 eth_test->flags |= ETH_TEST_FL_FAILED;
1164 data[1] = (u64) qlcnic_test_link(dev);
1165 if (data[1])
1166 eth_test->flags |= ETH_TEST_FL_FAILED;
1168 if (eth_test->flags & ETH_TEST_FL_OFFLINE) {
1169 data[2] = qlcnic_irq_test(dev);
1170 if (data[2])
1171 eth_test->flags |= ETH_TEST_FL_FAILED;
1173 data[3] = qlcnic_loopback_test(dev, QLCNIC_ILB_MODE);
1174 if (data[3])
1175 eth_test->flags |= ETH_TEST_FL_FAILED;
1177 if (eth_test->flags & ETH_TEST_FL_EXTERNAL_LB) {
1178 data[4] = qlcnic_loopback_test(dev, QLCNIC_ELB_MODE);
1179 if (data[4])
1180 eth_test->flags |= ETH_TEST_FL_FAILED;
1181 eth_test->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE;
1184 data[5] = qlcnic_eeprom_test(dev);
1185 if (data[5])
1186 eth_test->flags |= ETH_TEST_FL_FAILED;
1190 static void
1191 qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 *data)
1193 struct qlcnic_adapter *adapter = netdev_priv(dev);
1194 int index, i, num_stats;
1196 switch (stringset) {
1197 case ETH_SS_TEST:
1198 memcpy(data, *qlcnic_gstrings_test,
1199 QLCNIC_TEST_LEN * ETH_GSTRING_LEN);
1200 break;
1201 case ETH_SS_STATS:
1202 num_stats = ARRAY_SIZE(qlcnic_tx_queue_stats_strings);
1203 for (i = 0; i < adapter->drv_tx_rings; i++) {
1204 for (index = 0; index < num_stats; index++) {
1205 sprintf(data, "tx_queue_%d %s", i,
1206 qlcnic_tx_queue_stats_strings[index]);
1207 data += ETH_GSTRING_LEN;
1211 for (index = 0; index < QLCNIC_STATS_LEN; index++) {
1212 memcpy(data + index * ETH_GSTRING_LEN,
1213 qlcnic_gstrings_stats[index].stat_string,
1214 ETH_GSTRING_LEN);
1217 if (qlcnic_83xx_check(adapter)) {
1218 num_stats = ARRAY_SIZE(qlcnic_83xx_tx_stats_strings);
1219 for (i = 0; i < num_stats; i++, index++)
1220 memcpy(data + index * ETH_GSTRING_LEN,
1221 qlcnic_83xx_tx_stats_strings[i],
1222 ETH_GSTRING_LEN);
1223 num_stats = ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
1224 for (i = 0; i < num_stats; i++, index++)
1225 memcpy(data + index * ETH_GSTRING_LEN,
1226 qlcnic_83xx_mac_stats_strings[i],
1227 ETH_GSTRING_LEN);
1228 num_stats = ARRAY_SIZE(qlcnic_83xx_rx_stats_strings);
1229 for (i = 0; i < num_stats; i++, index++)
1230 memcpy(data + index * ETH_GSTRING_LEN,
1231 qlcnic_83xx_rx_stats_strings[i],
1232 ETH_GSTRING_LEN);
1233 return;
1234 } else {
1235 num_stats = ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
1236 for (i = 0; i < num_stats; i++, index++)
1237 memcpy(data + index * ETH_GSTRING_LEN,
1238 qlcnic_83xx_mac_stats_strings[i],
1239 ETH_GSTRING_LEN);
1241 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1242 return;
1243 num_stats = ARRAY_SIZE(qlcnic_device_gstrings_stats);
1244 for (i = 0; i < num_stats; index++, i++) {
1245 memcpy(data + index * ETH_GSTRING_LEN,
1246 qlcnic_device_gstrings_stats[i],
1247 ETH_GSTRING_LEN);
1252 static u64 *qlcnic_fill_stats(u64 *data, void *stats, int type)
1254 if (type == QLCNIC_MAC_STATS) {
1255 struct qlcnic_mac_statistics *mac_stats =
1256 (struct qlcnic_mac_statistics *)stats;
1257 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_frames);
1258 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_bytes);
1259 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_mcast_pkts);
1260 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_bcast_pkts);
1261 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_pause_cnt);
1262 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_ctrl_pkt);
1263 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_64b_pkts);
1264 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_127b_pkts);
1265 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_255b_pkts);
1266 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_511b_pkts);
1267 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1023b_pkts);
1268 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1518b_pkts);
1269 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_gt_1518b_pkts);
1270 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_frames);
1271 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_bytes);
1272 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_mcast_pkts);
1273 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_bcast_pkts);
1274 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_pause_cnt);
1275 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_ctrl_pkt);
1276 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_64b_pkts);
1277 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_127b_pkts);
1278 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_255b_pkts);
1279 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_511b_pkts);
1280 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1023b_pkts);
1281 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1518b_pkts);
1282 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_gt_1518b_pkts);
1283 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_error);
1284 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_small);
1285 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_large);
1286 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_jabber);
1287 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_dropped);
1288 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_crc_error);
1289 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_align_error);
1290 } else if (type == QLCNIC_ESW_STATS) {
1291 struct __qlcnic_esw_statistics *esw_stats =
1292 (struct __qlcnic_esw_statistics *)stats;
1293 *data++ = QLCNIC_FILL_STATS(esw_stats->unicast_frames);
1294 *data++ = QLCNIC_FILL_STATS(esw_stats->multicast_frames);
1295 *data++ = QLCNIC_FILL_STATS(esw_stats->broadcast_frames);
1296 *data++ = QLCNIC_FILL_STATS(esw_stats->dropped_frames);
1297 *data++ = QLCNIC_FILL_STATS(esw_stats->errors);
1298 *data++ = QLCNIC_FILL_STATS(esw_stats->local_frames);
1299 *data++ = QLCNIC_FILL_STATS(esw_stats->numbytes);
1301 return data;
1304 void qlcnic_update_stats(struct qlcnic_adapter *adapter)
1306 struct qlcnic_tx_queue_stats tx_stats;
1307 struct qlcnic_host_tx_ring *tx_ring;
1308 int ring;
1310 memset(&tx_stats, 0, sizeof(tx_stats));
1311 for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
1312 tx_ring = &adapter->tx_ring[ring];
1313 tx_stats.xmit_on += tx_ring->tx_stats.xmit_on;
1314 tx_stats.xmit_off += tx_ring->tx_stats.xmit_off;
1315 tx_stats.xmit_called += tx_ring->tx_stats.xmit_called;
1316 tx_stats.xmit_finished += tx_ring->tx_stats.xmit_finished;
1317 tx_stats.tx_bytes += tx_ring->tx_stats.tx_bytes;
1320 adapter->stats.xmit_on = tx_stats.xmit_on;
1321 adapter->stats.xmit_off = tx_stats.xmit_off;
1322 adapter->stats.xmitcalled = tx_stats.xmit_called;
1323 adapter->stats.xmitfinished = tx_stats.xmit_finished;
1324 adapter->stats.txbytes = tx_stats.tx_bytes;
1327 static u64 *qlcnic_fill_tx_queue_stats(u64 *data, void *stats)
1329 struct qlcnic_host_tx_ring *tx_ring;
1331 tx_ring = (struct qlcnic_host_tx_ring *)stats;
1333 *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_on);
1334 *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_off);
1335 *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_called);
1336 *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_finished);
1337 *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.tx_bytes);
1339 return data;
1342 static void qlcnic_get_ethtool_stats(struct net_device *dev,
1343 struct ethtool_stats *stats, u64 *data)
1345 struct qlcnic_adapter *adapter = netdev_priv(dev);
1346 struct qlcnic_host_tx_ring *tx_ring;
1347 struct qlcnic_esw_statistics port_stats;
1348 struct qlcnic_mac_statistics mac_stats;
1349 int index, ret, length, size, ring;
1350 char *p;
1352 memset(data, 0, stats->n_stats * sizeof(u64));
1354 for (ring = 0, index = 0; ring < adapter->drv_tx_rings; ring++) {
1355 if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) {
1356 tx_ring = &adapter->tx_ring[ring];
1357 data = qlcnic_fill_tx_queue_stats(data, tx_ring);
1358 qlcnic_update_stats(adapter);
1359 } else {
1360 data += QLCNIC_TX_STATS_LEN;
1364 length = QLCNIC_STATS_LEN;
1365 for (index = 0; index < length; index++) {
1366 p = (char *)adapter + qlcnic_gstrings_stats[index].stat_offset;
1367 size = qlcnic_gstrings_stats[index].sizeof_stat;
1368 *data++ = (size == sizeof(u64)) ? (*(u64 *)p) : ((*(u32 *)p));
1371 if (qlcnic_83xx_check(adapter)) {
1372 if (adapter->ahw->linkup)
1373 qlcnic_83xx_get_stats(adapter, data);
1374 return;
1375 } else {
1376 /* Retrieve MAC statistics from firmware */
1377 memset(&mac_stats, 0, sizeof(struct qlcnic_mac_statistics));
1378 qlcnic_get_mac_stats(adapter, &mac_stats);
1379 data = qlcnic_fill_stats(data, &mac_stats, QLCNIC_MAC_STATS);
1382 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1383 return;
1385 memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics));
1386 ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
1387 QLCNIC_QUERY_RX_COUNTER, &port_stats.rx);
1388 if (ret)
1389 return;
1391 data = qlcnic_fill_stats(data, &port_stats.rx, QLCNIC_ESW_STATS);
1392 ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
1393 QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
1394 if (ret)
1395 return;
1397 qlcnic_fill_stats(data, &port_stats.tx, QLCNIC_ESW_STATS);
1400 static int qlcnic_set_led(struct net_device *dev,
1401 enum ethtool_phys_id_state state)
1403 struct qlcnic_adapter *adapter = netdev_priv(dev);
1404 int drv_sds_rings = adapter->drv_sds_rings;
1405 int err = -EIO, active = 1;
1407 if (qlcnic_83xx_check(adapter))
1408 return qlcnic_83xx_set_led(dev, state);
1410 if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1411 netdev_warn(dev, "LED test not supported for non "
1412 "privilege function\n");
1413 return -EOPNOTSUPP;
1416 switch (state) {
1417 case ETHTOOL_ID_ACTIVE:
1418 if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
1419 return -EBUSY;
1421 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1422 break;
1424 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
1425 if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
1426 break;
1427 set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
1430 if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) {
1431 err = 0;
1432 break;
1435 dev_err(&adapter->pdev->dev,
1436 "Failed to set LED blink state.\n");
1437 break;
1439 case ETHTOOL_ID_INACTIVE:
1440 active = 0;
1442 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1443 break;
1445 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
1446 if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
1447 break;
1448 set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
1451 if (adapter->nic_ops->config_led(adapter, 0, 0xf))
1452 dev_err(&adapter->pdev->dev,
1453 "Failed to reset LED blink state.\n");
1455 break;
1457 default:
1458 return -EINVAL;
1461 if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
1462 qlcnic_diag_free_res(dev, drv_sds_rings);
1464 if (!active || err)
1465 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
1467 return err;
1470 static void
1471 qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1473 struct qlcnic_adapter *adapter = netdev_priv(dev);
1474 u32 wol_cfg;
1475 int err = 0;
1477 if (qlcnic_83xx_check(adapter))
1478 return;
1479 wol->supported = 0;
1480 wol->wolopts = 0;
1482 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV, &err);
1483 if (err == -EIO)
1484 return;
1485 if (wol_cfg & (1UL << adapter->portnum))
1486 wol->supported |= WAKE_MAGIC;
1488 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG, &err);
1489 if (wol_cfg & (1UL << adapter->portnum))
1490 wol->wolopts |= WAKE_MAGIC;
1493 static int
1494 qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1496 struct qlcnic_adapter *adapter = netdev_priv(dev);
1497 u32 wol_cfg;
1498 int err = 0;
1500 if (qlcnic_83xx_check(adapter))
1501 return -EOPNOTSUPP;
1502 if (wol->wolopts & ~WAKE_MAGIC)
1503 return -EINVAL;
1505 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV, &err);
1506 if (err == -EIO)
1507 return err;
1508 if (!(wol_cfg & (1 << adapter->portnum)))
1509 return -EOPNOTSUPP;
1511 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG, &err);
1512 if (err == -EIO)
1513 return err;
1514 if (wol->wolopts & WAKE_MAGIC)
1515 wol_cfg |= 1UL << adapter->portnum;
1516 else
1517 wol_cfg &= ~(1UL << adapter->portnum);
1519 QLCWR32(adapter, QLCNIC_WOL_CONFIG, wol_cfg);
1521 return 0;
1525 * Set the coalescing parameters. Currently only normal is supported.
1526 * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
1527 * firmware coalescing to default.
1529 static int qlcnic_set_intr_coalesce(struct net_device *netdev,
1530 struct ethtool_coalesce *ethcoal)
1532 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1533 int err;
1535 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
1536 return -EINVAL;
1539 * Return Error if unsupported values or
1540 * unsupported parameters are set.
1542 if (ethcoal->rx_coalesce_usecs > 0xffff ||
1543 ethcoal->rx_max_coalesced_frames > 0xffff ||
1544 ethcoal->tx_coalesce_usecs > 0xffff ||
1545 ethcoal->tx_max_coalesced_frames > 0xffff ||
1546 ethcoal->rx_coalesce_usecs_irq ||
1547 ethcoal->rx_max_coalesced_frames_irq ||
1548 ethcoal->tx_coalesce_usecs_irq ||
1549 ethcoal->tx_max_coalesced_frames_irq ||
1550 ethcoal->stats_block_coalesce_usecs ||
1551 ethcoal->use_adaptive_rx_coalesce ||
1552 ethcoal->use_adaptive_tx_coalesce ||
1553 ethcoal->pkt_rate_low ||
1554 ethcoal->rx_coalesce_usecs_low ||
1555 ethcoal->rx_max_coalesced_frames_low ||
1556 ethcoal->tx_coalesce_usecs_low ||
1557 ethcoal->tx_max_coalesced_frames_low ||
1558 ethcoal->pkt_rate_high ||
1559 ethcoal->rx_coalesce_usecs_high ||
1560 ethcoal->rx_max_coalesced_frames_high ||
1561 ethcoal->tx_coalesce_usecs_high ||
1562 ethcoal->tx_max_coalesced_frames_high)
1563 return -EINVAL;
1565 err = qlcnic_config_intr_coalesce(adapter, ethcoal);
1567 return err;
1570 static int qlcnic_get_intr_coalesce(struct net_device *netdev,
1571 struct ethtool_coalesce *ethcoal)
1573 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1575 if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
1576 return -EINVAL;
1578 ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us;
1579 ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets;
1580 ethcoal->tx_coalesce_usecs = adapter->ahw->coal.tx_time_us;
1581 ethcoal->tx_max_coalesced_frames = adapter->ahw->coal.tx_packets;
1583 return 0;
1586 static u32 qlcnic_get_msglevel(struct net_device *netdev)
1588 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1590 return adapter->ahw->msg_enable;
1593 static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
1595 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1597 adapter->ahw->msg_enable = msglvl;
1600 int qlcnic_enable_fw_dump_state(struct qlcnic_adapter *adapter)
1602 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1603 u32 val;
1605 if (qlcnic_84xx_check(adapter)) {
1606 if (qlcnic_83xx_lock_driver(adapter))
1607 return -EBUSY;
1609 val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
1610 val &= ~QLC_83XX_IDC_DISABLE_FW_DUMP;
1611 QLCWRX(adapter->ahw, QLC_83XX_IDC_CTRL, val);
1613 qlcnic_83xx_unlock_driver(adapter);
1614 } else {
1615 fw_dump->enable = true;
1618 dev_info(&adapter->pdev->dev, "FW dump enabled\n");
1620 return 0;
1623 static int qlcnic_disable_fw_dump_state(struct qlcnic_adapter *adapter)
1625 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1626 u32 val;
1628 if (qlcnic_84xx_check(adapter)) {
1629 if (qlcnic_83xx_lock_driver(adapter))
1630 return -EBUSY;
1632 val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
1633 val |= QLC_83XX_IDC_DISABLE_FW_DUMP;
1634 QLCWRX(adapter->ahw, QLC_83XX_IDC_CTRL, val);
1636 qlcnic_83xx_unlock_driver(adapter);
1637 } else {
1638 fw_dump->enable = false;
1641 dev_info(&adapter->pdev->dev, "FW dump disabled\n");
1643 return 0;
1646 bool qlcnic_check_fw_dump_state(struct qlcnic_adapter *adapter)
1648 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1649 bool state;
1650 u32 val;
1652 if (qlcnic_84xx_check(adapter)) {
1653 val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
1654 state = (val & QLC_83XX_IDC_DISABLE_FW_DUMP) ? false : true;
1655 } else {
1656 state = fw_dump->enable;
1659 return state;
1662 static int
1663 qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
1665 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1666 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1668 if (!fw_dump->tmpl_hdr) {
1669 netdev_err(adapter->netdev, "FW Dump not supported\n");
1670 return -ENOTSUPP;
1673 if (fw_dump->clr)
1674 dump->len = fw_dump->tmpl_hdr_size + fw_dump->size;
1675 else
1676 dump->len = 0;
1678 if (!qlcnic_check_fw_dump_state(adapter))
1679 dump->flag = ETH_FW_DUMP_DISABLE;
1680 else
1681 dump->flag = fw_dump->cap_mask;
1683 dump->version = adapter->fw_version;
1684 return 0;
1687 static int
1688 qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
1689 void *buffer)
1691 int i, copy_sz;
1692 u32 *hdr_ptr;
1693 __le32 *data;
1694 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1695 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1697 if (!fw_dump->tmpl_hdr) {
1698 netdev_err(netdev, "FW Dump not supported\n");
1699 return -ENOTSUPP;
1702 if (!fw_dump->clr) {
1703 netdev_info(netdev, "Dump not available\n");
1704 return -EINVAL;
1707 /* Copy template header first */
1708 copy_sz = fw_dump->tmpl_hdr_size;
1709 hdr_ptr = (u32 *)fw_dump->tmpl_hdr;
1710 data = buffer;
1711 for (i = 0; i < copy_sz/sizeof(u32); i++)
1712 *data++ = cpu_to_le32(*hdr_ptr++);
1714 /* Copy captured dump data */
1715 memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size);
1716 dump->len = copy_sz + fw_dump->size;
1717 dump->flag = fw_dump->cap_mask;
1719 /* Free dump area once data has been captured */
1720 vfree(fw_dump->data);
1721 fw_dump->data = NULL;
1722 fw_dump->clr = 0;
1723 netdev_info(netdev, "extracted the FW dump Successfully\n");
1724 return 0;
1727 static int qlcnic_set_dump_mask(struct qlcnic_adapter *adapter, u32 mask)
1729 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1730 struct net_device *netdev = adapter->netdev;
1732 if (!qlcnic_check_fw_dump_state(adapter)) {
1733 netdev_info(netdev,
1734 "Can not change driver mask to 0x%x. FW dump not enabled\n",
1735 mask);
1736 return -EOPNOTSUPP;
1739 fw_dump->cap_mask = mask;
1741 /* Store new capture mask in template header as well*/
1742 qlcnic_store_cap_mask(adapter, fw_dump->tmpl_hdr, mask);
1744 netdev_info(netdev, "Driver mask changed to: 0x%x\n", mask);
1745 return 0;
1748 static int
1749 qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
1751 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1752 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1753 bool valid_mask = false;
1754 int i, ret = 0;
1756 switch (val->flag) {
1757 case QLCNIC_FORCE_FW_DUMP_KEY:
1758 if (!fw_dump->tmpl_hdr) {
1759 netdev_err(netdev, "FW dump not supported\n");
1760 ret = -EOPNOTSUPP;
1761 break;
1764 if (!qlcnic_check_fw_dump_state(adapter)) {
1765 netdev_info(netdev, "FW dump not enabled\n");
1766 ret = -EOPNOTSUPP;
1767 break;
1770 if (fw_dump->clr) {
1771 netdev_info(netdev,
1772 "Previous dump not cleared, not forcing dump\n");
1773 break;
1776 netdev_info(netdev, "Forcing a FW dump\n");
1777 qlcnic_dev_request_reset(adapter, val->flag);
1778 break;
1779 case QLCNIC_DISABLE_FW_DUMP:
1780 if (!fw_dump->tmpl_hdr) {
1781 netdev_err(netdev, "FW dump not supported\n");
1782 ret = -EOPNOTSUPP;
1783 break;
1786 ret = qlcnic_disable_fw_dump_state(adapter);
1787 break;
1789 case QLCNIC_ENABLE_FW_DUMP:
1790 if (!fw_dump->tmpl_hdr) {
1791 netdev_err(netdev, "FW dump not supported\n");
1792 ret = -EOPNOTSUPP;
1793 break;
1796 ret = qlcnic_enable_fw_dump_state(adapter);
1797 break;
1799 case QLCNIC_FORCE_FW_RESET:
1800 netdev_info(netdev, "Forcing a FW reset\n");
1801 qlcnic_dev_request_reset(adapter, val->flag);
1802 adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
1803 break;
1805 case QLCNIC_SET_QUIESCENT:
1806 case QLCNIC_RESET_QUIESCENT:
1807 if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state))
1808 netdev_info(netdev, "Device is in non-operational state\n");
1809 break;
1811 default:
1812 if (!fw_dump->tmpl_hdr) {
1813 netdev_err(netdev, "FW dump not supported\n");
1814 ret = -EOPNOTSUPP;
1815 break;
1818 for (i = 0; i < ARRAY_SIZE(qlcnic_fw_dump_level); i++) {
1819 if (val->flag == qlcnic_fw_dump_level[i]) {
1820 valid_mask = true;
1821 break;
1825 if (valid_mask) {
1826 ret = qlcnic_set_dump_mask(adapter, val->flag);
1827 } else {
1828 netdev_info(netdev, "Invalid dump level: 0x%x\n",
1829 val->flag);
1830 ret = -EINVAL;
1833 return ret;
1836 const struct ethtool_ops qlcnic_ethtool_ops = {
1837 .get_drvinfo = qlcnic_get_drvinfo,
1838 .get_regs_len = qlcnic_get_regs_len,
1839 .get_regs = qlcnic_get_regs,
1840 .get_link = ethtool_op_get_link,
1841 .get_eeprom_len = qlcnic_get_eeprom_len,
1842 .get_eeprom = qlcnic_get_eeprom,
1843 .get_ringparam = qlcnic_get_ringparam,
1844 .set_ringparam = qlcnic_set_ringparam,
1845 .get_channels = qlcnic_get_channels,
1846 .set_channels = qlcnic_set_channels,
1847 .get_pauseparam = qlcnic_get_pauseparam,
1848 .set_pauseparam = qlcnic_set_pauseparam,
1849 .get_wol = qlcnic_get_wol,
1850 .set_wol = qlcnic_set_wol,
1851 .self_test = qlcnic_diag_test,
1852 .get_strings = qlcnic_get_strings,
1853 .get_ethtool_stats = qlcnic_get_ethtool_stats,
1854 .get_sset_count = qlcnic_get_sset_count,
1855 .get_coalesce = qlcnic_get_intr_coalesce,
1856 .set_coalesce = qlcnic_set_intr_coalesce,
1857 .set_phys_id = qlcnic_set_led,
1858 .set_msglevel = qlcnic_set_msglevel,
1859 .get_msglevel = qlcnic_get_msglevel,
1860 .get_dump_flag = qlcnic_get_dump_flag,
1861 .get_dump_data = qlcnic_get_dump_data,
1862 .set_dump = qlcnic_set_dump,
1863 .get_link_ksettings = qlcnic_get_link_ksettings,
1864 .set_link_ksettings = qlcnic_set_link_ksettings,
1867 const struct ethtool_ops qlcnic_sriov_vf_ethtool_ops = {
1868 .get_drvinfo = qlcnic_get_drvinfo,
1869 .get_regs_len = qlcnic_get_regs_len,
1870 .get_regs = qlcnic_get_regs,
1871 .get_link = ethtool_op_get_link,
1872 .get_eeprom_len = qlcnic_get_eeprom_len,
1873 .get_eeprom = qlcnic_get_eeprom,
1874 .get_ringparam = qlcnic_get_ringparam,
1875 .set_ringparam = qlcnic_set_ringparam,
1876 .get_channels = qlcnic_get_channels,
1877 .get_pauseparam = qlcnic_get_pauseparam,
1878 .get_wol = qlcnic_get_wol,
1879 .get_strings = qlcnic_get_strings,
1880 .get_ethtool_stats = qlcnic_get_ethtool_stats,
1881 .get_sset_count = qlcnic_get_sset_count,
1882 .get_coalesce = qlcnic_get_intr_coalesce,
1883 .set_coalesce = qlcnic_set_intr_coalesce,
1884 .set_msglevel = qlcnic_set_msglevel,
1885 .get_msglevel = qlcnic_get_msglevel,
1886 .get_link_ksettings = qlcnic_get_link_ksettings,
1889 const struct ethtool_ops qlcnic_ethtool_failed_ops = {
1890 .get_drvinfo = qlcnic_get_drvinfo,
1891 .set_msglevel = qlcnic_set_msglevel,
1892 .get_msglevel = qlcnic_get_msglevel,
1893 .set_dump = qlcnic_set_dump,
1894 .get_link_ksettings = qlcnic_get_link_ksettings,