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