hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
....@@ -1,10 +1,8 @@
1
-/*
2
- * aQuantia Corporation Network Driver
3
- * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
1
+// SPDX-License-Identifier: GPL-2.0-only
2
+/* Atlantic Network Driver
43 *
5
- * This program is free software; you can redistribute it and/or modify it
6
- * under the terms and conditions of the GNU General Public License,
7
- * version 2, as published by the Free Software Foundation.
4
+ * Copyright (C) 2014-2019 aQuantia Corporation
5
+ * Copyright (C) 2019-2020 Marvell International Ltd.
86 */
97
108 /* File aq_ethtool.c: Definition of ethertool related functions. */
....@@ -12,12 +10,20 @@
1210 #include "aq_ethtool.h"
1311 #include "aq_nic.h"
1412 #include "aq_vec.h"
13
+#include "aq_ptp.h"
14
+#include "aq_filters.h"
15
+#include "aq_macsec.h"
16
+#include "aq_main.h"
17
+
18
+#include <linux/ptp_clock_kernel.h>
1519
1620 static void aq_ethtool_get_regs(struct net_device *ndev,
1721 struct ethtool_regs *regs, void *p)
1822 {
1923 struct aq_nic_s *aq_nic = netdev_priv(ndev);
20
- u32 regs_count = aq_nic_get_regs_count(aq_nic);
24
+ u32 regs_count;
25
+
26
+ regs_count = aq_nic_get_regs_count(aq_nic);
2127
2228 memset(p, 0, regs_count * sizeof(u32));
2329 aq_nic_get_regs(aq_nic, regs, p);
....@@ -26,7 +32,9 @@
2632 static int aq_ethtool_get_regs_len(struct net_device *ndev)
2733 {
2834 struct aq_nic_s *aq_nic = netdev_priv(ndev);
29
- u32 regs_count = aq_nic_get_regs_count(aq_nic);
35
+ u32 regs_count;
36
+
37
+ regs_count = aq_nic_get_regs_count(aq_nic);
3038
3139 return regs_count * sizeof(u32);
3240 }
....@@ -82,38 +90,141 @@
8290 "InDroppedDma",
8391 };
8492
85
-static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = {
86
- "Queue[%d] InPackets",
87
- "Queue[%d] OutPackets",
88
- "Queue[%d] Restarts",
89
- "Queue[%d] InJumboPackets",
90
- "Queue[%d] InLroPackets",
91
- "Queue[%d] InErrors",
93
+static const char * const aq_ethtool_queue_rx_stat_names[] = {
94
+ "%sQueue[%d] InPackets",
95
+ "%sQueue[%d] InJumboPackets",
96
+ "%sQueue[%d] InLroPackets",
97
+ "%sQueue[%d] InErrors",
98
+ "%sQueue[%d] AllocFails",
99
+ "%sQueue[%d] SkbAllocFails",
100
+ "%sQueue[%d] Polls",
92101 };
102
+
103
+static const char * const aq_ethtool_queue_tx_stat_names[] = {
104
+ "%sQueue[%d] OutPackets",
105
+ "%sQueue[%d] Restarts",
106
+};
107
+
108
+#if IS_ENABLED(CONFIG_MACSEC)
109
+static const char aq_macsec_stat_names[][ETH_GSTRING_LEN] = {
110
+ "MACSec InCtlPackets",
111
+ "MACSec InTaggedMissPackets",
112
+ "MACSec InUntaggedMissPackets",
113
+ "MACSec InNotagPackets",
114
+ "MACSec InUntaggedPackets",
115
+ "MACSec InBadTagPackets",
116
+ "MACSec InNoSciPackets",
117
+ "MACSec InUnknownSciPackets",
118
+ "MACSec InCtrlPortPassPackets",
119
+ "MACSec InUnctrlPortPassPackets",
120
+ "MACSec InCtrlPortFailPackets",
121
+ "MACSec InUnctrlPortFailPackets",
122
+ "MACSec InTooLongPackets",
123
+ "MACSec InIgpocCtlPackets",
124
+ "MACSec InEccErrorPackets",
125
+ "MACSec InUnctrlHitDropRedir",
126
+ "MACSec OutCtlPackets",
127
+ "MACSec OutUnknownSaPackets",
128
+ "MACSec OutUntaggedPackets",
129
+ "MACSec OutTooLong",
130
+ "MACSec OutEccErrorPackets",
131
+ "MACSec OutUnctrlHitDropRedir",
132
+};
133
+
134
+static const char * const aq_macsec_txsc_stat_names[] = {
135
+ "MACSecTXSC%d ProtectedPkts",
136
+ "MACSecTXSC%d EncryptedPkts",
137
+ "MACSecTXSC%d ProtectedOctets",
138
+ "MACSecTXSC%d EncryptedOctets",
139
+};
140
+
141
+static const char * const aq_macsec_txsa_stat_names[] = {
142
+ "MACSecTXSC%dSA%d HitDropRedirect",
143
+ "MACSecTXSC%dSA%d Protected2Pkts",
144
+ "MACSecTXSC%dSA%d ProtectedPkts",
145
+ "MACSecTXSC%dSA%d EncryptedPkts",
146
+};
147
+
148
+static const char * const aq_macsec_rxsa_stat_names[] = {
149
+ "MACSecRXSC%dSA%d UntaggedHitPkts",
150
+ "MACSecRXSC%dSA%d CtrlHitDrpRedir",
151
+ "MACSecRXSC%dSA%d NotUsingSa",
152
+ "MACSecRXSC%dSA%d UnusedSa",
153
+ "MACSecRXSC%dSA%d NotValidPkts",
154
+ "MACSecRXSC%dSA%d InvalidPkts",
155
+ "MACSecRXSC%dSA%d OkPkts",
156
+ "MACSecRXSC%dSA%d LatePkts",
157
+ "MACSecRXSC%dSA%d DelayedPkts",
158
+ "MACSecRXSC%dSA%d UncheckedPkts",
159
+ "MACSecRXSC%dSA%d ValidatedOctets",
160
+ "MACSecRXSC%dSA%d DecryptedOctets",
161
+};
162
+#endif
163
+
164
+static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
165
+ "DMASystemLoopback",
166
+ "PKTSystemLoopback",
167
+ "DMANetworkLoopback",
168
+ "PHYInternalLoopback",
169
+ "PHYExternalLoopback",
170
+};
171
+
172
+static u32 aq_ethtool_n_stats(struct net_device *ndev)
173
+{
174
+ const int rx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_rx_stat_names);
175
+ const int tx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_tx_stat_names);
176
+ struct aq_nic_s *nic = netdev_priv(ndev);
177
+ struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(nic);
178
+ u32 n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
179
+ (rx_stat_cnt + tx_stat_cnt) * cfg->vecs * cfg->tcs;
180
+
181
+#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
182
+ n_stats += rx_stat_cnt * aq_ptp_get_ring_cnt(nic, ATL_RING_RX) +
183
+ tx_stat_cnt * aq_ptp_get_ring_cnt(nic, ATL_RING_TX);
184
+#endif
185
+
186
+#if IS_ENABLED(CONFIG_MACSEC)
187
+ if (nic->macsec_cfg) {
188
+ n_stats += ARRAY_SIZE(aq_macsec_stat_names) +
189
+ ARRAY_SIZE(aq_macsec_txsc_stat_names) *
190
+ aq_macsec_tx_sc_cnt(nic) +
191
+ ARRAY_SIZE(aq_macsec_txsa_stat_names) *
192
+ aq_macsec_tx_sa_cnt(nic) +
193
+ ARRAY_SIZE(aq_macsec_rxsa_stat_names) *
194
+ aq_macsec_rx_sa_cnt(nic);
195
+ }
196
+#endif
197
+
198
+ return n_stats;
199
+}
93200
94201 static void aq_ethtool_stats(struct net_device *ndev,
95202 struct ethtool_stats *stats, u64 *data)
96203 {
97204 struct aq_nic_s *aq_nic = netdev_priv(ndev);
98
- struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
99205
100
- memset(data, 0, (ARRAY_SIZE(aq_ethtool_stat_names) +
101
- ARRAY_SIZE(aq_ethtool_queue_stat_names) *
102
- cfg->vecs) * sizeof(u64));
103
- aq_nic_get_stats(aq_nic, data);
206
+ memset(data, 0, aq_ethtool_n_stats(ndev) * sizeof(u64));
207
+ data = aq_nic_get_stats(aq_nic, data);
208
+#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
209
+ data = aq_ptp_get_stats(aq_nic, data);
210
+#endif
211
+#if IS_ENABLED(CONFIG_MACSEC)
212
+ data = aq_macsec_get_stats(aq_nic, data);
213
+#endif
104214 }
105215
106216 static void aq_ethtool_get_drvinfo(struct net_device *ndev,
107217 struct ethtool_drvinfo *drvinfo)
108218 {
109
- struct aq_nic_s *aq_nic = netdev_priv(ndev);
110
- struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
111219 struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
112
- u32 firmware_version = aq_nic_get_fw_version(aq_nic);
113
- u32 regs_count = aq_nic_get_regs_count(aq_nic);
220
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
221
+ u32 firmware_version;
222
+ u32 regs_count;
223
+
224
+ firmware_version = aq_nic_get_fw_version(aq_nic);
225
+ regs_count = aq_nic_get_regs_count(aq_nic);
114226
115227 strlcat(drvinfo->driver, AQ_CFG_DRV_NAME, sizeof(drvinfo->driver));
116
- strlcat(drvinfo->version, AQ_CFG_DRV_VERSION, sizeof(drvinfo->version));
117228
118229 snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
119230 "%u.%u.%u", firmware_version >> 24,
....@@ -121,8 +232,7 @@
121232
122233 strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "",
123234 sizeof(drvinfo->bus_info));
124
- drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
125
- cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
235
+ drvinfo->n_stats = aq_ethtool_n_stats(ndev);
126236 drvinfo->testinfo_len = 0;
127237 drvinfo->regdump_len = regs_count;
128238 drvinfo->eedump_len = 0;
....@@ -131,41 +241,185 @@
131241 static void aq_ethtool_get_strings(struct net_device *ndev,
132242 u32 stringset, u8 *data)
133243 {
134
- int i, si;
135
- struct aq_nic_s *aq_nic = netdev_priv(ndev);
136
- struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
244
+ struct aq_nic_s *nic = netdev_priv(ndev);
245
+ struct aq_nic_cfg_s *cfg;
137246 u8 *p = data;
247
+ int i, si;
248
+#if IS_ENABLED(CONFIG_MACSEC)
249
+ int sa;
250
+#endif
138251
139
- if (stringset == ETH_SS_STATS) {
140
- memcpy(p, *aq_ethtool_stat_names,
252
+ cfg = aq_nic_get_cfg(nic);
253
+
254
+ switch (stringset) {
255
+ case ETH_SS_STATS: {
256
+ const int rx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_rx_stat_names);
257
+ const int tx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_tx_stat_names);
258
+ char tc_string[8];
259
+ int tc;
260
+
261
+ memset(tc_string, 0, sizeof(tc_string));
262
+ memcpy(p, aq_ethtool_stat_names,
141263 sizeof(aq_ethtool_stat_names));
142264 p = p + sizeof(aq_ethtool_stat_names);
143
- for (i = 0; i < cfg->vecs; i++) {
144
- for (si = 0;
145
- si < ARRAY_SIZE(aq_ethtool_queue_stat_names);
146
- si++) {
147
- snprintf(p, ETH_GSTRING_LEN,
148
- aq_ethtool_queue_stat_names[si], i);
149
- p += ETH_GSTRING_LEN;
265
+
266
+ for (tc = 0; tc < cfg->tcs; tc++) {
267
+ if (cfg->is_qos)
268
+ snprintf(tc_string, 8, "TC%d ", tc);
269
+
270
+ for (i = 0; i < cfg->vecs; i++) {
271
+ for (si = 0; si < rx_stat_cnt; si++) {
272
+ snprintf(p, ETH_GSTRING_LEN,
273
+ aq_ethtool_queue_rx_stat_names[si],
274
+ tc_string,
275
+ AQ_NIC_CFG_TCVEC2RING(cfg, tc, i));
276
+ p += ETH_GSTRING_LEN;
277
+ }
278
+ for (si = 0; si < tx_stat_cnt; si++) {
279
+ snprintf(p, ETH_GSTRING_LEN,
280
+ aq_ethtool_queue_tx_stat_names[si],
281
+ tc_string,
282
+ AQ_NIC_CFG_TCVEC2RING(cfg, tc, i));
283
+ p += ETH_GSTRING_LEN;
284
+ }
150285 }
151286 }
287
+#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
288
+ if (nic->aq_ptp) {
289
+ const int rx_ring_cnt = aq_ptp_get_ring_cnt(nic, ATL_RING_RX);
290
+ const int tx_ring_cnt = aq_ptp_get_ring_cnt(nic, ATL_RING_TX);
291
+ unsigned int ptp_ring_idx =
292
+ aq_ptp_ring_idx(nic->aq_nic_cfg.tc_mode);
293
+
294
+ snprintf(tc_string, 8, "PTP ");
295
+
296
+ for (i = 0; i < max(rx_ring_cnt, tx_ring_cnt); i++) {
297
+ for (si = 0; si < rx_stat_cnt; si++) {
298
+ snprintf(p, ETH_GSTRING_LEN,
299
+ aq_ethtool_queue_rx_stat_names[si],
300
+ tc_string,
301
+ i ? PTP_HWST_RING_IDX : ptp_ring_idx);
302
+ p += ETH_GSTRING_LEN;
303
+ }
304
+ if (i >= tx_ring_cnt)
305
+ continue;
306
+ for (si = 0; si < tx_stat_cnt; si++) {
307
+ snprintf(p, ETH_GSTRING_LEN,
308
+ aq_ethtool_queue_tx_stat_names[si],
309
+ tc_string,
310
+ i ? PTP_HWST_RING_IDX : ptp_ring_idx);
311
+ p += ETH_GSTRING_LEN;
312
+ }
313
+ }
314
+ }
315
+#endif
316
+#if IS_ENABLED(CONFIG_MACSEC)
317
+ if (!nic->macsec_cfg)
318
+ break;
319
+
320
+ memcpy(p, aq_macsec_stat_names, sizeof(aq_macsec_stat_names));
321
+ p = p + sizeof(aq_macsec_stat_names);
322
+ for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
323
+ struct aq_macsec_txsc *aq_txsc;
324
+
325
+ if (!(test_bit(i, &nic->macsec_cfg->txsc_idx_busy)))
326
+ continue;
327
+
328
+ for (si = 0;
329
+ si < ARRAY_SIZE(aq_macsec_txsc_stat_names);
330
+ si++) {
331
+ snprintf(p, ETH_GSTRING_LEN,
332
+ aq_macsec_txsc_stat_names[si], i);
333
+ p += ETH_GSTRING_LEN;
334
+ }
335
+ aq_txsc = &nic->macsec_cfg->aq_txsc[i];
336
+ for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
337
+ if (!(test_bit(sa, &aq_txsc->tx_sa_idx_busy)))
338
+ continue;
339
+ for (si = 0;
340
+ si < ARRAY_SIZE(aq_macsec_txsa_stat_names);
341
+ si++) {
342
+ snprintf(p, ETH_GSTRING_LEN,
343
+ aq_macsec_txsa_stat_names[si],
344
+ i, sa);
345
+ p += ETH_GSTRING_LEN;
346
+ }
347
+ }
348
+ }
349
+ for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
350
+ struct aq_macsec_rxsc *aq_rxsc;
351
+
352
+ if (!(test_bit(i, &nic->macsec_cfg->rxsc_idx_busy)))
353
+ continue;
354
+
355
+ aq_rxsc = &nic->macsec_cfg->aq_rxsc[i];
356
+ for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
357
+ if (!(test_bit(sa, &aq_rxsc->rx_sa_idx_busy)))
358
+ continue;
359
+ for (si = 0;
360
+ si < ARRAY_SIZE(aq_macsec_rxsa_stat_names);
361
+ si++) {
362
+ snprintf(p, ETH_GSTRING_LEN,
363
+ aq_macsec_rxsa_stat_names[si],
364
+ i, sa);
365
+ p += ETH_GSTRING_LEN;
366
+ }
367
+ }
368
+ }
369
+#endif
370
+ break;
152371 }
372
+ case ETH_SS_PRIV_FLAGS:
373
+ memcpy(p, aq_ethtool_priv_flag_names,
374
+ sizeof(aq_ethtool_priv_flag_names));
375
+ break;
376
+ }
377
+}
378
+
379
+static int aq_ethtool_set_phys_id(struct net_device *ndev,
380
+ enum ethtool_phys_id_state state)
381
+{
382
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
383
+ struct aq_hw_s *hw = aq_nic->aq_hw;
384
+ int ret = 0;
385
+
386
+ if (!aq_nic->aq_fw_ops->led_control)
387
+ return -EOPNOTSUPP;
388
+
389
+ mutex_lock(&aq_nic->fwreq_mutex);
390
+
391
+ switch (state) {
392
+ case ETHTOOL_ID_ACTIVE:
393
+ ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_BLINK |
394
+ AQ_HW_LED_BLINK << 2 | AQ_HW_LED_BLINK << 4);
395
+ break;
396
+ case ETHTOOL_ID_INACTIVE:
397
+ ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_DEFAULT);
398
+ break;
399
+ default:
400
+ break;
401
+ }
402
+
403
+ mutex_unlock(&aq_nic->fwreq_mutex);
404
+
405
+ return ret;
153406 }
154407
155408 static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
156409 {
157410 int ret = 0;
158
- struct aq_nic_s *aq_nic = netdev_priv(ndev);
159
- struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
160411
161412 switch (stringset) {
162413 case ETH_SS_STATS:
163
- ret = ARRAY_SIZE(aq_ethtool_stat_names) +
164
- cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
414
+ ret = aq_ethtool_n_stats(ndev);
415
+ break;
416
+ case ETH_SS_PRIV_FLAGS:
417
+ ret = ARRAY_SIZE(aq_ethtool_priv_flag_names);
165418 break;
166419 default:
167420 ret = -EOPNOTSUPP;
168421 }
422
+
169423 return ret;
170424 }
171425
....@@ -177,7 +431,9 @@
177431 static u32 aq_ethtool_get_rss_key_size(struct net_device *ndev)
178432 {
179433 struct aq_nic_s *aq_nic = netdev_priv(ndev);
180
- struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
434
+ struct aq_nic_cfg_s *cfg;
435
+
436
+ cfg = aq_nic_get_cfg(aq_nic);
181437
182438 return sizeof(cfg->aq_rss.hash_secret_key);
183439 }
....@@ -186,8 +442,10 @@
186442 u8 *hfunc)
187443 {
188444 struct aq_nic_s *aq_nic = netdev_priv(ndev);
189
- struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
445
+ struct aq_nic_cfg_s *cfg;
190446 unsigned int i = 0U;
447
+
448
+ cfg = aq_nic_get_cfg(aq_nic);
191449
192450 if (hfunc)
193451 *hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */
....@@ -198,7 +456,43 @@
198456 if (key)
199457 memcpy(key, cfg->aq_rss.hash_secret_key,
200458 sizeof(cfg->aq_rss.hash_secret_key));
459
+
201460 return 0;
461
+}
462
+
463
+static int aq_ethtool_set_rss(struct net_device *netdev, const u32 *indir,
464
+ const u8 *key, const u8 hfunc)
465
+{
466
+ struct aq_nic_s *aq_nic = netdev_priv(netdev);
467
+ struct aq_nic_cfg_s *cfg;
468
+ unsigned int i = 0U;
469
+ u32 rss_entries;
470
+ int err = 0;
471
+
472
+ cfg = aq_nic_get_cfg(aq_nic);
473
+ rss_entries = cfg->aq_rss.indirection_table_size;
474
+
475
+ /* We do not allow change in unsupported parameters */
476
+ if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
477
+ return -EOPNOTSUPP;
478
+ /* Fill out the redirection table */
479
+ if (indir)
480
+ for (i = 0; i < rss_entries; i++)
481
+ cfg->aq_rss.indirection_table[i] = indir[i];
482
+
483
+ /* Fill out the rss hash key */
484
+ if (key) {
485
+ memcpy(cfg->aq_rss.hash_secret_key, key,
486
+ sizeof(cfg->aq_rss.hash_secret_key));
487
+ err = aq_nic->aq_hw_ops->hw_rss_hash_set(aq_nic->aq_hw,
488
+ &cfg->aq_rss);
489
+ if (err)
490
+ return err;
491
+ }
492
+
493
+ err = aq_nic->aq_hw_ops->hw_rss_set(aq_nic->aq_hw, &cfg->aq_rss);
494
+
495
+ return err;
202496 }
203497
204498 static int aq_ethtool_get_rxnfc(struct net_device *ndev,
....@@ -206,14 +500,45 @@
206500 u32 *rule_locs)
207501 {
208502 struct aq_nic_s *aq_nic = netdev_priv(ndev);
209
- struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
503
+ struct aq_nic_cfg_s *cfg;
210504 int err = 0;
505
+
506
+ cfg = aq_nic_get_cfg(aq_nic);
211507
212508 switch (cmd->cmd) {
213509 case ETHTOOL_GRXRINGS:
214510 cmd->data = cfg->vecs;
215511 break;
512
+ case ETHTOOL_GRXCLSRLCNT:
513
+ cmd->rule_cnt = aq_get_rxnfc_count_all_rules(aq_nic);
514
+ break;
515
+ case ETHTOOL_GRXCLSRULE:
516
+ err = aq_get_rxnfc_rule(aq_nic, cmd);
517
+ break;
518
+ case ETHTOOL_GRXCLSRLALL:
519
+ err = aq_get_rxnfc_all_rules(aq_nic, cmd, rule_locs);
520
+ break;
521
+ default:
522
+ err = -EOPNOTSUPP;
523
+ break;
524
+ }
216525
526
+ return err;
527
+}
528
+
529
+static int aq_ethtool_set_rxnfc(struct net_device *ndev,
530
+ struct ethtool_rxnfc *cmd)
531
+{
532
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
533
+ int err = 0;
534
+
535
+ switch (cmd->cmd) {
536
+ case ETHTOOL_SRXCLSRLINS:
537
+ err = aq_add_rxnfc_rule(aq_nic, cmd);
538
+ break;
539
+ case ETHTOOL_SRXCLSRLDEL:
540
+ err = aq_del_rxnfc_rule(aq_nic, cmd);
541
+ break;
217542 default:
218543 err = -EOPNOTSUPP;
219544 break;
....@@ -226,7 +551,9 @@
226551 struct ethtool_coalesce *coal)
227552 {
228553 struct aq_nic_s *aq_nic = netdev_priv(ndev);
229
- struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
554
+ struct aq_nic_cfg_s *cfg;
555
+
556
+ cfg = aq_nic_get_cfg(aq_nic);
230557
231558 if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON ||
232559 cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) {
....@@ -240,6 +567,7 @@
240567 coal->rx_max_coalesced_frames = 1;
241568 coal->tx_max_coalesced_frames = 1;
242569 }
570
+
243571 return 0;
244572 }
245573
....@@ -247,23 +575,14 @@
247575 struct ethtool_coalesce *coal)
248576 {
249577 struct aq_nic_s *aq_nic = netdev_priv(ndev);
250
- struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
578
+ struct aq_nic_cfg_s *cfg;
251579
252
- /* This is not yet supported
253
- */
254
- if (coal->use_adaptive_rx_coalesce || coal->use_adaptive_tx_coalesce)
255
- return -EOPNOTSUPP;
580
+ cfg = aq_nic_get_cfg(aq_nic);
256581
257582 /* Atlantic only supports timing based coalescing
258583 */
259584 if (coal->rx_max_coalesced_frames > 1 ||
260
- coal->rx_coalesce_usecs_irq ||
261
- coal->rx_max_coalesced_frames_irq)
262
- return -EOPNOTSUPP;
263
-
264
- if (coal->tx_max_coalesced_frames > 1 ||
265
- coal->tx_coalesce_usecs_irq ||
266
- coal->tx_max_coalesced_frames_irq)
585
+ coal->tx_max_coalesced_frames > 1)
267586 return -EOPNOTSUPP;
268587
269588 /* We do not support frame counting. Check this
....@@ -285,30 +604,179 @@
285604 return aq_nic_update_interrupt_moderation_settings(aq_nic);
286605 }
287606
607
+static void aq_ethtool_get_wol(struct net_device *ndev,
608
+ struct ethtool_wolinfo *wol)
609
+{
610
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
611
+ struct aq_nic_cfg_s *cfg;
612
+
613
+ cfg = aq_nic_get_cfg(aq_nic);
614
+
615
+ wol->supported = AQ_NIC_WOL_MODES;
616
+ wol->wolopts = cfg->wol;
617
+}
618
+
619
+static int aq_ethtool_set_wol(struct net_device *ndev,
620
+ struct ethtool_wolinfo *wol)
621
+{
622
+ struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
623
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
624
+ struct aq_nic_cfg_s *cfg;
625
+ int err = 0;
626
+
627
+ cfg = aq_nic_get_cfg(aq_nic);
628
+
629
+ if (wol->wolopts & ~AQ_NIC_WOL_MODES)
630
+ return -EOPNOTSUPP;
631
+
632
+ cfg->wol = wol->wolopts;
633
+
634
+ err = device_set_wakeup_enable(&pdev->dev, !!cfg->wol);
635
+
636
+ return err;
637
+}
638
+
639
+static int aq_ethtool_get_ts_info(struct net_device *ndev,
640
+ struct ethtool_ts_info *info)
641
+{
642
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
643
+
644
+ ethtool_op_get_ts_info(ndev, info);
645
+
646
+ if (!aq_nic->aq_ptp)
647
+ return 0;
648
+
649
+ info->so_timestamping |=
650
+ SOF_TIMESTAMPING_TX_HARDWARE |
651
+ SOF_TIMESTAMPING_RX_HARDWARE |
652
+ SOF_TIMESTAMPING_RAW_HARDWARE;
653
+
654
+ info->tx_types = BIT(HWTSTAMP_TX_OFF) |
655
+ BIT(HWTSTAMP_TX_ON);
656
+
657
+ info->rx_filters = BIT(HWTSTAMP_FILTER_NONE);
658
+
659
+ info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
660
+ BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
661
+ BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
662
+
663
+#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
664
+ info->phc_index = ptp_clock_index(aq_ptp_get_ptp_clock(aq_nic->aq_ptp));
665
+#endif
666
+
667
+ return 0;
668
+}
669
+
670
+static u32 eee_mask_to_ethtool_mask(u32 speed)
671
+{
672
+ u32 rate = 0;
673
+
674
+ if (speed & AQ_NIC_RATE_EEE_10G)
675
+ rate |= SUPPORTED_10000baseT_Full;
676
+
677
+ if (speed & AQ_NIC_RATE_EEE_1G)
678
+ rate |= SUPPORTED_1000baseT_Full;
679
+
680
+ if (speed & AQ_NIC_RATE_EEE_100M)
681
+ rate |= SUPPORTED_100baseT_Full;
682
+
683
+ return rate;
684
+}
685
+
686
+static int aq_ethtool_get_eee(struct net_device *ndev, struct ethtool_eee *eee)
687
+{
688
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
689
+ u32 rate, supported_rates;
690
+ int err = 0;
691
+
692
+ if (!aq_nic->aq_fw_ops->get_eee_rate)
693
+ return -EOPNOTSUPP;
694
+
695
+ mutex_lock(&aq_nic->fwreq_mutex);
696
+ err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
697
+ &supported_rates);
698
+ mutex_unlock(&aq_nic->fwreq_mutex);
699
+ if (err < 0)
700
+ return err;
701
+
702
+ eee->supported = eee_mask_to_ethtool_mask(supported_rates);
703
+
704
+ if (aq_nic->aq_nic_cfg.eee_speeds)
705
+ eee->advertised = eee->supported;
706
+
707
+ eee->lp_advertised = eee_mask_to_ethtool_mask(rate);
708
+
709
+ eee->eee_enabled = !!eee->advertised;
710
+
711
+ eee->tx_lpi_enabled = eee->eee_enabled;
712
+ if ((supported_rates & rate) & AQ_NIC_RATE_EEE_MSK)
713
+ eee->eee_active = true;
714
+
715
+ return 0;
716
+}
717
+
718
+static int aq_ethtool_set_eee(struct net_device *ndev, struct ethtool_eee *eee)
719
+{
720
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
721
+ u32 rate, supported_rates;
722
+ struct aq_nic_cfg_s *cfg;
723
+ int err = 0;
724
+
725
+ cfg = aq_nic_get_cfg(aq_nic);
726
+
727
+ if (unlikely(!aq_nic->aq_fw_ops->get_eee_rate ||
728
+ !aq_nic->aq_fw_ops->set_eee_rate))
729
+ return -EOPNOTSUPP;
730
+
731
+ mutex_lock(&aq_nic->fwreq_mutex);
732
+ err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
733
+ &supported_rates);
734
+ mutex_unlock(&aq_nic->fwreq_mutex);
735
+ if (err < 0)
736
+ return err;
737
+
738
+ if (eee->eee_enabled) {
739
+ rate = supported_rates;
740
+ cfg->eee_speeds = rate;
741
+ } else {
742
+ rate = 0;
743
+ cfg->eee_speeds = 0;
744
+ }
745
+
746
+ mutex_lock(&aq_nic->fwreq_mutex);
747
+ err = aq_nic->aq_fw_ops->set_eee_rate(aq_nic->aq_hw, rate);
748
+ mutex_unlock(&aq_nic->fwreq_mutex);
749
+
750
+ return err;
751
+}
752
+
288753 static int aq_ethtool_nway_reset(struct net_device *ndev)
289754 {
290755 struct aq_nic_s *aq_nic = netdev_priv(ndev);
756
+ int err = 0;
291757
292758 if (unlikely(!aq_nic->aq_fw_ops->renegotiate))
293759 return -EOPNOTSUPP;
294760
295
- if (netif_running(ndev))
296
- return aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw);
761
+ if (netif_running(ndev)) {
762
+ mutex_lock(&aq_nic->fwreq_mutex);
763
+ err = aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw);
764
+ mutex_unlock(&aq_nic->fwreq_mutex);
765
+ }
297766
298
- return 0;
767
+ return err;
299768 }
300769
301770 static void aq_ethtool_get_pauseparam(struct net_device *ndev,
302771 struct ethtool_pauseparam *pause)
303772 {
304773 struct aq_nic_s *aq_nic = netdev_priv(ndev);
774
+ int fc = aq_nic->aq_nic_cfg.fc.req;
305775
306776 pause->autoneg = 0;
307777
308
- if (aq_nic->aq_hw->aq_nic_cfg->flow_control & AQ_NIC_FC_RX)
309
- pause->rx_pause = 1;
310
- if (aq_nic->aq_hw->aq_nic_cfg->flow_control & AQ_NIC_FC_TX)
311
- pause->tx_pause = 1;
778
+ pause->rx_pause = !!(fc & AQ_NIC_FC_RX);
779
+ pause->tx_pause = !!(fc & AQ_NIC_FC_TX);
312780 }
313781
314782 static int aq_ethtool_set_pauseparam(struct net_device *ndev,
....@@ -324,16 +792,18 @@
324792 return -EOPNOTSUPP;
325793
326794 if (pause->rx_pause)
327
- aq_nic->aq_hw->aq_nic_cfg->flow_control |= AQ_NIC_FC_RX;
795
+ aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_RX;
328796 else
329
- aq_nic->aq_hw->aq_nic_cfg->flow_control &= ~AQ_NIC_FC_RX;
797
+ aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_RX;
330798
331799 if (pause->tx_pause)
332
- aq_nic->aq_hw->aq_nic_cfg->flow_control |= AQ_NIC_FC_TX;
800
+ aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_TX;
333801 else
334
- aq_nic->aq_hw->aq_nic_cfg->flow_control &= ~AQ_NIC_FC_TX;
802
+ aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_TX;
335803
804
+ mutex_lock(&aq_nic->fwreq_mutex);
336805 err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw);
806
+ mutex_unlock(&aq_nic->fwreq_mutex);
337807
338808 return err;
339809 }
....@@ -342,23 +812,28 @@
342812 struct ethtool_ringparam *ring)
343813 {
344814 struct aq_nic_s *aq_nic = netdev_priv(ndev);
345
- struct aq_nic_cfg_s *aq_nic_cfg = aq_nic_get_cfg(aq_nic);
815
+ struct aq_nic_cfg_s *cfg;
346816
347
- ring->rx_pending = aq_nic_cfg->rxds;
348
- ring->tx_pending = aq_nic_cfg->txds;
817
+ cfg = aq_nic_get_cfg(aq_nic);
349818
350
- ring->rx_max_pending = aq_nic_cfg->aq_hw_caps->rxds_max;
351
- ring->tx_max_pending = aq_nic_cfg->aq_hw_caps->txds_max;
819
+ ring->rx_pending = cfg->rxds;
820
+ ring->tx_pending = cfg->txds;
821
+
822
+ ring->rx_max_pending = cfg->aq_hw_caps->rxds_max;
823
+ ring->tx_max_pending = cfg->aq_hw_caps->txds_max;
352824 }
353825
354826 static int aq_set_ringparam(struct net_device *ndev,
355827 struct ethtool_ringparam *ring)
356828 {
357
- int err = 0;
358
- bool ndev_running = false;
359829 struct aq_nic_s *aq_nic = netdev_priv(ndev);
360
- struct aq_nic_cfg_s *aq_nic_cfg = aq_nic_get_cfg(aq_nic);
361
- const struct aq_hw_caps_s *hw_caps = aq_nic_cfg->aq_hw_caps;
830
+ const struct aq_hw_caps_s *hw_caps;
831
+ bool ndev_running = false;
832
+ struct aq_nic_cfg_s *cfg;
833
+ int err = 0;
834
+
835
+ cfg = aq_nic_get_cfg(aq_nic);
836
+ hw_caps = cfg->aq_hw_caps;
362837
363838 if (ring->rx_mini_pending || ring->rx_jumbo_pending) {
364839 err = -EOPNOTSUPP;
....@@ -367,54 +842,168 @@
367842
368843 if (netif_running(ndev)) {
369844 ndev_running = true;
370
- dev_close(ndev);
845
+ aq_ndev_close(ndev);
371846 }
372847
373
- aq_nic_free_vectors(aq_nic);
848
+ cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min);
849
+ cfg->rxds = min(cfg->rxds, hw_caps->rxds_max);
850
+ cfg->rxds = ALIGN(cfg->rxds, AQ_HW_RXD_MULTIPLE);
374851
375
- aq_nic_cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min);
376
- aq_nic_cfg->rxds = min(aq_nic_cfg->rxds, hw_caps->rxds_max);
377
- aq_nic_cfg->rxds = ALIGN(aq_nic_cfg->rxds, AQ_HW_RXD_MULTIPLE);
852
+ cfg->txds = max(ring->tx_pending, hw_caps->txds_min);
853
+ cfg->txds = min(cfg->txds, hw_caps->txds_max);
854
+ cfg->txds = ALIGN(cfg->txds, AQ_HW_TXD_MULTIPLE);
378855
379
- aq_nic_cfg->txds = max(ring->tx_pending, hw_caps->txds_min);
380
- aq_nic_cfg->txds = min(aq_nic_cfg->txds, hw_caps->txds_max);
381
- aq_nic_cfg->txds = ALIGN(aq_nic_cfg->txds, AQ_HW_TXD_MULTIPLE);
856
+ err = aq_nic_realloc_vectors(aq_nic);
857
+ if (err)
858
+ goto err_exit;
382859
383
- for (aq_nic->aq_vecs = 0; aq_nic->aq_vecs < aq_nic_cfg->vecs;
384
- aq_nic->aq_vecs++) {
385
- aq_nic->aq_vec[aq_nic->aq_vecs] =
386
- aq_vec_alloc(aq_nic, aq_nic->aq_vecs, aq_nic_cfg);
387
- if (unlikely(!aq_nic->aq_vec[aq_nic->aq_vecs])) {
388
- err = -ENOMEM;
389
- goto err_exit;
390
- }
391
- }
392860 if (ndev_running)
393
- err = dev_open(ndev);
861
+ err = aq_ndev_open(ndev);
394862
395863 err_exit:
396864 return err;
397865 }
398866
867
+static u32 aq_get_msg_level(struct net_device *ndev)
868
+{
869
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
870
+
871
+ return aq_nic->msg_enable;
872
+}
873
+
874
+static void aq_set_msg_level(struct net_device *ndev, u32 data)
875
+{
876
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
877
+
878
+ aq_nic->msg_enable = data;
879
+}
880
+
881
+static u32 aq_ethtool_get_priv_flags(struct net_device *ndev)
882
+{
883
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
884
+
885
+ return aq_nic->aq_nic_cfg.priv_flags;
886
+}
887
+
888
+static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
889
+{
890
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
891
+ struct aq_nic_cfg_s *cfg;
892
+ u32 priv_flags;
893
+ int ret = 0;
894
+
895
+ cfg = aq_nic_get_cfg(aq_nic);
896
+ priv_flags = cfg->priv_flags;
897
+
898
+ if (flags & ~AQ_PRIV_FLAGS_MASK)
899
+ return -EOPNOTSUPP;
900
+
901
+ if (hweight32((flags | priv_flags) & AQ_HW_LOOPBACK_MASK) > 1) {
902
+ netdev_info(ndev, "Can't enable more than one loopback simultaneously\n");
903
+ return -EINVAL;
904
+ }
905
+
906
+ cfg->priv_flags = flags;
907
+
908
+ if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
909
+ if (netif_running(ndev)) {
910
+ dev_close(ndev);
911
+
912
+ dev_open(ndev, NULL);
913
+ }
914
+ } else if ((priv_flags ^ flags) & AQ_HW_LOOPBACK_MASK) {
915
+ ret = aq_nic_set_loopback(aq_nic);
916
+ }
917
+
918
+ return ret;
919
+}
920
+
921
+static int aq_ethtool_get_phy_tunable(struct net_device *ndev,
922
+ const struct ethtool_tunable *tuna, void *data)
923
+{
924
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
925
+
926
+ switch (tuna->id) {
927
+ case ETHTOOL_PHY_EDPD: {
928
+ u16 *val = data;
929
+
930
+ *val = aq_nic->aq_nic_cfg.is_media_detect ? AQ_HW_MEDIA_DETECT_CNT : 0;
931
+ break;
932
+ }
933
+ case ETHTOOL_PHY_DOWNSHIFT: {
934
+ u8 *val = data;
935
+
936
+ *val = (u8)aq_nic->aq_nic_cfg.downshift_counter;
937
+ break;
938
+ }
939
+ default:
940
+ return -EOPNOTSUPP;
941
+ }
942
+
943
+ return 0;
944
+}
945
+
946
+static int aq_ethtool_set_phy_tunable(struct net_device *ndev,
947
+ const struct ethtool_tunable *tuna, const void *data)
948
+{
949
+ int err = -EOPNOTSUPP;
950
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
951
+
952
+ switch (tuna->id) {
953
+ case ETHTOOL_PHY_EDPD: {
954
+ const u16 *val = data;
955
+
956
+ err = aq_nic_set_media_detect(aq_nic, *val);
957
+ break;
958
+ }
959
+ case ETHTOOL_PHY_DOWNSHIFT: {
960
+ const u8 *val = data;
961
+
962
+ err = aq_nic_set_downshift(aq_nic, *val);
963
+ break;
964
+ }
965
+ default:
966
+ break;
967
+ }
968
+
969
+ return err;
970
+}
971
+
399972 const struct ethtool_ops aq_ethtool_ops = {
973
+ .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
974
+ ETHTOOL_COALESCE_MAX_FRAMES,
400975 .get_link = aq_ethtool_get_link,
401976 .get_regs_len = aq_ethtool_get_regs_len,
402977 .get_regs = aq_ethtool_get_regs,
403978 .get_drvinfo = aq_ethtool_get_drvinfo,
404979 .get_strings = aq_ethtool_get_strings,
980
+ .set_phys_id = aq_ethtool_set_phys_id,
405981 .get_rxfh_indir_size = aq_ethtool_get_rss_indir_size,
982
+ .get_wol = aq_ethtool_get_wol,
983
+ .set_wol = aq_ethtool_set_wol,
406984 .nway_reset = aq_ethtool_nway_reset,
407985 .get_ringparam = aq_get_ringparam,
408986 .set_ringparam = aq_set_ringparam,
987
+ .get_eee = aq_ethtool_get_eee,
988
+ .set_eee = aq_ethtool_set_eee,
409989 .get_pauseparam = aq_ethtool_get_pauseparam,
410990 .set_pauseparam = aq_ethtool_set_pauseparam,
411991 .get_rxfh_key_size = aq_ethtool_get_rss_key_size,
412992 .get_rxfh = aq_ethtool_get_rss,
993
+ .set_rxfh = aq_ethtool_set_rss,
413994 .get_rxnfc = aq_ethtool_get_rxnfc,
995
+ .set_rxnfc = aq_ethtool_set_rxnfc,
996
+ .get_msglevel = aq_get_msg_level,
997
+ .set_msglevel = aq_set_msg_level,
414998 .get_sset_count = aq_ethtool_get_sset_count,
415999 .get_ethtool_stats = aq_ethtool_stats,
1000
+ .get_priv_flags = aq_ethtool_get_priv_flags,
1001
+ .set_priv_flags = aq_ethtool_set_priv_flags,
4161002 .get_link_ksettings = aq_ethtool_get_link_ksettings,
4171003 .set_link_ksettings = aq_ethtool_set_link_ksettings,
4181004 .get_coalesce = aq_ethtool_get_coalesce,
4191005 .set_coalesce = aq_ethtool_set_coalesce,
1006
+ .get_ts_info = aq_ethtool_get_ts_info,
1007
+ .get_phy_tunable = aq_ethtool_get_phy_tunable,
1008
+ .set_phy_tunable = aq_ethtool_set_phy_tunable,
4201009 };