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