Merge tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck...
[GitHub/mt8127/android_kernel_alcatel_ttab.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 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
850
851 cmd.req.arg[1] = ahw->pci_func;
852 ret = qlcnic_issue_cmd(adapter, &cmd);
853 if (ret)
854 goto done;
855
856 usleep_range(1000, 12000);
857 ret = !ahw->diag_cnt;
858
859 done:
860 qlcnic_free_mbx_args(&cmd);
861 qlcnic_diag_free_res(netdev, max_sds_rings);
862
863 clear_diag_irq:
864 adapter->max_sds_rings = max_sds_rings;
865 clear_bit(__QLCNIC_RESETTING, &adapter->state);
866 return ret;
867 }
868
869 #define QLCNIC_ILB_PKT_SIZE 64
870 #define QLCNIC_NUM_ILB_PKT 16
871 #define QLCNIC_ILB_MAX_RCV_LOOP 10
872 #define QLCNIC_LB_PKT_POLL_DELAY_MSEC 1
873 #define QLCNIC_LB_PKT_POLL_COUNT 20
874
875 static void qlcnic_create_loopback_buff(unsigned char *data, u8 mac[])
876 {
877 unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00};
878
879 memset(data, 0x4e, QLCNIC_ILB_PKT_SIZE);
880
881 memcpy(data, mac, ETH_ALEN);
882 memcpy(data + ETH_ALEN, mac, ETH_ALEN);
883
884 memcpy(data + 2 * ETH_ALEN, random_data, sizeof(random_data));
885 }
886
887 int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[])
888 {
889 unsigned char buff[QLCNIC_ILB_PKT_SIZE];
890 qlcnic_create_loopback_buff(buff, mac);
891 return memcmp(data, buff, QLCNIC_ILB_PKT_SIZE);
892 }
893
894 int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
895 {
896 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
897 struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0];
898 struct sk_buff *skb;
899 int i, loop, cnt = 0;
900
901 for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) {
902 skb = netdev_alloc_skb(adapter->netdev, QLCNIC_ILB_PKT_SIZE);
903 qlcnic_create_loopback_buff(skb->data, adapter->mac_addr);
904 skb_put(skb, QLCNIC_ILB_PKT_SIZE);
905 adapter->ahw->diag_cnt = 0;
906 qlcnic_xmit_frame(skb, adapter->netdev);
907 loop = 0;
908
909 do {
910 msleep(QLCNIC_LB_PKT_POLL_DELAY_MSEC);
911 qlcnic_process_rcv_ring_diag(sds_ring);
912 if (loop++ > QLCNIC_LB_PKT_POLL_COUNT)
913 break;
914 } while (!adapter->ahw->diag_cnt);
915
916 dev_kfree_skb_any(skb);
917
918 if (!adapter->ahw->diag_cnt)
919 dev_warn(&adapter->pdev->dev,
920 "LB Test: packet #%d was not received\n",
921 i + 1);
922 else
923 cnt++;
924 }
925 if (cnt != i) {
926 dev_err(&adapter->pdev->dev,
927 "LB Test: failed, TX[%d], RX[%d]\n", i, cnt);
928 if (mode != QLCNIC_ILB_MODE)
929 dev_warn(&adapter->pdev->dev,
930 "WARNING: Please check loopback cable\n");
931 return -1;
932 }
933 return 0;
934 }
935
936 int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
937 {
938 struct qlcnic_adapter *adapter = netdev_priv(netdev);
939 int max_sds_rings = adapter->max_sds_rings;
940 struct qlcnic_host_sds_ring *sds_ring;
941 struct qlcnic_hardware_context *ahw = adapter->ahw;
942 int loop = 0;
943 int ret;
944
945 if (qlcnic_83xx_check(adapter))
946 return qlcnic_83xx_loopback_test(netdev, mode);
947
948 if (!(ahw->capabilities & QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK)) {
949 dev_info(&adapter->pdev->dev,
950 "Firmware do not support loopback test\n");
951 return -EOPNOTSUPP;
952 }
953
954 dev_warn(&adapter->pdev->dev, "%s loopback test in progress\n",
955 mode == QLCNIC_ILB_MODE ? "internal" : "external");
956 if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
957 dev_warn(&adapter->pdev->dev,
958 "Loopback test not supported in nonprivileged mode\n");
959 return 0;
960 }
961
962 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
963 return -EBUSY;
964
965 ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
966 if (ret)
967 goto clear_it;
968
969 sds_ring = &adapter->recv_ctx->sds_rings[0];
970 ret = qlcnic_set_lb_mode(adapter, mode);
971 if (ret)
972 goto free_res;
973
974 ahw->diag_cnt = 0;
975 do {
976 msleep(500);
977 qlcnic_process_rcv_ring_diag(sds_ring);
978 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
979 netdev_info(netdev, "firmware didnt respond to loopback"
980 " configure request\n");
981 ret = -QLCNIC_FW_NOT_RESPOND;
982 goto free_res;
983 } else if (adapter->ahw->diag_cnt) {
984 ret = adapter->ahw->diag_cnt;
985 goto free_res;
986 }
987 } while (!QLCNIC_IS_LB_CONFIGURED(ahw->loopback_state));
988
989 ret = qlcnic_do_lb_test(adapter, mode);
990
991 qlcnic_clear_lb_mode(adapter, mode);
992
993 free_res:
994 qlcnic_diag_free_res(netdev, max_sds_rings);
995
996 clear_it:
997 adapter->max_sds_rings = max_sds_rings;
998 clear_bit(__QLCNIC_RESETTING, &adapter->state);
999 return ret;
1000 }
1001
1002 static void
1003 qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
1004 u64 *data)
1005 {
1006 memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
1007
1008 data[0] = qlcnic_reg_test(dev);
1009 if (data[0])
1010 eth_test->flags |= ETH_TEST_FL_FAILED;
1011
1012 data[1] = (u64) qlcnic_test_link(dev);
1013 if (data[1])
1014 eth_test->flags |= ETH_TEST_FL_FAILED;
1015
1016 if (eth_test->flags & ETH_TEST_FL_OFFLINE) {
1017 data[2] = qlcnic_irq_test(dev);
1018 if (data[2])
1019 eth_test->flags |= ETH_TEST_FL_FAILED;
1020
1021 data[3] = qlcnic_loopback_test(dev, QLCNIC_ILB_MODE);
1022 if (data[3])
1023 eth_test->flags |= ETH_TEST_FL_FAILED;
1024
1025 data[4] = qlcnic_eeprom_test(dev);
1026 if (data[4])
1027 eth_test->flags |= ETH_TEST_FL_FAILED;
1028 }
1029 }
1030
1031 static void
1032 qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 *data)
1033 {
1034 struct qlcnic_adapter *adapter = netdev_priv(dev);
1035 int index, i, num_stats;
1036
1037 switch (stringset) {
1038 case ETH_SS_TEST:
1039 memcpy(data, *qlcnic_gstrings_test,
1040 QLCNIC_TEST_LEN * ETH_GSTRING_LEN);
1041 break;
1042 case ETH_SS_STATS:
1043 for (index = 0; index < QLCNIC_STATS_LEN; index++) {
1044 memcpy(data + index * ETH_GSTRING_LEN,
1045 qlcnic_gstrings_stats[index].stat_string,
1046 ETH_GSTRING_LEN);
1047 }
1048 if (qlcnic_83xx_check(adapter)) {
1049 num_stats = ARRAY_SIZE(qlcnic_83xx_tx_stats_strings);
1050 for (i = 0; i < num_stats; i++, index++)
1051 memcpy(data + index * ETH_GSTRING_LEN,
1052 qlcnic_83xx_tx_stats_strings[i],
1053 ETH_GSTRING_LEN);
1054 num_stats = ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
1055 for (i = 0; i < num_stats; i++, index++)
1056 memcpy(data + index * ETH_GSTRING_LEN,
1057 qlcnic_83xx_mac_stats_strings[i],
1058 ETH_GSTRING_LEN);
1059 num_stats = ARRAY_SIZE(qlcnic_83xx_rx_stats_strings);
1060 for (i = 0; i < num_stats; i++, index++)
1061 memcpy(data + index * ETH_GSTRING_LEN,
1062 qlcnic_83xx_rx_stats_strings[i],
1063 ETH_GSTRING_LEN);
1064 return;
1065 } else {
1066 num_stats = ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
1067 for (i = 0; i < num_stats; i++, index++)
1068 memcpy(data + index * ETH_GSTRING_LEN,
1069 qlcnic_83xx_mac_stats_strings[i],
1070 ETH_GSTRING_LEN);
1071 }
1072 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1073 return;
1074 num_stats = ARRAY_SIZE(qlcnic_device_gstrings_stats);
1075 for (i = 0; i < num_stats; index++, i++) {
1076 memcpy(data + index * ETH_GSTRING_LEN,
1077 qlcnic_device_gstrings_stats[i],
1078 ETH_GSTRING_LEN);
1079 }
1080 }
1081 }
1082
1083 static u64 *qlcnic_fill_stats(u64 *data, void *stats, int type)
1084 {
1085 if (type == QLCNIC_MAC_STATS) {
1086 struct qlcnic_mac_statistics *mac_stats =
1087 (struct qlcnic_mac_statistics *)stats;
1088 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_frames);
1089 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_bytes);
1090 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_mcast_pkts);
1091 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_bcast_pkts);
1092 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_pause_cnt);
1093 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_ctrl_pkt);
1094 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_64b_pkts);
1095 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_127b_pkts);
1096 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_255b_pkts);
1097 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_511b_pkts);
1098 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1023b_pkts);
1099 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1518b_pkts);
1100 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_gt_1518b_pkts);
1101 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_frames);
1102 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_bytes);
1103 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_mcast_pkts);
1104 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_bcast_pkts);
1105 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_pause_cnt);
1106 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_ctrl_pkt);
1107 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_64b_pkts);
1108 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_127b_pkts);
1109 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_255b_pkts);
1110 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_511b_pkts);
1111 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1023b_pkts);
1112 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1518b_pkts);
1113 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_gt_1518b_pkts);
1114 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_error);
1115 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_small);
1116 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_large);
1117 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_jabber);
1118 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_dropped);
1119 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_crc_error);
1120 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_align_error);
1121 } else if (type == QLCNIC_ESW_STATS) {
1122 struct __qlcnic_esw_statistics *esw_stats =
1123 (struct __qlcnic_esw_statistics *)stats;
1124 *data++ = QLCNIC_FILL_STATS(esw_stats->unicast_frames);
1125 *data++ = QLCNIC_FILL_STATS(esw_stats->multicast_frames);
1126 *data++ = QLCNIC_FILL_STATS(esw_stats->broadcast_frames);
1127 *data++ = QLCNIC_FILL_STATS(esw_stats->dropped_frames);
1128 *data++ = QLCNIC_FILL_STATS(esw_stats->errors);
1129 *data++ = QLCNIC_FILL_STATS(esw_stats->local_frames);
1130 *data++ = QLCNIC_FILL_STATS(esw_stats->numbytes);
1131 }
1132 return data;
1133 }
1134
1135 static void qlcnic_get_ethtool_stats(struct net_device *dev,
1136 struct ethtool_stats *stats, u64 *data)
1137 {
1138 struct qlcnic_adapter *adapter = netdev_priv(dev);
1139 struct qlcnic_esw_statistics port_stats;
1140 struct qlcnic_mac_statistics mac_stats;
1141 int index, ret, length, size;
1142 char *p;
1143
1144 memset(data, 0, stats->n_stats * sizeof(u64));
1145 length = QLCNIC_STATS_LEN;
1146 for (index = 0; index < length; index++) {
1147 p = (char *)adapter + qlcnic_gstrings_stats[index].stat_offset;
1148 size = qlcnic_gstrings_stats[index].sizeof_stat;
1149 *data++ = (size == sizeof(u64)) ? (*(u64 *)p) : ((*(u32 *)p));
1150 }
1151
1152 if (qlcnic_83xx_check(adapter)) {
1153 if (adapter->ahw->linkup)
1154 qlcnic_83xx_get_stats(adapter, data);
1155 return;
1156 } else {
1157 /* Retrieve MAC statistics from firmware */
1158 memset(&mac_stats, 0, sizeof(struct qlcnic_mac_statistics));
1159 qlcnic_get_mac_stats(adapter, &mac_stats);
1160 data = qlcnic_fill_stats(data, &mac_stats, QLCNIC_MAC_STATS);
1161 }
1162
1163 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1164 return;
1165
1166 memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics));
1167 ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
1168 QLCNIC_QUERY_RX_COUNTER, &port_stats.rx);
1169 if (ret)
1170 return;
1171
1172 data = qlcnic_fill_stats(data, &port_stats.rx, QLCNIC_ESW_STATS);
1173 ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
1174 QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
1175 if (ret)
1176 return;
1177
1178 qlcnic_fill_stats(data, &port_stats.tx, QLCNIC_ESW_STATS);
1179 }
1180
1181 static int qlcnic_set_led(struct net_device *dev,
1182 enum ethtool_phys_id_state state)
1183 {
1184 struct qlcnic_adapter *adapter = netdev_priv(dev);
1185 int max_sds_rings = adapter->max_sds_rings;
1186 int err = -EIO, active = 1;
1187
1188 if (qlcnic_83xx_check(adapter))
1189 return qlcnic_83xx_set_led(dev, state);
1190
1191 if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1192 netdev_warn(dev, "LED test not supported for non "
1193 "privilege function\n");
1194 return -EOPNOTSUPP;
1195 }
1196
1197 switch (state) {
1198 case ETHTOOL_ID_ACTIVE:
1199 if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
1200 return -EBUSY;
1201
1202 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1203 break;
1204
1205 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
1206 if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
1207 break;
1208 set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
1209 }
1210
1211 if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) {
1212 err = 0;
1213 break;
1214 }
1215
1216 dev_err(&adapter->pdev->dev,
1217 "Failed to set LED blink state.\n");
1218 break;
1219
1220 case ETHTOOL_ID_INACTIVE:
1221 active = 0;
1222
1223 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1224 break;
1225
1226 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
1227 if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
1228 break;
1229 set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
1230 }
1231
1232 if (adapter->nic_ops->config_led(adapter, 0, 0xf))
1233 dev_err(&adapter->pdev->dev,
1234 "Failed to reset LED blink state.\n");
1235
1236 break;
1237
1238 default:
1239 return -EINVAL;
1240 }
1241
1242 if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
1243 qlcnic_diag_free_res(dev, max_sds_rings);
1244
1245 if (!active || err)
1246 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
1247
1248 return err;
1249 }
1250
1251 static void
1252 qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1253 {
1254 struct qlcnic_adapter *adapter = netdev_priv(dev);
1255 u32 wol_cfg;
1256
1257 if (qlcnic_83xx_check(adapter))
1258 return;
1259 wol->supported = 0;
1260 wol->wolopts = 0;
1261
1262 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
1263 if (wol_cfg & (1UL << adapter->portnum))
1264 wol->supported |= WAKE_MAGIC;
1265
1266 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
1267 if (wol_cfg & (1UL << adapter->portnum))
1268 wol->wolopts |= WAKE_MAGIC;
1269 }
1270
1271 static int
1272 qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1273 {
1274 struct qlcnic_adapter *adapter = netdev_priv(dev);
1275 u32 wol_cfg;
1276
1277 if (qlcnic_83xx_check(adapter))
1278 return -EOPNOTSUPP;
1279 if (wol->wolopts & ~WAKE_MAGIC)
1280 return -EINVAL;
1281
1282 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
1283 if (!(wol_cfg & (1 << adapter->portnum)))
1284 return -EOPNOTSUPP;
1285
1286 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
1287 if (wol->wolopts & WAKE_MAGIC)
1288 wol_cfg |= 1UL << adapter->portnum;
1289 else
1290 wol_cfg &= ~(1UL << adapter->portnum);
1291
1292 QLCWR32(adapter, QLCNIC_WOL_CONFIG, wol_cfg);
1293
1294 return 0;
1295 }
1296
1297 /*
1298 * Set the coalescing parameters. Currently only normal is supported.
1299 * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
1300 * firmware coalescing to default.
1301 */
1302 static int qlcnic_set_intr_coalesce(struct net_device *netdev,
1303 struct ethtool_coalesce *ethcoal)
1304 {
1305 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1306 struct qlcnic_nic_intr_coalesce *coal;
1307 u32 rx_coalesce_usecs, rx_max_frames;
1308 u32 tx_coalesce_usecs, tx_max_frames;
1309
1310 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
1311 return -EINVAL;
1312
1313 /*
1314 * Return Error if unsupported values or
1315 * unsupported parameters are set.
1316 */
1317 if (ethcoal->rx_coalesce_usecs > 0xffff ||
1318 ethcoal->rx_max_coalesced_frames > 0xffff ||
1319 ethcoal->tx_coalesce_usecs > 0xffff ||
1320 ethcoal->tx_max_coalesced_frames > 0xffff ||
1321 ethcoal->rx_coalesce_usecs_irq ||
1322 ethcoal->rx_max_coalesced_frames_irq ||
1323 ethcoal->tx_coalesce_usecs_irq ||
1324 ethcoal->tx_max_coalesced_frames_irq ||
1325 ethcoal->stats_block_coalesce_usecs ||
1326 ethcoal->use_adaptive_rx_coalesce ||
1327 ethcoal->use_adaptive_tx_coalesce ||
1328 ethcoal->pkt_rate_low ||
1329 ethcoal->rx_coalesce_usecs_low ||
1330 ethcoal->rx_max_coalesced_frames_low ||
1331 ethcoal->tx_coalesce_usecs_low ||
1332 ethcoal->tx_max_coalesced_frames_low ||
1333 ethcoal->pkt_rate_high ||
1334 ethcoal->rx_coalesce_usecs_high ||
1335 ethcoal->rx_max_coalesced_frames_high ||
1336 ethcoal->tx_coalesce_usecs_high ||
1337 ethcoal->tx_max_coalesced_frames_high)
1338 return -EINVAL;
1339
1340 coal = &adapter->ahw->coal;
1341
1342 if (qlcnic_83xx_check(adapter)) {
1343 if (!ethcoal->tx_coalesce_usecs ||
1344 !ethcoal->tx_max_coalesced_frames ||
1345 !ethcoal->rx_coalesce_usecs ||
1346 !ethcoal->rx_max_coalesced_frames) {
1347 coal->flag = QLCNIC_INTR_DEFAULT;
1348 coal->type = QLCNIC_INTR_COAL_TYPE_RX;
1349 coal->rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
1350 coal->rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
1351 coal->tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US;
1352 coal->tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS;
1353 } else {
1354 tx_coalesce_usecs = ethcoal->tx_coalesce_usecs;
1355 tx_max_frames = ethcoal->tx_max_coalesced_frames;
1356 rx_coalesce_usecs = ethcoal->rx_coalesce_usecs;
1357 rx_max_frames = ethcoal->rx_max_coalesced_frames;
1358 coal->flag = 0;
1359
1360 if ((coal->rx_time_us == rx_coalesce_usecs) &&
1361 (coal->rx_packets == rx_max_frames)) {
1362 coal->type = QLCNIC_INTR_COAL_TYPE_TX;
1363 coal->tx_time_us = tx_coalesce_usecs;
1364 coal->tx_packets = tx_max_frames;
1365 } else if ((coal->tx_time_us == tx_coalesce_usecs) &&
1366 (coal->tx_packets == tx_max_frames)) {
1367 coal->type = QLCNIC_INTR_COAL_TYPE_RX;
1368 coal->rx_time_us = rx_coalesce_usecs;
1369 coal->rx_packets = rx_max_frames;
1370 } else {
1371 coal->type = QLCNIC_INTR_COAL_TYPE_RX;
1372 coal->rx_time_us = rx_coalesce_usecs;
1373 coal->rx_packets = rx_max_frames;
1374 coal->tx_time_us = tx_coalesce_usecs;
1375 coal->tx_packets = tx_max_frames;
1376 }
1377 }
1378 } else {
1379 if (!ethcoal->rx_coalesce_usecs ||
1380 !ethcoal->rx_max_coalesced_frames) {
1381 coal->flag = QLCNIC_INTR_DEFAULT;
1382 coal->rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
1383 coal->rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
1384 } else {
1385 coal->flag = 0;
1386 coal->rx_time_us = ethcoal->rx_coalesce_usecs;
1387 coal->rx_packets = ethcoal->rx_max_coalesced_frames;
1388 }
1389 }
1390
1391 qlcnic_config_intr_coalesce(adapter);
1392
1393 return 0;
1394 }
1395
1396 static int qlcnic_get_intr_coalesce(struct net_device *netdev,
1397 struct ethtool_coalesce *ethcoal)
1398 {
1399 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1400
1401 if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
1402 return -EINVAL;
1403
1404 ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us;
1405 ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets;
1406 ethcoal->tx_coalesce_usecs = adapter->ahw->coal.tx_time_us;
1407 ethcoal->tx_max_coalesced_frames = adapter->ahw->coal.tx_packets;
1408
1409 return 0;
1410 }
1411
1412 static u32 qlcnic_get_msglevel(struct net_device *netdev)
1413 {
1414 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1415
1416 return adapter->ahw->msg_enable;
1417 }
1418
1419 static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
1420 {
1421 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1422
1423 adapter->ahw->msg_enable = msglvl;
1424 }
1425
1426 static int
1427 qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
1428 {
1429 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1430 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1431
1432 if (!fw_dump->tmpl_hdr) {
1433 netdev_err(adapter->netdev, "FW Dump not supported\n");
1434 return -ENOTSUPP;
1435 }
1436
1437 if (fw_dump->clr)
1438 dump->len = fw_dump->tmpl_hdr->size + fw_dump->size;
1439 else
1440 dump->len = 0;
1441
1442 if (!fw_dump->enable)
1443 dump->flag = ETH_FW_DUMP_DISABLE;
1444 else
1445 dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
1446
1447 dump->version = adapter->fw_version;
1448 return 0;
1449 }
1450
1451 static int
1452 qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
1453 void *buffer)
1454 {
1455 int i, copy_sz;
1456 u32 *hdr_ptr;
1457 __le32 *data;
1458 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1459 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1460
1461 if (!fw_dump->tmpl_hdr) {
1462 netdev_err(netdev, "FW Dump not supported\n");
1463 return -ENOTSUPP;
1464 }
1465
1466 if (!fw_dump->clr) {
1467 netdev_info(netdev, "Dump not available\n");
1468 return -EINVAL;
1469 }
1470 /* Copy template header first */
1471 copy_sz = fw_dump->tmpl_hdr->size;
1472 hdr_ptr = (u32 *) fw_dump->tmpl_hdr;
1473 data = buffer;
1474 for (i = 0; i < copy_sz/sizeof(u32); i++)
1475 *data++ = cpu_to_le32(*hdr_ptr++);
1476
1477 /* Copy captured dump data */
1478 memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size);
1479 dump->len = copy_sz + fw_dump->size;
1480 dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
1481
1482 /* Free dump area once data has been captured */
1483 vfree(fw_dump->data);
1484 fw_dump->data = NULL;
1485 fw_dump->clr = 0;
1486 netdev_info(netdev, "extracted the FW dump Successfully\n");
1487 return 0;
1488 }
1489
1490 static int
1491 qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
1492 {
1493 int i;
1494 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1495 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1496 u32 state;
1497
1498 switch (val->flag) {
1499 case QLCNIC_FORCE_FW_DUMP_KEY:
1500 if (!fw_dump->tmpl_hdr) {
1501 netdev_err(netdev, "FW dump not supported\n");
1502 return -ENOTSUPP;
1503 }
1504 if (!fw_dump->enable) {
1505 netdev_info(netdev, "FW dump not enabled\n");
1506 return 0;
1507 }
1508 if (fw_dump->clr) {
1509 netdev_info(netdev,
1510 "Previous dump not cleared, not forcing dump\n");
1511 return 0;
1512 }
1513 netdev_info(netdev, "Forcing a FW dump\n");
1514 qlcnic_dev_request_reset(adapter, val->flag);
1515 break;
1516 case QLCNIC_DISABLE_FW_DUMP:
1517 if (fw_dump->enable && fw_dump->tmpl_hdr) {
1518 netdev_info(netdev, "Disabling FW dump\n");
1519 fw_dump->enable = 0;
1520 }
1521 return 0;
1522 case QLCNIC_ENABLE_FW_DUMP:
1523 if (!fw_dump->tmpl_hdr) {
1524 netdev_err(netdev, "FW dump not supported\n");
1525 return -ENOTSUPP;
1526 }
1527 if (!fw_dump->enable) {
1528 netdev_info(netdev, "Enabling FW dump\n");
1529 fw_dump->enable = 1;
1530 }
1531 return 0;
1532 case QLCNIC_FORCE_FW_RESET:
1533 netdev_info(netdev, "Forcing a FW reset\n");
1534 qlcnic_dev_request_reset(adapter, val->flag);
1535 adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
1536 return 0;
1537 case QLCNIC_SET_QUIESCENT:
1538 case QLCNIC_RESET_QUIESCENT:
1539 state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
1540 if (state == QLCNIC_DEV_FAILED || (state == QLCNIC_DEV_BADBAD))
1541 netdev_info(netdev, "Device in FAILED state\n");
1542 return 0;
1543 default:
1544 if (!fw_dump->tmpl_hdr) {
1545 netdev_err(netdev, "FW dump not supported\n");
1546 return -ENOTSUPP;
1547 }
1548 for (i = 0; i < ARRAY_SIZE(qlcnic_fw_dump_level); i++) {
1549 if (val->flag == qlcnic_fw_dump_level[i]) {
1550 fw_dump->tmpl_hdr->drv_cap_mask =
1551 val->flag;
1552 netdev_info(netdev, "Driver mask changed to: 0x%x\n",
1553 fw_dump->tmpl_hdr->drv_cap_mask);
1554 return 0;
1555 }
1556 }
1557 netdev_info(netdev, "Invalid dump level: 0x%x\n", val->flag);
1558 return -EINVAL;
1559 }
1560 return 0;
1561 }
1562
1563 const struct ethtool_ops qlcnic_ethtool_ops = {
1564 .get_settings = qlcnic_get_settings,
1565 .set_settings = qlcnic_set_settings,
1566 .get_drvinfo = qlcnic_get_drvinfo,
1567 .get_regs_len = qlcnic_get_regs_len,
1568 .get_regs = qlcnic_get_regs,
1569 .get_link = ethtool_op_get_link,
1570 .get_eeprom_len = qlcnic_get_eeprom_len,
1571 .get_eeprom = qlcnic_get_eeprom,
1572 .get_ringparam = qlcnic_get_ringparam,
1573 .set_ringparam = qlcnic_set_ringparam,
1574 .get_channels = qlcnic_get_channels,
1575 .set_channels = qlcnic_set_channels,
1576 .get_pauseparam = qlcnic_get_pauseparam,
1577 .set_pauseparam = qlcnic_set_pauseparam,
1578 .get_wol = qlcnic_get_wol,
1579 .set_wol = qlcnic_set_wol,
1580 .self_test = qlcnic_diag_test,
1581 .get_strings = qlcnic_get_strings,
1582 .get_ethtool_stats = qlcnic_get_ethtool_stats,
1583 .get_sset_count = qlcnic_get_sset_count,
1584 .get_coalesce = qlcnic_get_intr_coalesce,
1585 .set_coalesce = qlcnic_set_intr_coalesce,
1586 .set_phys_id = qlcnic_set_led,
1587 .set_msglevel = qlcnic_set_msglevel,
1588 .get_msglevel = qlcnic_get_msglevel,
1589 .get_dump_flag = qlcnic_get_dump_flag,
1590 .get_dump_data = qlcnic_get_dump_data,
1591 .set_dump = qlcnic_set_dump,
1592 };
1593
1594 const struct ethtool_ops qlcnic_sriov_vf_ethtool_ops = {
1595 .get_settings = qlcnic_get_settings,
1596 .get_drvinfo = qlcnic_get_drvinfo,
1597 .get_regs_len = qlcnic_get_regs_len,
1598 .get_regs = qlcnic_get_regs,
1599 .get_link = ethtool_op_get_link,
1600 .get_eeprom_len = qlcnic_get_eeprom_len,
1601 .get_eeprom = qlcnic_get_eeprom,
1602 .get_ringparam = qlcnic_get_ringparam,
1603 .set_ringparam = qlcnic_set_ringparam,
1604 .get_channels = qlcnic_get_channels,
1605 .get_pauseparam = qlcnic_get_pauseparam,
1606 .get_wol = qlcnic_get_wol,
1607 .get_strings = qlcnic_get_strings,
1608 .get_ethtool_stats = qlcnic_get_ethtool_stats,
1609 .get_sset_count = qlcnic_get_sset_count,
1610 .get_coalesce = qlcnic_get_intr_coalesce,
1611 .set_coalesce = qlcnic_set_intr_coalesce,
1612 .set_msglevel = qlcnic_set_msglevel,
1613 .get_msglevel = qlcnic_get_msglevel,
1614 };