]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blame - drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 422
[mirror_ubuntu-eoan-kernel.git] / drivers / net / ethernet / aquantia / atlantic / aq_ethtool.c
CommitLineData
75a6faf6 1// SPDX-License-Identifier: GPL-2.0-only
c5760d03
DV
2/*
3 * aQuantia Corporation Network Driver
4 * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
c5760d03
DV
5 */
6
7/* File aq_ethtool.c: Definition of ethertool related functions. */
8
9#include "aq_ethtool.h"
10#include "aq_nic.h"
c1af5427 11#include "aq_vec.h"
8d0bcb01 12#include "aq_filters.h"
c5760d03
DV
13
14static void aq_ethtool_get_regs(struct net_device *ndev,
15 struct ethtool_regs *regs, void *p)
16{
17 struct aq_nic_s *aq_nic = netdev_priv(ndev);
18 u32 regs_count = aq_nic_get_regs_count(aq_nic);
19
20 memset(p, 0, regs_count * sizeof(u32));
21 aq_nic_get_regs(aq_nic, regs, p);
22}
23
24static int aq_ethtool_get_regs_len(struct net_device *ndev)
25{
26 struct aq_nic_s *aq_nic = netdev_priv(ndev);
27 u32 regs_count = aq_nic_get_regs_count(aq_nic);
28
29 return regs_count * sizeof(u32);
30}
31
32static u32 aq_ethtool_get_link(struct net_device *ndev)
33{
34 return ethtool_op_get_link(ndev);
35}
36
f8244ab5
PR
37static int aq_ethtool_get_link_ksettings(struct net_device *ndev,
38 struct ethtool_link_ksettings *cmd)
c5760d03
DV
39{
40 struct aq_nic_s *aq_nic = netdev_priv(ndev);
41
f8244ab5
PR
42 aq_nic_get_link_ksettings(aq_nic, cmd);
43 cmd->base.speed = netif_carrier_ok(ndev) ?
44 aq_nic_get_link_speed(aq_nic) : 0U;
c5760d03
DV
45
46 return 0;
47}
48
f8244ab5
PR
49static int
50aq_ethtool_set_link_ksettings(struct net_device *ndev,
51 const struct ethtool_link_ksettings *cmd)
c5760d03
DV
52{
53 struct aq_nic_s *aq_nic = netdev_priv(ndev);
54
f8244ab5 55 return aq_nic_set_link_ksettings(aq_nic, cmd);
c5760d03
DV
56}
57
c5760d03
DV
58static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
59 "InPackets",
60 "InUCast",
61 "InMCast",
62 "InBCast",
63 "InErrors",
64 "OutPackets",
65 "OutUCast",
66 "OutMCast",
67 "OutBCast",
98bc036d
IR
68 "InUCastOctets",
69 "OutUCastOctets",
70 "InMCastOctets",
71 "OutMCastOctets",
72 "InBCastOctets",
73 "OutBCastOctets",
74 "InOctets",
75 "OutOctets",
c5760d03
DV
76 "InPacketsDma",
77 "OutPacketsDma",
78 "InOctetsDma",
79 "OutOctetsDma",
80 "InDroppedDma",
5d8d84e9
IR
81};
82
83static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = {
84 "Queue[%d] InPackets",
85 "Queue[%d] OutPackets",
86 "Queue[%d] Restarts",
87 "Queue[%d] InJumboPackets",
88 "Queue[%d] InLroPackets",
89 "Queue[%d] InErrors",
c5760d03
DV
90};
91
92static void aq_ethtool_stats(struct net_device *ndev,
93 struct ethtool_stats *stats, u64 *data)
94{
95 struct aq_nic_s *aq_nic = netdev_priv(ndev);
5d8d84e9 96 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
c5760d03 97
5d8d84e9 98 memset(data, 0, (ARRAY_SIZE(aq_ethtool_stat_names) +
e9157848
ND
99 ARRAY_SIZE(aq_ethtool_queue_stat_names) *
100 cfg->vecs) * sizeof(u64));
c5760d03
DV
101 aq_nic_get_stats(aq_nic, data);
102}
103
104static void aq_ethtool_get_drvinfo(struct net_device *ndev,
105 struct ethtool_drvinfo *drvinfo)
106{
107 struct aq_nic_s *aq_nic = netdev_priv(ndev);
108 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
109 struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
110 u32 firmware_version = aq_nic_get_fw_version(aq_nic);
111 u32 regs_count = aq_nic_get_regs_count(aq_nic);
112
113 strlcat(drvinfo->driver, AQ_CFG_DRV_NAME, sizeof(drvinfo->driver));
114 strlcat(drvinfo->version, AQ_CFG_DRV_VERSION, sizeof(drvinfo->version));
115
116 snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
117 "%u.%u.%u", firmware_version >> 24,
118 (firmware_version >> 16) & 0xFFU, firmware_version & 0xFFFFU);
119
120 strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "",
121 sizeof(drvinfo->bus_info));
5d8d84e9
IR
122 drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
123 cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
c5760d03
DV
124 drvinfo->testinfo_len = 0;
125 drvinfo->regdump_len = regs_count;
126 drvinfo->eedump_len = 0;
127}
128
129static void aq_ethtool_get_strings(struct net_device *ndev,
130 u32 stringset, u8 *data)
131{
5d8d84e9 132 int i, si;
c5760d03
DV
133 struct aq_nic_s *aq_nic = netdev_priv(ndev);
134 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
5d8d84e9
IR
135 u8 *p = data;
136
137 if (stringset == ETH_SS_STATS) {
ff83dbf2 138 memcpy(p, aq_ethtool_stat_names,
5d8d84e9
IR
139 sizeof(aq_ethtool_stat_names));
140 p = p + sizeof(aq_ethtool_stat_names);
141 for (i = 0; i < cfg->vecs; i++) {
142 for (si = 0;
143 si < ARRAY_SIZE(aq_ethtool_queue_stat_names);
144 si++) {
145 snprintf(p, ETH_GSTRING_LEN,
146 aq_ethtool_queue_stat_names[si], i);
147 p += ETH_GSTRING_LEN;
148 }
149 }
150 }
c5760d03
DV
151}
152
153static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
154{
155 int ret = 0;
156 struct aq_nic_s *aq_nic = netdev_priv(ndev);
157 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
158
159 switch (stringset) {
160 case ETH_SS_STATS:
5d8d84e9
IR
161 ret = ARRAY_SIZE(aq_ethtool_stat_names) +
162 cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
c5760d03
DV
163 break;
164 default:
165 ret = -EOPNOTSUPP;
166 }
167 return ret;
168}
169
170static u32 aq_ethtool_get_rss_indir_size(struct net_device *ndev)
171{
172 return AQ_CFG_RSS_INDIRECTION_TABLE_MAX;
173}
174
175static u32 aq_ethtool_get_rss_key_size(struct net_device *ndev)
176{
177 struct aq_nic_s *aq_nic = netdev_priv(ndev);
178 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
179
180 return sizeof(cfg->aq_rss.hash_secret_key);
181}
182
183static int aq_ethtool_get_rss(struct net_device *ndev, u32 *indir, u8 *key,
184 u8 *hfunc)
185{
186 struct aq_nic_s *aq_nic = netdev_priv(ndev);
187 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
188 unsigned int i = 0U;
189
190 if (hfunc)
191 *hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */
192 if (indir) {
193 for (i = 0; i < AQ_CFG_RSS_INDIRECTION_TABLE_MAX; i++)
194 indir[i] = cfg->aq_rss.indirection_table[i];
195 }
196 if (key)
197 memcpy(key, cfg->aq_rss.hash_secret_key,
198 sizeof(cfg->aq_rss.hash_secret_key));
199 return 0;
200}
201
39163767
DB
202static int aq_ethtool_set_rss(struct net_device *netdev, const u32 *indir,
203 const u8 *key, const u8 hfunc)
204{
205 struct aq_nic_s *aq_nic = netdev_priv(netdev);
206 struct aq_nic_cfg_s *cfg;
207 unsigned int i = 0U;
208 u32 rss_entries;
209 int err = 0;
210
211 cfg = aq_nic_get_cfg(aq_nic);
212 rss_entries = cfg->aq_rss.indirection_table_size;
213
214 /* We do not allow change in unsupported parameters */
215 if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
216 return -EOPNOTSUPP;
217 /* Fill out the redirection table */
218 if (indir)
219 for (i = 0; i < rss_entries; i++)
220 cfg->aq_rss.indirection_table[i] = indir[i];
221
222 /* Fill out the rss hash key */
223 if (key) {
224 memcpy(cfg->aq_rss.hash_secret_key, key,
225 sizeof(cfg->aq_rss.hash_secret_key));
226 err = aq_nic->aq_hw_ops->hw_rss_hash_set(aq_nic->aq_hw,
227 &cfg->aq_rss);
228 if (err)
229 return err;
230 }
231
232 err = aq_nic->aq_hw_ops->hw_rss_set(aq_nic->aq_hw, &cfg->aq_rss);
233
234 return err;
235}
236
c5760d03
DV
237static int aq_ethtool_get_rxnfc(struct net_device *ndev,
238 struct ethtool_rxnfc *cmd,
239 u32 *rule_locs)
240{
241 struct aq_nic_s *aq_nic = netdev_priv(ndev);
242 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
243 int err = 0;
244
245 switch (cmd->cmd) {
246 case ETHTOOL_GRXRINGS:
247 cmd->data = cfg->vecs;
248 break;
8d0bcb01
DB
249 case ETHTOOL_GRXCLSRLCNT:
250 cmd->rule_cnt = aq_get_rxnfc_count_all_rules(aq_nic);
251 break;
252 case ETHTOOL_GRXCLSRULE:
253 err = aq_get_rxnfc_rule(aq_nic, cmd);
254 break;
255 case ETHTOOL_GRXCLSRLALL:
256 err = aq_get_rxnfc_all_rules(aq_nic, cmd, rule_locs);
257 break;
258 default:
259 err = -EOPNOTSUPP;
260 break;
261 }
c5760d03 262
8d0bcb01
DB
263 return err;
264}
265
266static int aq_ethtool_set_rxnfc(struct net_device *ndev,
267 struct ethtool_rxnfc *cmd)
268{
269 int err = 0;
270 struct aq_nic_s *aq_nic = netdev_priv(ndev);
271
272 switch (cmd->cmd) {
273 case ETHTOOL_SRXCLSRLINS:
274 err = aq_add_rxnfc_rule(aq_nic, cmd);
275 break;
276 case ETHTOOL_SRXCLSRLDEL:
277 err = aq_del_rxnfc_rule(aq_nic, cmd);
278 break;
c5760d03
DV
279 default:
280 err = -EOPNOTSUPP;
281 break;
282 }
283
284 return err;
285}
286
2660d226
WY
287static int aq_ethtool_get_coalesce(struct net_device *ndev,
288 struct ethtool_coalesce *coal)
b82ee71a
IR
289{
290 struct aq_nic_s *aq_nic = netdev_priv(ndev);
291 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
292
293 if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON ||
294 cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) {
295 coal->rx_coalesce_usecs = cfg->rx_itr;
296 coal->tx_coalesce_usecs = cfg->tx_itr;
297 coal->rx_max_coalesced_frames = 0;
298 coal->tx_max_coalesced_frames = 0;
299 } else {
300 coal->rx_coalesce_usecs = 0;
301 coal->tx_coalesce_usecs = 0;
302 coal->rx_max_coalesced_frames = 1;
303 coal->tx_max_coalesced_frames = 1;
304 }
305 return 0;
306}
307
2660d226
WY
308static int aq_ethtool_set_coalesce(struct net_device *ndev,
309 struct ethtool_coalesce *coal)
b82ee71a
IR
310{
311 struct aq_nic_s *aq_nic = netdev_priv(ndev);
312 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
313
314 /* This is not yet supported
315 */
316 if (coal->use_adaptive_rx_coalesce || coal->use_adaptive_tx_coalesce)
317 return -EOPNOTSUPP;
318
319 /* Atlantic only supports timing based coalescing
320 */
321 if (coal->rx_max_coalesced_frames > 1 ||
322 coal->rx_coalesce_usecs_irq ||
323 coal->rx_max_coalesced_frames_irq)
324 return -EOPNOTSUPP;
325
326 if (coal->tx_max_coalesced_frames > 1 ||
327 coal->tx_coalesce_usecs_irq ||
328 coal->tx_max_coalesced_frames_irq)
329 return -EOPNOTSUPP;
330
331 /* We do not support frame counting. Check this
332 */
333 if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs))
334 return -EOPNOTSUPP;
335 if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs))
336 return -EOPNOTSUPP;
337
338 if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX ||
339 coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX)
340 return -EINVAL;
341
342 cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON;
343
344 cfg->rx_itr = coal->rx_coalesce_usecs;
345 cfg->tx_itr = coal->tx_coalesce_usecs;
346
347 return aq_nic_update_interrupt_moderation_settings(aq_nic);
348}
349
a0da96c0
YE
350static void aq_ethtool_get_wol(struct net_device *ndev,
351 struct ethtool_wolinfo *wol)
352{
353 struct aq_nic_s *aq_nic = netdev_priv(ndev);
354 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
355
356 wol->supported = WAKE_MAGIC;
357 wol->wolopts = 0;
358
359 if (cfg->wol)
360 wol->wolopts |= WAKE_MAGIC;
361}
362
363static int aq_ethtool_set_wol(struct net_device *ndev,
364 struct ethtool_wolinfo *wol)
365{
366 struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
367 struct aq_nic_s *aq_nic = netdev_priv(ndev);
368 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
369 int err = 0;
370
371 if (wol->wolopts & WAKE_MAGIC)
372 cfg->wol |= AQ_NIC_WOL_ENABLED;
373 else
374 cfg->wol &= ~AQ_NIC_WOL_ENABLED;
375 err = device_set_wakeup_enable(&pdev->dev, wol->wolopts);
376
377 return err;
378}
379
92ab6407
YE
380static enum hw_atl_fw2x_rate eee_mask_to_ethtool_mask(u32 speed)
381{
382 u32 rate = 0;
383
384 if (speed & AQ_NIC_RATE_EEE_10G)
385 rate |= SUPPORTED_10000baseT_Full;
386
387 if (speed & AQ_NIC_RATE_EEE_2GS)
388 rate |= SUPPORTED_2500baseX_Full;
389
390 if (speed & AQ_NIC_RATE_EEE_1G)
391 rate |= SUPPORTED_1000baseT_Full;
392
393 return rate;
394}
395
396static int aq_ethtool_get_eee(struct net_device *ndev, struct ethtool_eee *eee)
397{
398 struct aq_nic_s *aq_nic = netdev_priv(ndev);
399 u32 rate, supported_rates;
400 int err = 0;
401
402 if (!aq_nic->aq_fw_ops->get_eee_rate)
403 return -EOPNOTSUPP;
404
f5dce08a 405 mutex_lock(&aq_nic->fwreq_mutex);
92ab6407
YE
406 err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
407 &supported_rates);
f5dce08a 408 mutex_unlock(&aq_nic->fwreq_mutex);
92ab6407
YE
409 if (err < 0)
410 return err;
411
412 eee->supported = eee_mask_to_ethtool_mask(supported_rates);
413
414 if (aq_nic->aq_nic_cfg.eee_speeds)
415 eee->advertised = eee->supported;
416
417 eee->lp_advertised = eee_mask_to_ethtool_mask(rate);
418
419 eee->eee_enabled = !!eee->advertised;
420
421 eee->tx_lpi_enabled = eee->eee_enabled;
422 if (eee->advertised & eee->lp_advertised)
423 eee->eee_active = true;
424
425 return 0;
426}
427
428static int aq_ethtool_set_eee(struct net_device *ndev, struct ethtool_eee *eee)
429{
430 struct aq_nic_s *aq_nic = netdev_priv(ndev);
431 u32 rate, supported_rates;
432 struct aq_nic_cfg_s *cfg;
433 int err = 0;
434
435 cfg = aq_nic_get_cfg(aq_nic);
436
437 if (unlikely(!aq_nic->aq_fw_ops->get_eee_rate ||
438 !aq_nic->aq_fw_ops->set_eee_rate))
439 return -EOPNOTSUPP;
440
f5dce08a 441 mutex_lock(&aq_nic->fwreq_mutex);
92ab6407
YE
442 err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
443 &supported_rates);
f5dce08a 444 mutex_unlock(&aq_nic->fwreq_mutex);
92ab6407
YE
445 if (err < 0)
446 return err;
447
448 if (eee->eee_enabled) {
449 rate = supported_rates;
450 cfg->eee_speeds = rate;
451 } else {
452 rate = 0;
453 cfg->eee_speeds = 0;
454 }
455
f5dce08a
ND
456 mutex_lock(&aq_nic->fwreq_mutex);
457 err = aq_nic->aq_fw_ops->set_eee_rate(aq_nic->aq_hw, rate);
458 mutex_unlock(&aq_nic->fwreq_mutex);
459
460 return err;
92ab6407
YE
461}
462
b8d68b62
AM
463static int aq_ethtool_nway_reset(struct net_device *ndev)
464{
465 struct aq_nic_s *aq_nic = netdev_priv(ndev);
f5dce08a 466 int err = 0;
b8d68b62
AM
467
468 if (unlikely(!aq_nic->aq_fw_ops->renegotiate))
469 return -EOPNOTSUPP;
470
f5dce08a
ND
471 if (netif_running(ndev)) {
472 mutex_lock(&aq_nic->fwreq_mutex);
473 err = aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw);
474 mutex_unlock(&aq_nic->fwreq_mutex);
475 }
b8d68b62 476
f5dce08a 477 return err;
b8d68b62
AM
478}
479
288551de
IR
480static void aq_ethtool_get_pauseparam(struct net_device *ndev,
481 struct ethtool_pauseparam *pause)
482{
483 struct aq_nic_s *aq_nic = netdev_priv(ndev);
35e8e8b4 484 u32 fc = aq_nic->aq_nic_cfg.flow_control;
288551de
IR
485
486 pause->autoneg = 0;
487
35e8e8b4
IR
488 pause->rx_pause = !!(fc & AQ_NIC_FC_RX);
489 pause->tx_pause = !!(fc & AQ_NIC_FC_TX);
490
288551de
IR
491}
492
493static int aq_ethtool_set_pauseparam(struct net_device *ndev,
494 struct ethtool_pauseparam *pause)
495{
496 struct aq_nic_s *aq_nic = netdev_priv(ndev);
497 int err = 0;
498
499 if (!aq_nic->aq_fw_ops->set_flow_control)
500 return -EOPNOTSUPP;
501
502 if (pause->autoneg == AUTONEG_ENABLE)
503 return -EOPNOTSUPP;
504
505 if (pause->rx_pause)
506 aq_nic->aq_hw->aq_nic_cfg->flow_control |= AQ_NIC_FC_RX;
507 else
508 aq_nic->aq_hw->aq_nic_cfg->flow_control &= ~AQ_NIC_FC_RX;
509
510 if (pause->tx_pause)
511 aq_nic->aq_hw->aq_nic_cfg->flow_control |= AQ_NIC_FC_TX;
512 else
513 aq_nic->aq_hw->aq_nic_cfg->flow_control &= ~AQ_NIC_FC_TX;
514
f5dce08a 515 mutex_lock(&aq_nic->fwreq_mutex);
288551de 516 err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw);
f5dce08a 517 mutex_unlock(&aq_nic->fwreq_mutex);
288551de
IR
518
519 return err;
520}
521
c1af5427
AM
522static void aq_get_ringparam(struct net_device *ndev,
523 struct ethtool_ringparam *ring)
524{
525 struct aq_nic_s *aq_nic = netdev_priv(ndev);
526 struct aq_nic_cfg_s *aq_nic_cfg = aq_nic_get_cfg(aq_nic);
527
528 ring->rx_pending = aq_nic_cfg->rxds;
529 ring->tx_pending = aq_nic_cfg->txds;
530
531 ring->rx_max_pending = aq_nic_cfg->aq_hw_caps->rxds_max;
532 ring->tx_max_pending = aq_nic_cfg->aq_hw_caps->txds_max;
533}
534
535static int aq_set_ringparam(struct net_device *ndev,
536 struct ethtool_ringparam *ring)
537{
538 int err = 0;
539 bool ndev_running = false;
540 struct aq_nic_s *aq_nic = netdev_priv(ndev);
541 struct aq_nic_cfg_s *aq_nic_cfg = aq_nic_get_cfg(aq_nic);
542 const struct aq_hw_caps_s *hw_caps = aq_nic_cfg->aq_hw_caps;
543
544 if (ring->rx_mini_pending || ring->rx_jumbo_pending) {
545 err = -EOPNOTSUPP;
546 goto err_exit;
547 }
548
549 if (netif_running(ndev)) {
550 ndev_running = true;
551 dev_close(ndev);
552 }
553
554 aq_nic_free_vectors(aq_nic);
555
556 aq_nic_cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min);
557 aq_nic_cfg->rxds = min(aq_nic_cfg->rxds, hw_caps->rxds_max);
558 aq_nic_cfg->rxds = ALIGN(aq_nic_cfg->rxds, AQ_HW_RXD_MULTIPLE);
559
560 aq_nic_cfg->txds = max(ring->tx_pending, hw_caps->txds_min);
561 aq_nic_cfg->txds = min(aq_nic_cfg->txds, hw_caps->txds_max);
562 aq_nic_cfg->txds = ALIGN(aq_nic_cfg->txds, AQ_HW_TXD_MULTIPLE);
563
564 for (aq_nic->aq_vecs = 0; aq_nic->aq_vecs < aq_nic_cfg->vecs;
565 aq_nic->aq_vecs++) {
566 aq_nic->aq_vec[aq_nic->aq_vecs] =
567 aq_vec_alloc(aq_nic, aq_nic->aq_vecs, aq_nic_cfg);
568 if (unlikely(!aq_nic->aq_vec[aq_nic->aq_vecs])) {
569 err = -ENOMEM;
570 goto err_exit;
571 }
572 }
573 if (ndev_running)
00f54e68 574 err = dev_open(ndev, NULL);
c1af5427
AM
575
576err_exit:
577 return err;
578}
579
c5760d03
DV
580const struct ethtool_ops aq_ethtool_ops = {
581 .get_link = aq_ethtool_get_link,
582 .get_regs_len = aq_ethtool_get_regs_len,
583 .get_regs = aq_ethtool_get_regs,
c5760d03
DV
584 .get_drvinfo = aq_ethtool_get_drvinfo,
585 .get_strings = aq_ethtool_get_strings,
586 .get_rxfh_indir_size = aq_ethtool_get_rss_indir_size,
a0da96c0
YE
587 .get_wol = aq_ethtool_get_wol,
588 .set_wol = aq_ethtool_set_wol,
b8d68b62 589 .nway_reset = aq_ethtool_nway_reset,
c1af5427
AM
590 .get_ringparam = aq_get_ringparam,
591 .set_ringparam = aq_set_ringparam,
92ab6407
YE
592 .get_eee = aq_ethtool_get_eee,
593 .set_eee = aq_ethtool_set_eee,
288551de
IR
594 .get_pauseparam = aq_ethtool_get_pauseparam,
595 .set_pauseparam = aq_ethtool_set_pauseparam,
c5760d03
DV
596 .get_rxfh_key_size = aq_ethtool_get_rss_key_size,
597 .get_rxfh = aq_ethtool_get_rss,
39163767 598 .set_rxfh = aq_ethtool_set_rss,
c5760d03 599 .get_rxnfc = aq_ethtool_get_rxnfc,
8d0bcb01 600 .set_rxnfc = aq_ethtool_set_rxnfc,
c5760d03 601 .get_sset_count = aq_ethtool_get_sset_count,
f8244ab5
PR
602 .get_ethtool_stats = aq_ethtool_stats,
603 .get_link_ksettings = aq_ethtool_get_link_ksettings,
604 .set_link_ksettings = aq_ethtool_set_link_ksettings,
b82ee71a
IR
605 .get_coalesce = aq_ethtool_get_coalesce,
606 .set_coalesce = aq_ethtool_set_coalesce,
c5760d03 607};