Merge branch 'fix/misc' into for-linus
[deliverable/linux.git] / drivers / net / qlcnic / qlcnic_ethtool.c
1 /*
2 * QLogic qlcnic NIC Driver
3 * Copyright (c) 2009-2010 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
26 static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
27 {"xmit_called",
28 QLC_SIZEOF(stats.xmitcalled), QLC_OFF(stats.xmitcalled)},
29 {"xmit_finished",
30 QLC_SIZEOF(stats.xmitfinished), QLC_OFF(stats.xmitfinished)},
31 {"rx_dropped",
32 QLC_SIZEOF(stats.rxdropped), QLC_OFF(stats.rxdropped)},
33 {"tx_dropped",
34 QLC_SIZEOF(stats.txdropped), QLC_OFF(stats.txdropped)},
35 {"csummed",
36 QLC_SIZEOF(stats.csummed), QLC_OFF(stats.csummed)},
37 {"rx_pkts",
38 QLC_SIZEOF(stats.rx_pkts), QLC_OFF(stats.rx_pkts)},
39 {"lro_pkts",
40 QLC_SIZEOF(stats.lro_pkts), QLC_OFF(stats.lro_pkts)},
41 {"rx_bytes",
42 QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)},
43 {"tx_bytes",
44 QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)},
45 {"lrobytes",
46 QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)},
47 {"lso_frames",
48 QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)},
49 {"xmit_on",
50 QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)},
51 {"xmit_off",
52 QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)},
53 {"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
54 QLC_OFF(stats.skb_alloc_failure)},
55 {"null rxbuf",
56 QLC_SIZEOF(stats.null_rxbuf), QLC_OFF(stats.null_rxbuf)},
57 {"rx dma map error", QLC_SIZEOF(stats.rx_dma_map_error),
58 QLC_OFF(stats.rx_dma_map_error)},
59 {"tx dma map error", QLC_SIZEOF(stats.tx_dma_map_error),
60 QLC_OFF(stats.tx_dma_map_error)},
61
62 };
63
64 static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
65 "rx unicast frames",
66 "rx multicast frames",
67 "rx broadcast frames",
68 "rx dropped frames",
69 "rx errors",
70 "rx local frames",
71 "rx numbytes",
72 "tx unicast frames",
73 "tx multicast frames",
74 "tx broadcast frames",
75 "tx dropped frames",
76 "tx errors",
77 "tx local frames",
78 "tx numbytes",
79 };
80
81 #define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats)
82 #define QLCNIC_DEVICE_STATS_LEN ARRAY_SIZE(qlcnic_device_gstrings_stats)
83
84 static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
85 "Register_Test_on_offline",
86 "Link_Test_on_offline",
87 "Interrupt_Test_offline"
88 };
89
90 #define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test)
91
92 #define QLCNIC_RING_REGS_COUNT 20
93 #define QLCNIC_RING_REGS_LEN (QLCNIC_RING_REGS_COUNT * sizeof(u32))
94 #define QLCNIC_MAX_EEPROM_LEN 1024
95
96 static const u32 diag_registers[] = {
97 CRB_CMDPEG_STATE,
98 CRB_RCVPEG_STATE,
99 CRB_XG_STATE_P3P,
100 CRB_FW_CAPABILITIES_1,
101 ISR_INT_STATE_REG,
102 QLCNIC_CRB_DRV_ACTIVE,
103 QLCNIC_CRB_DEV_STATE,
104 QLCNIC_CRB_DRV_STATE,
105 QLCNIC_CRB_DRV_SCRATCH,
106 QLCNIC_CRB_DEV_PARTITION_INFO,
107 QLCNIC_CRB_DRV_IDC_VER,
108 QLCNIC_PEG_ALIVE_COUNTER,
109 QLCNIC_PEG_HALT_STATUS1,
110 QLCNIC_PEG_HALT_STATUS2,
111 QLCNIC_CRB_PEG_NET_0+0x3c,
112 QLCNIC_CRB_PEG_NET_1+0x3c,
113 QLCNIC_CRB_PEG_NET_2+0x3c,
114 QLCNIC_CRB_PEG_NET_4+0x3c,
115 -1
116 };
117
118 #define QLCNIC_MGMT_API_VERSION 2
119 #define QLCNIC_DEV_INFO_SIZE 1
120 #define QLCNIC_ETHTOOL_REGS_VER 2
121 static int qlcnic_get_regs_len(struct net_device *dev)
122 {
123 return sizeof(diag_registers) + QLCNIC_RING_REGS_LEN +
124 QLCNIC_DEV_INFO_SIZE + 1;
125 }
126
127 static int qlcnic_get_eeprom_len(struct net_device *dev)
128 {
129 return QLCNIC_FLASH_TOTAL_SIZE;
130 }
131
132 static void
133 qlcnic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
134 {
135 struct qlcnic_adapter *adapter = netdev_priv(dev);
136 u32 fw_major, fw_minor, fw_build;
137
138 fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR);
139 fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR);
140 fw_build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB);
141 sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build);
142
143 strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
144 strlcpy(drvinfo->driver, qlcnic_driver_name, 32);
145 strlcpy(drvinfo->version, QLCNIC_LINUX_VERSIONID, 32);
146 }
147
148 static int
149 qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
150 {
151 struct qlcnic_adapter *adapter = netdev_priv(dev);
152 int check_sfp_module = 0;
153 u16 pcifn = adapter->ahw.pci_func;
154
155 /* read which mode */
156 if (adapter->ahw.port_type == QLCNIC_GBE) {
157 ecmd->supported = (SUPPORTED_10baseT_Half |
158 SUPPORTED_10baseT_Full |
159 SUPPORTED_100baseT_Half |
160 SUPPORTED_100baseT_Full |
161 SUPPORTED_1000baseT_Half |
162 SUPPORTED_1000baseT_Full);
163
164 ecmd->advertising = (ADVERTISED_100baseT_Half |
165 ADVERTISED_100baseT_Full |
166 ADVERTISED_1000baseT_Half |
167 ADVERTISED_1000baseT_Full);
168
169 ecmd->speed = adapter->link_speed;
170 ecmd->duplex = adapter->link_duplex;
171 ecmd->autoneg = adapter->link_autoneg;
172
173 } else if (adapter->ahw.port_type == QLCNIC_XGBE) {
174 u32 val;
175
176 val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
177 if (val == QLCNIC_PORT_MODE_802_3_AP) {
178 ecmd->supported = SUPPORTED_1000baseT_Full;
179 ecmd->advertising = ADVERTISED_1000baseT_Full;
180 } else {
181 ecmd->supported = SUPPORTED_10000baseT_Full;
182 ecmd->advertising = ADVERTISED_10000baseT_Full;
183 }
184
185 if (netif_running(dev) && adapter->has_link_events) {
186 ecmd->speed = adapter->link_speed;
187 ecmd->autoneg = adapter->link_autoneg;
188 ecmd->duplex = adapter->link_duplex;
189 goto skip;
190 }
191
192 val = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn));
193 ecmd->speed = P3P_LINK_SPEED_MHZ *
194 P3P_LINK_SPEED_VAL(pcifn, val);
195 ecmd->duplex = DUPLEX_FULL;
196 ecmd->autoneg = AUTONEG_DISABLE;
197 } else
198 return -EIO;
199
200 skip:
201 ecmd->phy_address = adapter->physical_port;
202 ecmd->transceiver = XCVR_EXTERNAL;
203
204 switch (adapter->ahw.board_type) {
205 case QLCNIC_BRDTYPE_P3P_REF_QG:
206 case QLCNIC_BRDTYPE_P3P_4_GB:
207 case QLCNIC_BRDTYPE_P3P_4_GB_MM:
208
209 ecmd->supported |= SUPPORTED_Autoneg;
210 ecmd->advertising |= ADVERTISED_Autoneg;
211 case QLCNIC_BRDTYPE_P3P_10G_CX4:
212 case QLCNIC_BRDTYPE_P3P_10G_CX4_LP:
213 case QLCNIC_BRDTYPE_P3P_10000_BASE_T:
214 ecmd->supported |= SUPPORTED_TP;
215 ecmd->advertising |= ADVERTISED_TP;
216 ecmd->port = PORT_TP;
217 ecmd->autoneg = adapter->link_autoneg;
218 break;
219 case QLCNIC_BRDTYPE_P3P_IMEZ:
220 case QLCNIC_BRDTYPE_P3P_XG_LOM:
221 case QLCNIC_BRDTYPE_P3P_HMEZ:
222 ecmd->supported |= SUPPORTED_MII;
223 ecmd->advertising |= ADVERTISED_MII;
224 ecmd->port = PORT_MII;
225 ecmd->autoneg = AUTONEG_DISABLE;
226 break;
227 case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS:
228 case QLCNIC_BRDTYPE_P3P_10G_SFP_CT:
229 case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
230 ecmd->advertising |= ADVERTISED_TP;
231 ecmd->supported |= SUPPORTED_TP;
232 check_sfp_module = netif_running(dev) &&
233 adapter->has_link_events;
234 case QLCNIC_BRDTYPE_P3P_10G_XFP:
235 ecmd->supported |= SUPPORTED_FIBRE;
236 ecmd->advertising |= ADVERTISED_FIBRE;
237 ecmd->port = PORT_FIBRE;
238 ecmd->autoneg = AUTONEG_DISABLE;
239 break;
240 case QLCNIC_BRDTYPE_P3P_10G_TP:
241 if (adapter->ahw.port_type == QLCNIC_XGBE) {
242 ecmd->autoneg = AUTONEG_DISABLE;
243 ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
244 ecmd->advertising |=
245 (ADVERTISED_FIBRE | ADVERTISED_TP);
246 ecmd->port = PORT_FIBRE;
247 check_sfp_module = netif_running(dev) &&
248 adapter->has_link_events;
249 } else {
250 ecmd->autoneg = AUTONEG_ENABLE;
251 ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
252 ecmd->advertising |=
253 (ADVERTISED_TP | ADVERTISED_Autoneg);
254 ecmd->port = PORT_TP;
255 }
256 break;
257 default:
258 dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
259 adapter->ahw.board_type);
260 return -EIO;
261 }
262
263 if (check_sfp_module) {
264 switch (adapter->module_type) {
265 case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
266 case LINKEVENT_MODULE_OPTICAL_SRLR:
267 case LINKEVENT_MODULE_OPTICAL_LRM:
268 case LINKEVENT_MODULE_OPTICAL_SFP_1G:
269 ecmd->port = PORT_FIBRE;
270 break;
271 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
272 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
273 case LINKEVENT_MODULE_TWINAX:
274 ecmd->port = PORT_TP;
275 break;
276 default:
277 ecmd->port = PORT_OTHER;
278 }
279 }
280
281 return 0;
282 }
283
284 static int
285 qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
286 {
287 struct qlcnic_adapter *adapter = netdev_priv(dev);
288 __u32 status;
289
290 /* read which mode */
291 if (adapter->ahw.port_type == QLCNIC_GBE) {
292 /* autonegotiation */
293 if (qlcnic_fw_cmd_set_phy(adapter,
294 QLCNIC_NIU_GB_MII_MGMT_ADDR_AUTONEG,
295 ecmd->autoneg) != 0)
296 return -EIO;
297 else
298 adapter->link_autoneg = ecmd->autoneg;
299
300 if (qlcnic_fw_cmd_query_phy(adapter,
301 QLCNIC_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
302 &status) != 0)
303 return -EIO;
304
305 switch (ecmd->speed) {
306 case SPEED_10:
307 qlcnic_set_phy_speed(status, 0);
308 break;
309 case SPEED_100:
310 qlcnic_set_phy_speed(status, 1);
311 break;
312 case SPEED_1000:
313 qlcnic_set_phy_speed(status, 2);
314 break;
315 }
316
317 if (ecmd->duplex == DUPLEX_HALF)
318 qlcnic_clear_phy_duplex(status);
319 if (ecmd->duplex == DUPLEX_FULL)
320 qlcnic_set_phy_duplex(status);
321 if (qlcnic_fw_cmd_set_phy(adapter,
322 QLCNIC_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
323 *((int *)&status)) != 0)
324 return -EIO;
325 else {
326 adapter->link_speed = ecmd->speed;
327 adapter->link_duplex = ecmd->duplex;
328 }
329 } else
330 return -EOPNOTSUPP;
331
332 if (!netif_running(dev))
333 return 0;
334
335 dev->netdev_ops->ndo_stop(dev);
336 return dev->netdev_ops->ndo_open(dev);
337 }
338
339 static void
340 qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
341 {
342 struct qlcnic_adapter *adapter = netdev_priv(dev);
343 struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
344 struct qlcnic_host_sds_ring *sds_ring;
345 u32 *regs_buff = p;
346 int ring, i = 0, j = 0;
347
348 memset(p, 0, qlcnic_get_regs_len(dev));
349 regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
350 (adapter->ahw.revision_id << 16) | (adapter->pdev)->device;
351
352 regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
353 regs_buff[1] = QLCNIC_MGMT_API_VERSION;
354
355 for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++)
356 regs_buff[i] = QLCRD32(adapter, diag_registers[j]);
357
358 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
359 return;
360
361 regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/
362
363 regs_buff[i++] = 1; /* No. of tx ring */
364 regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
365 regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer);
366
367 regs_buff[i++] = 2; /* No. of rx ring */
368 regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer);
369 regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer);
370
371 regs_buff[i++] = adapter->max_sds_rings;
372
373 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
374 sds_ring = &(recv_ctx->sds_rings[ring]);
375 regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
376 }
377 }
378
379 static u32 qlcnic_test_link(struct net_device *dev)
380 {
381 struct qlcnic_adapter *adapter = netdev_priv(dev);
382 u32 val;
383
384 val = QLCRD32(adapter, CRB_XG_STATE_P3P);
385 val = XG_LINK_STATE_P3P(adapter->ahw.pci_func, val);
386 return (val == XG_LINK_UP_P3P) ? 0 : 1;
387 }
388
389 static int
390 qlcnic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
391 u8 *bytes)
392 {
393 struct qlcnic_adapter *adapter = netdev_priv(dev);
394 int offset;
395 int ret;
396
397 if (eeprom->len == 0)
398 return -EINVAL;
399
400 eeprom->magic = (adapter->pdev)->vendor |
401 ((adapter->pdev)->device << 16);
402 offset = eeprom->offset;
403
404 ret = qlcnic_rom_fast_read_words(adapter, offset, bytes,
405 eeprom->len);
406 if (ret < 0)
407 return ret;
408
409 return 0;
410 }
411
412 static void
413 qlcnic_get_ringparam(struct net_device *dev,
414 struct ethtool_ringparam *ring)
415 {
416 struct qlcnic_adapter *adapter = netdev_priv(dev);
417
418 ring->rx_pending = adapter->num_rxd;
419 ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
420 ring->tx_pending = adapter->num_txd;
421
422 ring->rx_max_pending = adapter->max_rxd;
423 ring->rx_jumbo_max_pending = adapter->max_jumbo_rxd;
424 ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
425
426 ring->rx_mini_max_pending = 0;
427 ring->rx_mini_pending = 0;
428 }
429
430 static u32
431 qlcnic_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
432 {
433 u32 num_desc;
434 num_desc = max(val, min);
435 num_desc = min(num_desc, max);
436 num_desc = roundup_pow_of_two(num_desc);
437
438 if (val != num_desc) {
439 printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
440 qlcnic_driver_name, r_name, num_desc, val);
441 }
442
443 return num_desc;
444 }
445
446 static int
447 qlcnic_set_ringparam(struct net_device *dev,
448 struct ethtool_ringparam *ring)
449 {
450 struct qlcnic_adapter *adapter = netdev_priv(dev);
451 u16 num_rxd, num_jumbo_rxd, num_txd;
452
453 if (ring->rx_mini_pending)
454 return -EOPNOTSUPP;
455
456 num_rxd = qlcnic_validate_ringparam(ring->rx_pending,
457 MIN_RCV_DESCRIPTORS, adapter->max_rxd, "rx");
458
459 num_jumbo_rxd = qlcnic_validate_ringparam(ring->rx_jumbo_pending,
460 MIN_JUMBO_DESCRIPTORS, adapter->max_jumbo_rxd,
461 "rx jumbo");
462
463 num_txd = qlcnic_validate_ringparam(ring->tx_pending,
464 MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
465
466 if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
467 num_jumbo_rxd == adapter->num_jumbo_rxd)
468 return 0;
469
470 adapter->num_rxd = num_rxd;
471 adapter->num_jumbo_rxd = num_jumbo_rxd;
472 adapter->num_txd = num_txd;
473
474 return qlcnic_reset_context(adapter);
475 }
476
477 static void
478 qlcnic_get_pauseparam(struct net_device *netdev,
479 struct ethtool_pauseparam *pause)
480 {
481 struct qlcnic_adapter *adapter = netdev_priv(netdev);
482 int port = adapter->physical_port;
483 __u32 val;
484
485 if (adapter->ahw.port_type == QLCNIC_GBE) {
486 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
487 return;
488 /* get flow control settings */
489 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
490 pause->rx_pause = qlcnic_gb_get_rx_flowctl(val);
491 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
492 switch (port) {
493 case 0:
494 pause->tx_pause = !(qlcnic_gb_get_gb0_mask(val));
495 break;
496 case 1:
497 pause->tx_pause = !(qlcnic_gb_get_gb1_mask(val));
498 break;
499 case 2:
500 pause->tx_pause = !(qlcnic_gb_get_gb2_mask(val));
501 break;
502 case 3:
503 default:
504 pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val));
505 break;
506 }
507 } else if (adapter->ahw.port_type == QLCNIC_XGBE) {
508 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
509 return;
510 pause->rx_pause = 1;
511 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
512 if (port == 0)
513 pause->tx_pause = !(qlcnic_xg_get_xg0_mask(val));
514 else
515 pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val));
516 } else {
517 dev_err(&netdev->dev, "Unknown board type: %x\n",
518 adapter->ahw.port_type);
519 }
520 }
521
522 static int
523 qlcnic_set_pauseparam(struct net_device *netdev,
524 struct ethtool_pauseparam *pause)
525 {
526 struct qlcnic_adapter *adapter = netdev_priv(netdev);
527 int port = adapter->physical_port;
528 __u32 val;
529
530 /* read mode */
531 if (adapter->ahw.port_type == QLCNIC_GBE) {
532 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
533 return -EIO;
534 /* set flow control */
535 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
536
537 if (pause->rx_pause)
538 qlcnic_gb_rx_flowctl(val);
539 else
540 qlcnic_gb_unset_rx_flowctl(val);
541
542 QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port),
543 val);
544 /* set autoneg */
545 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
546 switch (port) {
547 case 0:
548 if (pause->tx_pause)
549 qlcnic_gb_unset_gb0_mask(val);
550 else
551 qlcnic_gb_set_gb0_mask(val);
552 break;
553 case 1:
554 if (pause->tx_pause)
555 qlcnic_gb_unset_gb1_mask(val);
556 else
557 qlcnic_gb_set_gb1_mask(val);
558 break;
559 case 2:
560 if (pause->tx_pause)
561 qlcnic_gb_unset_gb2_mask(val);
562 else
563 qlcnic_gb_set_gb2_mask(val);
564 break;
565 case 3:
566 default:
567 if (pause->tx_pause)
568 qlcnic_gb_unset_gb3_mask(val);
569 else
570 qlcnic_gb_set_gb3_mask(val);
571 break;
572 }
573 QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val);
574 } else if (adapter->ahw.port_type == QLCNIC_XGBE) {
575 if (!pause->rx_pause || pause->autoneg)
576 return -EOPNOTSUPP;
577
578 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
579 return -EIO;
580
581 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
582 if (port == 0) {
583 if (pause->tx_pause)
584 qlcnic_xg_unset_xg0_mask(val);
585 else
586 qlcnic_xg_set_xg0_mask(val);
587 } else {
588 if (pause->tx_pause)
589 qlcnic_xg_unset_xg1_mask(val);
590 else
591 qlcnic_xg_set_xg1_mask(val);
592 }
593 QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val);
594 } else {
595 dev_err(&netdev->dev, "Unknown board type: %x\n",
596 adapter->ahw.port_type);
597 }
598 return 0;
599 }
600
601 static int qlcnic_reg_test(struct net_device *dev)
602 {
603 struct qlcnic_adapter *adapter = netdev_priv(dev);
604 u32 data_read;
605
606 data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0));
607 if ((data_read & 0xffff) != adapter->pdev->vendor)
608 return 1;
609
610 return 0;
611 }
612
613 static int qlcnic_get_sset_count(struct net_device *dev, int sset)
614 {
615 struct qlcnic_adapter *adapter = netdev_priv(dev);
616 switch (sset) {
617 case ETH_SS_TEST:
618 return QLCNIC_TEST_LEN;
619 case ETH_SS_STATS:
620 if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
621 return QLCNIC_STATS_LEN + QLCNIC_DEVICE_STATS_LEN;
622 return QLCNIC_STATS_LEN;
623 default:
624 return -EOPNOTSUPP;
625 }
626 }
627
628 static int qlcnic_irq_test(struct net_device *netdev)
629 {
630 struct qlcnic_adapter *adapter = netdev_priv(netdev);
631 int max_sds_rings = adapter->max_sds_rings;
632 int ret;
633
634 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
635 return -EIO;
636
637 ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST);
638 if (ret)
639 goto clear_it;
640
641 adapter->diag_cnt = 0;
642 ret = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func,
643 adapter->fw_hal_version, adapter->portnum,
644 0, 0, 0x00000011);
645 if (ret)
646 goto done;
647
648 msleep(10);
649
650 ret = !adapter->diag_cnt;
651
652 done:
653 qlcnic_diag_free_res(netdev, max_sds_rings);
654
655 clear_it:
656 adapter->max_sds_rings = max_sds_rings;
657 clear_bit(__QLCNIC_RESETTING, &adapter->state);
658 return ret;
659 }
660
661 static void
662 qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
663 u64 *data)
664 {
665 memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
666
667 data[0] = qlcnic_reg_test(dev);
668 if (data[0])
669 eth_test->flags |= ETH_TEST_FL_FAILED;
670
671 data[1] = (u64) qlcnic_test_link(dev);
672 if (data[1])
673 eth_test->flags |= ETH_TEST_FL_FAILED;
674
675 if (eth_test->flags & ETH_TEST_FL_OFFLINE) {
676 data[2] = qlcnic_irq_test(dev);
677 if (data[2])
678 eth_test->flags |= ETH_TEST_FL_FAILED;
679
680
681 }
682 }
683
684 static void
685 qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data)
686 {
687 struct qlcnic_adapter *adapter = netdev_priv(dev);
688 int index, i;
689
690 switch (stringset) {
691 case ETH_SS_TEST:
692 memcpy(data, *qlcnic_gstrings_test,
693 QLCNIC_TEST_LEN * ETH_GSTRING_LEN);
694 break;
695 case ETH_SS_STATS:
696 for (index = 0; index < QLCNIC_STATS_LEN; index++) {
697 memcpy(data + index * ETH_GSTRING_LEN,
698 qlcnic_gstrings_stats[index].stat_string,
699 ETH_GSTRING_LEN);
700 }
701 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
702 return;
703 for (i = 0; i < QLCNIC_DEVICE_STATS_LEN; index++, i++) {
704 memcpy(data + index * ETH_GSTRING_LEN,
705 qlcnic_device_gstrings_stats[i],
706 ETH_GSTRING_LEN);
707 }
708 }
709 }
710
711 #define QLCNIC_FILL_ESWITCH_STATS(VAL1) \
712 (((VAL1) == QLCNIC_ESW_STATS_NOT_AVAIL) ? 0 : VAL1)
713
714 static void
715 qlcnic_fill_device_stats(int *index, u64 *data,
716 struct __qlcnic_esw_statistics *stats)
717 {
718 int ind = *index;
719
720 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->unicast_frames);
721 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->multicast_frames);
722 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->broadcast_frames);
723 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->dropped_frames);
724 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->errors);
725 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->local_frames);
726 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->numbytes);
727
728 *index = ind;
729 }
730
731 static void
732 qlcnic_get_ethtool_stats(struct net_device *dev,
733 struct ethtool_stats *stats, u64 * data)
734 {
735 struct qlcnic_adapter *adapter = netdev_priv(dev);
736 struct qlcnic_esw_statistics port_stats;
737 int index, ret;
738
739 for (index = 0; index < QLCNIC_STATS_LEN; index++) {
740 char *p =
741 (char *)adapter +
742 qlcnic_gstrings_stats[index].stat_offset;
743 data[index] =
744 (qlcnic_gstrings_stats[index].sizeof_stat ==
745 sizeof(u64)) ? *(u64 *)p:(*(u32 *)p);
746 }
747
748 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
749 return;
750
751 memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics));
752 ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func,
753 QLCNIC_QUERY_RX_COUNTER, &port_stats.rx);
754 if (ret)
755 return;
756
757 qlcnic_fill_device_stats(&index, data, &port_stats.rx);
758
759 ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func,
760 QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
761 if (ret)
762 return;
763
764 qlcnic_fill_device_stats(&index, data, &port_stats.tx);
765 }
766
767 static int qlcnic_set_tx_csum(struct net_device *dev, u32 data)
768 {
769 struct qlcnic_adapter *adapter = netdev_priv(dev);
770
771 if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
772 return -EOPNOTSUPP;
773 if (data)
774 dev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
775 else
776 dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
777
778 return 0;
779
780 }
781 static u32 qlcnic_get_tx_csum(struct net_device *dev)
782 {
783 return dev->features & NETIF_F_IP_CSUM;
784 }
785
786 static u32 qlcnic_get_rx_csum(struct net_device *dev)
787 {
788 struct qlcnic_adapter *adapter = netdev_priv(dev);
789 return adapter->rx_csum;
790 }
791
792 static int qlcnic_set_rx_csum(struct net_device *dev, u32 data)
793 {
794 struct qlcnic_adapter *adapter = netdev_priv(dev);
795
796 if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
797 return -EOPNOTSUPP;
798 if (!!data) {
799 adapter->rx_csum = !!data;
800 return 0;
801 }
802
803 if (dev->features & NETIF_F_LRO) {
804 if (qlcnic_config_hw_lro(adapter, QLCNIC_LRO_DISABLED))
805 return -EIO;
806
807 dev->features &= ~NETIF_F_LRO;
808 qlcnic_send_lro_cleanup(adapter);
809 dev_info(&adapter->pdev->dev,
810 "disabling LRO as rx_csum is off\n");
811 }
812 adapter->rx_csum = !!data;
813 return 0;
814 }
815
816 static u32 qlcnic_get_tso(struct net_device *dev)
817 {
818 return (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) != 0;
819 }
820
821 static int qlcnic_set_tso(struct net_device *dev, u32 data)
822 {
823 struct qlcnic_adapter *adapter = netdev_priv(dev);
824 if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO))
825 return -EOPNOTSUPP;
826 if (data)
827 dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
828 else
829 dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
830
831 return 0;
832 }
833
834 static int qlcnic_blink_led(struct net_device *dev, u32 val)
835 {
836 struct qlcnic_adapter *adapter = netdev_priv(dev);
837 int max_sds_rings = adapter->max_sds_rings;
838 int dev_down = 0;
839 int ret;
840
841 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
842 dev_down = 1;
843 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
844 return -EIO;
845
846 ret = qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST);
847 if (ret) {
848 clear_bit(__QLCNIC_RESETTING, &adapter->state);
849 return ret;
850 }
851 }
852
853 ret = adapter->nic_ops->config_led(adapter, 1, 0xf);
854 if (ret) {
855 dev_err(&adapter->pdev->dev,
856 "Failed to set LED blink state.\n");
857 goto done;
858 }
859
860 msleep_interruptible(val * 1000);
861
862 ret = adapter->nic_ops->config_led(adapter, 0, 0xf);
863 if (ret) {
864 dev_err(&adapter->pdev->dev,
865 "Failed to reset LED blink state.\n");
866 goto done;
867 }
868
869 done:
870 if (dev_down) {
871 qlcnic_diag_free_res(dev, max_sds_rings);
872 clear_bit(__QLCNIC_RESETTING, &adapter->state);
873 }
874 return ret;
875
876 }
877
878 static void
879 qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
880 {
881 struct qlcnic_adapter *adapter = netdev_priv(dev);
882 u32 wol_cfg;
883
884 wol->supported = 0;
885 wol->wolopts = 0;
886
887 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
888 if (wol_cfg & (1UL << adapter->portnum))
889 wol->supported |= WAKE_MAGIC;
890
891 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
892 if (wol_cfg & (1UL << adapter->portnum))
893 wol->wolopts |= WAKE_MAGIC;
894 }
895
896 static int
897 qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
898 {
899 struct qlcnic_adapter *adapter = netdev_priv(dev);
900 u32 wol_cfg;
901
902 if (wol->wolopts & ~WAKE_MAGIC)
903 return -EOPNOTSUPP;
904
905 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
906 if (!(wol_cfg & (1 << adapter->portnum)))
907 return -EOPNOTSUPP;
908
909 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
910 if (wol->wolopts & WAKE_MAGIC)
911 wol_cfg |= 1UL << adapter->portnum;
912 else
913 wol_cfg &= ~(1UL << adapter->portnum);
914
915 QLCWR32(adapter, QLCNIC_WOL_CONFIG, wol_cfg);
916
917 return 0;
918 }
919
920 /*
921 * Set the coalescing parameters. Currently only normal is supported.
922 * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
923 * firmware coalescing to default.
924 */
925 static int qlcnic_set_intr_coalesce(struct net_device *netdev,
926 struct ethtool_coalesce *ethcoal)
927 {
928 struct qlcnic_adapter *adapter = netdev_priv(netdev);
929
930 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
931 return -EINVAL;
932
933 /*
934 * Return Error if unsupported values or
935 * unsupported parameters are set.
936 */
937 if (ethcoal->rx_coalesce_usecs > 0xffff ||
938 ethcoal->rx_max_coalesced_frames > 0xffff ||
939 ethcoal->tx_coalesce_usecs > 0xffff ||
940 ethcoal->tx_max_coalesced_frames > 0xffff ||
941 ethcoal->rx_coalesce_usecs_irq ||
942 ethcoal->rx_max_coalesced_frames_irq ||
943 ethcoal->tx_coalesce_usecs_irq ||
944 ethcoal->tx_max_coalesced_frames_irq ||
945 ethcoal->stats_block_coalesce_usecs ||
946 ethcoal->use_adaptive_rx_coalesce ||
947 ethcoal->use_adaptive_tx_coalesce ||
948 ethcoal->pkt_rate_low ||
949 ethcoal->rx_coalesce_usecs_low ||
950 ethcoal->rx_max_coalesced_frames_low ||
951 ethcoal->tx_coalesce_usecs_low ||
952 ethcoal->tx_max_coalesced_frames_low ||
953 ethcoal->pkt_rate_high ||
954 ethcoal->rx_coalesce_usecs_high ||
955 ethcoal->rx_max_coalesced_frames_high ||
956 ethcoal->tx_coalesce_usecs_high ||
957 ethcoal->tx_max_coalesced_frames_high)
958 return -EINVAL;
959
960 if (!ethcoal->rx_coalesce_usecs ||
961 !ethcoal->rx_max_coalesced_frames) {
962 adapter->coal.flags = QLCNIC_INTR_DEFAULT;
963 adapter->coal.normal.data.rx_time_us =
964 QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
965 adapter->coal.normal.data.rx_packets =
966 QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS;
967 } else {
968 adapter->coal.flags = 0;
969 adapter->coal.normal.data.rx_time_us =
970 ethcoal->rx_coalesce_usecs;
971 adapter->coal.normal.data.rx_packets =
972 ethcoal->rx_max_coalesced_frames;
973 }
974 adapter->coal.normal.data.tx_time_us = ethcoal->tx_coalesce_usecs;
975 adapter->coal.normal.data.tx_packets =
976 ethcoal->tx_max_coalesced_frames;
977
978 qlcnic_config_intr_coalesce(adapter);
979
980 return 0;
981 }
982
983 static int qlcnic_get_intr_coalesce(struct net_device *netdev,
984 struct ethtool_coalesce *ethcoal)
985 {
986 struct qlcnic_adapter *adapter = netdev_priv(netdev);
987
988 if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
989 return -EINVAL;
990
991 ethcoal->rx_coalesce_usecs = adapter->coal.normal.data.rx_time_us;
992 ethcoal->tx_coalesce_usecs = adapter->coal.normal.data.tx_time_us;
993 ethcoal->rx_max_coalesced_frames =
994 adapter->coal.normal.data.rx_packets;
995 ethcoal->tx_max_coalesced_frames =
996 adapter->coal.normal.data.tx_packets;
997
998 return 0;
999 }
1000
1001 static int qlcnic_set_flags(struct net_device *netdev, u32 data)
1002 {
1003 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1004 int hw_lro;
1005
1006 if (data & ~ETH_FLAG_LRO)
1007 return -EINVAL;
1008
1009 if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO))
1010 return -EINVAL;
1011
1012 if (!adapter->rx_csum) {
1013 dev_info(&adapter->pdev->dev, "rx csum is off, "
1014 "cannot toggle lro\n");
1015 return -EINVAL;
1016 }
1017
1018 if ((data & ETH_FLAG_LRO) && (netdev->features & NETIF_F_LRO))
1019 return 0;
1020
1021 if (data & ETH_FLAG_LRO) {
1022 hw_lro = QLCNIC_LRO_ENABLED;
1023 netdev->features |= NETIF_F_LRO;
1024 } else {
1025 hw_lro = 0;
1026 netdev->features &= ~NETIF_F_LRO;
1027 }
1028
1029 if (qlcnic_config_hw_lro(adapter, hw_lro))
1030 return -EIO;
1031
1032 if ((hw_lro == 0) && qlcnic_send_lro_cleanup(adapter))
1033 return -EIO;
1034
1035
1036 return 0;
1037 }
1038
1039 static u32 qlcnic_get_msglevel(struct net_device *netdev)
1040 {
1041 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1042
1043 return adapter->msg_enable;
1044 }
1045
1046 static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
1047 {
1048 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1049
1050 adapter->msg_enable = msglvl;
1051 }
1052
1053 const struct ethtool_ops qlcnic_ethtool_ops = {
1054 .get_settings = qlcnic_get_settings,
1055 .set_settings = qlcnic_set_settings,
1056 .get_drvinfo = qlcnic_get_drvinfo,
1057 .get_regs_len = qlcnic_get_regs_len,
1058 .get_regs = qlcnic_get_regs,
1059 .get_link = ethtool_op_get_link,
1060 .get_eeprom_len = qlcnic_get_eeprom_len,
1061 .get_eeprom = qlcnic_get_eeprom,
1062 .get_ringparam = qlcnic_get_ringparam,
1063 .set_ringparam = qlcnic_set_ringparam,
1064 .get_pauseparam = qlcnic_get_pauseparam,
1065 .set_pauseparam = qlcnic_set_pauseparam,
1066 .get_tx_csum = qlcnic_get_tx_csum,
1067 .set_tx_csum = qlcnic_set_tx_csum,
1068 .set_sg = ethtool_op_set_sg,
1069 .get_tso = qlcnic_get_tso,
1070 .set_tso = qlcnic_set_tso,
1071 .get_wol = qlcnic_get_wol,
1072 .set_wol = qlcnic_set_wol,
1073 .self_test = qlcnic_diag_test,
1074 .get_strings = qlcnic_get_strings,
1075 .get_ethtool_stats = qlcnic_get_ethtool_stats,
1076 .get_sset_count = qlcnic_get_sset_count,
1077 .get_rx_csum = qlcnic_get_rx_csum,
1078 .set_rx_csum = qlcnic_set_rx_csum,
1079 .get_coalesce = qlcnic_get_intr_coalesce,
1080 .set_coalesce = qlcnic_set_intr_coalesce,
1081 .get_flags = ethtool_op_get_flags,
1082 .set_flags = qlcnic_set_flags,
1083 .phys_id = qlcnic_blink_led,
1084 .set_msglevel = qlcnic_set_msglevel,
1085 .get_msglevel = qlcnic_get_msglevel,
1086 };
This page took 0.060177 seconds and 5 git commands to generate.