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