1
2
3
4
5
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)
25
26static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
27 {"xmit_called",
28 QLC_SIZEOF(stats.xmitcalled), QLC_OFF(stats.xmitcalled)},
29 {"xmit_finished",
30 QLC_SIZEOF(stats.xmitfinished), QLC_OFF(stats.xmitfinished)},
31 {"rx_dropped",
32 QLC_SIZEOF(stats.rxdropped), QLC_OFF(stats.rxdropped)},
33 {"tx_dropped",
34 QLC_SIZEOF(stats.txdropped), QLC_OFF(stats.txdropped)},
35 {"csummed",
36 QLC_SIZEOF(stats.csummed), QLC_OFF(stats.csummed)},
37 {"rx_pkts",
38 QLC_SIZEOF(stats.rx_pkts), QLC_OFF(stats.rx_pkts)},
39 {"lro_pkts",
40 QLC_SIZEOF(stats.lro_pkts), QLC_OFF(stats.lro_pkts)},
41 {"rx_bytes",
42 QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)},
43 {"tx_bytes",
44 QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)},
45 {"lrobytes",
46 QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)},
47 {"lso_frames",
48 QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)},
49 {"xmit_on",
50 QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)},
51 {"xmit_off",
52 QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)},
53 {"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
54 QLC_OFF(stats.skb_alloc_failure)},
55 {"null rxbuf",
56 QLC_SIZEOF(stats.null_rxbuf), QLC_OFF(stats.null_rxbuf)},
57 {"rx dma map error", QLC_SIZEOF(stats.rx_dma_map_error),
58 QLC_OFF(stats.rx_dma_map_error)},
59 {"tx dma map error", QLC_SIZEOF(stats.tx_dma_map_error),
60 QLC_OFF(stats.tx_dma_map_error)},
61
62};
63
64static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
65 "rx unicast frames",
66 "rx multicast frames",
67 "rx broadcast frames",
68 "rx dropped frames",
69 "rx errors",
70 "rx local frames",
71 "rx numbytes",
72 "tx unicast frames",
73 "tx multicast frames",
74 "tx broadcast frames",
75 "tx dropped frames",
76 "tx errors",
77 "tx local frames",
78 "tx numbytes",
79};
80
81#define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats)
82#define QLCNIC_DEVICE_STATS_LEN ARRAY_SIZE(qlcnic_device_gstrings_stats)
83
84static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
85 "Register_Test_on_offline",
86 "Link_Test_on_offline",
87 "Interrupt_Test_offline",
88 "Internal_Loopback_offline",
89 "External_Loopback_offline"
90};
91
92#define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test)
93
94#define QLCNIC_RING_REGS_COUNT 20
95#define QLCNIC_RING_REGS_LEN (QLCNIC_RING_REGS_COUNT * sizeof(u32))
96#define QLCNIC_MAX_EEPROM_LEN 1024
97
98static const u32 diag_registers[] = {
99 CRB_CMDPEG_STATE,
100 CRB_RCVPEG_STATE,
101 CRB_XG_STATE_P3P,
102 CRB_FW_CAPABILITIES_1,
103 ISR_INT_STATE_REG,
104 QLCNIC_CRB_DRV_ACTIVE,
105 QLCNIC_CRB_DEV_STATE,
106 QLCNIC_CRB_DRV_STATE,
107 QLCNIC_CRB_DRV_SCRATCH,
108 QLCNIC_CRB_DEV_PARTITION_INFO,
109 QLCNIC_CRB_DRV_IDC_VER,
110 QLCNIC_PEG_ALIVE_COUNTER,
111 QLCNIC_PEG_HALT_STATUS1,
112 QLCNIC_PEG_HALT_STATUS2,
113 QLCNIC_CRB_PEG_NET_0+0x3c,
114 QLCNIC_CRB_PEG_NET_1+0x3c,
115 QLCNIC_CRB_PEG_NET_2+0x3c,
116 QLCNIC_CRB_PEG_NET_4+0x3c,
117 -1
118};
119
120#define QLCNIC_MGMT_API_VERSION 2
121#define QLCNIC_DEV_INFO_SIZE 1
122#define QLCNIC_ETHTOOL_REGS_VER 2
123static int qlcnic_get_regs_len(struct net_device *dev)
124{
125 return sizeof(diag_registers) + QLCNIC_RING_REGS_LEN +
126 QLCNIC_DEV_INFO_SIZE + 1;
127}
128
129static int qlcnic_get_eeprom_len(struct net_device *dev)
130{
131 return QLCNIC_FLASH_TOTAL_SIZE;
132}
133
134static void
135qlcnic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
136{
137 struct qlcnic_adapter *adapter = netdev_priv(dev);
138 u32 fw_major, fw_minor, fw_build;
139
140 fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR);
141 fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR);
142 fw_build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB);
143 snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
144 "%d.%d.%d", fw_major, fw_minor, fw_build);
145
146 strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
147 sizeof(drvinfo->bus_info));
148 strlcpy(drvinfo->driver, qlcnic_driver_name, sizeof(drvinfo->driver));
149 strlcpy(drvinfo->version, QLCNIC_LINUX_VERSIONID,
150 sizeof(drvinfo->version));
151}
152
153static int
154qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
155{
156 struct qlcnic_adapter *adapter = netdev_priv(dev);
157 int check_sfp_module = 0;
158 u16 pcifn = adapter->ahw->pci_func;
159
160
161 if (adapter->ahw->port_type == QLCNIC_GBE) {
162 ecmd->supported = (SUPPORTED_10baseT_Half |
163 SUPPORTED_10baseT_Full |
164 SUPPORTED_100baseT_Half |
165 SUPPORTED_100baseT_Full |
166 SUPPORTED_1000baseT_Half |
167 SUPPORTED_1000baseT_Full);
168
169 ecmd->advertising = (ADVERTISED_100baseT_Half |
170 ADVERTISED_100baseT_Full |
171 ADVERTISED_1000baseT_Half |
172 ADVERTISED_1000baseT_Full);
173
174 ethtool_cmd_speed_set(ecmd, adapter->link_speed);
175 ecmd->duplex = adapter->link_duplex;
176 ecmd->autoneg = adapter->link_autoneg;
177
178 } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
179 u32 val;
180
181 val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
182 if (val == QLCNIC_PORT_MODE_802_3_AP) {
183 ecmd->supported = SUPPORTED_1000baseT_Full;
184 ecmd->advertising = ADVERTISED_1000baseT_Full;
185 } else {
186 ecmd->supported = SUPPORTED_10000baseT_Full;
187 ecmd->advertising = ADVERTISED_10000baseT_Full;
188 }
189
190 if (netif_running(dev) && adapter->has_link_events) {
191 ethtool_cmd_speed_set(ecmd, adapter->link_speed);
192 ecmd->autoneg = adapter->link_autoneg;
193 ecmd->duplex = adapter->link_duplex;
194 goto skip;
195 }
196
197 val = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn));
198 ethtool_cmd_speed_set(ecmd, P3P_LINK_SPEED_MHZ *
199 P3P_LINK_SPEED_VAL(pcifn, val));
200 ecmd->duplex = DUPLEX_FULL;
201 ecmd->autoneg = AUTONEG_DISABLE;
202 } else
203 return -EIO;
204
205skip:
206 ecmd->phy_address = adapter->physical_port;
207 ecmd->transceiver = XCVR_EXTERNAL;
208
209 switch (adapter->ahw->board_type) {
210 case QLCNIC_BRDTYPE_P3P_REF_QG:
211 case QLCNIC_BRDTYPE_P3P_4_GB:
212 case QLCNIC_BRDTYPE_P3P_4_GB_MM:
213
214 ecmd->supported |= SUPPORTED_Autoneg;
215 ecmd->advertising |= ADVERTISED_Autoneg;
216 case QLCNIC_BRDTYPE_P3P_10G_CX4:
217 case QLCNIC_BRDTYPE_P3P_10G_CX4_LP:
218 case QLCNIC_BRDTYPE_P3P_10000_BASE_T:
219 ecmd->supported |= SUPPORTED_TP;
220 ecmd->advertising |= ADVERTISED_TP;
221 ecmd->port = PORT_TP;
222 ecmd->autoneg = adapter->link_autoneg;
223 break;
224 case QLCNIC_BRDTYPE_P3P_IMEZ:
225 case QLCNIC_BRDTYPE_P3P_XG_LOM:
226 case QLCNIC_BRDTYPE_P3P_HMEZ:
227 ecmd->supported |= SUPPORTED_MII;
228 ecmd->advertising |= ADVERTISED_MII;
229 ecmd->port = PORT_MII;
230 ecmd->autoneg = AUTONEG_DISABLE;
231 break;
232 case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS:
233 case QLCNIC_BRDTYPE_P3P_10G_SFP_CT:
234 case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
235 ecmd->advertising |= ADVERTISED_TP;
236 ecmd->supported |= SUPPORTED_TP;
237 check_sfp_module = netif_running(dev) &&
238 adapter->has_link_events;
239 case QLCNIC_BRDTYPE_P3P_10G_XFP:
240 ecmd->supported |= SUPPORTED_FIBRE;
241 ecmd->advertising |= ADVERTISED_FIBRE;
242 ecmd->port = PORT_FIBRE;
243 ecmd->autoneg = AUTONEG_DISABLE;
244 break;
245 case QLCNIC_BRDTYPE_P3P_10G_TP:
246 if (adapter->ahw->port_type == QLCNIC_XGBE) {
247 ecmd->autoneg = AUTONEG_DISABLE;
248 ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
249 ecmd->advertising |=
250 (ADVERTISED_FIBRE | ADVERTISED_TP);
251 ecmd->port = PORT_FIBRE;
252 check_sfp_module = netif_running(dev) &&
253 adapter->has_link_events;
254 } else {
255 ecmd->autoneg = AUTONEG_ENABLE;
256 ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
257 ecmd->advertising |=
258 (ADVERTISED_TP | ADVERTISED_Autoneg);
259 ecmd->port = PORT_TP;
260 }
261 break;
262 default:
263 dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
264 adapter->ahw->board_type);
265 return -EIO;
266 }
267
268 if (check_sfp_module) {
269 switch (adapter->module_type) {
270 case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
271 case LINKEVENT_MODULE_OPTICAL_SRLR:
272 case LINKEVENT_MODULE_OPTICAL_LRM:
273 case LINKEVENT_MODULE_OPTICAL_SFP_1G:
274 ecmd->port = PORT_FIBRE;
275 break;
276 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
277 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
278 case LINKEVENT_MODULE_TWINAX:
279 ecmd->port = PORT_TP;
280 break;
281 default:
282 ecmd->port = PORT_OTHER;
283 }
284 }
285
286 return 0;
287}
288
289static int
290qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
291{
292 u32 config = 0;
293 u32 ret = 0;
294 struct qlcnic_adapter *adapter = netdev_priv(dev);
295
296 if (adapter->ahw->port_type != QLCNIC_GBE)
297 return -EOPNOTSUPP;
298
299
300 if (ecmd->duplex)
301 config |= 0x1;
302
303 if (ecmd->autoneg)
304 config |= 0x2;
305
306 switch (ethtool_cmd_speed(ecmd)) {
307 case SPEED_10:
308 config |= (0 << 8);
309 break;
310 case SPEED_100:
311 config |= (1 << 8);
312 break;
313 case SPEED_1000:
314 config |= (10 << 8);
315 break;
316 default:
317 return -EIO;
318 }
319
320 ret = qlcnic_fw_cmd_set_port(adapter, config);
321
322 if (ret == QLCNIC_RCODE_NOT_SUPPORTED)
323 return -EOPNOTSUPP;
324 else if (ret)
325 return -EIO;
326
327 adapter->link_speed = ethtool_cmd_speed(ecmd);
328 adapter->link_duplex = ecmd->duplex;
329 adapter->link_autoneg = ecmd->autoneg;
330
331 if (!netif_running(dev))
332 return 0;
333
334 dev->netdev_ops->ndo_stop(dev);
335 return dev->netdev_ops->ndo_open(dev);
336}
337
338static void
339qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
340{
341 struct qlcnic_adapter *adapter = netdev_priv(dev);
342 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
343 struct qlcnic_host_sds_ring *sds_ring;
344 u32 *regs_buff = p;
345 int ring, i = 0, j = 0;
346
347 memset(p, 0, qlcnic_get_regs_len(dev));
348 regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
349 (adapter->ahw->revision_id << 16) | (adapter->pdev)->device;
350
351 regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
352 regs_buff[1] = QLCNIC_MGMT_API_VERSION;
353
354 for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++)
355 regs_buff[i] = QLCRD32(adapter, diag_registers[j]);
356
357 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
358 return;
359
360 regs_buff[i++] = 0xFFEFCDAB;
361
362 regs_buff[i++] = 1;
363 regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
364 regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer);
365
366 regs_buff[i++] = 2;
367 regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer);
368 regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer);
369
370 regs_buff[i++] = adapter->max_sds_rings;
371
372 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
373 sds_ring = &(recv_ctx->sds_rings[ring]);
374 regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
375 }
376}
377
378static u32 qlcnic_test_link(struct net_device *dev)
379{
380 struct qlcnic_adapter *adapter = netdev_priv(dev);
381 u32 val;
382
383 val = QLCRD32(adapter, CRB_XG_STATE_P3P);
384 val = XG_LINK_STATE_P3P(adapter->ahw->pci_func, val);
385 return (val == XG_LINK_UP_P3P) ? 0 : 1;
386}
387
388static int
389qlcnic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
390 u8 *bytes)
391{
392 struct qlcnic_adapter *adapter = netdev_priv(dev);
393 int offset;
394 int ret;
395
396 if (eeprom->len == 0)
397 return -EINVAL;
398
399 eeprom->magic = (adapter->pdev)->vendor |
400 ((adapter->pdev)->device << 16);
401 offset = eeprom->offset;
402
403 ret = qlcnic_rom_fast_read_words(adapter, offset, bytes,
404 eeprom->len);
405 if (ret < 0)
406 return ret;
407
408 return 0;
409}
410
411static void
412qlcnic_get_ringparam(struct net_device *dev,
413 struct ethtool_ringparam *ring)
414{
415 struct qlcnic_adapter *adapter = netdev_priv(dev);
416
417 ring->rx_pending = adapter->num_rxd;
418 ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
419 ring->tx_pending = adapter->num_txd;
420
421 ring->rx_max_pending = adapter->max_rxd;
422 ring->rx_jumbo_max_pending = adapter->max_jumbo_rxd;
423 ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
424}
425
426static u32
427qlcnic_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
428{
429 u32 num_desc;
430 num_desc = max(val, min);
431 num_desc = min(num_desc, max);
432 num_desc = roundup_pow_of_two(num_desc);
433
434 if (val != num_desc) {
435 printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
436 qlcnic_driver_name, r_name, num_desc, val);
437 }
438
439 return num_desc;
440}
441
442static int
443qlcnic_set_ringparam(struct net_device *dev,
444 struct ethtool_ringparam *ring)
445{
446 struct qlcnic_adapter *adapter = netdev_priv(dev);
447 u16 num_rxd, num_jumbo_rxd, num_txd;
448
449 if (ring->rx_mini_pending)
450 return -EOPNOTSUPP;
451
452 num_rxd = qlcnic_validate_ringparam(ring->rx_pending,
453 MIN_RCV_DESCRIPTORS, adapter->max_rxd, "rx");
454
455 num_jumbo_rxd = qlcnic_validate_ringparam(ring->rx_jumbo_pending,
456 MIN_JUMBO_DESCRIPTORS, adapter->max_jumbo_rxd,
457 "rx jumbo");
458
459 num_txd = qlcnic_validate_ringparam(ring->tx_pending,
460 MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
461
462 if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
463 num_jumbo_rxd == adapter->num_jumbo_rxd)
464 return 0;
465
466 adapter->num_rxd = num_rxd;
467 adapter->num_jumbo_rxd = num_jumbo_rxd;
468 adapter->num_txd = num_txd;
469
470 return qlcnic_reset_context(adapter);
471}
472
473static void qlcnic_get_channels(struct net_device *dev,
474 struct ethtool_channels *channel)
475{
476 struct qlcnic_adapter *adapter = netdev_priv(dev);
477
478 channel->max_rx = rounddown_pow_of_two(min_t(int,
479 adapter->max_rx_ques, num_online_cpus()));
480 channel->max_tx = adapter->max_tx_ques;
481
482 channel->rx_count = adapter->max_sds_rings;
483 channel->tx_count = adapter->max_tx_ques;
484}
485
486static int qlcnic_set_channels(struct net_device *dev,
487 struct ethtool_channels *channel)
488{
489 struct qlcnic_adapter *adapter = netdev_priv(dev);
490 int err;
491
492 if (channel->other_count || channel->combined_count ||
493 channel->tx_count != channel->max_tx)
494 return -EINVAL;
495
496 err = qlcnic_validate_max_rss(dev, channel->max_rx, channel->rx_count);
497 if (err)
498 return err;
499
500 err = qlcnic_set_max_rss(adapter, channel->rx_count);
501 netdev_info(dev, "allocated 0x%x sds rings\n",
502 adapter->max_sds_rings);
503 return err;
504}
505
506static void
507qlcnic_get_pauseparam(struct net_device *netdev,
508 struct ethtool_pauseparam *pause)
509{
510 struct qlcnic_adapter *adapter = netdev_priv(netdev);
511 int port = adapter->physical_port;
512 __u32 val;
513
514 if (adapter->ahw->port_type == QLCNIC_GBE) {
515 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
516 return;
517
518 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
519 pause->rx_pause = qlcnic_gb_get_rx_flowctl(val);
520 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
521 switch (port) {
522 case 0:
523 pause->tx_pause = !(qlcnic_gb_get_gb0_mask(val));
524 break;
525 case 1:
526 pause->tx_pause = !(qlcnic_gb_get_gb1_mask(val));
527 break;
528 case 2:
529 pause->tx_pause = !(qlcnic_gb_get_gb2_mask(val));
530 break;
531 case 3:
532 default:
533 pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val));
534 break;
535 }
536 } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
537 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
538 return;
539 pause->rx_pause = 1;
540 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
541 if (port == 0)
542 pause->tx_pause = !(qlcnic_xg_get_xg0_mask(val));
543 else
544 pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val));
545 } else {
546 dev_err(&netdev->dev, "Unknown board type: %x\n",
547 adapter->ahw->port_type);
548 }
549}
550
551static int
552qlcnic_set_pauseparam(struct net_device *netdev,
553 struct ethtool_pauseparam *pause)
554{
555 struct qlcnic_adapter *adapter = netdev_priv(netdev);
556 int port = adapter->physical_port;
557 __u32 val;
558
559
560 if (adapter->ahw->port_type == QLCNIC_GBE) {
561 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
562 return -EIO;
563
564 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
565
566 if (pause->rx_pause)
567 qlcnic_gb_rx_flowctl(val);
568 else
569 qlcnic_gb_unset_rx_flowctl(val);
570
571 QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port),
572 val);
573
574 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
575 switch (port) {
576 case 0:
577 if (pause->tx_pause)
578 qlcnic_gb_unset_gb0_mask(val);
579 else
580 qlcnic_gb_set_gb0_mask(val);
581 break;
582 case 1:
583 if (pause->tx_pause)
584 qlcnic_gb_unset_gb1_mask(val);
585 else
586 qlcnic_gb_set_gb1_mask(val);
587 break;
588 case 2:
589 if (pause->tx_pause)
590 qlcnic_gb_unset_gb2_mask(val);
591 else
592 qlcnic_gb_set_gb2_mask(val);
593 break;
594 case 3:
595 default:
596 if (pause->tx_pause)
597 qlcnic_gb_unset_gb3_mask(val);
598 else
599 qlcnic_gb_set_gb3_mask(val);
600 break;
601 }
602 QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val);
603 } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
604 if (!pause->rx_pause || pause->autoneg)
605 return -EOPNOTSUPP;
606
607 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
608 return -EIO;
609
610 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
611 if (port == 0) {
612 if (pause->tx_pause)
613 qlcnic_xg_unset_xg0_mask(val);
614 else
615 qlcnic_xg_set_xg0_mask(val);
616 } else {
617 if (pause->tx_pause)
618 qlcnic_xg_unset_xg1_mask(val);
619 else
620 qlcnic_xg_set_xg1_mask(val);
621 }
622 QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val);
623 } else {
624 dev_err(&netdev->dev, "Unknown board type: %x\n",
625 adapter->ahw->port_type);
626 }
627 return 0;
628}
629
630static int qlcnic_reg_test(struct net_device *dev)
631{
632 struct qlcnic_adapter *adapter = netdev_priv(dev);
633 u32 data_read;
634
635 data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0));
636 if ((data_read & 0xffff) != adapter->pdev->vendor)
637 return 1;
638
639 return 0;
640}
641
642static int qlcnic_get_sset_count(struct net_device *dev, int sset)
643{
644 struct qlcnic_adapter *adapter = netdev_priv(dev);
645 switch (sset) {
646 case ETH_SS_TEST:
647 return QLCNIC_TEST_LEN;
648 case ETH_SS_STATS:
649 if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
650 return QLCNIC_STATS_LEN + QLCNIC_DEVICE_STATS_LEN;
651 return QLCNIC_STATS_LEN;
652 default:
653 return -EOPNOTSUPP;
654 }
655}
656
657static int qlcnic_irq_test(struct net_device *netdev)
658{
659 struct qlcnic_adapter *adapter = netdev_priv(netdev);
660 int max_sds_rings = adapter->max_sds_rings;
661 int ret;
662 struct qlcnic_cmd_args cmd;
663
664 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
665 return -EIO;
666
667 ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST);
668 if (ret)
669 goto clear_it;
670
671 adapter->diag_cnt = 0;
672 memset(&cmd, 0, sizeof(cmd));
673 cmd.req.cmd = QLCNIC_CDRP_CMD_INTRPT_TEST;
674 cmd.req.arg1 = adapter->ahw->pci_func;
675 qlcnic_issue_cmd(adapter, &cmd);
676 ret = cmd.rsp.cmd;
677
678 if (ret)
679 goto done;
680
681 msleep(10);
682
683 ret = !adapter->diag_cnt;
684
685done:
686 qlcnic_diag_free_res(netdev, max_sds_rings);
687
688clear_it:
689 adapter->max_sds_rings = max_sds_rings;
690 clear_bit(__QLCNIC_RESETTING, &adapter->state);
691 return ret;
692}
693
694#define QLCNIC_ILB_PKT_SIZE 64
695#define QLCNIC_NUM_ILB_PKT 16
696#define QLCNIC_ILB_MAX_RCV_LOOP 10
697
698static void qlcnic_create_loopback_buff(unsigned char *data, u8 mac[])
699{
700 unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00};
701
702 memset(data, 0x4e, QLCNIC_ILB_PKT_SIZE);
703
704 memcpy(data, mac, ETH_ALEN);
705 memcpy(data + ETH_ALEN, mac, ETH_ALEN);
706
707 memcpy(data + 2 * ETH_ALEN, random_data, sizeof(random_data));
708}
709
710int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[])
711{
712 unsigned char buff[QLCNIC_ILB_PKT_SIZE];
713 qlcnic_create_loopback_buff(buff, mac);
714 return memcmp(data, buff, QLCNIC_ILB_PKT_SIZE);
715}
716
717static int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
718{
719 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
720 struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0];
721 struct sk_buff *skb;
722 int i, loop, cnt = 0;
723
724 for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) {
725 skb = dev_alloc_skb(QLCNIC_ILB_PKT_SIZE);
726 qlcnic_create_loopback_buff(skb->data, adapter->mac_addr);
727 skb_put(skb, QLCNIC_ILB_PKT_SIZE);
728
729 adapter->diag_cnt = 0;
730 qlcnic_xmit_frame(skb, adapter->netdev);
731
732 loop = 0;
733 do {
734 msleep(1);
735 qlcnic_process_rcv_ring_diag(sds_ring);
736 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP)
737 break;
738 } while (!adapter->diag_cnt);
739
740 dev_kfree_skb_any(skb);
741
742 if (!adapter->diag_cnt)
743 QLCDB(adapter, DRV,
744 "LB Test: packet #%d was not received\n", i + 1);
745 else
746 cnt++;
747 }
748 if (cnt != i) {
749 dev_warn(&adapter->pdev->dev, "LB Test failed\n");
750 if (mode != QLCNIC_ILB_MODE) {
751 dev_warn(&adapter->pdev->dev,
752 "WARNING: Please make sure external"
753 "loopback connector is plugged in\n");
754 }
755 return -1;
756 }
757 return 0;
758}
759
760static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
761{
762 struct qlcnic_adapter *adapter = netdev_priv(netdev);
763 int max_sds_rings = adapter->max_sds_rings;
764 struct qlcnic_host_sds_ring *sds_ring;
765 int loop = 0;
766 int ret;
767
768 if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK)) {
769 netdev_info(netdev, "Firmware is not loopback test capable\n");
770 return -EOPNOTSUPP;
771 }
772
773 QLCDB(adapter, DRV, "%s loopback test in progress\n",
774 mode == QLCNIC_ILB_MODE ? "internal" : "external");
775 if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
776 netdev_warn(netdev, "Loopback test not supported for non "
777 "privilege function\n");
778 return 0;
779 }
780
781 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
782 return -EBUSY;
783
784 ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
785 if (ret)
786 goto clear_it;
787
788 sds_ring = &adapter->recv_ctx->sds_rings[0];
789
790 ret = qlcnic_set_lb_mode(adapter, mode);
791 if (ret)
792 goto free_res;
793
794 adapter->diag_cnt = 0;
795 do {
796 msleep(500);
797 qlcnic_process_rcv_ring_diag(sds_ring);
798 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
799 netdev_info(netdev, "firmware didnt respond to loopback"
800 " configure request\n");
801 ret = -QLCNIC_FW_NOT_RESPOND;
802 goto free_res;
803 } else if (adapter->diag_cnt) {
804 ret = adapter->diag_cnt;
805 goto free_res;
806 }
807 } while (!QLCNIC_IS_LB_CONFIGURED(adapter->ahw->loopback_state));
808
809 ret = qlcnic_do_lb_test(adapter, mode);
810
811 qlcnic_clear_lb_mode(adapter);
812
813 free_res:
814 qlcnic_diag_free_res(netdev, max_sds_rings);
815
816 clear_it:
817 adapter->max_sds_rings = max_sds_rings;
818 clear_bit(__QLCNIC_RESETTING, &adapter->state);
819 return ret;
820}
821
822static void
823qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
824 u64 *data)
825{
826 memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
827
828 data[0] = qlcnic_reg_test(dev);
829 if (data[0])
830 eth_test->flags |= ETH_TEST_FL_FAILED;
831
832 data[1] = (u64) qlcnic_test_link(dev);
833 if (data[1])
834 eth_test->flags |= ETH_TEST_FL_FAILED;
835
836 if (eth_test->flags & ETH_TEST_FL_OFFLINE) {
837 data[2] = qlcnic_irq_test(dev);
838 if (data[2])
839 eth_test->flags |= ETH_TEST_FL_FAILED;
840
841 data[3] = qlcnic_loopback_test(dev, QLCNIC_ILB_MODE);
842 if (data[3])
843 eth_test->flags |= ETH_TEST_FL_FAILED;
844 if (eth_test->flags & ETH_TEST_FL_EXTERNAL_LB) {
845 data[4] = qlcnic_loopback_test(dev, QLCNIC_ELB_MODE);
846 if (data[4])
847 eth_test->flags |= ETH_TEST_FL_FAILED;
848 eth_test->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE;
849 }
850 }
851}
852
853static void
854qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data)
855{
856 struct qlcnic_adapter *adapter = netdev_priv(dev);
857 int index, i;
858
859 switch (stringset) {
860 case ETH_SS_TEST:
861 memcpy(data, *qlcnic_gstrings_test,
862 QLCNIC_TEST_LEN * ETH_GSTRING_LEN);
863 break;
864 case ETH_SS_STATS:
865 for (index = 0; index < QLCNIC_STATS_LEN; index++) {
866 memcpy(data + index * ETH_GSTRING_LEN,
867 qlcnic_gstrings_stats[index].stat_string,
868 ETH_GSTRING_LEN);
869 }
870 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
871 return;
872 for (i = 0; i < QLCNIC_DEVICE_STATS_LEN; index++, i++) {
873 memcpy(data + index * ETH_GSTRING_LEN,
874 qlcnic_device_gstrings_stats[i],
875 ETH_GSTRING_LEN);
876 }
877 }
878}
879
880#define QLCNIC_FILL_ESWITCH_STATS(VAL1) \
881 (((VAL1) == QLCNIC_ESW_STATS_NOT_AVAIL) ? 0 : VAL1)
882
883static void
884qlcnic_fill_device_stats(int *index, u64 *data,
885 struct __qlcnic_esw_statistics *stats)
886{
887 int ind = *index;
888
889 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->unicast_frames);
890 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->multicast_frames);
891 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->broadcast_frames);
892 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->dropped_frames);
893 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->errors);
894 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->local_frames);
895 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->numbytes);
896
897 *index = ind;
898}
899
900static void
901qlcnic_get_ethtool_stats(struct net_device *dev,
902 struct ethtool_stats *stats, u64 * data)
903{
904 struct qlcnic_adapter *adapter = netdev_priv(dev);
905 struct qlcnic_esw_statistics port_stats;
906 int index, ret;
907
908 for (index = 0; index < QLCNIC_STATS_LEN; index++) {
909 char *p =
910 (char *)adapter +
911 qlcnic_gstrings_stats[index].stat_offset;
912 data[index] =
913 (qlcnic_gstrings_stats[index].sizeof_stat ==
914 sizeof(u64)) ? *(u64 *)p:(*(u32 *)p);
915 }
916
917 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
918 return;
919
920 memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics));
921 ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
922 QLCNIC_QUERY_RX_COUNTER, &port_stats.rx);
923 if (ret)
924 return;
925
926 qlcnic_fill_device_stats(&index, data, &port_stats.rx);
927
928 ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
929 QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
930 if (ret)
931 return;
932
933 qlcnic_fill_device_stats(&index, data, &port_stats.tx);
934}
935
936static int qlcnic_set_led(struct net_device *dev,
937 enum ethtool_phys_id_state state)
938{
939 struct qlcnic_adapter *adapter = netdev_priv(dev);
940 int max_sds_rings = adapter->max_sds_rings;
941 int err = -EIO, active = 1;
942
943 if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
944 netdev_warn(dev, "LED test not supported for non "
945 "privilege function\n");
946 return -EOPNOTSUPP;
947 }
948
949 switch (state) {
950 case ETHTOOL_ID_ACTIVE:
951 if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
952 return -EBUSY;
953
954 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
955 break;
956
957 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
958 if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
959 break;
960 set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
961 }
962
963 if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) {
964 err = 0;
965 break;
966 }
967
968 dev_err(&adapter->pdev->dev,
969 "Failed to set LED blink state.\n");
970 break;
971
972 case ETHTOOL_ID_INACTIVE:
973 active = 0;
974
975 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
976 break;
977
978 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
979 if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
980 break;
981 set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
982 }
983
984 if (adapter->nic_ops->config_led(adapter, 0, 0xf))
985 dev_err(&adapter->pdev->dev,
986 "Failed to reset LED blink state.\n");
987
988 break;
989
990 default:
991 return -EINVAL;
992 }
993
994 if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
995 qlcnic_diag_free_res(dev, max_sds_rings);
996
997 if (!active || err)
998 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
999
1000 return err;
1001}
1002
1003static void
1004qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1005{
1006 struct qlcnic_adapter *adapter = netdev_priv(dev);
1007 u32 wol_cfg;
1008
1009 wol->supported = 0;
1010 wol->wolopts = 0;
1011
1012 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
1013 if (wol_cfg & (1UL << adapter->portnum))
1014 wol->supported |= WAKE_MAGIC;
1015
1016 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
1017 if (wol_cfg & (1UL << adapter->portnum))
1018 wol->wolopts |= WAKE_MAGIC;
1019}
1020
1021static int
1022qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1023{
1024 struct qlcnic_adapter *adapter = netdev_priv(dev);
1025 u32 wol_cfg;
1026
1027 if (wol->wolopts & ~WAKE_MAGIC)
1028 return -EOPNOTSUPP;
1029
1030 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
1031 if (!(wol_cfg & (1 << adapter->portnum)))
1032 return -EOPNOTSUPP;
1033
1034 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
1035 if (wol->wolopts & WAKE_MAGIC)
1036 wol_cfg |= 1UL << adapter->portnum;
1037 else
1038 wol_cfg &= ~(1UL << adapter->portnum);
1039
1040 QLCWR32(adapter, QLCNIC_WOL_CONFIG, wol_cfg);
1041
1042 return 0;
1043}
1044
1045
1046
1047
1048
1049
1050static int qlcnic_set_intr_coalesce(struct net_device *netdev,
1051 struct ethtool_coalesce *ethcoal)
1052{
1053 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1054
1055 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
1056 return -EINVAL;
1057
1058
1059
1060
1061
1062 if (ethcoal->rx_coalesce_usecs > 0xffff ||
1063 ethcoal->rx_max_coalesced_frames > 0xffff ||
1064 ethcoal->tx_coalesce_usecs ||
1065 ethcoal->tx_max_coalesced_frames ||
1066 ethcoal->rx_coalesce_usecs_irq ||
1067 ethcoal->rx_max_coalesced_frames_irq ||
1068 ethcoal->tx_coalesce_usecs_irq ||
1069 ethcoal->tx_max_coalesced_frames_irq ||
1070 ethcoal->stats_block_coalesce_usecs ||
1071 ethcoal->use_adaptive_rx_coalesce ||
1072 ethcoal->use_adaptive_tx_coalesce ||
1073 ethcoal->pkt_rate_low ||
1074 ethcoal->rx_coalesce_usecs_low ||
1075 ethcoal->rx_max_coalesced_frames_low ||
1076 ethcoal->tx_coalesce_usecs_low ||
1077 ethcoal->tx_max_coalesced_frames_low ||
1078 ethcoal->pkt_rate_high ||
1079 ethcoal->rx_coalesce_usecs_high ||
1080 ethcoal->rx_max_coalesced_frames_high ||
1081 ethcoal->tx_coalesce_usecs_high ||
1082 ethcoal->tx_max_coalesced_frames_high)
1083 return -EINVAL;
1084
1085 if (!ethcoal->rx_coalesce_usecs ||
1086 !ethcoal->rx_max_coalesced_frames) {
1087 adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT;
1088 adapter->ahw->coal.rx_time_us =
1089 QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
1090 adapter->ahw->coal.rx_packets =
1091 QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS;
1092 } else {
1093 adapter->ahw->coal.flag = 0;
1094 adapter->ahw->coal.rx_time_us = ethcoal->rx_coalesce_usecs;
1095 adapter->ahw->coal.rx_packets =
1096 ethcoal->rx_max_coalesced_frames;
1097 }
1098
1099 qlcnic_config_intr_coalesce(adapter);
1100
1101 return 0;
1102}
1103
1104static int qlcnic_get_intr_coalesce(struct net_device *netdev,
1105 struct ethtool_coalesce *ethcoal)
1106{
1107 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1108
1109 if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
1110 return -EINVAL;
1111
1112 ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us;
1113 ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets;
1114
1115 return 0;
1116}
1117
1118static u32 qlcnic_get_msglevel(struct net_device *netdev)
1119{
1120 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1121
1122 return adapter->msg_enable;
1123}
1124
1125static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
1126{
1127 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1128
1129 adapter->msg_enable = msglvl;
1130}
1131
1132static int
1133qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
1134{
1135 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1136 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1137
1138 if (fw_dump->clr)
1139 dump->len = fw_dump->tmpl_hdr->size + fw_dump->size;
1140 else
1141 dump->len = 0;
1142 dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
1143 dump->version = adapter->fw_version;
1144 return 0;
1145}
1146
1147static int
1148qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
1149 void *buffer)
1150{
1151 int i, copy_sz;
1152 u32 *hdr_ptr, *data;
1153 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1154 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1155
1156 if (!fw_dump->clr) {
1157 netdev_info(netdev, "Dump not available\n");
1158 qlcnic_api_unlock(adapter);
1159 return -EINVAL;
1160 }
1161
1162 copy_sz = fw_dump->tmpl_hdr->size;
1163 hdr_ptr = (u32 *) fw_dump->tmpl_hdr;
1164 data = buffer;
1165 for (i = 0; i < copy_sz/sizeof(u32); i++)
1166 *data++ = cpu_to_le32(*hdr_ptr++);
1167
1168
1169 memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size);
1170 dump->len = copy_sz + fw_dump->size;
1171 dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
1172
1173
1174 vfree(fw_dump->data);
1175 fw_dump->data = NULL;
1176 fw_dump->clr = 0;
1177
1178 return 0;
1179}
1180
1181static int
1182qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
1183{
1184 int ret = 0;
1185 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1186 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1187
1188 switch (val->flag) {
1189 case QLCNIC_FORCE_FW_DUMP_KEY:
1190 if (!fw_dump->enable) {
1191 netdev_info(netdev, "FW dump not enabled\n");
1192 return ret;
1193 }
1194 if (fw_dump->clr) {
1195 dev_info(&adapter->pdev->dev,
1196 "Previous dump not cleared, not forcing dump\n");
1197 return ret;
1198 }
1199 netdev_info(netdev, "Forcing a FW dump\n");
1200 qlcnic_dev_request_reset(adapter);
1201 break;
1202 case QLCNIC_DISABLE_FW_DUMP:
1203 if (fw_dump->enable) {
1204 netdev_info(netdev, "Disabling FW dump\n");
1205 fw_dump->enable = 0;
1206 }
1207 break;
1208 case QLCNIC_ENABLE_FW_DUMP:
1209 if (!fw_dump->enable && fw_dump->tmpl_hdr) {
1210 netdev_info(netdev, "Enabling FW dump\n");
1211 fw_dump->enable = 1;
1212 }
1213 break;
1214 case QLCNIC_FORCE_FW_RESET:
1215 netdev_info(netdev, "Forcing a FW reset\n");
1216 qlcnic_dev_request_reset(adapter);
1217 adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
1218 break;
1219 default:
1220 if (val->flag > QLCNIC_DUMP_MASK_MAX ||
1221 val->flag < QLCNIC_DUMP_MASK_MIN) {
1222 netdev_info(netdev,
1223 "Invalid dump level: 0x%x\n", val->flag);
1224 ret = -EINVAL;
1225 goto out;
1226 }
1227 fw_dump->tmpl_hdr->drv_cap_mask = val->flag & 0xff;
1228 netdev_info(netdev, "Driver mask changed to: 0x%x\n",
1229 fw_dump->tmpl_hdr->drv_cap_mask);
1230 }
1231out:
1232 return ret;
1233}
1234
1235const struct ethtool_ops qlcnic_ethtool_ops = {
1236 .get_settings = qlcnic_get_settings,
1237 .set_settings = qlcnic_set_settings,
1238 .get_drvinfo = qlcnic_get_drvinfo,
1239 .get_regs_len = qlcnic_get_regs_len,
1240 .get_regs = qlcnic_get_regs,
1241 .get_link = ethtool_op_get_link,
1242 .get_eeprom_len = qlcnic_get_eeprom_len,
1243 .get_eeprom = qlcnic_get_eeprom,
1244 .get_ringparam = qlcnic_get_ringparam,
1245 .set_ringparam = qlcnic_set_ringparam,
1246 .get_channels = qlcnic_get_channels,
1247 .set_channels = qlcnic_set_channels,
1248 .get_pauseparam = qlcnic_get_pauseparam,
1249 .set_pauseparam = qlcnic_set_pauseparam,
1250 .get_wol = qlcnic_get_wol,
1251 .set_wol = qlcnic_set_wol,
1252 .self_test = qlcnic_diag_test,
1253 .get_strings = qlcnic_get_strings,
1254 .get_ethtool_stats = qlcnic_get_ethtool_stats,
1255 .get_sset_count = qlcnic_get_sset_count,
1256 .get_coalesce = qlcnic_get_intr_coalesce,
1257 .set_coalesce = qlcnic_set_intr_coalesce,
1258 .set_phys_id = qlcnic_set_led,
1259 .set_msglevel = qlcnic_set_msglevel,
1260 .get_msglevel = qlcnic_get_msglevel,
1261 .get_dump_flag = qlcnic_get_dump_flag,
1262 .get_dump_data = qlcnic_get_dump_data,
1263 .set_dump = qlcnic_set_dump,
1264};
1265