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