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