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