2aa9d8b2bab3f766814b72e4b037040a0055aa40
[deliverable/linux.git] / drivers / net / qlcnic / qlcnic_ethtool.c
1 /*
2 * Copyright (C) 2009 - QLogic Corporation.
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 * MA 02111-1307, USA.
19 *
20 * The full GNU General Public License is included in this distribution
21 * in the file called "COPYING".
22 *
23 */
24
25 #include <linux/types.h>
26 #include <linux/delay.h>
27 #include <linux/pci.h>
28 #include <linux/io.h>
29 #include <linux/netdevice.h>
30 #include <linux/ethtool.h>
31
32 #include "qlcnic.h"
33
34 struct qlcnic_stats {
35 char stat_string[ETH_GSTRING_LEN];
36 int sizeof_stat;
37 int stat_offset;
38 };
39
40 #define QLC_SIZEOF(m) FIELD_SIZEOF(struct qlcnic_adapter, m)
41 #define QLC_OFF(m) offsetof(struct qlcnic_adapter, m)
42
43 static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
44 {"xmit_called",
45 QLC_SIZEOF(stats.xmitcalled), QLC_OFF(stats.xmitcalled)},
46 {"xmit_finished",
47 QLC_SIZEOF(stats.xmitfinished), QLC_OFF(stats.xmitfinished)},
48 {"rx_dropped",
49 QLC_SIZEOF(stats.rxdropped), QLC_OFF(stats.rxdropped)},
50 {"tx_dropped",
51 QLC_SIZEOF(stats.txdropped), QLC_OFF(stats.txdropped)},
52 {"csummed",
53 QLC_SIZEOF(stats.csummed), QLC_OFF(stats.csummed)},
54 {"rx_pkts",
55 QLC_SIZEOF(stats.rx_pkts), QLC_OFF(stats.rx_pkts)},
56 {"lro_pkts",
57 QLC_SIZEOF(stats.lro_pkts), QLC_OFF(stats.lro_pkts)},
58 {"rx_bytes",
59 QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)},
60 {"tx_bytes",
61 QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)},
62 {"lrobytes",
63 QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)},
64 {"lso_frames",
65 QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)},
66 {"xmit_on",
67 QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)},
68 {"xmit_off",
69 QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)},
70 {"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
71 QLC_OFF(stats.skb_alloc_failure)},
72 {"null rxbuf",
73 QLC_SIZEOF(stats.null_rxbuf), QLC_OFF(stats.null_rxbuf)},
74 {"rx dma map error", QLC_SIZEOF(stats.rx_dma_map_error),
75 QLC_OFF(stats.rx_dma_map_error)},
76 {"tx dma map error", QLC_SIZEOF(stats.tx_dma_map_error),
77 QLC_OFF(stats.tx_dma_map_error)},
78
79 };
80
81 static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
82 "rx unicast frames",
83 "rx multicast frames",
84 "rx broadcast frames",
85 "rx dropped frames",
86 "rx errors",
87 "rx local frames",
88 "rx numbytes",
89 "tx unicast frames",
90 "tx multicast frames",
91 "tx broadcast frames",
92 "tx dropped frames",
93 "tx errors",
94 "tx local frames",
95 "tx numbytes",
96 };
97
98 #define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats)
99 #define QLCNIC_DEVICE_STATS_LEN ARRAY_SIZE(qlcnic_device_gstrings_stats)
100
101 static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
102 "Register_Test_on_offline",
103 "Link_Test_on_offline",
104 "Interrupt_Test_offline"
105 };
106
107 #define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test)
108
109 #define QLCNIC_RING_REGS_COUNT 20
110 #define QLCNIC_RING_REGS_LEN (QLCNIC_RING_REGS_COUNT * sizeof(u32))
111 #define QLCNIC_MAX_EEPROM_LEN 1024
112
113 static const u32 diag_registers[] = {
114 CRB_CMDPEG_STATE,
115 CRB_RCVPEG_STATE,
116 CRB_XG_STATE_P3P,
117 CRB_FW_CAPABILITIES_1,
118 ISR_INT_STATE_REG,
119 QLCNIC_CRB_DRV_ACTIVE,
120 QLCNIC_CRB_DEV_STATE,
121 QLCNIC_CRB_DRV_STATE,
122 QLCNIC_CRB_DRV_SCRATCH,
123 QLCNIC_CRB_DEV_PARTITION_INFO,
124 QLCNIC_CRB_DRV_IDC_VER,
125 QLCNIC_PEG_ALIVE_COUNTER,
126 QLCNIC_PEG_HALT_STATUS1,
127 QLCNIC_PEG_HALT_STATUS2,
128 QLCNIC_CRB_PEG_NET_0+0x3c,
129 QLCNIC_CRB_PEG_NET_1+0x3c,
130 QLCNIC_CRB_PEG_NET_2+0x3c,
131 QLCNIC_CRB_PEG_NET_4+0x3c,
132 -1
133 };
134
135 #define QLCNIC_MGMT_API_VERSION 2
136 #define QLCNIC_DEV_INFO_SIZE 1
137 #define QLCNIC_ETHTOOL_REGS_VER 2
138 static int qlcnic_get_regs_len(struct net_device *dev)
139 {
140 return sizeof(diag_registers) + QLCNIC_RING_REGS_LEN +
141 QLCNIC_DEV_INFO_SIZE + 1;
142 }
143
144 static int qlcnic_get_eeprom_len(struct net_device *dev)
145 {
146 return QLCNIC_FLASH_TOTAL_SIZE;
147 }
148
149 static void
150 qlcnic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
151 {
152 struct qlcnic_adapter *adapter = netdev_priv(dev);
153 u32 fw_major, fw_minor, fw_build;
154
155 fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR);
156 fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR);
157 fw_build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB);
158 sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build);
159
160 strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
161 strlcpy(drvinfo->driver, qlcnic_driver_name, 32);
162 strlcpy(drvinfo->version, QLCNIC_LINUX_VERSIONID, 32);
163 }
164
165 static int
166 qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
167 {
168 struct qlcnic_adapter *adapter = netdev_priv(dev);
169 int check_sfp_module = 0;
170 u16 pcifn = adapter->ahw.pci_func;
171
172 /* read which mode */
173 if (adapter->ahw.port_type == QLCNIC_GBE) {
174 ecmd->supported = (SUPPORTED_10baseT_Half |
175 SUPPORTED_10baseT_Full |
176 SUPPORTED_100baseT_Half |
177 SUPPORTED_100baseT_Full |
178 SUPPORTED_1000baseT_Half |
179 SUPPORTED_1000baseT_Full);
180
181 ecmd->advertising = (ADVERTISED_100baseT_Half |
182 ADVERTISED_100baseT_Full |
183 ADVERTISED_1000baseT_Half |
184 ADVERTISED_1000baseT_Full);
185
186 ecmd->speed = adapter->link_speed;
187 ecmd->duplex = adapter->link_duplex;
188 ecmd->autoneg = adapter->link_autoneg;
189
190 } else if (adapter->ahw.port_type == QLCNIC_XGBE) {
191 u32 val;
192
193 val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
194 if (val == QLCNIC_PORT_MODE_802_3_AP) {
195 ecmd->supported = SUPPORTED_1000baseT_Full;
196 ecmd->advertising = ADVERTISED_1000baseT_Full;
197 } else {
198 ecmd->supported = SUPPORTED_10000baseT_Full;
199 ecmd->advertising = ADVERTISED_10000baseT_Full;
200 }
201
202 if (netif_running(dev) && adapter->has_link_events) {
203 ecmd->speed = adapter->link_speed;
204 ecmd->autoneg = adapter->link_autoneg;
205 ecmd->duplex = adapter->link_duplex;
206 goto skip;
207 }
208
209 val = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn));
210 ecmd->speed = P3P_LINK_SPEED_MHZ *
211 P3P_LINK_SPEED_VAL(pcifn, val);
212 ecmd->duplex = DUPLEX_FULL;
213 ecmd->autoneg = AUTONEG_DISABLE;
214 } else
215 return -EIO;
216
217 skip:
218 ecmd->phy_address = adapter->physical_port;
219 ecmd->transceiver = XCVR_EXTERNAL;
220
221 switch (adapter->ahw.board_type) {
222 case QLCNIC_BRDTYPE_P3P_REF_QG:
223 case QLCNIC_BRDTYPE_P3P_4_GB:
224 case QLCNIC_BRDTYPE_P3P_4_GB_MM:
225
226 ecmd->supported |= SUPPORTED_Autoneg;
227 ecmd->advertising |= ADVERTISED_Autoneg;
228 case QLCNIC_BRDTYPE_P3P_10G_CX4:
229 case QLCNIC_BRDTYPE_P3P_10G_CX4_LP:
230 case QLCNIC_BRDTYPE_P3P_10000_BASE_T:
231 ecmd->supported |= SUPPORTED_TP;
232 ecmd->advertising |= ADVERTISED_TP;
233 ecmd->port = PORT_TP;
234 ecmd->autoneg = adapter->link_autoneg;
235 break;
236 case QLCNIC_BRDTYPE_P3P_IMEZ:
237 case QLCNIC_BRDTYPE_P3P_XG_LOM:
238 case QLCNIC_BRDTYPE_P3P_HMEZ:
239 ecmd->supported |= SUPPORTED_MII;
240 ecmd->advertising |= ADVERTISED_MII;
241 ecmd->port = PORT_MII;
242 ecmd->autoneg = AUTONEG_DISABLE;
243 break;
244 case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS:
245 case QLCNIC_BRDTYPE_P3P_10G_SFP_CT:
246 case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
247 ecmd->advertising |= ADVERTISED_TP;
248 ecmd->supported |= SUPPORTED_TP;
249 check_sfp_module = netif_running(dev) &&
250 adapter->has_link_events;
251 case QLCNIC_BRDTYPE_P3P_10G_XFP:
252 ecmd->supported |= SUPPORTED_FIBRE;
253 ecmd->advertising |= ADVERTISED_FIBRE;
254 ecmd->port = PORT_FIBRE;
255 ecmd->autoneg = AUTONEG_DISABLE;
256 break;
257 case QLCNIC_BRDTYPE_P3P_10G_TP:
258 if (adapter->ahw.port_type == QLCNIC_XGBE) {
259 ecmd->autoneg = AUTONEG_DISABLE;
260 ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
261 ecmd->advertising |=
262 (ADVERTISED_FIBRE | ADVERTISED_TP);
263 ecmd->port = PORT_FIBRE;
264 check_sfp_module = netif_running(dev) &&
265 adapter->has_link_events;
266 } else {
267 ecmd->autoneg = AUTONEG_ENABLE;
268 ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
269 ecmd->advertising |=
270 (ADVERTISED_TP | ADVERTISED_Autoneg);
271 ecmd->port = PORT_TP;
272 }
273 break;
274 default:
275 dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
276 adapter->ahw.board_type);
277 return -EIO;
278 }
279
280 if (check_sfp_module) {
281 switch (adapter->module_type) {
282 case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
283 case LINKEVENT_MODULE_OPTICAL_SRLR:
284 case LINKEVENT_MODULE_OPTICAL_LRM:
285 case LINKEVENT_MODULE_OPTICAL_SFP_1G:
286 ecmd->port = PORT_FIBRE;
287 break;
288 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
289 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
290 case LINKEVENT_MODULE_TWINAX:
291 ecmd->port = PORT_TP;
292 break;
293 default:
294 ecmd->port = PORT_OTHER;
295 }
296 }
297
298 return 0;
299 }
300
301 static int
302 qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
303 {
304 struct qlcnic_adapter *adapter = netdev_priv(dev);
305 __u32 status;
306
307 /* read which mode */
308 if (adapter->ahw.port_type == QLCNIC_GBE) {
309 /* autonegotiation */
310 if (qlcnic_fw_cmd_set_phy(adapter,
311 QLCNIC_NIU_GB_MII_MGMT_ADDR_AUTONEG,
312 ecmd->autoneg) != 0)
313 return -EIO;
314 else
315 adapter->link_autoneg = ecmd->autoneg;
316
317 if (qlcnic_fw_cmd_query_phy(adapter,
318 QLCNIC_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
319 &status) != 0)
320 return -EIO;
321
322 switch (ecmd->speed) {
323 case SPEED_10:
324 qlcnic_set_phy_speed(status, 0);
325 break;
326 case SPEED_100:
327 qlcnic_set_phy_speed(status, 1);
328 break;
329 case SPEED_1000:
330 qlcnic_set_phy_speed(status, 2);
331 break;
332 }
333
334 if (ecmd->duplex == DUPLEX_HALF)
335 qlcnic_clear_phy_duplex(status);
336 if (ecmd->duplex == DUPLEX_FULL)
337 qlcnic_set_phy_duplex(status);
338 if (qlcnic_fw_cmd_set_phy(adapter,
339 QLCNIC_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
340 *((int *)&status)) != 0)
341 return -EIO;
342 else {
343 adapter->link_speed = ecmd->speed;
344 adapter->link_duplex = ecmd->duplex;
345 }
346 } else
347 return -EOPNOTSUPP;
348
349 if (!netif_running(dev))
350 return 0;
351
352 dev->netdev_ops->ndo_stop(dev);
353 return dev->netdev_ops->ndo_open(dev);
354 }
355
356 static void
357 qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
358 {
359 struct qlcnic_adapter *adapter = netdev_priv(dev);
360 struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
361 struct qlcnic_host_sds_ring *sds_ring;
362 u32 *regs_buff = p;
363 int ring, i = 0, j = 0;
364
365 memset(p, 0, qlcnic_get_regs_len(dev));
366 regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
367 (adapter->ahw.revision_id << 16) | (adapter->pdev)->device;
368
369 regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
370 regs_buff[1] = QLCNIC_MGMT_API_VERSION;
371
372 for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++)
373 regs_buff[i] = QLCRD32(adapter, diag_registers[j]);
374
375 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
376 return;
377
378 regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/
379
380 regs_buff[i++] = 1; /* No. of tx ring */
381 regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
382 regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer);
383
384 regs_buff[i++] = 2; /* No. of rx ring */
385 regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer);
386 regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer);
387
388 regs_buff[i++] = adapter->max_sds_rings;
389
390 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
391 sds_ring = &(recv_ctx->sds_rings[ring]);
392 regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
393 }
394 }
395
396 static u32 qlcnic_test_link(struct net_device *dev)
397 {
398 struct qlcnic_adapter *adapter = netdev_priv(dev);
399 u32 val;
400
401 val = QLCRD32(adapter, CRB_XG_STATE_P3P);
402 val = XG_LINK_STATE_P3P(adapter->ahw.pci_func, val);
403 return (val == XG_LINK_UP_P3P) ? 0 : 1;
404 }
405
406 static int
407 qlcnic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
408 u8 *bytes)
409 {
410 struct qlcnic_adapter *adapter = netdev_priv(dev);
411 int offset;
412 int ret;
413
414 if (eeprom->len == 0)
415 return -EINVAL;
416
417 eeprom->magic = (adapter->pdev)->vendor |
418 ((adapter->pdev)->device << 16);
419 offset = eeprom->offset;
420
421 ret = qlcnic_rom_fast_read_words(adapter, offset, bytes,
422 eeprom->len);
423 if (ret < 0)
424 return ret;
425
426 return 0;
427 }
428
429 static void
430 qlcnic_get_ringparam(struct net_device *dev,
431 struct ethtool_ringparam *ring)
432 {
433 struct qlcnic_adapter *adapter = netdev_priv(dev);
434
435 ring->rx_pending = adapter->num_rxd;
436 ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
437 ring->tx_pending = adapter->num_txd;
438
439 ring->rx_max_pending = adapter->max_rxd;
440 ring->rx_jumbo_max_pending = adapter->max_jumbo_rxd;
441 ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
442
443 ring->rx_mini_max_pending = 0;
444 ring->rx_mini_pending = 0;
445 }
446
447 static u32
448 qlcnic_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
449 {
450 u32 num_desc;
451 num_desc = max(val, min);
452 num_desc = min(num_desc, max);
453 num_desc = roundup_pow_of_two(num_desc);
454
455 if (val != num_desc) {
456 printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
457 qlcnic_driver_name, r_name, num_desc, val);
458 }
459
460 return num_desc;
461 }
462
463 static int
464 qlcnic_set_ringparam(struct net_device *dev,
465 struct ethtool_ringparam *ring)
466 {
467 struct qlcnic_adapter *adapter = netdev_priv(dev);
468 u16 num_rxd, num_jumbo_rxd, num_txd;
469
470 if (ring->rx_mini_pending)
471 return -EOPNOTSUPP;
472
473 num_rxd = qlcnic_validate_ringparam(ring->rx_pending,
474 MIN_RCV_DESCRIPTORS, adapter->max_rxd, "rx");
475
476 num_jumbo_rxd = qlcnic_validate_ringparam(ring->rx_jumbo_pending,
477 MIN_JUMBO_DESCRIPTORS, adapter->max_jumbo_rxd,
478 "rx jumbo");
479
480 num_txd = qlcnic_validate_ringparam(ring->tx_pending,
481 MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
482
483 if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
484 num_jumbo_rxd == adapter->num_jumbo_rxd)
485 return 0;
486
487 adapter->num_rxd = num_rxd;
488 adapter->num_jumbo_rxd = num_jumbo_rxd;
489 adapter->num_txd = num_txd;
490
491 return qlcnic_reset_context(adapter);
492 }
493
494 static void
495 qlcnic_get_pauseparam(struct net_device *netdev,
496 struct ethtool_pauseparam *pause)
497 {
498 struct qlcnic_adapter *adapter = netdev_priv(netdev);
499 int port = adapter->physical_port;
500 __u32 val;
501
502 if (adapter->ahw.port_type == QLCNIC_GBE) {
503 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
504 return;
505 /* get flow control settings */
506 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
507 pause->rx_pause = qlcnic_gb_get_rx_flowctl(val);
508 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
509 switch (port) {
510 case 0:
511 pause->tx_pause = !(qlcnic_gb_get_gb0_mask(val));
512 break;
513 case 1:
514 pause->tx_pause = !(qlcnic_gb_get_gb1_mask(val));
515 break;
516 case 2:
517 pause->tx_pause = !(qlcnic_gb_get_gb2_mask(val));
518 break;
519 case 3:
520 default:
521 pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val));
522 break;
523 }
524 } else if (adapter->ahw.port_type == QLCNIC_XGBE) {
525 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
526 return;
527 pause->rx_pause = 1;
528 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
529 if (port == 0)
530 pause->tx_pause = !(qlcnic_xg_get_xg0_mask(val));
531 else
532 pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val));
533 } else {
534 dev_err(&netdev->dev, "Unknown board type: %x\n",
535 adapter->ahw.port_type);
536 }
537 }
538
539 static int
540 qlcnic_set_pauseparam(struct net_device *netdev,
541 struct ethtool_pauseparam *pause)
542 {
543 struct qlcnic_adapter *adapter = netdev_priv(netdev);
544 int port = adapter->physical_port;
545 __u32 val;
546
547 /* read mode */
548 if (adapter->ahw.port_type == QLCNIC_GBE) {
549 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
550 return -EIO;
551 /* set flow control */
552 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
553
554 if (pause->rx_pause)
555 qlcnic_gb_rx_flowctl(val);
556 else
557 qlcnic_gb_unset_rx_flowctl(val);
558
559 QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port),
560 val);
561 /* set autoneg */
562 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
563 switch (port) {
564 case 0:
565 if (pause->tx_pause)
566 qlcnic_gb_unset_gb0_mask(val);
567 else
568 qlcnic_gb_set_gb0_mask(val);
569 break;
570 case 1:
571 if (pause->tx_pause)
572 qlcnic_gb_unset_gb1_mask(val);
573 else
574 qlcnic_gb_set_gb1_mask(val);
575 break;
576 case 2:
577 if (pause->tx_pause)
578 qlcnic_gb_unset_gb2_mask(val);
579 else
580 qlcnic_gb_set_gb2_mask(val);
581 break;
582 case 3:
583 default:
584 if (pause->tx_pause)
585 qlcnic_gb_unset_gb3_mask(val);
586 else
587 qlcnic_gb_set_gb3_mask(val);
588 break;
589 }
590 QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val);
591 } else if (adapter->ahw.port_type == QLCNIC_XGBE) {
592 if (!pause->rx_pause || pause->autoneg)
593 return -EOPNOTSUPP;
594
595 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
596 return -EIO;
597
598 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
599 if (port == 0) {
600 if (pause->tx_pause)
601 qlcnic_xg_unset_xg0_mask(val);
602 else
603 qlcnic_xg_set_xg0_mask(val);
604 } else {
605 if (pause->tx_pause)
606 qlcnic_xg_unset_xg1_mask(val);
607 else
608 qlcnic_xg_set_xg1_mask(val);
609 }
610 QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val);
611 } else {
612 dev_err(&netdev->dev, "Unknown board type: %x\n",
613 adapter->ahw.port_type);
614 }
615 return 0;
616 }
617
618 static int qlcnic_reg_test(struct net_device *dev)
619 {
620 struct qlcnic_adapter *adapter = netdev_priv(dev);
621 u32 data_read;
622
623 data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0));
624 if ((data_read & 0xffff) != adapter->pdev->vendor)
625 return 1;
626
627 return 0;
628 }
629
630 static int qlcnic_get_sset_count(struct net_device *dev, int sset)
631 {
632 struct qlcnic_adapter *adapter = netdev_priv(dev);
633 switch (sset) {
634 case ETH_SS_TEST:
635 return QLCNIC_TEST_LEN;
636 case ETH_SS_STATS:
637 if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
638 return QLCNIC_STATS_LEN + QLCNIC_DEVICE_STATS_LEN;
639 return QLCNIC_STATS_LEN;
640 default:
641 return -EOPNOTSUPP;
642 }
643 }
644
645 static int qlcnic_irq_test(struct net_device *netdev)
646 {
647 struct qlcnic_adapter *adapter = netdev_priv(netdev);
648 int max_sds_rings = adapter->max_sds_rings;
649 int ret;
650
651 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
652 return -EIO;
653
654 ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST);
655 if (ret)
656 goto clear_it;
657
658 adapter->diag_cnt = 0;
659 ret = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func,
660 adapter->fw_hal_version, adapter->portnum,
661 0, 0, 0x00000011);
662 if (ret)
663 goto done;
664
665 msleep(10);
666
667 ret = !adapter->diag_cnt;
668
669 done:
670 qlcnic_diag_free_res(netdev, max_sds_rings);
671
672 clear_it:
673 adapter->max_sds_rings = max_sds_rings;
674 clear_bit(__QLCNIC_RESETTING, &adapter->state);
675 return ret;
676 }
677
678 static void
679 qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
680 u64 *data)
681 {
682 memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
683
684 data[0] = qlcnic_reg_test(dev);
685 if (data[0])
686 eth_test->flags |= ETH_TEST_FL_FAILED;
687
688 data[1] = (u64) qlcnic_test_link(dev);
689 if (data[1])
690 eth_test->flags |= ETH_TEST_FL_FAILED;
691
692 if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
693 data[2] = qlcnic_irq_test(dev);
694 if (data[2])
695 eth_test->flags |= ETH_TEST_FL_FAILED;
696
697
698 }
699 }
700
701 static void
702 qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data)
703 {
704 struct qlcnic_adapter *adapter = netdev_priv(dev);
705 int index, i;
706
707 switch (stringset) {
708 case ETH_SS_TEST:
709 memcpy(data, *qlcnic_gstrings_test,
710 QLCNIC_TEST_LEN * ETH_GSTRING_LEN);
711 break;
712 case ETH_SS_STATS:
713 for (index = 0; index < QLCNIC_STATS_LEN; index++) {
714 memcpy(data + index * ETH_GSTRING_LEN,
715 qlcnic_gstrings_stats[index].stat_string,
716 ETH_GSTRING_LEN);
717 }
718 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
719 return;
720 for (i = 0; i < QLCNIC_DEVICE_STATS_LEN; index++, i++) {
721 memcpy(data + index * ETH_GSTRING_LEN,
722 qlcnic_device_gstrings_stats[i],
723 ETH_GSTRING_LEN);
724 }
725 }
726 }
727
728 #define QLCNIC_FILL_ESWITCH_STATS(VAL1) \
729 (((VAL1) == QLCNIC_ESW_STATS_NOT_AVAIL) ? 0 : VAL1)
730
731 static void
732 qlcnic_fill_device_stats(int *index, u64 *data,
733 struct __qlcnic_esw_statistics *stats)
734 {
735 int ind = *index;
736
737 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->unicast_frames);
738 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->multicast_frames);
739 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->broadcast_frames);
740 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->dropped_frames);
741 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->errors);
742 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->local_frames);
743 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->numbytes);
744
745 *index = ind;
746 }
747
748 static void
749 qlcnic_get_ethtool_stats(struct net_device *dev,
750 struct ethtool_stats *stats, u64 * data)
751 {
752 struct qlcnic_adapter *adapter = netdev_priv(dev);
753 struct qlcnic_esw_statistics port_stats;
754 int index, ret;
755
756 for (index = 0; index < QLCNIC_STATS_LEN; index++) {
757 char *p =
758 (char *)adapter +
759 qlcnic_gstrings_stats[index].stat_offset;
760 data[index] =
761 (qlcnic_gstrings_stats[index].sizeof_stat ==
762 sizeof(u64)) ? *(u64 *)p:(*(u32 *)p);
763 }
764
765 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
766 return;
767
768 memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics));
769 ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func,
770 QLCNIC_QUERY_RX_COUNTER, &port_stats.rx);
771 if (ret)
772 return;
773
774 qlcnic_fill_device_stats(&index, data, &port_stats.rx);
775
776 ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func,
777 QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
778 if (ret)
779 return;
780
781 qlcnic_fill_device_stats(&index, data, &port_stats.tx);
782 }
783
784 static int qlcnic_set_tx_csum(struct net_device *dev, u32 data)
785 {
786 struct qlcnic_adapter *adapter = netdev_priv(dev);
787
788 if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
789 return -EOPNOTSUPP;
790 if (data)
791 dev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
792 else
793 dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
794
795 return 0;
796
797 }
798 static u32 qlcnic_get_tx_csum(struct net_device *dev)
799 {
800 return dev->features & NETIF_F_IP_CSUM;
801 }
802
803 static u32 qlcnic_get_rx_csum(struct net_device *dev)
804 {
805 struct qlcnic_adapter *adapter = netdev_priv(dev);
806 return adapter->rx_csum;
807 }
808
809 static int qlcnic_set_rx_csum(struct net_device *dev, u32 data)
810 {
811 struct qlcnic_adapter *adapter = netdev_priv(dev);
812
813 if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
814 return -EOPNOTSUPP;
815 if (!!data) {
816 adapter->rx_csum = !!data;
817 return 0;
818 }
819
820 if (dev->features & NETIF_F_LRO) {
821 if (qlcnic_config_hw_lro(adapter, QLCNIC_LRO_DISABLED))
822 return -EIO;
823
824 dev->features &= ~NETIF_F_LRO;
825 qlcnic_send_lro_cleanup(adapter);
826 dev_info(&adapter->pdev->dev,
827 "disabling LRO as rx_csum is off\n");
828 }
829 adapter->rx_csum = !!data;
830 return 0;
831 }
832
833 static u32 qlcnic_get_tso(struct net_device *dev)
834 {
835 return (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) != 0;
836 }
837
838 static int qlcnic_set_tso(struct net_device *dev, u32 data)
839 {
840 struct qlcnic_adapter *adapter = netdev_priv(dev);
841 if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO))
842 return -EOPNOTSUPP;
843 if (data)
844 dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
845 else
846 dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
847
848 return 0;
849 }
850
851 static int qlcnic_blink_led(struct net_device *dev, u32 val)
852 {
853 struct qlcnic_adapter *adapter = netdev_priv(dev);
854 int ret;
855
856 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
857 return -EIO;
858
859 ret = adapter->nic_ops->config_led(adapter, 1, 0xf);
860 if (ret) {
861 dev_err(&adapter->pdev->dev,
862 "Failed to set LED blink state.\n");
863 return ret;
864 }
865
866 msleep_interruptible(val * 1000);
867
868 ret = adapter->nic_ops->config_led(adapter, 0, 0xf);
869 if (ret) {
870 dev_err(&adapter->pdev->dev,
871 "Failed to reset LED blink state.\n");
872 return ret;
873 }
874
875 return 0;
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.07199 seconds and 5 git commands to generate.