sfc: Don't use enums as a bitmask.
[zen-stable.git] / drivers / net / qlcnic / qlcnic_ethtool.c
blob9efc690a289f0951740bfd489526f263f38056d5
1 /*
2 * QLogic qlcnic NIC Driver
3 * Copyright (c) 2009-2010 QLogic Corporation
5 * See LICENSE.qlcnic for copyright and licensing details.
6 */
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>
15 #include "qlcnic.h"
17 struct qlcnic_stats {
18 char stat_string[ETH_GSTRING_LEN];
19 int sizeof_stat;
20 int stat_offset;
23 #define QLC_SIZEOF(m) FIELD_SIZEOF(struct qlcnic_adapter, m)
24 #define QLC_OFF(m) offsetof(struct qlcnic_adapter, m)
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)},
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",
81 #define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats)
82 #define QLCNIC_DEVICE_STATS_LEN ARRAY_SIZE(qlcnic_device_gstrings_stats)
84 static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
85 "Register_Test_on_offline",
86 "Link_Test_on_offline",
87 "Interrupt_Test_offline"
90 #define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test)
92 #define QLCNIC_RING_REGS_COUNT 20
93 #define QLCNIC_RING_REGS_LEN (QLCNIC_RING_REGS_COUNT * sizeof(u32))
94 #define QLCNIC_MAX_EEPROM_LEN 1024
96 static const u32 diag_registers[] = {
97 CRB_CMDPEG_STATE,
98 CRB_RCVPEG_STATE,
99 CRB_XG_STATE_P3P,
100 CRB_FW_CAPABILITIES_1,
101 ISR_INT_STATE_REG,
102 QLCNIC_CRB_DRV_ACTIVE,
103 QLCNIC_CRB_DEV_STATE,
104 QLCNIC_CRB_DRV_STATE,
105 QLCNIC_CRB_DRV_SCRATCH,
106 QLCNIC_CRB_DEV_PARTITION_INFO,
107 QLCNIC_CRB_DRV_IDC_VER,
108 QLCNIC_PEG_ALIVE_COUNTER,
109 QLCNIC_PEG_HALT_STATUS1,
110 QLCNIC_PEG_HALT_STATUS2,
111 QLCNIC_CRB_PEG_NET_0+0x3c,
112 QLCNIC_CRB_PEG_NET_1+0x3c,
113 QLCNIC_CRB_PEG_NET_2+0x3c,
114 QLCNIC_CRB_PEG_NET_4+0x3c,
118 #define QLCNIC_MGMT_API_VERSION 2
119 #define QLCNIC_DEV_INFO_SIZE 1
120 #define QLCNIC_ETHTOOL_REGS_VER 2
121 static int qlcnic_get_regs_len(struct net_device *dev)
123 return sizeof(diag_registers) + QLCNIC_RING_REGS_LEN +
124 QLCNIC_DEV_INFO_SIZE + 1;
127 static int qlcnic_get_eeprom_len(struct net_device *dev)
129 return QLCNIC_FLASH_TOTAL_SIZE;
132 static void
133 qlcnic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
135 struct qlcnic_adapter *adapter = netdev_priv(dev);
136 u32 fw_major, fw_minor, fw_build;
138 fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR);
139 fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR);
140 fw_build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB);
141 sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build);
143 strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
144 strlcpy(drvinfo->driver, qlcnic_driver_name, 32);
145 strlcpy(drvinfo->version, QLCNIC_LINUX_VERSIONID, 32);
148 static int
149 qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
151 struct qlcnic_adapter *adapter = netdev_priv(dev);
152 int check_sfp_module = 0;
153 u16 pcifn = adapter->ahw->pci_func;
155 /* read which mode */
156 if (adapter->ahw->port_type == QLCNIC_GBE) {
157 ecmd->supported = (SUPPORTED_10baseT_Half |
158 SUPPORTED_10baseT_Full |
159 SUPPORTED_100baseT_Half |
160 SUPPORTED_100baseT_Full |
161 SUPPORTED_1000baseT_Half |
162 SUPPORTED_1000baseT_Full);
164 ecmd->advertising = (ADVERTISED_100baseT_Half |
165 ADVERTISED_100baseT_Full |
166 ADVERTISED_1000baseT_Half |
167 ADVERTISED_1000baseT_Full);
169 ethtool_cmd_speed_set(ecmd, adapter->link_speed);
170 ecmd->duplex = adapter->link_duplex;
171 ecmd->autoneg = adapter->link_autoneg;
173 } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
174 u32 val;
176 val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
177 if (val == QLCNIC_PORT_MODE_802_3_AP) {
178 ecmd->supported = SUPPORTED_1000baseT_Full;
179 ecmd->advertising = ADVERTISED_1000baseT_Full;
180 } else {
181 ecmd->supported = SUPPORTED_10000baseT_Full;
182 ecmd->advertising = ADVERTISED_10000baseT_Full;
185 if (netif_running(dev) && adapter->has_link_events) {
186 ethtool_cmd_speed_set(ecmd, adapter->link_speed);
187 ecmd->autoneg = adapter->link_autoneg;
188 ecmd->duplex = adapter->link_duplex;
189 goto skip;
192 val = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn));
193 ethtool_cmd_speed_set(ecmd, P3P_LINK_SPEED_MHZ *
194 P3P_LINK_SPEED_VAL(pcifn, val));
195 ecmd->duplex = DUPLEX_FULL;
196 ecmd->autoneg = AUTONEG_DISABLE;
197 } else
198 return -EIO;
200 skip:
201 ecmd->phy_address = adapter->physical_port;
202 ecmd->transceiver = XCVR_EXTERNAL;
204 switch (adapter->ahw->board_type) {
205 case QLCNIC_BRDTYPE_P3P_REF_QG:
206 case QLCNIC_BRDTYPE_P3P_4_GB:
207 case QLCNIC_BRDTYPE_P3P_4_GB_MM:
209 ecmd->supported |= SUPPORTED_Autoneg;
210 ecmd->advertising |= ADVERTISED_Autoneg;
211 case QLCNIC_BRDTYPE_P3P_10G_CX4:
212 case QLCNIC_BRDTYPE_P3P_10G_CX4_LP:
213 case QLCNIC_BRDTYPE_P3P_10000_BASE_T:
214 ecmd->supported |= SUPPORTED_TP;
215 ecmd->advertising |= ADVERTISED_TP;
216 ecmd->port = PORT_TP;
217 ecmd->autoneg = adapter->link_autoneg;
218 break;
219 case QLCNIC_BRDTYPE_P3P_IMEZ:
220 case QLCNIC_BRDTYPE_P3P_XG_LOM:
221 case QLCNIC_BRDTYPE_P3P_HMEZ:
222 ecmd->supported |= SUPPORTED_MII;
223 ecmd->advertising |= ADVERTISED_MII;
224 ecmd->port = PORT_MII;
225 ecmd->autoneg = AUTONEG_DISABLE;
226 break;
227 case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS:
228 case QLCNIC_BRDTYPE_P3P_10G_SFP_CT:
229 case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
230 ecmd->advertising |= ADVERTISED_TP;
231 ecmd->supported |= SUPPORTED_TP;
232 check_sfp_module = netif_running(dev) &&
233 adapter->has_link_events;
234 case QLCNIC_BRDTYPE_P3P_10G_XFP:
235 ecmd->supported |= SUPPORTED_FIBRE;
236 ecmd->advertising |= ADVERTISED_FIBRE;
237 ecmd->port = PORT_FIBRE;
238 ecmd->autoneg = AUTONEG_DISABLE;
239 break;
240 case QLCNIC_BRDTYPE_P3P_10G_TP:
241 if (adapter->ahw->port_type == QLCNIC_XGBE) {
242 ecmd->autoneg = AUTONEG_DISABLE;
243 ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
244 ecmd->advertising |=
245 (ADVERTISED_FIBRE | ADVERTISED_TP);
246 ecmd->port = PORT_FIBRE;
247 check_sfp_module = netif_running(dev) &&
248 adapter->has_link_events;
249 } else {
250 ecmd->autoneg = AUTONEG_ENABLE;
251 ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
252 ecmd->advertising |=
253 (ADVERTISED_TP | ADVERTISED_Autoneg);
254 ecmd->port = PORT_TP;
256 break;
257 default:
258 dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
259 adapter->ahw->board_type);
260 return -EIO;
263 if (check_sfp_module) {
264 switch (adapter->module_type) {
265 case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
266 case LINKEVENT_MODULE_OPTICAL_SRLR:
267 case LINKEVENT_MODULE_OPTICAL_LRM:
268 case LINKEVENT_MODULE_OPTICAL_SFP_1G:
269 ecmd->port = PORT_FIBRE;
270 break;
271 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
272 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
273 case LINKEVENT_MODULE_TWINAX:
274 ecmd->port = PORT_TP;
275 break;
276 default:
277 ecmd->port = PORT_OTHER;
281 return 0;
284 static int
285 qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
287 u32 config = 0;
288 u32 ret = 0;
289 struct qlcnic_adapter *adapter = netdev_priv(dev);
291 if (adapter->ahw->port_type != QLCNIC_GBE)
292 return -EOPNOTSUPP;
294 /* read which mode */
295 if (ecmd->duplex)
296 config |= 0x1;
298 if (ecmd->autoneg)
299 config |= 0x2;
301 switch (ethtool_cmd_speed(ecmd)) {
302 case SPEED_10:
303 config |= (0 << 8);
304 break;
305 case SPEED_100:
306 config |= (1 << 8);
307 break;
308 case SPEED_1000:
309 config |= (10 << 8);
310 break;
311 default:
312 return -EIO;
315 ret = qlcnic_fw_cmd_set_port(adapter, config);
317 if (ret == QLCNIC_RCODE_NOT_SUPPORTED)
318 return -EOPNOTSUPP;
319 else if (ret)
320 return -EIO;
322 adapter->link_speed = ethtool_cmd_speed(ecmd);
323 adapter->link_duplex = ecmd->duplex;
324 adapter->link_autoneg = ecmd->autoneg;
326 if (!netif_running(dev))
327 return 0;
329 dev->netdev_ops->ndo_stop(dev);
330 return dev->netdev_ops->ndo_open(dev);
333 static void
334 qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
336 struct qlcnic_adapter *adapter = netdev_priv(dev);
337 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
338 struct qlcnic_host_sds_ring *sds_ring;
339 u32 *regs_buff = p;
340 int ring, i = 0, j = 0;
342 memset(p, 0, qlcnic_get_regs_len(dev));
343 regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
344 (adapter->ahw->revision_id << 16) | (adapter->pdev)->device;
346 regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
347 regs_buff[1] = QLCNIC_MGMT_API_VERSION;
349 for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++)
350 regs_buff[i] = QLCRD32(adapter, diag_registers[j]);
352 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
353 return;
355 regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/
357 regs_buff[i++] = 1; /* No. of tx ring */
358 regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
359 regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer);
361 regs_buff[i++] = 2; /* No. of rx ring */
362 regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer);
363 regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer);
365 regs_buff[i++] = adapter->max_sds_rings;
367 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
368 sds_ring = &(recv_ctx->sds_rings[ring]);
369 regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
373 static u32 qlcnic_test_link(struct net_device *dev)
375 struct qlcnic_adapter *adapter = netdev_priv(dev);
376 u32 val;
378 val = QLCRD32(adapter, CRB_XG_STATE_P3P);
379 val = XG_LINK_STATE_P3P(adapter->ahw->pci_func, val);
380 return (val == XG_LINK_UP_P3P) ? 0 : 1;
383 static int
384 qlcnic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
385 u8 *bytes)
387 struct qlcnic_adapter *adapter = netdev_priv(dev);
388 int offset;
389 int ret;
391 if (eeprom->len == 0)
392 return -EINVAL;
394 eeprom->magic = (adapter->pdev)->vendor |
395 ((adapter->pdev)->device << 16);
396 offset = eeprom->offset;
398 ret = qlcnic_rom_fast_read_words(adapter, offset, bytes,
399 eeprom->len);
400 if (ret < 0)
401 return ret;
403 return 0;
406 static void
407 qlcnic_get_ringparam(struct net_device *dev,
408 struct ethtool_ringparam *ring)
410 struct qlcnic_adapter *adapter = netdev_priv(dev);
412 ring->rx_pending = adapter->num_rxd;
413 ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
414 ring->tx_pending = adapter->num_txd;
416 ring->rx_max_pending = adapter->max_rxd;
417 ring->rx_jumbo_max_pending = adapter->max_jumbo_rxd;
418 ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
420 ring->rx_mini_max_pending = 0;
421 ring->rx_mini_pending = 0;
424 static u32
425 qlcnic_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
427 u32 num_desc;
428 num_desc = max(val, min);
429 num_desc = min(num_desc, max);
430 num_desc = roundup_pow_of_two(num_desc);
432 if (val != num_desc) {
433 printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
434 qlcnic_driver_name, r_name, num_desc, val);
437 return num_desc;
440 static int
441 qlcnic_set_ringparam(struct net_device *dev,
442 struct ethtool_ringparam *ring)
444 struct qlcnic_adapter *adapter = netdev_priv(dev);
445 u16 num_rxd, num_jumbo_rxd, num_txd;
447 if (ring->rx_mini_pending)
448 return -EOPNOTSUPP;
450 num_rxd = qlcnic_validate_ringparam(ring->rx_pending,
451 MIN_RCV_DESCRIPTORS, adapter->max_rxd, "rx");
453 num_jumbo_rxd = qlcnic_validate_ringparam(ring->rx_jumbo_pending,
454 MIN_JUMBO_DESCRIPTORS, adapter->max_jumbo_rxd,
455 "rx jumbo");
457 num_txd = qlcnic_validate_ringparam(ring->tx_pending,
458 MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
460 if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
461 num_jumbo_rxd == adapter->num_jumbo_rxd)
462 return 0;
464 adapter->num_rxd = num_rxd;
465 adapter->num_jumbo_rxd = num_jumbo_rxd;
466 adapter->num_txd = num_txd;
468 return qlcnic_reset_context(adapter);
471 static void qlcnic_get_channels(struct net_device *dev,
472 struct ethtool_channels *channel)
474 struct qlcnic_adapter *adapter = netdev_priv(dev);
476 channel->max_rx = rounddown_pow_of_two(min_t(int,
477 adapter->max_rx_ques, num_online_cpus()));
478 channel->max_tx = adapter->max_tx_ques;
480 channel->rx_count = adapter->max_sds_rings;
481 channel->tx_count = adapter->max_tx_ques;
484 static int qlcnic_set_channels(struct net_device *dev,
485 struct ethtool_channels *channel)
487 struct qlcnic_adapter *adapter = netdev_priv(dev);
488 int err;
490 if (channel->other_count || channel->combined_count ||
491 channel->tx_count != channel->max_tx)
492 return -EINVAL;
494 err = qlcnic_validate_max_rss(dev, channel->max_rx, channel->rx_count);
495 if (err)
496 return err;
498 err = qlcnic_set_max_rss(adapter, channel->rx_count);
499 netdev_info(dev, "allocated 0x%x sds rings\n",
500 adapter->max_sds_rings);
501 return err;
504 static void
505 qlcnic_get_pauseparam(struct net_device *netdev,
506 struct ethtool_pauseparam *pause)
508 struct qlcnic_adapter *adapter = netdev_priv(netdev);
509 int port = adapter->physical_port;
510 __u32 val;
512 if (adapter->ahw->port_type == QLCNIC_GBE) {
513 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
514 return;
515 /* get flow control settings */
516 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
517 pause->rx_pause = qlcnic_gb_get_rx_flowctl(val);
518 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
519 switch (port) {
520 case 0:
521 pause->tx_pause = !(qlcnic_gb_get_gb0_mask(val));
522 break;
523 case 1:
524 pause->tx_pause = !(qlcnic_gb_get_gb1_mask(val));
525 break;
526 case 2:
527 pause->tx_pause = !(qlcnic_gb_get_gb2_mask(val));
528 break;
529 case 3:
530 default:
531 pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val));
532 break;
534 } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
535 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
536 return;
537 pause->rx_pause = 1;
538 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
539 if (port == 0)
540 pause->tx_pause = !(qlcnic_xg_get_xg0_mask(val));
541 else
542 pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val));
543 } else {
544 dev_err(&netdev->dev, "Unknown board type: %x\n",
545 adapter->ahw->port_type);
549 static int
550 qlcnic_set_pauseparam(struct net_device *netdev,
551 struct ethtool_pauseparam *pause)
553 struct qlcnic_adapter *adapter = netdev_priv(netdev);
554 int port = adapter->physical_port;
555 __u32 val;
557 /* read mode */
558 if (adapter->ahw->port_type == QLCNIC_GBE) {
559 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
560 return -EIO;
561 /* set flow control */
562 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
564 if (pause->rx_pause)
565 qlcnic_gb_rx_flowctl(val);
566 else
567 qlcnic_gb_unset_rx_flowctl(val);
569 QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port),
570 val);
571 /* set autoneg */
572 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
573 switch (port) {
574 case 0:
575 if (pause->tx_pause)
576 qlcnic_gb_unset_gb0_mask(val);
577 else
578 qlcnic_gb_set_gb0_mask(val);
579 break;
580 case 1:
581 if (pause->tx_pause)
582 qlcnic_gb_unset_gb1_mask(val);
583 else
584 qlcnic_gb_set_gb1_mask(val);
585 break;
586 case 2:
587 if (pause->tx_pause)
588 qlcnic_gb_unset_gb2_mask(val);
589 else
590 qlcnic_gb_set_gb2_mask(val);
591 break;
592 case 3:
593 default:
594 if (pause->tx_pause)
595 qlcnic_gb_unset_gb3_mask(val);
596 else
597 qlcnic_gb_set_gb3_mask(val);
598 break;
600 QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val);
601 } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
602 if (!pause->rx_pause || pause->autoneg)
603 return -EOPNOTSUPP;
605 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
606 return -EIO;
608 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
609 if (port == 0) {
610 if (pause->tx_pause)
611 qlcnic_xg_unset_xg0_mask(val);
612 else
613 qlcnic_xg_set_xg0_mask(val);
614 } else {
615 if (pause->tx_pause)
616 qlcnic_xg_unset_xg1_mask(val);
617 else
618 qlcnic_xg_set_xg1_mask(val);
620 QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val);
621 } else {
622 dev_err(&netdev->dev, "Unknown board type: %x\n",
623 adapter->ahw->port_type);
625 return 0;
628 static int qlcnic_reg_test(struct net_device *dev)
630 struct qlcnic_adapter *adapter = netdev_priv(dev);
631 u32 data_read;
633 data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0));
634 if ((data_read & 0xffff) != adapter->pdev->vendor)
635 return 1;
637 return 0;
640 static int qlcnic_get_sset_count(struct net_device *dev, int sset)
642 struct qlcnic_adapter *adapter = netdev_priv(dev);
643 switch (sset) {
644 case ETH_SS_TEST:
645 return QLCNIC_TEST_LEN;
646 case ETH_SS_STATS:
647 if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
648 return QLCNIC_STATS_LEN + QLCNIC_DEVICE_STATS_LEN;
649 return QLCNIC_STATS_LEN;
650 default:
651 return -EOPNOTSUPP;
655 static int qlcnic_irq_test(struct net_device *netdev)
657 struct qlcnic_adapter *adapter = netdev_priv(netdev);
658 int max_sds_rings = adapter->max_sds_rings;
659 int ret;
661 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
662 return -EIO;
664 ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST);
665 if (ret)
666 goto clear_it;
668 adapter->diag_cnt = 0;
669 ret = qlcnic_issue_cmd(adapter, adapter->ahw->pci_func,
670 adapter->fw_hal_version, adapter->ahw->pci_func,
671 0, 0, 0x00000011);
672 if (ret)
673 goto done;
675 msleep(10);
677 ret = !adapter->diag_cnt;
679 done:
680 qlcnic_diag_free_res(netdev, max_sds_rings);
682 clear_it:
683 adapter->max_sds_rings = max_sds_rings;
684 clear_bit(__QLCNIC_RESETTING, &adapter->state);
685 return ret;
688 static void
689 qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
690 u64 *data)
692 memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
694 data[0] = qlcnic_reg_test(dev);
695 if (data[0])
696 eth_test->flags |= ETH_TEST_FL_FAILED;
698 data[1] = (u64) qlcnic_test_link(dev);
699 if (data[1])
700 eth_test->flags |= ETH_TEST_FL_FAILED;
702 if (eth_test->flags & ETH_TEST_FL_OFFLINE) {
703 data[2] = qlcnic_irq_test(dev);
704 if (data[2])
705 eth_test->flags |= ETH_TEST_FL_FAILED;
711 static void
712 qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data)
714 struct qlcnic_adapter *adapter = netdev_priv(dev);
715 int index, i;
717 switch (stringset) {
718 case ETH_SS_TEST:
719 memcpy(data, *qlcnic_gstrings_test,
720 QLCNIC_TEST_LEN * ETH_GSTRING_LEN);
721 break;
722 case ETH_SS_STATS:
723 for (index = 0; index < QLCNIC_STATS_LEN; index++) {
724 memcpy(data + index * ETH_GSTRING_LEN,
725 qlcnic_gstrings_stats[index].stat_string,
726 ETH_GSTRING_LEN);
728 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
729 return;
730 for (i = 0; i < QLCNIC_DEVICE_STATS_LEN; index++, i++) {
731 memcpy(data + index * ETH_GSTRING_LEN,
732 qlcnic_device_gstrings_stats[i],
733 ETH_GSTRING_LEN);
738 #define QLCNIC_FILL_ESWITCH_STATS(VAL1) \
739 (((VAL1) == QLCNIC_ESW_STATS_NOT_AVAIL) ? 0 : VAL1)
741 static void
742 qlcnic_fill_device_stats(int *index, u64 *data,
743 struct __qlcnic_esw_statistics *stats)
745 int ind = *index;
747 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->unicast_frames);
748 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->multicast_frames);
749 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->broadcast_frames);
750 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->dropped_frames);
751 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->errors);
752 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->local_frames);
753 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->numbytes);
755 *index = ind;
758 static void
759 qlcnic_get_ethtool_stats(struct net_device *dev,
760 struct ethtool_stats *stats, u64 * data)
762 struct qlcnic_adapter *adapter = netdev_priv(dev);
763 struct qlcnic_esw_statistics port_stats;
764 int index, ret;
766 for (index = 0; index < QLCNIC_STATS_LEN; index++) {
767 char *p =
768 (char *)adapter +
769 qlcnic_gstrings_stats[index].stat_offset;
770 data[index] =
771 (qlcnic_gstrings_stats[index].sizeof_stat ==
772 sizeof(u64)) ? *(u64 *)p:(*(u32 *)p);
775 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
776 return;
778 memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics));
779 ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
780 QLCNIC_QUERY_RX_COUNTER, &port_stats.rx);
781 if (ret)
782 return;
784 qlcnic_fill_device_stats(&index, data, &port_stats.rx);
786 ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
787 QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
788 if (ret)
789 return;
791 qlcnic_fill_device_stats(&index, data, &port_stats.tx);
794 static int qlcnic_set_led(struct net_device *dev,
795 enum ethtool_phys_id_state state)
797 struct qlcnic_adapter *adapter = netdev_priv(dev);
798 int max_sds_rings = adapter->max_sds_rings;
800 switch (state) {
801 case ETHTOOL_ID_ACTIVE:
802 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
803 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
804 return -EIO;
806 if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST)) {
807 clear_bit(__QLCNIC_RESETTING, &adapter->state);
808 return -EIO;
810 set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
813 if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0)
814 return 0;
816 dev_err(&adapter->pdev->dev,
817 "Failed to set LED blink state.\n");
818 break;
820 case ETHTOOL_ID_INACTIVE:
821 if (adapter->nic_ops->config_led(adapter, 0, 0xf))
822 dev_err(&adapter->pdev->dev,
823 "Failed to reset LED blink state.\n");
825 break;
827 default:
828 return -EINVAL;
831 if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state)) {
832 qlcnic_diag_free_res(dev, max_sds_rings);
833 clear_bit(__QLCNIC_RESETTING, &adapter->state);
836 return -EIO;
839 static void
840 qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
842 struct qlcnic_adapter *adapter = netdev_priv(dev);
843 u32 wol_cfg;
845 wol->supported = 0;
846 wol->wolopts = 0;
848 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
849 if (wol_cfg & (1UL << adapter->portnum))
850 wol->supported |= WAKE_MAGIC;
852 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
853 if (wol_cfg & (1UL << adapter->portnum))
854 wol->wolopts |= WAKE_MAGIC;
857 static int
858 qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
860 struct qlcnic_adapter *adapter = netdev_priv(dev);
861 u32 wol_cfg;
863 if (wol->wolopts & ~WAKE_MAGIC)
864 return -EOPNOTSUPP;
866 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
867 if (!(wol_cfg & (1 << adapter->portnum)))
868 return -EOPNOTSUPP;
870 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
871 if (wol->wolopts & WAKE_MAGIC)
872 wol_cfg |= 1UL << adapter->portnum;
873 else
874 wol_cfg &= ~(1UL << adapter->portnum);
876 QLCWR32(adapter, QLCNIC_WOL_CONFIG, wol_cfg);
878 return 0;
882 * Set the coalescing parameters. Currently only normal is supported.
883 * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
884 * firmware coalescing to default.
886 static int qlcnic_set_intr_coalesce(struct net_device *netdev,
887 struct ethtool_coalesce *ethcoal)
889 struct qlcnic_adapter *adapter = netdev_priv(netdev);
891 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
892 return -EINVAL;
895 * Return Error if unsupported values or
896 * unsupported parameters are set.
898 if (ethcoal->rx_coalesce_usecs > 0xffff ||
899 ethcoal->rx_max_coalesced_frames > 0xffff ||
900 ethcoal->tx_coalesce_usecs ||
901 ethcoal->tx_max_coalesced_frames ||
902 ethcoal->rx_coalesce_usecs_irq ||
903 ethcoal->rx_max_coalesced_frames_irq ||
904 ethcoal->tx_coalesce_usecs_irq ||
905 ethcoal->tx_max_coalesced_frames_irq ||
906 ethcoal->stats_block_coalesce_usecs ||
907 ethcoal->use_adaptive_rx_coalesce ||
908 ethcoal->use_adaptive_tx_coalesce ||
909 ethcoal->pkt_rate_low ||
910 ethcoal->rx_coalesce_usecs_low ||
911 ethcoal->rx_max_coalesced_frames_low ||
912 ethcoal->tx_coalesce_usecs_low ||
913 ethcoal->tx_max_coalesced_frames_low ||
914 ethcoal->pkt_rate_high ||
915 ethcoal->rx_coalesce_usecs_high ||
916 ethcoal->rx_max_coalesced_frames_high ||
917 ethcoal->tx_coalesce_usecs_high ||
918 ethcoal->tx_max_coalesced_frames_high)
919 return -EINVAL;
921 if (!ethcoal->rx_coalesce_usecs ||
922 !ethcoal->rx_max_coalesced_frames) {
923 adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT;
924 adapter->ahw->coal.rx_time_us =
925 QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
926 adapter->ahw->coal.rx_packets =
927 QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS;
928 } else {
929 adapter->ahw->coal.flag = 0;
930 adapter->ahw->coal.rx_time_us = ethcoal->rx_coalesce_usecs;
931 adapter->ahw->coal.rx_packets =
932 ethcoal->rx_max_coalesced_frames;
935 qlcnic_config_intr_coalesce(adapter);
937 return 0;
940 static int qlcnic_get_intr_coalesce(struct net_device *netdev,
941 struct ethtool_coalesce *ethcoal)
943 struct qlcnic_adapter *adapter = netdev_priv(netdev);
945 if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
946 return -EINVAL;
948 ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us;
949 ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets;
951 return 0;
954 static u32 qlcnic_get_msglevel(struct net_device *netdev)
956 struct qlcnic_adapter *adapter = netdev_priv(netdev);
958 return adapter->msg_enable;
961 static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
963 struct qlcnic_adapter *adapter = netdev_priv(netdev);
965 adapter->msg_enable = msglvl;
968 static int
969 qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
971 struct qlcnic_adapter *adapter = netdev_priv(netdev);
972 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
974 dump->len = fw_dump->tmpl_hdr->size + fw_dump->size;
975 dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
976 dump->version = adapter->fw_version;
977 return 0;
980 static int
981 qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
982 void *buffer)
984 int i, copy_sz;
985 u32 *hdr_ptr, *data;
986 struct qlcnic_adapter *adapter = netdev_priv(netdev);
987 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
989 if (qlcnic_api_lock(adapter))
990 return -EIO;
991 if (!fw_dump->clr) {
992 netdev_info(netdev, "Dump not available\n");
993 qlcnic_api_unlock(adapter);
994 return -EINVAL;
996 /* Copy template header first */
997 copy_sz = fw_dump->tmpl_hdr->size;
998 hdr_ptr = (u32 *) fw_dump->tmpl_hdr;
999 data = (u32 *) buffer;
1000 for (i = 0; i < copy_sz/sizeof(u32); i++)
1001 *data++ = cpu_to_le32(*hdr_ptr++);
1003 /* Copy captured dump data */
1004 memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size);
1005 dump->len = copy_sz + fw_dump->size;
1006 dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
1008 /* Free dump area once data has been captured */
1009 vfree(fw_dump->data);
1010 fw_dump->data = NULL;
1011 fw_dump->clr = 0;
1012 qlcnic_api_unlock(adapter);
1014 return 0;
1017 static int
1018 qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
1020 int ret = 0;
1021 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1022 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1024 if (val->flag == QLCNIC_FORCE_FW_DUMP_KEY) {
1025 netdev_info(netdev, "Forcing a FW dump\n");
1026 qlcnic_dev_request_reset(adapter);
1027 } else {
1028 if (val->flag > QLCNIC_DUMP_MASK_MAX ||
1029 val->flag < QLCNIC_DUMP_MASK_MIN) {
1030 netdev_info(netdev,
1031 "Invalid dump level: 0x%x\n", val->flag);
1032 ret = -EINVAL;
1033 goto out;
1035 if (qlcnic_api_lock(adapter))
1036 return -EIO;
1037 fw_dump->tmpl_hdr->drv_cap_mask = val->flag & 0xff;
1038 qlcnic_api_unlock(adapter);
1039 netdev_info(netdev, "Driver mask changed to: 0x%x\n",
1040 fw_dump->tmpl_hdr->drv_cap_mask);
1042 out:
1043 return ret;
1046 const struct ethtool_ops qlcnic_ethtool_ops = {
1047 .get_settings = qlcnic_get_settings,
1048 .set_settings = qlcnic_set_settings,
1049 .get_drvinfo = qlcnic_get_drvinfo,
1050 .get_regs_len = qlcnic_get_regs_len,
1051 .get_regs = qlcnic_get_regs,
1052 .get_link = ethtool_op_get_link,
1053 .get_eeprom_len = qlcnic_get_eeprom_len,
1054 .get_eeprom = qlcnic_get_eeprom,
1055 .get_ringparam = qlcnic_get_ringparam,
1056 .set_ringparam = qlcnic_set_ringparam,
1057 .get_channels = qlcnic_get_channels,
1058 .set_channels = qlcnic_set_channels,
1059 .get_pauseparam = qlcnic_get_pauseparam,
1060 .set_pauseparam = qlcnic_set_pauseparam,
1061 .get_wol = qlcnic_get_wol,
1062 .set_wol = qlcnic_set_wol,
1063 .self_test = qlcnic_diag_test,
1064 .get_strings = qlcnic_get_strings,
1065 .get_ethtool_stats = qlcnic_get_ethtool_stats,
1066 .get_sset_count = qlcnic_get_sset_count,
1067 .get_coalesce = qlcnic_get_intr_coalesce,
1068 .set_coalesce = qlcnic_set_intr_coalesce,
1069 .set_phys_id = qlcnic_set_led,
1070 .set_msglevel = qlcnic_set_msglevel,
1071 .get_msglevel = qlcnic_get_msglevel,
1072 .get_dump_flag = qlcnic_get_dump_flag,
1073 .get_dump_data = qlcnic_get_dump_data,
1074 .set_dump = qlcnic_set_dump,