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