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