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