Merge branch 'for-linus/i2c-3.2' of git://git.fluff.org/bjdooks/linux
[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         int err = -EIO, active = 1;
939
940         if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
941                 netdev_warn(dev, "LED test not supported for non "
942                                 "privilege function\n");
943                 return -EOPNOTSUPP;
944         }
945
946         switch (state) {
947         case ETHTOOL_ID_ACTIVE:
948                 if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
949                         return -EBUSY;
950
951                 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
952                         break;
953
954                 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
955                         if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
956                                 break;
957                         set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
958                 }
959
960                 if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) {
961                         err = 0;
962                         break;
963                 }
964
965                 dev_err(&adapter->pdev->dev,
966                         "Failed to set LED blink state.\n");
967                 break;
968
969         case ETHTOOL_ID_INACTIVE:
970                 active = 0;
971
972                 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
973                         break;
974
975                 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
976                         if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
977                                 break;
978                         set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
979                 }
980
981                 if (adapter->nic_ops->config_led(adapter, 0, 0xf))
982                         dev_err(&adapter->pdev->dev,
983                                 "Failed to reset LED blink state.\n");
984
985                 break;
986
987         default:
988                 return -EINVAL;
989         }
990
991         if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
992                 qlcnic_diag_free_res(dev, max_sds_rings);
993
994         if (!active || err)
995                 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
996
997         return err;
998 }
999
1000 static void
1001 qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1002 {
1003         struct qlcnic_adapter *adapter = netdev_priv(dev);
1004         u32 wol_cfg;
1005
1006         wol->supported = 0;
1007         wol->wolopts = 0;
1008
1009         wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
1010         if (wol_cfg & (1UL << adapter->portnum))
1011                 wol->supported |= WAKE_MAGIC;
1012
1013         wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
1014         if (wol_cfg & (1UL << adapter->portnum))
1015                 wol->wolopts |= WAKE_MAGIC;
1016 }
1017
1018 static int
1019 qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1020 {
1021         struct qlcnic_adapter *adapter = netdev_priv(dev);
1022         u32 wol_cfg;
1023
1024         if (wol->wolopts & ~WAKE_MAGIC)
1025                 return -EOPNOTSUPP;
1026
1027         wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
1028         if (!(wol_cfg & (1 << adapter->portnum)))
1029                 return -EOPNOTSUPP;
1030
1031         wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
1032         if (wol->wolopts & WAKE_MAGIC)
1033                 wol_cfg |= 1UL << adapter->portnum;
1034         else
1035                 wol_cfg &= ~(1UL << adapter->portnum);
1036
1037         QLCWR32(adapter, QLCNIC_WOL_CONFIG, wol_cfg);
1038
1039         return 0;
1040 }
1041
1042 /*
1043  * Set the coalescing parameters. Currently only normal is supported.
1044  * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
1045  * firmware coalescing to default.
1046  */
1047 static int qlcnic_set_intr_coalesce(struct net_device *netdev,
1048                         struct ethtool_coalesce *ethcoal)
1049 {
1050         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1051
1052         if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
1053                 return -EINVAL;
1054
1055         /*
1056         * Return Error if unsupported values or
1057         * unsupported parameters are set.
1058         */
1059         if (ethcoal->rx_coalesce_usecs > 0xffff ||
1060                 ethcoal->rx_max_coalesced_frames > 0xffff ||
1061                 ethcoal->tx_coalesce_usecs ||
1062                 ethcoal->tx_max_coalesced_frames ||
1063                 ethcoal->rx_coalesce_usecs_irq ||
1064                 ethcoal->rx_max_coalesced_frames_irq ||
1065                 ethcoal->tx_coalesce_usecs_irq ||
1066                 ethcoal->tx_max_coalesced_frames_irq ||
1067                 ethcoal->stats_block_coalesce_usecs ||
1068                 ethcoal->use_adaptive_rx_coalesce ||
1069                 ethcoal->use_adaptive_tx_coalesce ||
1070                 ethcoal->pkt_rate_low ||
1071                 ethcoal->rx_coalesce_usecs_low ||
1072                 ethcoal->rx_max_coalesced_frames_low ||
1073                 ethcoal->tx_coalesce_usecs_low ||
1074                 ethcoal->tx_max_coalesced_frames_low ||
1075                 ethcoal->pkt_rate_high ||
1076                 ethcoal->rx_coalesce_usecs_high ||
1077                 ethcoal->rx_max_coalesced_frames_high ||
1078                 ethcoal->tx_coalesce_usecs_high ||
1079                 ethcoal->tx_max_coalesced_frames_high)
1080                 return -EINVAL;
1081
1082         if (!ethcoal->rx_coalesce_usecs ||
1083                 !ethcoal->rx_max_coalesced_frames) {
1084                 adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT;
1085                 adapter->ahw->coal.rx_time_us =
1086                         QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
1087                 adapter->ahw->coal.rx_packets =
1088                         QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS;
1089         } else {
1090                 adapter->ahw->coal.flag = 0;
1091                 adapter->ahw->coal.rx_time_us = ethcoal->rx_coalesce_usecs;
1092                 adapter->ahw->coal.rx_packets =
1093                         ethcoal->rx_max_coalesced_frames;
1094         }
1095
1096         qlcnic_config_intr_coalesce(adapter);
1097
1098         return 0;
1099 }
1100
1101 static int qlcnic_get_intr_coalesce(struct net_device *netdev,
1102                         struct ethtool_coalesce *ethcoal)
1103 {
1104         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1105
1106         if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
1107                 return -EINVAL;
1108
1109         ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us;
1110         ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets;
1111
1112         return 0;
1113 }
1114
1115 static u32 qlcnic_get_msglevel(struct net_device *netdev)
1116 {
1117         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1118
1119         return adapter->msg_enable;
1120 }
1121
1122 static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
1123 {
1124         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1125
1126         adapter->msg_enable = msglvl;
1127 }
1128
1129 static int
1130 qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
1131 {
1132         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1133         struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1134
1135         if (fw_dump->clr)
1136                 dump->len = fw_dump->tmpl_hdr->size + fw_dump->size;
1137         else
1138                 dump->len = 0;
1139         dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
1140         dump->version = adapter->fw_version;
1141         return 0;
1142 }
1143
1144 static int
1145 qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
1146                         void *buffer)
1147 {
1148         int i, copy_sz;
1149         u32 *hdr_ptr, *data;
1150         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1151         struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1152
1153         if (!fw_dump->clr) {
1154                 netdev_info(netdev, "Dump not available\n");
1155                 qlcnic_api_unlock(adapter);
1156                 return -EINVAL;
1157         }
1158         /* Copy template header first */
1159         copy_sz = fw_dump->tmpl_hdr->size;
1160         hdr_ptr = (u32 *) fw_dump->tmpl_hdr;
1161         data = buffer;
1162         for (i = 0; i < copy_sz/sizeof(u32); i++)
1163                 *data++ = cpu_to_le32(*hdr_ptr++);
1164
1165         /* Copy captured dump data */
1166         memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size);
1167         dump->len = copy_sz + fw_dump->size;
1168         dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
1169
1170         /* Free dump area once data has been captured */
1171         vfree(fw_dump->data);
1172         fw_dump->data = NULL;
1173         fw_dump->clr = 0;
1174
1175         return 0;
1176 }
1177
1178 static int
1179 qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
1180 {
1181         int ret = 0;
1182         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1183         struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1184
1185         switch (val->flag) {
1186         case QLCNIC_FORCE_FW_DUMP_KEY:
1187                 if (!fw_dump->enable) {
1188                         netdev_info(netdev, "FW dump not enabled\n");
1189                         return ret;
1190                 }
1191                 if (fw_dump->clr) {
1192                         dev_info(&adapter->pdev->dev,
1193                         "Previous dump not cleared, not forcing dump\n");
1194                         return ret;
1195                 }
1196                 netdev_info(netdev, "Forcing a FW dump\n");
1197                 qlcnic_dev_request_reset(adapter);
1198                 break;
1199         case QLCNIC_DISABLE_FW_DUMP:
1200                 if (fw_dump->enable) {
1201                         netdev_info(netdev, "Disabling FW dump\n");
1202                         fw_dump->enable = 0;
1203                 }
1204                 break;
1205         case QLCNIC_ENABLE_FW_DUMP:
1206                 if (!fw_dump->enable && fw_dump->tmpl_hdr) {
1207                         netdev_info(netdev, "Enabling FW dump\n");
1208                         fw_dump->enable = 1;
1209                 }
1210                 break;
1211         case QLCNIC_FORCE_FW_RESET:
1212                 netdev_info(netdev, "Forcing a FW reset\n");
1213                 qlcnic_dev_request_reset(adapter);
1214                 adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
1215                 break;
1216         default:
1217                 if (val->flag > QLCNIC_DUMP_MASK_MAX ||
1218                         val->flag < QLCNIC_DUMP_MASK_MIN) {
1219                                 netdev_info(netdev,
1220                                 "Invalid dump level: 0x%x\n", val->flag);
1221                                 ret = -EINVAL;
1222                                 goto out;
1223                 }
1224                 fw_dump->tmpl_hdr->drv_cap_mask = val->flag & 0xff;
1225                 netdev_info(netdev, "Driver mask changed to: 0x%x\n",
1226                         fw_dump->tmpl_hdr->drv_cap_mask);
1227         }
1228 out:
1229         return ret;
1230 }
1231
1232 const struct ethtool_ops qlcnic_ethtool_ops = {
1233         .get_settings = qlcnic_get_settings,
1234         .set_settings = qlcnic_set_settings,
1235         .get_drvinfo = qlcnic_get_drvinfo,
1236         .get_regs_len = qlcnic_get_regs_len,
1237         .get_regs = qlcnic_get_regs,
1238         .get_link = ethtool_op_get_link,
1239         .get_eeprom_len = qlcnic_get_eeprom_len,
1240         .get_eeprom = qlcnic_get_eeprom,
1241         .get_ringparam = qlcnic_get_ringparam,
1242         .set_ringparam = qlcnic_set_ringparam,
1243         .get_channels = qlcnic_get_channels,
1244         .set_channels = qlcnic_set_channels,
1245         .get_pauseparam = qlcnic_get_pauseparam,
1246         .set_pauseparam = qlcnic_set_pauseparam,
1247         .get_wol = qlcnic_get_wol,
1248         .set_wol = qlcnic_set_wol,
1249         .self_test = qlcnic_diag_test,
1250         .get_strings = qlcnic_get_strings,
1251         .get_ethtool_stats = qlcnic_get_ethtool_stats,
1252         .get_sset_count = qlcnic_get_sset_count,
1253         .get_coalesce = qlcnic_get_intr_coalesce,
1254         .set_coalesce = qlcnic_set_intr_coalesce,
1255         .set_phys_id = qlcnic_set_led,
1256         .set_msglevel = qlcnic_set_msglevel,
1257         .get_msglevel = qlcnic_get_msglevel,
1258         .get_dump_flag = qlcnic_get_dump_flag,
1259         .get_dump_data = qlcnic_get_dump_data,
1260         .set_dump = qlcnic_set_dump,
1261 };