proc: use seq_puts()/seq_putc() where possible
[linux-2.6/next.git] / drivers / net / qlcnic / qlcnic_ethtool.c
blob4c14510e2a87ef04a10b66021d9a5f4eebb0486a
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 ecmd->speed = 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 ecmd->speed = 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 ecmd->speed = 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 struct qlcnic_adapter *adapter = netdev_priv(dev);
288 __u32 status;
290 /* read which mode */
291 if (adapter->ahw.port_type == QLCNIC_GBE) {
292 /* autonegotiation */
293 if (qlcnic_fw_cmd_set_phy(adapter,
294 QLCNIC_NIU_GB_MII_MGMT_ADDR_AUTONEG,
295 ecmd->autoneg) != 0)
296 return -EIO;
297 else
298 adapter->link_autoneg = ecmd->autoneg;
300 if (qlcnic_fw_cmd_query_phy(adapter,
301 QLCNIC_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
302 &status) != 0)
303 return -EIO;
305 switch (ecmd->speed) {
306 case SPEED_10:
307 qlcnic_set_phy_speed(status, 0);
308 break;
309 case SPEED_100:
310 qlcnic_set_phy_speed(status, 1);
311 break;
312 case SPEED_1000:
313 qlcnic_set_phy_speed(status, 2);
314 break;
317 if (ecmd->duplex == DUPLEX_HALF)
318 qlcnic_clear_phy_duplex(status);
319 if (ecmd->duplex == DUPLEX_FULL)
320 qlcnic_set_phy_duplex(status);
321 if (qlcnic_fw_cmd_set_phy(adapter,
322 QLCNIC_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
323 *((int *)&status)) != 0)
324 return -EIO;
325 else {
326 adapter->link_speed = ecmd->speed;
327 adapter->link_duplex = ecmd->duplex;
329 } else
330 return -EOPNOTSUPP;
332 if (!netif_running(dev))
333 return 0;
335 dev->netdev_ops->ndo_stop(dev);
336 return dev->netdev_ops->ndo_open(dev);
339 static void
340 qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
342 struct qlcnic_adapter *adapter = netdev_priv(dev);
343 struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
344 struct qlcnic_host_sds_ring *sds_ring;
345 u32 *regs_buff = p;
346 int ring, i = 0, j = 0;
348 memset(p, 0, qlcnic_get_regs_len(dev));
349 regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
350 (adapter->ahw.revision_id << 16) | (adapter->pdev)->device;
352 regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
353 regs_buff[1] = QLCNIC_MGMT_API_VERSION;
355 for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++)
356 regs_buff[i] = QLCRD32(adapter, diag_registers[j]);
358 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
359 return;
361 regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/
363 regs_buff[i++] = 1; /* No. of tx ring */
364 regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
365 regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer);
367 regs_buff[i++] = 2; /* No. of rx ring */
368 regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer);
369 regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer);
371 regs_buff[i++] = adapter->max_sds_rings;
373 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
374 sds_ring = &(recv_ctx->sds_rings[ring]);
375 regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
379 static u32 qlcnic_test_link(struct net_device *dev)
381 struct qlcnic_adapter *adapter = netdev_priv(dev);
382 u32 val;
384 val = QLCRD32(adapter, CRB_XG_STATE_P3P);
385 val = XG_LINK_STATE_P3P(adapter->ahw.pci_func, val);
386 return (val == XG_LINK_UP_P3P) ? 0 : 1;
389 static int
390 qlcnic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
391 u8 *bytes)
393 struct qlcnic_adapter *adapter = netdev_priv(dev);
394 int offset;
395 int ret;
397 if (eeprom->len == 0)
398 return -EINVAL;
400 eeprom->magic = (adapter->pdev)->vendor |
401 ((adapter->pdev)->device << 16);
402 offset = eeprom->offset;
404 ret = qlcnic_rom_fast_read_words(adapter, offset, bytes,
405 eeprom->len);
406 if (ret < 0)
407 return ret;
409 return 0;
412 static void
413 qlcnic_get_ringparam(struct net_device *dev,
414 struct ethtool_ringparam *ring)
416 struct qlcnic_adapter *adapter = netdev_priv(dev);
418 ring->rx_pending = adapter->num_rxd;
419 ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
420 ring->tx_pending = adapter->num_txd;
422 ring->rx_max_pending = adapter->max_rxd;
423 ring->rx_jumbo_max_pending = adapter->max_jumbo_rxd;
424 ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
426 ring->rx_mini_max_pending = 0;
427 ring->rx_mini_pending = 0;
430 static u32
431 qlcnic_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
433 u32 num_desc;
434 num_desc = max(val, min);
435 num_desc = min(num_desc, max);
436 num_desc = roundup_pow_of_two(num_desc);
438 if (val != num_desc) {
439 printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
440 qlcnic_driver_name, r_name, num_desc, val);
443 return num_desc;
446 static int
447 qlcnic_set_ringparam(struct net_device *dev,
448 struct ethtool_ringparam *ring)
450 struct qlcnic_adapter *adapter = netdev_priv(dev);
451 u16 num_rxd, num_jumbo_rxd, num_txd;
453 if (ring->rx_mini_pending)
454 return -EOPNOTSUPP;
456 num_rxd = qlcnic_validate_ringparam(ring->rx_pending,
457 MIN_RCV_DESCRIPTORS, adapter->max_rxd, "rx");
459 num_jumbo_rxd = qlcnic_validate_ringparam(ring->rx_jumbo_pending,
460 MIN_JUMBO_DESCRIPTORS, adapter->max_jumbo_rxd,
461 "rx jumbo");
463 num_txd = qlcnic_validate_ringparam(ring->tx_pending,
464 MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
466 if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
467 num_jumbo_rxd == adapter->num_jumbo_rxd)
468 return 0;
470 adapter->num_rxd = num_rxd;
471 adapter->num_jumbo_rxd = num_jumbo_rxd;
472 adapter->num_txd = num_txd;
474 return qlcnic_reset_context(adapter);
477 static void
478 qlcnic_get_pauseparam(struct net_device *netdev,
479 struct ethtool_pauseparam *pause)
481 struct qlcnic_adapter *adapter = netdev_priv(netdev);
482 int port = adapter->physical_port;
483 __u32 val;
485 if (adapter->ahw.port_type == QLCNIC_GBE) {
486 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
487 return;
488 /* get flow control settings */
489 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
490 pause->rx_pause = qlcnic_gb_get_rx_flowctl(val);
491 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
492 switch (port) {
493 case 0:
494 pause->tx_pause = !(qlcnic_gb_get_gb0_mask(val));
495 break;
496 case 1:
497 pause->tx_pause = !(qlcnic_gb_get_gb1_mask(val));
498 break;
499 case 2:
500 pause->tx_pause = !(qlcnic_gb_get_gb2_mask(val));
501 break;
502 case 3:
503 default:
504 pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val));
505 break;
507 } else if (adapter->ahw.port_type == QLCNIC_XGBE) {
508 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
509 return;
510 pause->rx_pause = 1;
511 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
512 if (port == 0)
513 pause->tx_pause = !(qlcnic_xg_get_xg0_mask(val));
514 else
515 pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val));
516 } else {
517 dev_err(&netdev->dev, "Unknown board type: %x\n",
518 adapter->ahw.port_type);
522 static int
523 qlcnic_set_pauseparam(struct net_device *netdev,
524 struct ethtool_pauseparam *pause)
526 struct qlcnic_adapter *adapter = netdev_priv(netdev);
527 int port = adapter->physical_port;
528 __u32 val;
530 /* read mode */
531 if (adapter->ahw.port_type == QLCNIC_GBE) {
532 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
533 return -EIO;
534 /* set flow control */
535 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
537 if (pause->rx_pause)
538 qlcnic_gb_rx_flowctl(val);
539 else
540 qlcnic_gb_unset_rx_flowctl(val);
542 QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port),
543 val);
544 /* set autoneg */
545 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
546 switch (port) {
547 case 0:
548 if (pause->tx_pause)
549 qlcnic_gb_unset_gb0_mask(val);
550 else
551 qlcnic_gb_set_gb0_mask(val);
552 break;
553 case 1:
554 if (pause->tx_pause)
555 qlcnic_gb_unset_gb1_mask(val);
556 else
557 qlcnic_gb_set_gb1_mask(val);
558 break;
559 case 2:
560 if (pause->tx_pause)
561 qlcnic_gb_unset_gb2_mask(val);
562 else
563 qlcnic_gb_set_gb2_mask(val);
564 break;
565 case 3:
566 default:
567 if (pause->tx_pause)
568 qlcnic_gb_unset_gb3_mask(val);
569 else
570 qlcnic_gb_set_gb3_mask(val);
571 break;
573 QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val);
574 } else if (adapter->ahw.port_type == QLCNIC_XGBE) {
575 if (!pause->rx_pause || pause->autoneg)
576 return -EOPNOTSUPP;
578 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
579 return -EIO;
581 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
582 if (port == 0) {
583 if (pause->tx_pause)
584 qlcnic_xg_unset_xg0_mask(val);
585 else
586 qlcnic_xg_set_xg0_mask(val);
587 } else {
588 if (pause->tx_pause)
589 qlcnic_xg_unset_xg1_mask(val);
590 else
591 qlcnic_xg_set_xg1_mask(val);
593 QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val);
594 } else {
595 dev_err(&netdev->dev, "Unknown board type: %x\n",
596 adapter->ahw.port_type);
598 return 0;
601 static int qlcnic_reg_test(struct net_device *dev)
603 struct qlcnic_adapter *adapter = netdev_priv(dev);
604 u32 data_read;
606 data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0));
607 if ((data_read & 0xffff) != adapter->pdev->vendor)
608 return 1;
610 return 0;
613 static int qlcnic_get_sset_count(struct net_device *dev, int sset)
615 struct qlcnic_adapter *adapter = netdev_priv(dev);
616 switch (sset) {
617 case ETH_SS_TEST:
618 return QLCNIC_TEST_LEN;
619 case ETH_SS_STATS:
620 if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
621 return QLCNIC_STATS_LEN + QLCNIC_DEVICE_STATS_LEN;
622 return QLCNIC_STATS_LEN;
623 default:
624 return -EOPNOTSUPP;
628 static int qlcnic_irq_test(struct net_device *netdev)
630 struct qlcnic_adapter *adapter = netdev_priv(netdev);
631 int max_sds_rings = adapter->max_sds_rings;
632 int ret;
634 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
635 return -EIO;
637 ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST);
638 if (ret)
639 goto clear_it;
641 adapter->diag_cnt = 0;
642 ret = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func,
643 adapter->fw_hal_version, adapter->portnum,
644 0, 0, 0x00000011);
645 if (ret)
646 goto done;
648 msleep(10);
650 ret = !adapter->diag_cnt;
652 done:
653 qlcnic_diag_free_res(netdev, max_sds_rings);
655 clear_it:
656 adapter->max_sds_rings = max_sds_rings;
657 clear_bit(__QLCNIC_RESETTING, &adapter->state);
658 return ret;
661 static void
662 qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
663 u64 *data)
665 memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
667 data[0] = qlcnic_reg_test(dev);
668 if (data[0])
669 eth_test->flags |= ETH_TEST_FL_FAILED;
671 data[1] = (u64) qlcnic_test_link(dev);
672 if (data[1])
673 eth_test->flags |= ETH_TEST_FL_FAILED;
675 if (eth_test->flags & ETH_TEST_FL_OFFLINE) {
676 data[2] = qlcnic_irq_test(dev);
677 if (data[2])
678 eth_test->flags |= ETH_TEST_FL_FAILED;
684 static void
685 qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data)
687 struct qlcnic_adapter *adapter = netdev_priv(dev);
688 int index, i;
690 switch (stringset) {
691 case ETH_SS_TEST:
692 memcpy(data, *qlcnic_gstrings_test,
693 QLCNIC_TEST_LEN * ETH_GSTRING_LEN);
694 break;
695 case ETH_SS_STATS:
696 for (index = 0; index < QLCNIC_STATS_LEN; index++) {
697 memcpy(data + index * ETH_GSTRING_LEN,
698 qlcnic_gstrings_stats[index].stat_string,
699 ETH_GSTRING_LEN);
701 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
702 return;
703 for (i = 0; i < QLCNIC_DEVICE_STATS_LEN; index++, i++) {
704 memcpy(data + index * ETH_GSTRING_LEN,
705 qlcnic_device_gstrings_stats[i],
706 ETH_GSTRING_LEN);
711 #define QLCNIC_FILL_ESWITCH_STATS(VAL1) \
712 (((VAL1) == QLCNIC_ESW_STATS_NOT_AVAIL) ? 0 : VAL1)
714 static void
715 qlcnic_fill_device_stats(int *index, u64 *data,
716 struct __qlcnic_esw_statistics *stats)
718 int ind = *index;
720 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->unicast_frames);
721 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->multicast_frames);
722 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->broadcast_frames);
723 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->dropped_frames);
724 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->errors);
725 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->local_frames);
726 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->numbytes);
728 *index = ind;
731 static void
732 qlcnic_get_ethtool_stats(struct net_device *dev,
733 struct ethtool_stats *stats, u64 * data)
735 struct qlcnic_adapter *adapter = netdev_priv(dev);
736 struct qlcnic_esw_statistics port_stats;
737 int index, ret;
739 for (index = 0; index < QLCNIC_STATS_LEN; index++) {
740 char *p =
741 (char *)adapter +
742 qlcnic_gstrings_stats[index].stat_offset;
743 data[index] =
744 (qlcnic_gstrings_stats[index].sizeof_stat ==
745 sizeof(u64)) ? *(u64 *)p:(*(u32 *)p);
748 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
749 return;
751 memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics));
752 ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func,
753 QLCNIC_QUERY_RX_COUNTER, &port_stats.rx);
754 if (ret)
755 return;
757 qlcnic_fill_device_stats(&index, data, &port_stats.rx);
759 ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func,
760 QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
761 if (ret)
762 return;
764 qlcnic_fill_device_stats(&index, data, &port_stats.tx);
767 static int qlcnic_set_tx_csum(struct net_device *dev, u32 data)
769 struct qlcnic_adapter *adapter = netdev_priv(dev);
771 if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
772 return -EOPNOTSUPP;
773 if (data)
774 dev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
775 else
776 dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
778 return 0;
781 static u32 qlcnic_get_tx_csum(struct net_device *dev)
783 return dev->features & NETIF_F_IP_CSUM;
786 static u32 qlcnic_get_rx_csum(struct net_device *dev)
788 struct qlcnic_adapter *adapter = netdev_priv(dev);
789 return adapter->rx_csum;
792 static int qlcnic_set_rx_csum(struct net_device *dev, u32 data)
794 struct qlcnic_adapter *adapter = netdev_priv(dev);
796 if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
797 return -EOPNOTSUPP;
798 if (!!data) {
799 adapter->rx_csum = !!data;
800 return 0;
803 if (dev->features & NETIF_F_LRO) {
804 if (qlcnic_config_hw_lro(adapter, QLCNIC_LRO_DISABLED))
805 return -EIO;
807 dev->features &= ~NETIF_F_LRO;
808 qlcnic_send_lro_cleanup(adapter);
809 dev_info(&adapter->pdev->dev,
810 "disabling LRO as rx_csum is off\n");
812 adapter->rx_csum = !!data;
813 return 0;
816 static u32 qlcnic_get_tso(struct net_device *dev)
818 return (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) != 0;
821 static int qlcnic_set_tso(struct net_device *dev, u32 data)
823 struct qlcnic_adapter *adapter = netdev_priv(dev);
824 if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO))
825 return -EOPNOTSUPP;
826 if (data)
827 dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
828 else
829 dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
831 return 0;
834 static int qlcnic_blink_led(struct net_device *dev, u32 val)
836 struct qlcnic_adapter *adapter = netdev_priv(dev);
837 int max_sds_rings = adapter->max_sds_rings;
838 int dev_down = 0;
839 int ret;
841 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
842 dev_down = 1;
843 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
844 return -EIO;
846 ret = qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST);
847 if (ret) {
848 clear_bit(__QLCNIC_RESETTING, &adapter->state);
849 return ret;
853 ret = adapter->nic_ops->config_led(adapter, 1, 0xf);
854 if (ret) {
855 dev_err(&adapter->pdev->dev,
856 "Failed to set LED blink state.\n");
857 goto done;
860 msleep_interruptible(val * 1000);
862 ret = adapter->nic_ops->config_led(adapter, 0, 0xf);
863 if (ret) {
864 dev_err(&adapter->pdev->dev,
865 "Failed to reset LED blink state.\n");
866 goto done;
869 done:
870 if (dev_down) {
871 qlcnic_diag_free_res(dev, max_sds_rings);
872 clear_bit(__QLCNIC_RESETTING, &adapter->state);
874 return ret;
878 static void
879 qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
881 struct qlcnic_adapter *adapter = netdev_priv(dev);
882 u32 wol_cfg;
884 wol->supported = 0;
885 wol->wolopts = 0;
887 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
888 if (wol_cfg & (1UL << adapter->portnum))
889 wol->supported |= WAKE_MAGIC;
891 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
892 if (wol_cfg & (1UL << adapter->portnum))
893 wol->wolopts |= WAKE_MAGIC;
896 static int
897 qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
899 struct qlcnic_adapter *adapter = netdev_priv(dev);
900 u32 wol_cfg;
902 if (wol->wolopts & ~WAKE_MAGIC)
903 return -EOPNOTSUPP;
905 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
906 if (!(wol_cfg & (1 << adapter->portnum)))
907 return -EOPNOTSUPP;
909 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
910 if (wol->wolopts & WAKE_MAGIC)
911 wol_cfg |= 1UL << adapter->portnum;
912 else
913 wol_cfg &= ~(1UL << adapter->portnum);
915 QLCWR32(adapter, QLCNIC_WOL_CONFIG, wol_cfg);
917 return 0;
921 * Set the coalescing parameters. Currently only normal is supported.
922 * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
923 * firmware coalescing to default.
925 static int qlcnic_set_intr_coalesce(struct net_device *netdev,
926 struct ethtool_coalesce *ethcoal)
928 struct qlcnic_adapter *adapter = netdev_priv(netdev);
930 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
931 return -EINVAL;
934 * Return Error if unsupported values or
935 * unsupported parameters are set.
937 if (ethcoal->rx_coalesce_usecs > 0xffff ||
938 ethcoal->rx_max_coalesced_frames > 0xffff ||
939 ethcoal->tx_coalesce_usecs > 0xffff ||
940 ethcoal->tx_max_coalesced_frames > 0xffff ||
941 ethcoal->rx_coalesce_usecs_irq ||
942 ethcoal->rx_max_coalesced_frames_irq ||
943 ethcoal->tx_coalesce_usecs_irq ||
944 ethcoal->tx_max_coalesced_frames_irq ||
945 ethcoal->stats_block_coalesce_usecs ||
946 ethcoal->use_adaptive_rx_coalesce ||
947 ethcoal->use_adaptive_tx_coalesce ||
948 ethcoal->pkt_rate_low ||
949 ethcoal->rx_coalesce_usecs_low ||
950 ethcoal->rx_max_coalesced_frames_low ||
951 ethcoal->tx_coalesce_usecs_low ||
952 ethcoal->tx_max_coalesced_frames_low ||
953 ethcoal->pkt_rate_high ||
954 ethcoal->rx_coalesce_usecs_high ||
955 ethcoal->rx_max_coalesced_frames_high ||
956 ethcoal->tx_coalesce_usecs_high ||
957 ethcoal->tx_max_coalesced_frames_high)
958 return -EINVAL;
960 if (!ethcoal->rx_coalesce_usecs ||
961 !ethcoal->rx_max_coalesced_frames) {
962 adapter->coal.flags = QLCNIC_INTR_DEFAULT;
963 adapter->coal.normal.data.rx_time_us =
964 QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
965 adapter->coal.normal.data.rx_packets =
966 QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS;
967 } else {
968 adapter->coal.flags = 0;
969 adapter->coal.normal.data.rx_time_us =
970 ethcoal->rx_coalesce_usecs;
971 adapter->coal.normal.data.rx_packets =
972 ethcoal->rx_max_coalesced_frames;
974 adapter->coal.normal.data.tx_time_us = ethcoal->tx_coalesce_usecs;
975 adapter->coal.normal.data.tx_packets =
976 ethcoal->tx_max_coalesced_frames;
978 qlcnic_config_intr_coalesce(adapter);
980 return 0;
983 static int qlcnic_get_intr_coalesce(struct net_device *netdev,
984 struct ethtool_coalesce *ethcoal)
986 struct qlcnic_adapter *adapter = netdev_priv(netdev);
988 if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
989 return -EINVAL;
991 ethcoal->rx_coalesce_usecs = adapter->coal.normal.data.rx_time_us;
992 ethcoal->tx_coalesce_usecs = adapter->coal.normal.data.tx_time_us;
993 ethcoal->rx_max_coalesced_frames =
994 adapter->coal.normal.data.rx_packets;
995 ethcoal->tx_max_coalesced_frames =
996 adapter->coal.normal.data.tx_packets;
998 return 0;
1001 static int qlcnic_set_flags(struct net_device *netdev, u32 data)
1003 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1004 int hw_lro;
1006 if (data & ~ETH_FLAG_LRO)
1007 return -EINVAL;
1009 if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO))
1010 return -EINVAL;
1012 if (!adapter->rx_csum) {
1013 dev_info(&adapter->pdev->dev, "rx csum is off, "
1014 "cannot toggle lro\n");
1015 return -EINVAL;
1018 if ((data & ETH_FLAG_LRO) && (netdev->features & NETIF_F_LRO))
1019 return 0;
1021 if (data & ETH_FLAG_LRO) {
1022 hw_lro = QLCNIC_LRO_ENABLED;
1023 netdev->features |= NETIF_F_LRO;
1024 } else {
1025 hw_lro = 0;
1026 netdev->features &= ~NETIF_F_LRO;
1029 if (qlcnic_config_hw_lro(adapter, hw_lro))
1030 return -EIO;
1032 if ((hw_lro == 0) && qlcnic_send_lro_cleanup(adapter))
1033 return -EIO;
1036 return 0;
1039 static u32 qlcnic_get_msglevel(struct net_device *netdev)
1041 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1043 return adapter->msg_enable;
1046 static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
1048 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1050 adapter->msg_enable = msglvl;
1053 const struct ethtool_ops qlcnic_ethtool_ops = {
1054 .get_settings = qlcnic_get_settings,
1055 .set_settings = qlcnic_set_settings,
1056 .get_drvinfo = qlcnic_get_drvinfo,
1057 .get_regs_len = qlcnic_get_regs_len,
1058 .get_regs = qlcnic_get_regs,
1059 .get_link = ethtool_op_get_link,
1060 .get_eeprom_len = qlcnic_get_eeprom_len,
1061 .get_eeprom = qlcnic_get_eeprom,
1062 .get_ringparam = qlcnic_get_ringparam,
1063 .set_ringparam = qlcnic_set_ringparam,
1064 .get_pauseparam = qlcnic_get_pauseparam,
1065 .set_pauseparam = qlcnic_set_pauseparam,
1066 .get_tx_csum = qlcnic_get_tx_csum,
1067 .set_tx_csum = qlcnic_set_tx_csum,
1068 .set_sg = ethtool_op_set_sg,
1069 .get_tso = qlcnic_get_tso,
1070 .set_tso = qlcnic_set_tso,
1071 .get_wol = qlcnic_get_wol,
1072 .set_wol = qlcnic_set_wol,
1073 .self_test = qlcnic_diag_test,
1074 .get_strings = qlcnic_get_strings,
1075 .get_ethtool_stats = qlcnic_get_ethtool_stats,
1076 .get_sset_count = qlcnic_get_sset_count,
1077 .get_rx_csum = qlcnic_get_rx_csum,
1078 .set_rx_csum = qlcnic_set_rx_csum,
1079 .get_coalesce = qlcnic_get_intr_coalesce,
1080 .set_coalesce = qlcnic_set_intr_coalesce,
1081 .get_flags = ethtool_op_get_flags,
1082 .set_flags = qlcnic_set_flags,
1083 .phys_id = qlcnic_blink_led,
1084 .set_msglevel = qlcnic_set_msglevel,
1085 .get_msglevel = qlcnic_get_msglevel,