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