]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
5f2ad819a5174dd87efa91b7b7e845a91408a0fd
[karo-tx-linux.git] / drivers / net / ethernet / qlogic / qlcnic / qlcnic_ethtool.c
1 /*
2  * QLogic qlcnic NIC Driver
3  * Copyright (c)  2009-2010 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
26 static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
27         {"xmit_called",
28                 QLC_SIZEOF(stats.xmitcalled), QLC_OFF(stats.xmitcalled)},
29         {"xmit_finished",
30                 QLC_SIZEOF(stats.xmitfinished), QLC_OFF(stats.xmitfinished)},
31         {"rx_dropped",
32                 QLC_SIZEOF(stats.rxdropped), QLC_OFF(stats.rxdropped)},
33         {"tx_dropped",
34                 QLC_SIZEOF(stats.txdropped), QLC_OFF(stats.txdropped)},
35         {"csummed",
36                 QLC_SIZEOF(stats.csummed), QLC_OFF(stats.csummed)},
37         {"rx_pkts",
38                 QLC_SIZEOF(stats.rx_pkts), QLC_OFF(stats.rx_pkts)},
39         {"lro_pkts",
40                 QLC_SIZEOF(stats.lro_pkts), QLC_OFF(stats.lro_pkts)},
41         {"rx_bytes",
42                 QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)},
43         {"tx_bytes",
44                 QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)},
45         {"lrobytes",
46                 QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)},
47         {"lso_frames",
48                 QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)},
49         {"xmit_on",
50                 QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)},
51         {"xmit_off",
52                 QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)},
53         {"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
54                 QLC_OFF(stats.skb_alloc_failure)},
55         {"null rxbuf",
56                 QLC_SIZEOF(stats.null_rxbuf), QLC_OFF(stats.null_rxbuf)},
57         {"rx dma map error", QLC_SIZEOF(stats.rx_dma_map_error),
58                                          QLC_OFF(stats.rx_dma_map_error)},
59         {"tx dma map error", QLC_SIZEOF(stats.tx_dma_map_error),
60                                          QLC_OFF(stats.tx_dma_map_error)},
61
62 };
63
64 static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
65         "rx unicast frames",
66         "rx multicast frames",
67         "rx broadcast frames",
68         "rx dropped frames",
69         "rx errors",
70         "rx local frames",
71         "rx numbytes",
72         "tx unicast frames",
73         "tx multicast frames",
74         "tx broadcast frames",
75         "tx dropped frames",
76         "tx errors",
77         "tx local frames",
78         "tx numbytes",
79 };
80
81 static const char qlcnic_mac_stats_strings [][ETH_GSTRING_LEN] = {
82         "mac_tx_frames",
83         "mac_tx_bytes",
84         "mac_tx_mcast_pkts",
85         "mac_tx_bcast_pkts",
86         "mac_tx_pause_cnt",
87         "mac_tx_ctrl_pkt",
88         "mac_tx_lt_64b_pkts",
89         "mac_tx_lt_127b_pkts",
90         "mac_tx_lt_255b_pkts",
91         "mac_tx_lt_511b_pkts",
92         "mac_tx_lt_1023b_pkts",
93         "mac_tx_lt_1518b_pkts",
94         "mac_tx_gt_1518b_pkts",
95         "mac_rx_frames",
96         "mac_rx_bytes",
97         "mac_rx_mcast_pkts",
98         "mac_rx_bcast_pkts",
99         "mac_rx_pause_cnt",
100         "mac_rx_ctrl_pkt",
101         "mac_rx_lt_64b_pkts",
102         "mac_rx_lt_127b_pkts",
103         "mac_rx_lt_255b_pkts",
104         "mac_rx_lt_511b_pkts",
105         "mac_rx_lt_1023b_pkts",
106         "mac_rx_lt_1518b_pkts",
107         "mac_rx_gt_1518b_pkts",
108         "mac_rx_length_error",
109         "mac_rx_length_small",
110         "mac_rx_length_large",
111         "mac_rx_jabber",
112         "mac_rx_dropped",
113         "mac_rx_crc_error",
114         "mac_align_error",
115 };
116
117 #define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats)
118 #define QLCNIC_MAC_STATS_LEN ARRAY_SIZE(qlcnic_mac_stats_strings)
119 #define QLCNIC_DEVICE_STATS_LEN ARRAY_SIZE(qlcnic_device_gstrings_stats)
120 #define QLCNIC_TOTAL_STATS_LEN QLCNIC_STATS_LEN + QLCNIC_MAC_STATS_LEN
121
122 static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
123         "Register_Test_on_offline",
124         "Link_Test_on_offline",
125         "Interrupt_Test_offline",
126         "Internal_Loopback_offline",
127         "External_Loopback_offline"
128 };
129
130 #define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test)
131
132 #define QLCNIC_RING_REGS_COUNT  20
133 #define QLCNIC_RING_REGS_LEN    (QLCNIC_RING_REGS_COUNT * sizeof(u32))
134 #define QLCNIC_MAX_EEPROM_LEN   1024
135
136 static const u32 diag_registers[] = {
137         CRB_CMDPEG_STATE,
138         CRB_RCVPEG_STATE,
139         CRB_XG_STATE_P3P,
140         CRB_FW_CAPABILITIES_1,
141         ISR_INT_STATE_REG,
142         QLCNIC_CRB_DRV_ACTIVE,
143         QLCNIC_CRB_DEV_STATE,
144         QLCNIC_CRB_DRV_STATE,
145         QLCNIC_CRB_DRV_SCRATCH,
146         QLCNIC_CRB_DEV_PARTITION_INFO,
147         QLCNIC_CRB_DRV_IDC_VER,
148         QLCNIC_PEG_ALIVE_COUNTER,
149         QLCNIC_PEG_HALT_STATUS1,
150         QLCNIC_PEG_HALT_STATUS2,
151         QLCNIC_CRB_PEG_NET_0+0x3c,
152         QLCNIC_CRB_PEG_NET_1+0x3c,
153         QLCNIC_CRB_PEG_NET_2+0x3c,
154         QLCNIC_CRB_PEG_NET_4+0x3c,
155         -1
156 };
157
158 #define QLCNIC_MGMT_API_VERSION 2
159 #define QLCNIC_DEV_INFO_SIZE    1
160 #define QLCNIC_ETHTOOL_REGS_VER 2
161 static int qlcnic_get_regs_len(struct net_device *dev)
162 {
163         return sizeof(diag_registers) + QLCNIC_RING_REGS_LEN +
164                                 QLCNIC_DEV_INFO_SIZE + 1;
165 }
166
167 static int qlcnic_get_eeprom_len(struct net_device *dev)
168 {
169         return QLCNIC_FLASH_TOTAL_SIZE;
170 }
171
172 static void
173 qlcnic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
174 {
175         struct qlcnic_adapter *adapter = netdev_priv(dev);
176         u32 fw_major, fw_minor, fw_build;
177
178         fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR);
179         fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR);
180         fw_build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB);
181         snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
182                 "%d.%d.%d", fw_major, fw_minor, fw_build);
183
184         strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
185                 sizeof(drvinfo->bus_info));
186         strlcpy(drvinfo->driver, qlcnic_driver_name, sizeof(drvinfo->driver));
187         strlcpy(drvinfo->version, QLCNIC_LINUX_VERSIONID,
188                 sizeof(drvinfo->version));
189 }
190
191 static int
192 qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
193 {
194         struct qlcnic_adapter *adapter = netdev_priv(dev);
195         int check_sfp_module = 0;
196
197         /* read which mode */
198         if (adapter->ahw->port_type == QLCNIC_GBE) {
199                 ecmd->supported = (SUPPORTED_10baseT_Half |
200                                    SUPPORTED_10baseT_Full |
201                                    SUPPORTED_100baseT_Half |
202                                    SUPPORTED_100baseT_Full |
203                                    SUPPORTED_1000baseT_Half |
204                                    SUPPORTED_1000baseT_Full);
205
206                 ecmd->advertising = (ADVERTISED_100baseT_Half |
207                                      ADVERTISED_100baseT_Full |
208                                      ADVERTISED_1000baseT_Half |
209                                      ADVERTISED_1000baseT_Full);
210
211                 ethtool_cmd_speed_set(ecmd, adapter->link_speed);
212                 ecmd->duplex = adapter->link_duplex;
213                 ecmd->autoneg = adapter->link_autoneg;
214
215         } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
216                 u32 val;
217
218                 val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
219                 if (val == QLCNIC_PORT_MODE_802_3_AP) {
220                         ecmd->supported = SUPPORTED_1000baseT_Full;
221                         ecmd->advertising = ADVERTISED_1000baseT_Full;
222                 } else {
223                         ecmd->supported = SUPPORTED_10000baseT_Full;
224                         ecmd->advertising = ADVERTISED_10000baseT_Full;
225                 }
226
227                 if (netif_running(dev) && adapter->has_link_events) {
228                         ethtool_cmd_speed_set(ecmd, adapter->link_speed);
229                         ecmd->autoneg = adapter->link_autoneg;
230                         ecmd->duplex = adapter->link_duplex;
231                         goto skip;
232                 }
233
234                 ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
235                 ecmd->duplex = DUPLEX_UNKNOWN;
236                 ecmd->autoneg = AUTONEG_DISABLE;
237         } else
238                 return -EIO;
239
240 skip:
241         ecmd->phy_address = adapter->physical_port;
242         ecmd->transceiver = XCVR_EXTERNAL;
243
244         switch (adapter->ahw->board_type) {
245         case QLCNIC_BRDTYPE_P3P_REF_QG:
246         case QLCNIC_BRDTYPE_P3P_4_GB:
247         case QLCNIC_BRDTYPE_P3P_4_GB_MM:
248
249                 ecmd->supported |= SUPPORTED_Autoneg;
250                 ecmd->advertising |= ADVERTISED_Autoneg;
251         case QLCNIC_BRDTYPE_P3P_10G_CX4:
252         case QLCNIC_BRDTYPE_P3P_10G_CX4_LP:
253         case QLCNIC_BRDTYPE_P3P_10000_BASE_T:
254                 ecmd->supported |= SUPPORTED_TP;
255                 ecmd->advertising |= ADVERTISED_TP;
256                 ecmd->port = PORT_TP;
257                 ecmd->autoneg =  adapter->link_autoneg;
258                 break;
259         case QLCNIC_BRDTYPE_P3P_IMEZ:
260         case QLCNIC_BRDTYPE_P3P_XG_LOM:
261         case QLCNIC_BRDTYPE_P3P_HMEZ:
262                 ecmd->supported |= SUPPORTED_MII;
263                 ecmd->advertising |= ADVERTISED_MII;
264                 ecmd->port = PORT_MII;
265                 ecmd->autoneg = AUTONEG_DISABLE;
266                 break;
267         case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS:
268         case QLCNIC_BRDTYPE_P3P_10G_SFP_CT:
269         case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
270                 ecmd->advertising |= ADVERTISED_TP;
271                 ecmd->supported |= SUPPORTED_TP;
272                 check_sfp_module = netif_running(dev) &&
273                         adapter->has_link_events;
274         case QLCNIC_BRDTYPE_P3P_10G_XFP:
275                 ecmd->supported |= SUPPORTED_FIBRE;
276                 ecmd->advertising |= ADVERTISED_FIBRE;
277                 ecmd->port = PORT_FIBRE;
278                 ecmd->autoneg = AUTONEG_DISABLE;
279                 break;
280         case QLCNIC_BRDTYPE_P3P_10G_TP:
281                 if (adapter->ahw->port_type == QLCNIC_XGBE) {
282                         ecmd->autoneg = AUTONEG_DISABLE;
283                         ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
284                         ecmd->advertising |=
285                                 (ADVERTISED_FIBRE | ADVERTISED_TP);
286                         ecmd->port = PORT_FIBRE;
287                         check_sfp_module = netif_running(dev) &&
288                                 adapter->has_link_events;
289                 } else {
290                         ecmd->autoneg = AUTONEG_ENABLE;
291                         ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
292                         ecmd->advertising |=
293                                 (ADVERTISED_TP | ADVERTISED_Autoneg);
294                         ecmd->port = PORT_TP;
295                 }
296                 break;
297         default:
298                 dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
299                         adapter->ahw->board_type);
300                 return -EIO;
301         }
302
303         if (check_sfp_module) {
304                 switch (adapter->module_type) {
305                 case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
306                 case LINKEVENT_MODULE_OPTICAL_SRLR:
307                 case LINKEVENT_MODULE_OPTICAL_LRM:
308                 case LINKEVENT_MODULE_OPTICAL_SFP_1G:
309                         ecmd->port = PORT_FIBRE;
310                         break;
311                 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
312                 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
313                 case LINKEVENT_MODULE_TWINAX:
314                         ecmd->port = PORT_TP;
315                         break;
316                 default:
317                         ecmd->port = PORT_OTHER;
318                 }
319         }
320
321         return 0;
322 }
323
324 static int
325 qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
326 {
327         u32 config = 0;
328         u32 ret = 0;
329         struct qlcnic_adapter *adapter = netdev_priv(dev);
330
331         if (adapter->ahw->port_type != QLCNIC_GBE)
332                 return -EOPNOTSUPP;
333
334         /* read which mode */
335         if (ecmd->duplex)
336                 config |= 0x1;
337
338         if (ecmd->autoneg)
339                 config |= 0x2;
340
341         switch (ethtool_cmd_speed(ecmd)) {
342         case SPEED_10:
343                 config |= (0 << 8);
344                 break;
345         case SPEED_100:
346                 config |= (1 << 8);
347                 break;
348         case SPEED_1000:
349                 config |= (10 << 8);
350                 break;
351         default:
352                 return -EIO;
353         }
354
355         ret = qlcnic_fw_cmd_set_port(adapter, config);
356
357         if (ret == QLCNIC_RCODE_NOT_SUPPORTED)
358                 return -EOPNOTSUPP;
359         else if (ret)
360                 return -EIO;
361
362         adapter->link_speed = ethtool_cmd_speed(ecmd);
363         adapter->link_duplex = ecmd->duplex;
364         adapter->link_autoneg = ecmd->autoneg;
365
366         if (!netif_running(dev))
367                 return 0;
368
369         dev->netdev_ops->ndo_stop(dev);
370         return dev->netdev_ops->ndo_open(dev);
371 }
372
373 static void
374 qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
375 {
376         struct qlcnic_adapter *adapter = netdev_priv(dev);
377         struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
378         struct qlcnic_host_sds_ring *sds_ring;
379         u32 *regs_buff = p;
380         int ring, i = 0, j = 0;
381
382         memset(p, 0, qlcnic_get_regs_len(dev));
383         regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
384                 (adapter->ahw->revision_id << 16) | (adapter->pdev)->device;
385
386         regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
387         regs_buff[1] = QLCNIC_MGMT_API_VERSION;
388
389         for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++)
390                 regs_buff[i] = QLCRD32(adapter, diag_registers[j]);
391
392         if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
393                 return;
394
395         regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/
396
397         regs_buff[i++] = 1; /* No. of tx ring */
398         regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
399         regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer);
400
401         regs_buff[i++] = 2; /* No. of rx ring */
402         regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer);
403         regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer);
404
405         regs_buff[i++] = adapter->max_sds_rings;
406
407         for (ring = 0; ring < adapter->max_sds_rings; ring++) {
408                 sds_ring = &(recv_ctx->sds_rings[ring]);
409                 regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
410         }
411 }
412
413 static u32 qlcnic_test_link(struct net_device *dev)
414 {
415         struct qlcnic_adapter *adapter = netdev_priv(dev);
416         u32 val;
417
418         val = QLCRD32(adapter, CRB_XG_STATE_P3P);
419         val = XG_LINK_STATE_P3P(adapter->ahw->pci_func, val);
420         return (val == XG_LINK_UP_P3P) ? 0 : 1;
421 }
422
423 static int
424 qlcnic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
425                       u8 *bytes)
426 {
427         struct qlcnic_adapter *adapter = netdev_priv(dev);
428         int offset;
429         int ret;
430
431         if (eeprom->len == 0)
432                 return -EINVAL;
433
434         eeprom->magic = (adapter->pdev)->vendor |
435                         ((adapter->pdev)->device << 16);
436         offset = eeprom->offset;
437
438         ret = qlcnic_rom_fast_read_words(adapter, offset, bytes,
439                                                 eeprom->len);
440         if (ret < 0)
441                 return ret;
442
443         return 0;
444 }
445
446 static void
447 qlcnic_get_ringparam(struct net_device *dev,
448                 struct ethtool_ringparam *ring)
449 {
450         struct qlcnic_adapter *adapter = netdev_priv(dev);
451
452         ring->rx_pending = adapter->num_rxd;
453         ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
454         ring->tx_pending = adapter->num_txd;
455
456         ring->rx_max_pending = adapter->max_rxd;
457         ring->rx_jumbo_max_pending = adapter->max_jumbo_rxd;
458         ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
459 }
460
461 static u32
462 qlcnic_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
463 {
464         u32 num_desc;
465         num_desc = max(val, min);
466         num_desc = min(num_desc, max);
467         num_desc = roundup_pow_of_two(num_desc);
468
469         if (val != num_desc) {
470                 printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
471                        qlcnic_driver_name, r_name, num_desc, val);
472         }
473
474         return num_desc;
475 }
476
477 static int
478 qlcnic_set_ringparam(struct net_device *dev,
479                 struct ethtool_ringparam *ring)
480 {
481         struct qlcnic_adapter *adapter = netdev_priv(dev);
482         u16 num_rxd, num_jumbo_rxd, num_txd;
483
484         if (ring->rx_mini_pending)
485                 return -EOPNOTSUPP;
486
487         num_rxd = qlcnic_validate_ringparam(ring->rx_pending,
488                         MIN_RCV_DESCRIPTORS, adapter->max_rxd, "rx");
489
490         num_jumbo_rxd = qlcnic_validate_ringparam(ring->rx_jumbo_pending,
491                         MIN_JUMBO_DESCRIPTORS, adapter->max_jumbo_rxd,
492                                                 "rx jumbo");
493
494         num_txd = qlcnic_validate_ringparam(ring->tx_pending,
495                         MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
496
497         if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
498                         num_jumbo_rxd == adapter->num_jumbo_rxd)
499                 return 0;
500
501         adapter->num_rxd = num_rxd;
502         adapter->num_jumbo_rxd = num_jumbo_rxd;
503         adapter->num_txd = num_txd;
504
505         return qlcnic_reset_context(adapter);
506 }
507
508 static void qlcnic_get_channels(struct net_device *dev,
509                 struct ethtool_channels *channel)
510 {
511         struct qlcnic_adapter *adapter = netdev_priv(dev);
512
513         channel->max_rx = rounddown_pow_of_two(min_t(int,
514                         adapter->max_rx_ques, num_online_cpus()));
515         channel->max_tx = adapter->max_tx_ques;
516
517         channel->rx_count = adapter->max_sds_rings;
518         channel->tx_count = adapter->max_tx_ques;
519 }
520
521 static int qlcnic_set_channels(struct net_device *dev,
522                 struct ethtool_channels *channel)
523 {
524         struct qlcnic_adapter *adapter = netdev_priv(dev);
525         int err;
526
527         if (channel->other_count || channel->combined_count ||
528             channel->tx_count != channel->max_tx)
529                 return -EINVAL;
530
531         err = qlcnic_validate_max_rss(dev, channel->max_rx, channel->rx_count);
532         if (err)
533                 return err;
534
535         err = qlcnic_set_max_rss(adapter, channel->rx_count);
536         netdev_info(dev, "allocated 0x%x sds rings\n",
537                                  adapter->max_sds_rings);
538         return err;
539 }
540
541 static void
542 qlcnic_get_pauseparam(struct net_device *netdev,
543                           struct ethtool_pauseparam *pause)
544 {
545         struct qlcnic_adapter *adapter = netdev_priv(netdev);
546         int port = adapter->physical_port;
547         __u32 val;
548
549         if (adapter->ahw->port_type == QLCNIC_GBE) {
550                 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
551                         return;
552                 /* get flow control settings */
553                 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
554                 pause->rx_pause = qlcnic_gb_get_rx_flowctl(val);
555                 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
556                 switch (port) {
557                 case 0:
558                         pause->tx_pause = !(qlcnic_gb_get_gb0_mask(val));
559                         break;
560                 case 1:
561                         pause->tx_pause = !(qlcnic_gb_get_gb1_mask(val));
562                         break;
563                 case 2:
564                         pause->tx_pause = !(qlcnic_gb_get_gb2_mask(val));
565                         break;
566                 case 3:
567                 default:
568                         pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val));
569                         break;
570                 }
571         } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
572                 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
573                         return;
574                 pause->rx_pause = 1;
575                 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
576                 if (port == 0)
577                         pause->tx_pause = !(qlcnic_xg_get_xg0_mask(val));
578                 else
579                         pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val));
580         } else {
581                 dev_err(&netdev->dev, "Unknown board type: %x\n",
582                                         adapter->ahw->port_type);
583         }
584 }
585
586 static int
587 qlcnic_set_pauseparam(struct net_device *netdev,
588                           struct ethtool_pauseparam *pause)
589 {
590         struct qlcnic_adapter *adapter = netdev_priv(netdev);
591         int port = adapter->physical_port;
592         __u32 val;
593
594         /* read mode */
595         if (adapter->ahw->port_type == QLCNIC_GBE) {
596                 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
597                         return -EIO;
598                 /* set flow control */
599                 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
600
601                 if (pause->rx_pause)
602                         qlcnic_gb_rx_flowctl(val);
603                 else
604                         qlcnic_gb_unset_rx_flowctl(val);
605
606                 QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port),
607                                 val);
608                 /* set autoneg */
609                 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
610                 switch (port) {
611                 case 0:
612                         if (pause->tx_pause)
613                                 qlcnic_gb_unset_gb0_mask(val);
614                         else
615                                 qlcnic_gb_set_gb0_mask(val);
616                         break;
617                 case 1:
618                         if (pause->tx_pause)
619                                 qlcnic_gb_unset_gb1_mask(val);
620                         else
621                                 qlcnic_gb_set_gb1_mask(val);
622                         break;
623                 case 2:
624                         if (pause->tx_pause)
625                                 qlcnic_gb_unset_gb2_mask(val);
626                         else
627                                 qlcnic_gb_set_gb2_mask(val);
628                         break;
629                 case 3:
630                 default:
631                         if (pause->tx_pause)
632                                 qlcnic_gb_unset_gb3_mask(val);
633                         else
634                                 qlcnic_gb_set_gb3_mask(val);
635                         break;
636                 }
637                 QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val);
638         } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
639                 if (!pause->rx_pause || pause->autoneg)
640                         return -EOPNOTSUPP;
641
642                 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
643                         return -EIO;
644
645                 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
646                 if (port == 0) {
647                         if (pause->tx_pause)
648                                 qlcnic_xg_unset_xg0_mask(val);
649                         else
650                                 qlcnic_xg_set_xg0_mask(val);
651                 } else {
652                         if (pause->tx_pause)
653                                 qlcnic_xg_unset_xg1_mask(val);
654                         else
655                                 qlcnic_xg_set_xg1_mask(val);
656                 }
657                 QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val);
658         } else {
659                 dev_err(&netdev->dev, "Unknown board type: %x\n",
660                                 adapter->ahw->port_type);
661         }
662         return 0;
663 }
664
665 static int qlcnic_reg_test(struct net_device *dev)
666 {
667         struct qlcnic_adapter *adapter = netdev_priv(dev);
668         u32 data_read;
669
670         data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0));
671         if ((data_read & 0xffff) != adapter->pdev->vendor)
672                 return 1;
673
674         return 0;
675 }
676
677 static int qlcnic_get_sset_count(struct net_device *dev, int sset)
678 {
679         struct qlcnic_adapter *adapter = netdev_priv(dev);
680         switch (sset) {
681         case ETH_SS_TEST:
682                 return QLCNIC_TEST_LEN;
683         case ETH_SS_STATS:
684                 if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
685                         return QLCNIC_TOTAL_STATS_LEN + QLCNIC_DEVICE_STATS_LEN;
686                 return QLCNIC_TOTAL_STATS_LEN;
687         default:
688                 return -EOPNOTSUPP;
689         }
690 }
691
692 static int qlcnic_irq_test(struct net_device *netdev)
693 {
694         struct qlcnic_adapter *adapter = netdev_priv(netdev);
695         int max_sds_rings = adapter->max_sds_rings;
696         int ret;
697         struct qlcnic_cmd_args cmd;
698
699         if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
700                 return -EIO;
701
702         ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST);
703         if (ret)
704                 goto clear_it;
705
706         adapter->diag_cnt = 0;
707         memset(&cmd, 0, sizeof(cmd));
708         cmd.req.cmd = QLCNIC_CDRP_CMD_INTRPT_TEST;
709         cmd.req.arg1 = adapter->ahw->pci_func;
710         qlcnic_issue_cmd(adapter, &cmd);
711         ret = cmd.rsp.cmd;
712
713         if (ret)
714                 goto done;
715
716         msleep(10);
717
718         ret = !adapter->diag_cnt;
719
720 done:
721         qlcnic_diag_free_res(netdev, max_sds_rings);
722
723 clear_it:
724         adapter->max_sds_rings = max_sds_rings;
725         clear_bit(__QLCNIC_RESETTING, &adapter->state);
726         return ret;
727 }
728
729 #define QLCNIC_ILB_PKT_SIZE 64
730 #define QLCNIC_NUM_ILB_PKT      16
731 #define QLCNIC_ILB_MAX_RCV_LOOP 10
732
733 static void qlcnic_create_loopback_buff(unsigned char *data, u8 mac[])
734 {
735         unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00};
736
737         memset(data, 0x4e, QLCNIC_ILB_PKT_SIZE);
738
739         memcpy(data, mac, ETH_ALEN);
740         memcpy(data + ETH_ALEN, mac, ETH_ALEN);
741
742         memcpy(data + 2 * ETH_ALEN, random_data, sizeof(random_data));
743 }
744
745 int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[])
746 {
747         unsigned char buff[QLCNIC_ILB_PKT_SIZE];
748         qlcnic_create_loopback_buff(buff, mac);
749         return memcmp(data, buff, QLCNIC_ILB_PKT_SIZE);
750 }
751
752 static int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
753 {
754         struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
755         struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0];
756         struct sk_buff *skb;
757         int i, loop, cnt = 0;
758
759         for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) {
760                 skb = netdev_alloc_skb(adapter->netdev, QLCNIC_ILB_PKT_SIZE);
761                 qlcnic_create_loopback_buff(skb->data, adapter->mac_addr);
762                 skb_put(skb, QLCNIC_ILB_PKT_SIZE);
763
764                 adapter->diag_cnt = 0;
765                 qlcnic_xmit_frame(skb, adapter->netdev);
766
767                 loop = 0;
768                 do {
769                         msleep(1);
770                         qlcnic_process_rcv_ring_diag(sds_ring);
771                         if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP)
772                                 break;
773                 } while (!adapter->diag_cnt);
774
775                 dev_kfree_skb_any(skb);
776
777                 if (!adapter->diag_cnt)
778                         QLCDB(adapter, DRV,
779                         "LB Test: packet #%d was not received\n", i + 1);
780                 else
781                         cnt++;
782         }
783         if (cnt != i) {
784                 dev_warn(&adapter->pdev->dev, "LB Test failed\n");
785                 if (mode != QLCNIC_ILB_MODE) {
786                         dev_warn(&adapter->pdev->dev,
787                                 "WARNING: Please make sure external"
788                                 "loopback connector is plugged in\n");
789                 }
790                 return -1;
791         }
792         return 0;
793 }
794
795 static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
796 {
797         struct qlcnic_adapter *adapter = netdev_priv(netdev);
798         int max_sds_rings = adapter->max_sds_rings;
799         struct qlcnic_host_sds_ring *sds_ring;
800         int loop = 0;
801         int ret;
802
803         if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK)) {
804                 netdev_info(netdev, "Firmware is not loopback test capable\n");
805                 return -EOPNOTSUPP;
806         }
807
808         QLCDB(adapter, DRV, "%s loopback test in progress\n",
809                    mode == QLCNIC_ILB_MODE ? "internal" : "external");
810         if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
811                 netdev_warn(netdev, "Loopback test not supported for non "
812                                 "privilege function\n");
813                 return 0;
814         }
815
816         if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
817                 return -EBUSY;
818
819         ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
820         if (ret)
821                 goto clear_it;
822
823         sds_ring = &adapter->recv_ctx->sds_rings[0];
824
825         ret = qlcnic_set_lb_mode(adapter, mode);
826         if (ret)
827                 goto free_res;
828
829         adapter->diag_cnt = 0;
830         do {
831                 msleep(500);
832                 qlcnic_process_rcv_ring_diag(sds_ring);
833                 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
834                         netdev_info(netdev, "firmware didnt respond to loopback"
835                                 " configure request\n");
836                         ret = -QLCNIC_FW_NOT_RESPOND;
837                         goto free_res;
838                 } else if (adapter->diag_cnt) {
839                         ret = adapter->diag_cnt;
840                         goto free_res;
841                 }
842         } while (!QLCNIC_IS_LB_CONFIGURED(adapter->ahw->loopback_state));
843
844         ret = qlcnic_do_lb_test(adapter, mode);
845
846         qlcnic_clear_lb_mode(adapter);
847
848  free_res:
849         qlcnic_diag_free_res(netdev, max_sds_rings);
850
851  clear_it:
852         adapter->max_sds_rings = max_sds_rings;
853         clear_bit(__QLCNIC_RESETTING, &adapter->state);
854         return ret;
855 }
856
857 static void
858 qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
859                      u64 *data)
860 {
861         memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
862
863         data[0] = qlcnic_reg_test(dev);
864         if (data[0])
865                 eth_test->flags |= ETH_TEST_FL_FAILED;
866
867         data[1] = (u64) qlcnic_test_link(dev);
868         if (data[1])
869                 eth_test->flags |= ETH_TEST_FL_FAILED;
870
871         if (eth_test->flags & ETH_TEST_FL_OFFLINE) {
872                 data[2] = qlcnic_irq_test(dev);
873                 if (data[2])
874                         eth_test->flags |= ETH_TEST_FL_FAILED;
875
876                 data[3] = qlcnic_loopback_test(dev, QLCNIC_ILB_MODE);
877                 if (data[3])
878                         eth_test->flags |= ETH_TEST_FL_FAILED;
879                 if (eth_test->flags & ETH_TEST_FL_EXTERNAL_LB) {
880                         data[4] = qlcnic_loopback_test(dev, QLCNIC_ELB_MODE);
881                         if (data[4])
882                                 eth_test->flags |= ETH_TEST_FL_FAILED;
883                         eth_test->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE;
884                 }
885         }
886 }
887
888 static void
889 qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data)
890 {
891         struct qlcnic_adapter *adapter = netdev_priv(dev);
892         int index, i, j;
893
894         switch (stringset) {
895         case ETH_SS_TEST:
896                 memcpy(data, *qlcnic_gstrings_test,
897                        QLCNIC_TEST_LEN * ETH_GSTRING_LEN);
898                 break;
899         case ETH_SS_STATS:
900                 for (index = 0; index < QLCNIC_STATS_LEN; index++) {
901                         memcpy(data + index * ETH_GSTRING_LEN,
902                                qlcnic_gstrings_stats[index].stat_string,
903                                ETH_GSTRING_LEN);
904                 }
905                 for (j = 0; j < QLCNIC_MAC_STATS_LEN; index++, j++) {
906                         memcpy(data + index * ETH_GSTRING_LEN,
907                                qlcnic_mac_stats_strings[j],
908                                ETH_GSTRING_LEN);
909                 }
910                 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
911                         return;
912                 for (i = 0; i < QLCNIC_DEVICE_STATS_LEN; index++, i++) {
913                         memcpy(data + index * ETH_GSTRING_LEN,
914                                qlcnic_device_gstrings_stats[i],
915                                ETH_GSTRING_LEN);
916                 }
917         }
918 }
919
920 static void
921 qlcnic_fill_stats(int *index, u64 *data, void *stats, int type)
922 {
923         int ind = *index;
924
925         if (type == QLCNIC_MAC_STATS) {
926                 struct qlcnic_mac_statistics *mac_stats =
927                                         (struct qlcnic_mac_statistics *)stats;
928                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_frames);
929                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_bytes);
930                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_mcast_pkts);
931                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_bcast_pkts);
932                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_pause_cnt);
933                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_ctrl_pkt);
934                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_64b_pkts);
935                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_127b_pkts);
936                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_255b_pkts);
937                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_511b_pkts);
938                 data[ind++] =
939                         QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1023b_pkts);
940                 data[ind++] =
941                         QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1518b_pkts);
942                 data[ind++] =
943                         QLCNIC_FILL_STATS(mac_stats->mac_tx_gt_1518b_pkts);
944                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_frames);
945                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_bytes);
946                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_mcast_pkts);
947                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_bcast_pkts);
948                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_pause_cnt);
949                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_ctrl_pkt);
950                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_64b_pkts);
951                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_127b_pkts);
952                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_255b_pkts);
953                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_511b_pkts);
954                 data[ind++] =
955                         QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1023b_pkts);
956                 data[ind++] =
957                         QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1518b_pkts);
958                 data[ind++] =
959                         QLCNIC_FILL_STATS(mac_stats->mac_rx_gt_1518b_pkts);
960                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_error);
961                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_small);
962                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_large);
963                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_jabber);
964                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_dropped);
965                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_rx_crc_error);
966                 data[ind++] = QLCNIC_FILL_STATS(mac_stats->mac_align_error);
967         } else if (type == QLCNIC_ESW_STATS) {
968                 struct __qlcnic_esw_statistics *esw_stats =
969                                 (struct __qlcnic_esw_statistics *)stats;
970                 data[ind++] = QLCNIC_FILL_STATS(esw_stats->unicast_frames);
971                 data[ind++] = QLCNIC_FILL_STATS(esw_stats->multicast_frames);
972                 data[ind++] = QLCNIC_FILL_STATS(esw_stats->broadcast_frames);
973                 data[ind++] = QLCNIC_FILL_STATS(esw_stats->dropped_frames);
974                 data[ind++] = QLCNIC_FILL_STATS(esw_stats->errors);
975                 data[ind++] = QLCNIC_FILL_STATS(esw_stats->local_frames);
976                 data[ind++] = QLCNIC_FILL_STATS(esw_stats->numbytes);
977         }
978
979         *index = ind;
980 }
981
982 static void
983 qlcnic_get_ethtool_stats(struct net_device *dev,
984                              struct ethtool_stats *stats, u64 * data)
985 {
986         struct qlcnic_adapter *adapter = netdev_priv(dev);
987         struct qlcnic_esw_statistics port_stats;
988         struct qlcnic_mac_statistics mac_stats;
989         int index, ret;
990
991         for (index = 0; index < QLCNIC_STATS_LEN; index++) {
992                 char *p =
993                     (char *)adapter +
994                     qlcnic_gstrings_stats[index].stat_offset;
995                 data[index] =
996                     (qlcnic_gstrings_stats[index].sizeof_stat ==
997                      sizeof(u64)) ? *(u64 *)p:(*(u32 *)p);
998         }
999
1000         /* Retrieve MAC statistics from firmware */
1001         memset(&mac_stats, 0, sizeof(struct qlcnic_mac_statistics));
1002         qlcnic_get_mac_stats(adapter, &mac_stats);
1003         qlcnic_fill_stats(&index, data, &mac_stats, QLCNIC_MAC_STATS);
1004
1005         if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1006                 return;
1007
1008         memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics));
1009         ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
1010                         QLCNIC_QUERY_RX_COUNTER, &port_stats.rx);
1011         if (ret)
1012                 return;
1013
1014         qlcnic_fill_stats(&index, data, &port_stats.rx, QLCNIC_ESW_STATS);
1015
1016         ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
1017                         QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
1018         if (ret)
1019                 return;
1020
1021         qlcnic_fill_stats(&index, data, &port_stats.tx, QLCNIC_ESW_STATS);
1022 }
1023
1024 static int qlcnic_set_led(struct net_device *dev,
1025                           enum ethtool_phys_id_state state)
1026 {
1027         struct qlcnic_adapter *adapter = netdev_priv(dev);
1028         int max_sds_rings = adapter->max_sds_rings;
1029         int err = -EIO, active = 1;
1030
1031         if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
1032                 netdev_warn(dev, "LED test not supported for non "
1033                                 "privilege function\n");
1034                 return -EOPNOTSUPP;
1035         }
1036
1037         switch (state) {
1038         case ETHTOOL_ID_ACTIVE:
1039                 if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
1040                         return -EBUSY;
1041
1042                 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1043                         break;
1044
1045                 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
1046                         if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
1047                                 break;
1048                         set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
1049                 }
1050
1051                 if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) {
1052                         err = 0;
1053                         break;
1054                 }
1055
1056                 dev_err(&adapter->pdev->dev,
1057                         "Failed to set LED blink state.\n");
1058                 break;
1059
1060         case ETHTOOL_ID_INACTIVE:
1061                 active = 0;
1062
1063                 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1064                         break;
1065
1066                 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
1067                         if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
1068                                 break;
1069                         set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
1070                 }
1071
1072                 if (adapter->nic_ops->config_led(adapter, 0, 0xf))
1073                         dev_err(&adapter->pdev->dev,
1074                                 "Failed to reset LED blink state.\n");
1075
1076                 break;
1077
1078         default:
1079                 return -EINVAL;
1080         }
1081
1082         if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
1083                 qlcnic_diag_free_res(dev, max_sds_rings);
1084
1085         if (!active || err)
1086                 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
1087
1088         return err;
1089 }
1090
1091 static void
1092 qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1093 {
1094         struct qlcnic_adapter *adapter = netdev_priv(dev);
1095         u32 wol_cfg;
1096
1097         wol->supported = 0;
1098         wol->wolopts = 0;
1099
1100         wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
1101         if (wol_cfg & (1UL << adapter->portnum))
1102                 wol->supported |= WAKE_MAGIC;
1103
1104         wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
1105         if (wol_cfg & (1UL << adapter->portnum))
1106                 wol->wolopts |= WAKE_MAGIC;
1107 }
1108
1109 static int
1110 qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1111 {
1112         struct qlcnic_adapter *adapter = netdev_priv(dev);
1113         u32 wol_cfg;
1114
1115         if (wol->wolopts & ~WAKE_MAGIC)
1116                 return -EOPNOTSUPP;
1117
1118         wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
1119         if (!(wol_cfg & (1 << adapter->portnum)))
1120                 return -EOPNOTSUPP;
1121
1122         wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
1123         if (wol->wolopts & WAKE_MAGIC)
1124                 wol_cfg |= 1UL << adapter->portnum;
1125         else
1126                 wol_cfg &= ~(1UL << adapter->portnum);
1127
1128         QLCWR32(adapter, QLCNIC_WOL_CONFIG, wol_cfg);
1129
1130         return 0;
1131 }
1132
1133 /*
1134  * Set the coalescing parameters. Currently only normal is supported.
1135  * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
1136  * firmware coalescing to default.
1137  */
1138 static int qlcnic_set_intr_coalesce(struct net_device *netdev,
1139                         struct ethtool_coalesce *ethcoal)
1140 {
1141         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1142
1143         if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
1144                 return -EINVAL;
1145
1146         /*
1147         * Return Error if unsupported values or
1148         * unsupported parameters are set.
1149         */
1150         if (ethcoal->rx_coalesce_usecs > 0xffff ||
1151                 ethcoal->rx_max_coalesced_frames > 0xffff ||
1152                 ethcoal->tx_coalesce_usecs ||
1153                 ethcoal->tx_max_coalesced_frames ||
1154                 ethcoal->rx_coalesce_usecs_irq ||
1155                 ethcoal->rx_max_coalesced_frames_irq ||
1156                 ethcoal->tx_coalesce_usecs_irq ||
1157                 ethcoal->tx_max_coalesced_frames_irq ||
1158                 ethcoal->stats_block_coalesce_usecs ||
1159                 ethcoal->use_adaptive_rx_coalesce ||
1160                 ethcoal->use_adaptive_tx_coalesce ||
1161                 ethcoal->pkt_rate_low ||
1162                 ethcoal->rx_coalesce_usecs_low ||
1163                 ethcoal->rx_max_coalesced_frames_low ||
1164                 ethcoal->tx_coalesce_usecs_low ||
1165                 ethcoal->tx_max_coalesced_frames_low ||
1166                 ethcoal->pkt_rate_high ||
1167                 ethcoal->rx_coalesce_usecs_high ||
1168                 ethcoal->rx_max_coalesced_frames_high ||
1169                 ethcoal->tx_coalesce_usecs_high ||
1170                 ethcoal->tx_max_coalesced_frames_high)
1171                 return -EINVAL;
1172
1173         if (!ethcoal->rx_coalesce_usecs ||
1174                 !ethcoal->rx_max_coalesced_frames) {
1175                 adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT;
1176                 adapter->ahw->coal.rx_time_us =
1177                         QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
1178                 adapter->ahw->coal.rx_packets =
1179                         QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS;
1180         } else {
1181                 adapter->ahw->coal.flag = 0;
1182                 adapter->ahw->coal.rx_time_us = ethcoal->rx_coalesce_usecs;
1183                 adapter->ahw->coal.rx_packets =
1184                         ethcoal->rx_max_coalesced_frames;
1185         }
1186
1187         qlcnic_config_intr_coalesce(adapter);
1188
1189         return 0;
1190 }
1191
1192 static int qlcnic_get_intr_coalesce(struct net_device *netdev,
1193                         struct ethtool_coalesce *ethcoal)
1194 {
1195         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1196
1197         if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
1198                 return -EINVAL;
1199
1200         ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us;
1201         ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets;
1202
1203         return 0;
1204 }
1205
1206 static u32 qlcnic_get_msglevel(struct net_device *netdev)
1207 {
1208         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1209
1210         return adapter->msg_enable;
1211 }
1212
1213 static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
1214 {
1215         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1216
1217         adapter->msg_enable = msglvl;
1218 }
1219
1220 static int
1221 qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
1222 {
1223         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1224         struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1225
1226         if (!fw_dump->tmpl_hdr) {
1227                 netdev_err(adapter->netdev, "FW Dump not supported\n");
1228                 return -ENOTSUPP;
1229         }
1230
1231         if (fw_dump->clr)
1232                 dump->len = fw_dump->tmpl_hdr->size + fw_dump->size;
1233         else
1234                 dump->len = 0;
1235         dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
1236         dump->version = adapter->fw_version;
1237         return 0;
1238 }
1239
1240 static int
1241 qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
1242                         void *buffer)
1243 {
1244         int i, copy_sz;
1245         u32 *hdr_ptr, *data;
1246         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1247         struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1248
1249         if (!fw_dump->tmpl_hdr) {
1250                 netdev_err(netdev, "FW Dump not supported\n");
1251                 return -ENOTSUPP;
1252         }
1253
1254         if (!fw_dump->clr) {
1255                 netdev_info(netdev, "Dump not available\n");
1256                 return -EINVAL;
1257         }
1258         /* Copy template header first */
1259         copy_sz = fw_dump->tmpl_hdr->size;
1260         hdr_ptr = (u32 *) fw_dump->tmpl_hdr;
1261         data = buffer;
1262         for (i = 0; i < copy_sz/sizeof(u32); i++)
1263                 *data++ = cpu_to_le32(*hdr_ptr++);
1264
1265         /* Copy captured dump data */
1266         memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size);
1267         dump->len = copy_sz + fw_dump->size;
1268         dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
1269
1270         /* Free dump area once data has been captured */
1271         vfree(fw_dump->data);
1272         fw_dump->data = NULL;
1273         fw_dump->clr = 0;
1274         netdev_info(netdev, "extracted the FW dump Successfully\n");
1275         return 0;
1276 }
1277
1278 static int
1279 qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
1280 {
1281         int ret = 0;
1282         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1283         struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1284         u32 state;
1285
1286         switch (val->flag) {
1287         case QLCNIC_FORCE_FW_DUMP_KEY:
1288                 if (!fw_dump->tmpl_hdr) {
1289                         netdev_err(netdev, "FW dump not supported\n");
1290                         return -ENOTSUPP;
1291                 }
1292                 if (!fw_dump->enable) {
1293                         netdev_info(netdev, "FW dump not enabled\n");
1294                         return ret;
1295                 }
1296                 if (fw_dump->clr) {
1297                         netdev_info(netdev,
1298                         "Previous dump not cleared, not forcing dump\n");
1299                         return ret;
1300                 }
1301                 netdev_info(netdev, "Forcing a FW dump\n");
1302                 qlcnic_dev_request_reset(adapter);
1303                 break;
1304         case QLCNIC_DISABLE_FW_DUMP:
1305                 if (fw_dump->enable && fw_dump->tmpl_hdr) {
1306                         netdev_info(netdev, "Disabling FW dump\n");
1307                         fw_dump->enable = 0;
1308                 }
1309                 return ret;
1310         case QLCNIC_ENABLE_FW_DUMP:
1311                 if (!fw_dump->tmpl_hdr) {
1312                         netdev_err(netdev, "FW dump not supported\n");
1313                         return -ENOTSUPP;
1314                 }
1315                 if (!fw_dump->enable) {
1316                         netdev_info(netdev, "Enabling FW dump\n");
1317                         fw_dump->enable = 1;
1318                 }
1319                 return ret;
1320         case QLCNIC_FORCE_FW_RESET:
1321                 netdev_info(netdev, "Forcing a FW reset\n");
1322                 qlcnic_dev_request_reset(adapter);
1323                 adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
1324                 return ret;
1325         case QLCNIC_SET_QUIESCENT:
1326         case QLCNIC_RESET_QUIESCENT:
1327                 state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
1328                 if (state == QLCNIC_DEV_FAILED || (state == QLCNIC_DEV_BADBAD))
1329                         netdev_info(netdev, "Device in FAILED state\n");
1330                 return ret;
1331         default:
1332                 if (!fw_dump->tmpl_hdr) {
1333                         netdev_err(netdev, "FW dump not supported\n");
1334                         return -ENOTSUPP;
1335                 }
1336                 if (val->flag > QLCNIC_DUMP_MASK_MAX ||
1337                         val->flag < QLCNIC_DUMP_MASK_MIN) {
1338                                 netdev_info(netdev,
1339                                 "Invalid dump level: 0x%x\n", val->flag);
1340                                 return -EINVAL;
1341                 }
1342                 fw_dump->tmpl_hdr->drv_cap_mask = val->flag & 0xff;
1343                 netdev_info(netdev, "Driver mask changed to: 0x%x\n",
1344                         fw_dump->tmpl_hdr->drv_cap_mask);
1345         }
1346         return ret;
1347 }
1348
1349 const struct ethtool_ops qlcnic_ethtool_ops = {
1350         .get_settings = qlcnic_get_settings,
1351         .set_settings = qlcnic_set_settings,
1352         .get_drvinfo = qlcnic_get_drvinfo,
1353         .get_regs_len = qlcnic_get_regs_len,
1354         .get_regs = qlcnic_get_regs,
1355         .get_link = ethtool_op_get_link,
1356         .get_eeprom_len = qlcnic_get_eeprom_len,
1357         .get_eeprom = qlcnic_get_eeprom,
1358         .get_ringparam = qlcnic_get_ringparam,
1359         .set_ringparam = qlcnic_set_ringparam,
1360         .get_channels = qlcnic_get_channels,
1361         .set_channels = qlcnic_set_channels,
1362         .get_pauseparam = qlcnic_get_pauseparam,
1363         .set_pauseparam = qlcnic_set_pauseparam,
1364         .get_wol = qlcnic_get_wol,
1365         .set_wol = qlcnic_set_wol,
1366         .self_test = qlcnic_diag_test,
1367         .get_strings = qlcnic_get_strings,
1368         .get_ethtool_stats = qlcnic_get_ethtool_stats,
1369         .get_sset_count = qlcnic_get_sset_count,
1370         .get_coalesce = qlcnic_get_intr_coalesce,
1371         .set_coalesce = qlcnic_set_intr_coalesce,
1372         .set_phys_id = qlcnic_set_led,
1373         .set_msglevel = qlcnic_set_msglevel,
1374         .get_msglevel = qlcnic_get_msglevel,
1375         .get_dump_flag = qlcnic_get_dump_flag,
1376         .get_dump_data = qlcnic_get_dump_data,
1377         .set_dump = qlcnic_set_dump,
1378 };
1379
1380 const struct ethtool_ops qlcnic_ethtool_failed_ops = {
1381         .get_settings = qlcnic_get_settings,
1382         .get_drvinfo = qlcnic_get_drvinfo,
1383         .set_msglevel = qlcnic_set_msglevel,
1384         .get_msglevel = qlcnic_get_msglevel,
1385 };