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