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