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