net: aquantia: reject all unsupported coalescing params
[linux-2.6-microblaze.git] / drivers / net / ethernet / aquantia / atlantic / aq_ethtool.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * aQuantia Corporation Network Driver
4  * Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
5  */
6
7 /* File aq_ethtool.c: Definition of ethertool related functions. */
8
9 #include "aq_ethtool.h"
10 #include "aq_nic.h"
11 #include "aq_vec.h"
12 #include "aq_ptp.h"
13 #include "aq_filters.h"
14
15 #include <linux/ptp_clock_kernel.h>
16
17 static void aq_ethtool_get_regs(struct net_device *ndev,
18                                 struct ethtool_regs *regs, void *p)
19 {
20         struct aq_nic_s *aq_nic = netdev_priv(ndev);
21         u32 regs_count;
22
23         regs_count = aq_nic_get_regs_count(aq_nic);
24
25         memset(p, 0, regs_count * sizeof(u32));
26         aq_nic_get_regs(aq_nic, regs, p);
27 }
28
29 static int aq_ethtool_get_regs_len(struct net_device *ndev)
30 {
31         struct aq_nic_s *aq_nic = netdev_priv(ndev);
32         u32 regs_count;
33
34         regs_count = aq_nic_get_regs_count(aq_nic);
35
36         return regs_count * sizeof(u32);
37 }
38
39 static u32 aq_ethtool_get_link(struct net_device *ndev)
40 {
41         return ethtool_op_get_link(ndev);
42 }
43
44 static int aq_ethtool_get_link_ksettings(struct net_device *ndev,
45                                          struct ethtool_link_ksettings *cmd)
46 {
47         struct aq_nic_s *aq_nic = netdev_priv(ndev);
48
49         aq_nic_get_link_ksettings(aq_nic, cmd);
50         cmd->base.speed = netif_carrier_ok(ndev) ?
51                                 aq_nic_get_link_speed(aq_nic) : 0U;
52
53         return 0;
54 }
55
56 static int
57 aq_ethtool_set_link_ksettings(struct net_device *ndev,
58                               const struct ethtool_link_ksettings *cmd)
59 {
60         struct aq_nic_s *aq_nic = netdev_priv(ndev);
61
62         return aq_nic_set_link_ksettings(aq_nic, cmd);
63 }
64
65 static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
66         "InPackets",
67         "InUCast",
68         "InMCast",
69         "InBCast",
70         "InErrors",
71         "OutPackets",
72         "OutUCast",
73         "OutMCast",
74         "OutBCast",
75         "InUCastOctets",
76         "OutUCastOctets",
77         "InMCastOctets",
78         "OutMCastOctets",
79         "InBCastOctets",
80         "OutBCastOctets",
81         "InOctets",
82         "OutOctets",
83         "InPacketsDma",
84         "OutPacketsDma",
85         "InOctetsDma",
86         "OutOctetsDma",
87         "InDroppedDma",
88 };
89
90 static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = {
91         "Queue[%d] InPackets",
92         "Queue[%d] OutPackets",
93         "Queue[%d] Restarts",
94         "Queue[%d] InJumboPackets",
95         "Queue[%d] InLroPackets",
96         "Queue[%d] InErrors",
97 };
98
99 static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
100         "DMASystemLoopback",
101         "PKTSystemLoopback",
102         "DMANetworkLoopback",
103         "PHYInternalLoopback",
104         "PHYExternalLoopback",
105 };
106
107 static void aq_ethtool_stats(struct net_device *ndev,
108                              struct ethtool_stats *stats, u64 *data)
109 {
110         struct aq_nic_s *aq_nic = netdev_priv(ndev);
111         struct aq_nic_cfg_s *cfg;
112
113         cfg = aq_nic_get_cfg(aq_nic);
114
115         memset(data, 0, (ARRAY_SIZE(aq_ethtool_stat_names) +
116                          ARRAY_SIZE(aq_ethtool_queue_stat_names) *
117                          cfg->vecs) * sizeof(u64));
118         aq_nic_get_stats(aq_nic, data);
119 }
120
121 static void aq_ethtool_get_drvinfo(struct net_device *ndev,
122                                    struct ethtool_drvinfo *drvinfo)
123 {
124         struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
125         struct aq_nic_s *aq_nic = netdev_priv(ndev);
126         struct aq_nic_cfg_s *cfg;
127         u32 firmware_version;
128         u32 regs_count;
129
130         cfg = aq_nic_get_cfg(aq_nic);
131         firmware_version = aq_nic_get_fw_version(aq_nic);
132         regs_count = aq_nic_get_regs_count(aq_nic);
133
134         strlcat(drvinfo->driver, AQ_CFG_DRV_NAME, sizeof(drvinfo->driver));
135
136         snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
137                  "%u.%u.%u", firmware_version >> 24,
138                  (firmware_version >> 16) & 0xFFU, firmware_version & 0xFFFFU);
139
140         strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "",
141                 sizeof(drvinfo->bus_info));
142         drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
143                 cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
144         drvinfo->testinfo_len = 0;
145         drvinfo->regdump_len = regs_count;
146         drvinfo->eedump_len = 0;
147 }
148
149 static void aq_ethtool_get_strings(struct net_device *ndev,
150                                    u32 stringset, u8 *data)
151 {
152         struct aq_nic_s *aq_nic = netdev_priv(ndev);
153         struct aq_nic_cfg_s *cfg;
154         u8 *p = data;
155         int i, si;
156
157         cfg = aq_nic_get_cfg(aq_nic);
158
159         switch (stringset) {
160         case ETH_SS_STATS:
161                 memcpy(p, aq_ethtool_stat_names,
162                        sizeof(aq_ethtool_stat_names));
163                 p = p + sizeof(aq_ethtool_stat_names);
164                 for (i = 0; i < cfg->vecs; i++) {
165                         for (si = 0;
166                                 si < ARRAY_SIZE(aq_ethtool_queue_stat_names);
167                                 si++) {
168                                 snprintf(p, ETH_GSTRING_LEN,
169                                          aq_ethtool_queue_stat_names[si], i);
170                                 p += ETH_GSTRING_LEN;
171                         }
172                 }
173                 break;
174         case ETH_SS_PRIV_FLAGS:
175                 memcpy(p, aq_ethtool_priv_flag_names,
176                        sizeof(aq_ethtool_priv_flag_names));
177                 break;
178         }
179 }
180
181 static int aq_ethtool_set_phys_id(struct net_device *ndev,
182                                   enum ethtool_phys_id_state state)
183 {
184         struct aq_nic_s *aq_nic = netdev_priv(ndev);
185         struct aq_hw_s *hw = aq_nic->aq_hw;
186         int ret = 0;
187
188         if (!aq_nic->aq_fw_ops->led_control)
189                 return -EOPNOTSUPP;
190
191         mutex_lock(&aq_nic->fwreq_mutex);
192
193         switch (state) {
194         case ETHTOOL_ID_ACTIVE:
195                 ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_BLINK |
196                                  AQ_HW_LED_BLINK << 2 | AQ_HW_LED_BLINK << 4);
197                 break;
198         case ETHTOOL_ID_INACTIVE:
199                 ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_DEFAULT);
200                 break;
201         default:
202                 break;
203         }
204
205         mutex_unlock(&aq_nic->fwreq_mutex);
206
207         return ret;
208 }
209
210 static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
211 {
212         struct aq_nic_s *aq_nic = netdev_priv(ndev);
213         struct aq_nic_cfg_s *cfg;
214         int ret = 0;
215
216         cfg = aq_nic_get_cfg(aq_nic);
217
218         switch (stringset) {
219         case ETH_SS_STATS:
220                 ret = ARRAY_SIZE(aq_ethtool_stat_names) +
221                         cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
222                 break;
223         case ETH_SS_PRIV_FLAGS:
224                 ret = ARRAY_SIZE(aq_ethtool_priv_flag_names);
225                 break;
226         default:
227                 ret = -EOPNOTSUPP;
228         }
229
230         return ret;
231 }
232
233 static u32 aq_ethtool_get_rss_indir_size(struct net_device *ndev)
234 {
235         return AQ_CFG_RSS_INDIRECTION_TABLE_MAX;
236 }
237
238 static u32 aq_ethtool_get_rss_key_size(struct net_device *ndev)
239 {
240         struct aq_nic_s *aq_nic = netdev_priv(ndev);
241         struct aq_nic_cfg_s *cfg;
242
243         cfg = aq_nic_get_cfg(aq_nic);
244
245         return sizeof(cfg->aq_rss.hash_secret_key);
246 }
247
248 static int aq_ethtool_get_rss(struct net_device *ndev, u32 *indir, u8 *key,
249                               u8 *hfunc)
250 {
251         struct aq_nic_s *aq_nic = netdev_priv(ndev);
252         struct aq_nic_cfg_s *cfg;
253         unsigned int i = 0U;
254
255         cfg = aq_nic_get_cfg(aq_nic);
256
257         if (hfunc)
258                 *hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */
259         if (indir) {
260                 for (i = 0; i < AQ_CFG_RSS_INDIRECTION_TABLE_MAX; i++)
261                         indir[i] = cfg->aq_rss.indirection_table[i];
262         }
263         if (key)
264                 memcpy(key, cfg->aq_rss.hash_secret_key,
265                        sizeof(cfg->aq_rss.hash_secret_key));
266
267         return 0;
268 }
269
270 static int aq_ethtool_set_rss(struct net_device *netdev, const u32 *indir,
271                               const u8 *key, const u8 hfunc)
272 {
273         struct aq_nic_s *aq_nic = netdev_priv(netdev);
274         struct aq_nic_cfg_s *cfg;
275         unsigned int i = 0U;
276         u32 rss_entries;
277         int err = 0;
278
279         cfg = aq_nic_get_cfg(aq_nic);
280         rss_entries = cfg->aq_rss.indirection_table_size;
281
282         /* We do not allow change in unsupported parameters */
283         if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
284                 return -EOPNOTSUPP;
285         /* Fill out the redirection table */
286         if (indir)
287                 for (i = 0; i < rss_entries; i++)
288                         cfg->aq_rss.indirection_table[i] = indir[i];
289
290         /* Fill out the rss hash key */
291         if (key) {
292                 memcpy(cfg->aq_rss.hash_secret_key, key,
293                        sizeof(cfg->aq_rss.hash_secret_key));
294                 err = aq_nic->aq_hw_ops->hw_rss_hash_set(aq_nic->aq_hw,
295                         &cfg->aq_rss);
296                 if (err)
297                         return err;
298         }
299
300         err = aq_nic->aq_hw_ops->hw_rss_set(aq_nic->aq_hw, &cfg->aq_rss);
301
302         return err;
303 }
304
305 static int aq_ethtool_get_rxnfc(struct net_device *ndev,
306                                 struct ethtool_rxnfc *cmd,
307                                 u32 *rule_locs)
308 {
309         struct aq_nic_s *aq_nic = netdev_priv(ndev);
310         struct aq_nic_cfg_s *cfg;
311         int err = 0;
312
313         cfg = aq_nic_get_cfg(aq_nic);
314
315         switch (cmd->cmd) {
316         case ETHTOOL_GRXRINGS:
317                 cmd->data = cfg->vecs;
318                 break;
319         case ETHTOOL_GRXCLSRLCNT:
320                 cmd->rule_cnt = aq_get_rxnfc_count_all_rules(aq_nic);
321                 break;
322         case ETHTOOL_GRXCLSRULE:
323                 err = aq_get_rxnfc_rule(aq_nic, cmd);
324                 break;
325         case ETHTOOL_GRXCLSRLALL:
326                 err = aq_get_rxnfc_all_rules(aq_nic, cmd, rule_locs);
327                 break;
328         default:
329                 err = -EOPNOTSUPP;
330                 break;
331         }
332
333         return err;
334 }
335
336 static int aq_ethtool_set_rxnfc(struct net_device *ndev,
337                                 struct ethtool_rxnfc *cmd)
338 {
339         struct aq_nic_s *aq_nic = netdev_priv(ndev);
340         int err = 0;
341
342         switch (cmd->cmd) {
343         case ETHTOOL_SRXCLSRLINS:
344                 err = aq_add_rxnfc_rule(aq_nic, cmd);
345                 break;
346         case ETHTOOL_SRXCLSRLDEL:
347                 err = aq_del_rxnfc_rule(aq_nic, cmd);
348                 break;
349         default:
350                 err = -EOPNOTSUPP;
351                 break;
352         }
353
354         return err;
355 }
356
357 static int aq_ethtool_get_coalesce(struct net_device *ndev,
358                                    struct ethtool_coalesce *coal)
359 {
360         struct aq_nic_s *aq_nic = netdev_priv(ndev);
361         struct aq_nic_cfg_s *cfg;
362
363         cfg = aq_nic_get_cfg(aq_nic);
364
365         if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON ||
366             cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) {
367                 coal->rx_coalesce_usecs = cfg->rx_itr;
368                 coal->tx_coalesce_usecs = cfg->tx_itr;
369                 coal->rx_max_coalesced_frames = 0;
370                 coal->tx_max_coalesced_frames = 0;
371         } else {
372                 coal->rx_coalesce_usecs = 0;
373                 coal->tx_coalesce_usecs = 0;
374                 coal->rx_max_coalesced_frames = 1;
375                 coal->tx_max_coalesced_frames = 1;
376         }
377
378         return 0;
379 }
380
381 static int aq_ethtool_set_coalesce(struct net_device *ndev,
382                                    struct ethtool_coalesce *coal)
383 {
384         struct aq_nic_s *aq_nic = netdev_priv(ndev);
385         struct aq_nic_cfg_s *cfg;
386
387         cfg = aq_nic_get_cfg(aq_nic);
388
389         /* Atlantic only supports timing based coalescing
390          */
391         if (coal->rx_max_coalesced_frames > 1 ||
392             coal->tx_max_coalesced_frames > 1)
393                 return -EOPNOTSUPP;
394
395         /* We do not support frame counting. Check this
396          */
397         if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs))
398                 return -EOPNOTSUPP;
399         if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs))
400                 return -EOPNOTSUPP;
401
402         if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX ||
403             coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX)
404                 return -EINVAL;
405
406         cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON;
407
408         cfg->rx_itr = coal->rx_coalesce_usecs;
409         cfg->tx_itr = coal->tx_coalesce_usecs;
410
411         return aq_nic_update_interrupt_moderation_settings(aq_nic);
412 }
413
414 static void aq_ethtool_get_wol(struct net_device *ndev,
415                                struct ethtool_wolinfo *wol)
416 {
417         struct aq_nic_s *aq_nic = netdev_priv(ndev);
418         struct aq_nic_cfg_s *cfg;
419
420         cfg = aq_nic_get_cfg(aq_nic);
421
422         wol->supported = AQ_NIC_WOL_MODES;
423         wol->wolopts = cfg->wol;
424 }
425
426 static int aq_ethtool_set_wol(struct net_device *ndev,
427                               struct ethtool_wolinfo *wol)
428 {
429         struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
430         struct aq_nic_s *aq_nic = netdev_priv(ndev);
431         struct aq_nic_cfg_s *cfg;
432         int err = 0;
433
434         cfg = aq_nic_get_cfg(aq_nic);
435
436         if (wol->wolopts & ~AQ_NIC_WOL_MODES)
437                 return -EOPNOTSUPP;
438
439         cfg->wol = wol->wolopts;
440
441         err = device_set_wakeup_enable(&pdev->dev, !!cfg->wol);
442
443         return err;
444 }
445
446 static int aq_ethtool_get_ts_info(struct net_device *ndev,
447                                   struct ethtool_ts_info *info)
448 {
449         struct aq_nic_s *aq_nic = netdev_priv(ndev);
450
451         ethtool_op_get_ts_info(ndev, info);
452
453         if (!aq_nic->aq_ptp)
454                 return 0;
455
456         info->so_timestamping |=
457                 SOF_TIMESTAMPING_TX_HARDWARE |
458                 SOF_TIMESTAMPING_RX_HARDWARE |
459                 SOF_TIMESTAMPING_RAW_HARDWARE;
460
461         info->tx_types = BIT(HWTSTAMP_TX_OFF) |
462                          BIT(HWTSTAMP_TX_ON);
463
464         info->rx_filters = BIT(HWTSTAMP_FILTER_NONE);
465
466         info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
467                             BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
468                             BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
469
470         info->phc_index = ptp_clock_index(aq_ptp_get_ptp_clock(aq_nic->aq_ptp));
471
472         return 0;
473 }
474
475 static enum hw_atl_fw2x_rate eee_mask_to_ethtool_mask(u32 speed)
476 {
477         u32 rate = 0;
478
479         if (speed & AQ_NIC_RATE_EEE_10G)
480                 rate |= SUPPORTED_10000baseT_Full;
481
482         if (speed & AQ_NIC_RATE_EEE_2GS)
483                 rate |= SUPPORTED_2500baseX_Full;
484
485         if (speed & AQ_NIC_RATE_EEE_1G)
486                 rate |= SUPPORTED_1000baseT_Full;
487
488         return rate;
489 }
490
491 static int aq_ethtool_get_eee(struct net_device *ndev, struct ethtool_eee *eee)
492 {
493         struct aq_nic_s *aq_nic = netdev_priv(ndev);
494         u32 rate, supported_rates;
495         int err = 0;
496
497         if (!aq_nic->aq_fw_ops->get_eee_rate)
498                 return -EOPNOTSUPP;
499
500         mutex_lock(&aq_nic->fwreq_mutex);
501         err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
502                                               &supported_rates);
503         mutex_unlock(&aq_nic->fwreq_mutex);
504         if (err < 0)
505                 return err;
506
507         eee->supported = eee_mask_to_ethtool_mask(supported_rates);
508
509         if (aq_nic->aq_nic_cfg.eee_speeds)
510                 eee->advertised = eee->supported;
511
512         eee->lp_advertised = eee_mask_to_ethtool_mask(rate);
513
514         eee->eee_enabled = !!eee->advertised;
515
516         eee->tx_lpi_enabled = eee->eee_enabled;
517         if (eee->advertised & eee->lp_advertised)
518                 eee->eee_active = true;
519
520         return 0;
521 }
522
523 static int aq_ethtool_set_eee(struct net_device *ndev, struct ethtool_eee *eee)
524 {
525         struct aq_nic_s *aq_nic = netdev_priv(ndev);
526         u32 rate, supported_rates;
527         struct aq_nic_cfg_s *cfg;
528         int err = 0;
529
530         cfg = aq_nic_get_cfg(aq_nic);
531
532         if (unlikely(!aq_nic->aq_fw_ops->get_eee_rate ||
533                      !aq_nic->aq_fw_ops->set_eee_rate))
534                 return -EOPNOTSUPP;
535
536         mutex_lock(&aq_nic->fwreq_mutex);
537         err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
538                                               &supported_rates);
539         mutex_unlock(&aq_nic->fwreq_mutex);
540         if (err < 0)
541                 return err;
542
543         if (eee->eee_enabled) {
544                 rate = supported_rates;
545                 cfg->eee_speeds = rate;
546         } else {
547                 rate = 0;
548                 cfg->eee_speeds = 0;
549         }
550
551         mutex_lock(&aq_nic->fwreq_mutex);
552         err = aq_nic->aq_fw_ops->set_eee_rate(aq_nic->aq_hw, rate);
553         mutex_unlock(&aq_nic->fwreq_mutex);
554
555         return err;
556 }
557
558 static int aq_ethtool_nway_reset(struct net_device *ndev)
559 {
560         struct aq_nic_s *aq_nic = netdev_priv(ndev);
561         int err = 0;
562
563         if (unlikely(!aq_nic->aq_fw_ops->renegotiate))
564                 return -EOPNOTSUPP;
565
566         if (netif_running(ndev)) {
567                 mutex_lock(&aq_nic->fwreq_mutex);
568                 err = aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw);
569                 mutex_unlock(&aq_nic->fwreq_mutex);
570         }
571
572         return err;
573 }
574
575 static void aq_ethtool_get_pauseparam(struct net_device *ndev,
576                                       struct ethtool_pauseparam *pause)
577 {
578         struct aq_nic_s *aq_nic = netdev_priv(ndev);
579         u32 fc = aq_nic->aq_nic_cfg.fc.req;
580
581         pause->autoneg = 0;
582
583         pause->rx_pause = !!(fc & AQ_NIC_FC_RX);
584         pause->tx_pause = !!(fc & AQ_NIC_FC_TX);
585
586 }
587
588 static int aq_ethtool_set_pauseparam(struct net_device *ndev,
589                                      struct ethtool_pauseparam *pause)
590 {
591         struct aq_nic_s *aq_nic = netdev_priv(ndev);
592         int err = 0;
593
594         if (!aq_nic->aq_fw_ops->set_flow_control)
595                 return -EOPNOTSUPP;
596
597         if (pause->autoneg == AUTONEG_ENABLE)
598                 return -EOPNOTSUPP;
599
600         if (pause->rx_pause)
601                 aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_RX;
602         else
603                 aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_RX;
604
605         if (pause->tx_pause)
606                 aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_TX;
607         else
608                 aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_TX;
609
610         mutex_lock(&aq_nic->fwreq_mutex);
611         err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw);
612         mutex_unlock(&aq_nic->fwreq_mutex);
613
614         return err;
615 }
616
617 static void aq_get_ringparam(struct net_device *ndev,
618                              struct ethtool_ringparam *ring)
619 {
620         struct aq_nic_s *aq_nic = netdev_priv(ndev);
621         struct aq_nic_cfg_s *cfg;
622
623         cfg = aq_nic_get_cfg(aq_nic);
624
625         ring->rx_pending = cfg->rxds;
626         ring->tx_pending = cfg->txds;
627
628         ring->rx_max_pending = cfg->aq_hw_caps->rxds_max;
629         ring->tx_max_pending = cfg->aq_hw_caps->txds_max;
630 }
631
632 static int aq_set_ringparam(struct net_device *ndev,
633                             struct ethtool_ringparam *ring)
634 {
635         struct aq_nic_s *aq_nic = netdev_priv(ndev);
636         const struct aq_hw_caps_s *hw_caps;
637         bool ndev_running = false;
638         struct aq_nic_cfg_s *cfg;
639         int err = 0;
640
641         cfg = aq_nic_get_cfg(aq_nic);
642         hw_caps = cfg->aq_hw_caps;
643
644         if (ring->rx_mini_pending || ring->rx_jumbo_pending) {
645                 err = -EOPNOTSUPP;
646                 goto err_exit;
647         }
648
649         if (netif_running(ndev)) {
650                 ndev_running = true;
651                 dev_close(ndev);
652         }
653
654         aq_nic_free_vectors(aq_nic);
655
656         cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min);
657         cfg->rxds = min(cfg->rxds, hw_caps->rxds_max);
658         cfg->rxds = ALIGN(cfg->rxds, AQ_HW_RXD_MULTIPLE);
659
660         cfg->txds = max(ring->tx_pending, hw_caps->txds_min);
661         cfg->txds = min(cfg->txds, hw_caps->txds_max);
662         cfg->txds = ALIGN(cfg->txds, AQ_HW_TXD_MULTIPLE);
663
664         for (aq_nic->aq_vecs = 0; aq_nic->aq_vecs < cfg->vecs;
665              aq_nic->aq_vecs++) {
666                 aq_nic->aq_vec[aq_nic->aq_vecs] =
667                     aq_vec_alloc(aq_nic, aq_nic->aq_vecs, cfg);
668                 if (unlikely(!aq_nic->aq_vec[aq_nic->aq_vecs])) {
669                         err = -ENOMEM;
670                         goto err_exit;
671                 }
672         }
673         if (ndev_running)
674                 err = dev_open(ndev, NULL);
675
676 err_exit:
677         return err;
678 }
679
680 static u32 aq_get_msg_level(struct net_device *ndev)
681 {
682         struct aq_nic_s *aq_nic = netdev_priv(ndev);
683
684         return aq_nic->msg_enable;
685 }
686
687 static void aq_set_msg_level(struct net_device *ndev, u32 data)
688 {
689         struct aq_nic_s *aq_nic = netdev_priv(ndev);
690
691         aq_nic->msg_enable = data;
692 }
693
694 static u32 aq_ethtool_get_priv_flags(struct net_device *ndev)
695 {
696         struct aq_nic_s *aq_nic = netdev_priv(ndev);
697
698         return aq_nic->aq_nic_cfg.priv_flags;
699 }
700
701 static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
702 {
703         struct aq_nic_s *aq_nic = netdev_priv(ndev);
704         struct aq_nic_cfg_s *cfg;
705         u32 priv_flags;
706
707         cfg = aq_nic_get_cfg(aq_nic);
708         priv_flags = cfg->priv_flags;
709
710         if (flags & ~AQ_PRIV_FLAGS_MASK)
711                 return -EOPNOTSUPP;
712
713         if (hweight32((flags | priv_flags) & AQ_HW_LOOPBACK_MASK) > 1) {
714                 netdev_info(ndev, "Can't enable more than one loopback simultaneously\n");
715                 return -EINVAL;
716         }
717
718         cfg->priv_flags = flags;
719
720         if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
721                 if (netif_running(ndev)) {
722                         dev_close(ndev);
723
724                         dev_open(ndev, NULL);
725                 }
726         } else if ((priv_flags ^ flags) & AQ_HW_LOOPBACK_MASK) {
727                 aq_nic_set_loopback(aq_nic);
728         }
729
730         return 0;
731 }
732
733 const struct ethtool_ops aq_ethtool_ops = {
734         .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
735                                      ETHTOOL_COALESCE_MAX_FRAMES,
736         .get_link            = aq_ethtool_get_link,
737         .get_regs_len        = aq_ethtool_get_regs_len,
738         .get_regs            = aq_ethtool_get_regs,
739         .get_drvinfo         = aq_ethtool_get_drvinfo,
740         .get_strings         = aq_ethtool_get_strings,
741         .set_phys_id         = aq_ethtool_set_phys_id,
742         .get_rxfh_indir_size = aq_ethtool_get_rss_indir_size,
743         .get_wol             = aq_ethtool_get_wol,
744         .set_wol             = aq_ethtool_set_wol,
745         .nway_reset          = aq_ethtool_nway_reset,
746         .get_ringparam       = aq_get_ringparam,
747         .set_ringparam       = aq_set_ringparam,
748         .get_eee             = aq_ethtool_get_eee,
749         .set_eee             = aq_ethtool_set_eee,
750         .get_pauseparam      = aq_ethtool_get_pauseparam,
751         .set_pauseparam      = aq_ethtool_set_pauseparam,
752         .get_rxfh_key_size   = aq_ethtool_get_rss_key_size,
753         .get_rxfh            = aq_ethtool_get_rss,
754         .set_rxfh            = aq_ethtool_set_rss,
755         .get_rxnfc           = aq_ethtool_get_rxnfc,
756         .set_rxnfc           = aq_ethtool_set_rxnfc,
757         .get_msglevel        = aq_get_msg_level,
758         .set_msglevel        = aq_set_msg_level,
759         .get_sset_count      = aq_ethtool_get_sset_count,
760         .get_ethtool_stats   = aq_ethtool_stats,
761         .get_priv_flags      = aq_ethtool_get_priv_flags,
762         .set_priv_flags      = aq_ethtool_set_priv_flags,
763         .get_link_ksettings  = aq_ethtool_get_link_ksettings,
764         .set_link_ksettings  = aq_ethtool_set_link_ksettings,
765         .get_coalesce        = aq_ethtool_get_coalesce,
766         .set_coalesce        = aq_ethtool_set_coalesce,
767         .get_ts_info         = aq_ethtool_get_ts_info,
768 };