1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2015 - 2023 Beijing WangXun Technology Co., Ltd. */
3
4 #include <linux/pci.h>
5 #include <linux/phy.h>
6 #include <linux/ethtool.h>
7
8 #include "wx_type.h"
9 #include "wx_ethtool.h"
10 #include "wx_hw.h"
11 #include "wx_lib.h"
12 #include "wx_vf_common.h"
13 #include "wx_vf_lib.h"
14
15 struct wx_stats {
16 char stat_string[ETH_GSTRING_LEN];
17 size_t sizeof_stat;
18 off_t stat_offset;
19 };
20
21 #define WX_STAT(str, m) { \
22 .stat_string = str, \
23 .sizeof_stat = sizeof(((struct wx *)0)->m), \
24 .stat_offset = offsetof(struct wx, m) }
25
26 static const struct wx_stats wx_gstrings_stats[] = {
27 WX_STAT("rx_dma_pkts", stats.gprc),
28 WX_STAT("tx_dma_pkts", stats.gptc),
29 WX_STAT("rx_dma_bytes", stats.gorc),
30 WX_STAT("tx_dma_bytes", stats.gotc),
31 WX_STAT("rx_total_pkts", stats.tpr),
32 WX_STAT("tx_total_pkts", stats.tpt),
33 WX_STAT("rx_long_length_count", stats.roc),
34 WX_STAT("rx_short_length_count", stats.ruc),
35 WX_STAT("os2bmc_rx_by_bmc", stats.o2bgptc),
36 WX_STAT("os2bmc_tx_by_bmc", stats.b2ospc),
37 WX_STAT("os2bmc_tx_by_host", stats.o2bspc),
38 WX_STAT("os2bmc_rx_by_host", stats.b2ogprc),
39 WX_STAT("rx_no_dma_resources", stats.rdmdrop),
40 WX_STAT("tx_busy", tx_busy),
41 WX_STAT("non_eop_descs", non_eop_descs),
42 WX_STAT("tx_restart_queue", restart_queue),
43 WX_STAT("rx_csum_offload_good_count", hw_csum_rx_good),
44 WX_STAT("rx_csum_offload_errors", hw_csum_rx_error),
45 WX_STAT("alloc_rx_buff_failed", alloc_rx_buff_failed),
46 WX_STAT("tx_hwtstamp_timeouts", tx_hwtstamp_timeouts),
47 WX_STAT("tx_hwtstamp_skipped", tx_hwtstamp_skipped),
48 WX_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared),
49 };
50
51 static const struct wx_stats wx_gstrings_fdir_stats[] = {
52 WX_STAT("fdir_match", stats.fdirmatch),
53 WX_STAT("fdir_miss", stats.fdirmiss),
54 };
55
56 static const struct wx_stats wx_gstrings_rsc_stats[] = {
57 WX_STAT("rsc_aggregated", rsc_count),
58 WX_STAT("rsc_flushed", rsc_flush),
59 };
60
61 /* drivers allocates num_tx_queues and num_rx_queues symmetrically so
62 * we set the num_rx_queues to evaluate to num_tx_queues. This is
63 * used because we do not have a good way to get the max number of
64 * rx queues with CONFIG_RPS disabled.
65 */
66 #define WX_NUM_RX_QUEUES netdev->num_tx_queues
67 #define WX_NUM_TX_QUEUES netdev->num_tx_queues
68
69 #define WX_QUEUE_STATS_LEN ( \
70 (WX_NUM_TX_QUEUES + WX_NUM_RX_QUEUES) * \
71 (sizeof(struct wx_queue_stats) / sizeof(u64)))
72 #define WX_GLOBAL_STATS_LEN ARRAY_SIZE(wx_gstrings_stats)
73 #define WX_FDIR_STATS_LEN ARRAY_SIZE(wx_gstrings_fdir_stats)
74 #define WX_RSC_STATS_LEN ARRAY_SIZE(wx_gstrings_rsc_stats)
75 #define WX_STATS_LEN (WX_GLOBAL_STATS_LEN + WX_QUEUE_STATS_LEN)
76
wx_get_sset_count(struct net_device * netdev,int sset)77 int wx_get_sset_count(struct net_device *netdev, int sset)
78 {
79 struct wx *wx = netdev_priv(netdev);
80 int len = WX_STATS_LEN;
81
82 switch (sset) {
83 case ETH_SS_STATS:
84 if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags))
85 len += WX_FDIR_STATS_LEN;
86 if (test_bit(WX_FLAG_RSC_CAPABLE, wx->flags))
87 len += WX_RSC_STATS_LEN;
88 return len;
89 default:
90 return -EOPNOTSUPP;
91 }
92 }
93 EXPORT_SYMBOL(wx_get_sset_count);
94
wx_get_strings(struct net_device * netdev,u32 stringset,u8 * data)95 void wx_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
96 {
97 struct wx *wx = netdev_priv(netdev);
98 u8 *p = data;
99 int i;
100
101 switch (stringset) {
102 case ETH_SS_STATS:
103 for (i = 0; i < WX_GLOBAL_STATS_LEN; i++)
104 ethtool_puts(&p, wx_gstrings_stats[i].stat_string);
105 if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags)) {
106 for (i = 0; i < WX_FDIR_STATS_LEN; i++)
107 ethtool_puts(&p, wx_gstrings_fdir_stats[i].stat_string);
108 }
109 if (test_bit(WX_FLAG_RSC_CAPABLE, wx->flags)) {
110 for (i = 0; i < WX_RSC_STATS_LEN; i++)
111 ethtool_puts(&p, wx_gstrings_rsc_stats[i].stat_string);
112 }
113 for (i = 0; i < netdev->num_tx_queues; i++) {
114 ethtool_sprintf(&p, "tx_queue_%u_packets", i);
115 ethtool_sprintf(&p, "tx_queue_%u_bytes", i);
116 }
117 for (i = 0; i < WX_NUM_RX_QUEUES; i++) {
118 ethtool_sprintf(&p, "rx_queue_%u_packets", i);
119 ethtool_sprintf(&p, "rx_queue_%u_bytes", i);
120 }
121 break;
122 }
123 }
124 EXPORT_SYMBOL(wx_get_strings);
125
wx_get_ethtool_stats(struct net_device * netdev,struct ethtool_stats * stats,u64 * data)126 void wx_get_ethtool_stats(struct net_device *netdev,
127 struct ethtool_stats *stats, u64 *data)
128 {
129 struct wx *wx = netdev_priv(netdev);
130 struct wx_ring *ring;
131 unsigned int start;
132 int i, j, k;
133 char *p;
134
135 wx_update_stats(wx);
136
137 for (i = 0; i < WX_GLOBAL_STATS_LEN; i++) {
138 p = (char *)wx + wx_gstrings_stats[i].stat_offset;
139 data[i] = (wx_gstrings_stats[i].sizeof_stat ==
140 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
141 }
142
143 if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags)) {
144 for (k = 0; k < WX_FDIR_STATS_LEN; k++) {
145 p = (char *)wx + wx_gstrings_fdir_stats[k].stat_offset;
146 data[i++] = *(u64 *)p;
147 }
148 }
149
150 if (test_bit(WX_FLAG_RSC_CAPABLE, wx->flags)) {
151 for (k = 0; k < WX_RSC_STATS_LEN; k++) {
152 p = (char *)wx + wx_gstrings_rsc_stats[k].stat_offset;
153 data[i++] = *(u64 *)p;
154 }
155 }
156
157 for (j = 0; j < netdev->num_tx_queues; j++) {
158 ring = wx->tx_ring[j];
159 if (!ring) {
160 data[i++] = 0;
161 data[i++] = 0;
162 continue;
163 }
164
165 do {
166 start = u64_stats_fetch_begin(&ring->syncp);
167 data[i] = ring->stats.packets;
168 data[i + 1] = ring->stats.bytes;
169 } while (u64_stats_fetch_retry(&ring->syncp, start));
170 i += 2;
171 }
172 for (j = 0; j < WX_NUM_RX_QUEUES; j++) {
173 ring = wx->rx_ring[j];
174 if (!ring) {
175 data[i++] = 0;
176 data[i++] = 0;
177 continue;
178 }
179
180 do {
181 start = u64_stats_fetch_begin(&ring->syncp);
182 data[i] = ring->stats.packets;
183 data[i + 1] = ring->stats.bytes;
184 } while (u64_stats_fetch_retry(&ring->syncp, start));
185 i += 2;
186 }
187 }
188 EXPORT_SYMBOL(wx_get_ethtool_stats);
189
wx_get_mac_stats(struct net_device * netdev,struct ethtool_eth_mac_stats * mac_stats)190 void wx_get_mac_stats(struct net_device *netdev,
191 struct ethtool_eth_mac_stats *mac_stats)
192 {
193 struct wx *wx = netdev_priv(netdev);
194 struct wx_hw_stats *hwstats;
195
196 wx_update_stats(wx);
197
198 hwstats = &wx->stats;
199 mac_stats->MulticastFramesXmittedOK = hwstats->mptc;
200 mac_stats->BroadcastFramesXmittedOK = hwstats->bptc;
201 mac_stats->MulticastFramesReceivedOK = hwstats->mprc;
202 mac_stats->BroadcastFramesReceivedOK = hwstats->bprc;
203 }
204 EXPORT_SYMBOL(wx_get_mac_stats);
205
wx_get_pause_stats(struct net_device * netdev,struct ethtool_pause_stats * stats)206 void wx_get_pause_stats(struct net_device *netdev,
207 struct ethtool_pause_stats *stats)
208 {
209 struct wx *wx = netdev_priv(netdev);
210 struct wx_hw_stats *hwstats;
211
212 wx_update_stats(wx);
213
214 hwstats = &wx->stats;
215 stats->tx_pause_frames = hwstats->lxontxc + hwstats->lxofftxc;
216 stats->rx_pause_frames = hwstats->lxonrxc + hwstats->lxoffrxc;
217 }
218 EXPORT_SYMBOL(wx_get_pause_stats);
219
wx_get_drvinfo(struct net_device * netdev,struct ethtool_drvinfo * info)220 void wx_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info)
221 {
222 unsigned int stats_len = WX_STATS_LEN;
223 struct wx *wx = netdev_priv(netdev);
224
225 if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags))
226 stats_len += WX_FDIR_STATS_LEN;
227
228 strscpy(info->driver, wx->driver_name, sizeof(info->driver));
229 strscpy(info->fw_version, wx->eeprom_id, sizeof(info->fw_version));
230 strscpy(info->bus_info, pci_name(wx->pdev), sizeof(info->bus_info));
231 if (wx->num_tx_queues <= WX_NUM_TX_QUEUES) {
232 info->n_stats = stats_len -
233 (WX_NUM_TX_QUEUES - wx->num_tx_queues) *
234 (sizeof(struct wx_queue_stats) / sizeof(u64)) * 2;
235 } else {
236 info->n_stats = stats_len;
237 }
238 }
239 EXPORT_SYMBOL(wx_get_drvinfo);
240
wx_nway_reset(struct net_device * netdev)241 int wx_nway_reset(struct net_device *netdev)
242 {
243 struct wx *wx = netdev_priv(netdev);
244
245 return phylink_ethtool_nway_reset(wx->phylink);
246 }
247 EXPORT_SYMBOL(wx_nway_reset);
248
wx_get_link_ksettings(struct net_device * netdev,struct ethtool_link_ksettings * cmd)249 int wx_get_link_ksettings(struct net_device *netdev,
250 struct ethtool_link_ksettings *cmd)
251 {
252 struct wx *wx = netdev_priv(netdev);
253
254 return phylink_ethtool_ksettings_get(wx->phylink, cmd);
255 }
256 EXPORT_SYMBOL(wx_get_link_ksettings);
257
wx_set_link_ksettings(struct net_device * netdev,const struct ethtool_link_ksettings * cmd)258 int wx_set_link_ksettings(struct net_device *netdev,
259 const struct ethtool_link_ksettings *cmd)
260 {
261 struct wx *wx = netdev_priv(netdev);
262
263 return phylink_ethtool_ksettings_set(wx->phylink, cmd);
264 }
265 EXPORT_SYMBOL(wx_set_link_ksettings);
266
wx_get_wol(struct net_device * netdev,struct ethtool_wolinfo * wol)267 void wx_get_wol(struct net_device *netdev,
268 struct ethtool_wolinfo *wol)
269 {
270 struct wx *wx = netdev_priv(netdev);
271
272 if (!wx->wol_hw_supported)
273 return;
274 wol->supported = WAKE_MAGIC;
275 wol->wolopts = 0;
276 if (wx->wol & WX_PSR_WKUP_CTL_MAG)
277 wol->wolopts |= WAKE_MAGIC;
278 }
279 EXPORT_SYMBOL(wx_get_wol);
280
wx_set_wol(struct net_device * netdev,struct ethtool_wolinfo * wol)281 int wx_set_wol(struct net_device *netdev,
282 struct ethtool_wolinfo *wol)
283 {
284 struct wx *wx = netdev_priv(netdev);
285 struct pci_dev *pdev = wx->pdev;
286
287 if (!wx->wol_hw_supported)
288 return -EOPNOTSUPP;
289
290 wx->wol = 0;
291 if (wol->wolopts & WAKE_MAGIC)
292 wx->wol = WX_PSR_WKUP_CTL_MAG;
293 wr32(wx, WX_PSR_WKUP_CTL, wx->wol);
294 device_set_wakeup_enable(&pdev->dev, !!(wx->wol));
295
296 return 0;
297 }
298 EXPORT_SYMBOL(wx_set_wol);
299
wx_get_pauseparam(struct net_device * netdev,struct ethtool_pauseparam * pause)300 void wx_get_pauseparam(struct net_device *netdev,
301 struct ethtool_pauseparam *pause)
302 {
303 struct wx *wx = netdev_priv(netdev);
304
305 phylink_ethtool_get_pauseparam(wx->phylink, pause);
306 }
307 EXPORT_SYMBOL(wx_get_pauseparam);
308
wx_set_pauseparam(struct net_device * netdev,struct ethtool_pauseparam * pause)309 int wx_set_pauseparam(struct net_device *netdev,
310 struct ethtool_pauseparam *pause)
311 {
312 struct wx *wx = netdev_priv(netdev);
313
314 return phylink_ethtool_set_pauseparam(wx->phylink, pause);
315 }
316 EXPORT_SYMBOL(wx_set_pauseparam);
317
wx_get_ringparam(struct net_device * netdev,struct ethtool_ringparam * ring,struct kernel_ethtool_ringparam * kernel_ring,struct netlink_ext_ack * extack)318 void wx_get_ringparam(struct net_device *netdev,
319 struct ethtool_ringparam *ring,
320 struct kernel_ethtool_ringparam *kernel_ring,
321 struct netlink_ext_ack *extack)
322 {
323 struct wx *wx = netdev_priv(netdev);
324
325 ring->rx_max_pending = WX_MAX_RXD;
326 ring->tx_max_pending = WX_MAX_TXD;
327 ring->rx_mini_max_pending = 0;
328 ring->rx_jumbo_max_pending = 0;
329 ring->rx_pending = wx->rx_ring_count;
330 ring->tx_pending = wx->tx_ring_count;
331 ring->rx_mini_pending = 0;
332 ring->rx_jumbo_pending = 0;
333 }
334 EXPORT_SYMBOL(wx_get_ringparam);
335
wx_get_coalesce(struct net_device * netdev,struct ethtool_coalesce * ec,struct kernel_ethtool_coalesce * kernel_coal,struct netlink_ext_ack * extack)336 int wx_get_coalesce(struct net_device *netdev,
337 struct ethtool_coalesce *ec,
338 struct kernel_ethtool_coalesce *kernel_coal,
339 struct netlink_ext_ack *extack)
340 {
341 struct wx *wx = netdev_priv(netdev);
342
343 ec->tx_max_coalesced_frames_irq = wx->tx_work_limit;
344 /* only valid if in constant ITR mode */
345 if (wx->rx_itr_setting <= 1)
346 ec->rx_coalesce_usecs = wx->rx_itr_setting;
347 else
348 ec->rx_coalesce_usecs = wx->rx_itr_setting >> 2;
349
350 if (wx->adaptive_itr) {
351 ec->use_adaptive_rx_coalesce = 1;
352 ec->use_adaptive_tx_coalesce = 1;
353 }
354
355 /* if in mixed tx/rx queues per vector mode, report only rx settings */
356 if (wx->q_vector[0]->tx.count && wx->q_vector[0]->rx.count)
357 return 0;
358
359 /* only valid if in constant ITR mode */
360 if (wx->tx_itr_setting <= 1)
361 ec->tx_coalesce_usecs = wx->tx_itr_setting;
362 else
363 ec->tx_coalesce_usecs = wx->tx_itr_setting >> 2;
364
365 return 0;
366 }
367 EXPORT_SYMBOL(wx_get_coalesce);
368
wx_update_rsc(struct wx * wx)369 static void wx_update_rsc(struct wx *wx)
370 {
371 struct net_device *netdev = wx->netdev;
372 bool need_reset = false;
373
374 /* nothing to do if LRO or RSC are not enabled */
375 if (!test_bit(WX_FLAG_RSC_CAPABLE, wx->flags) ||
376 !(netdev->features & NETIF_F_LRO))
377 return;
378
379 /* check the feature flag value and enable RSC if necessary */
380 if (wx->rx_itr_setting == 1 ||
381 wx->rx_itr_setting > WX_MIN_RSC_ITR) {
382 if (!test_bit(WX_FLAG_RSC_ENABLED, wx->flags)) {
383 set_bit(WX_FLAG_RSC_ENABLED, wx->flags);
384 dev_info(&wx->pdev->dev,
385 "rx-usecs value high enough to re-enable RSC\n");
386
387 need_reset = true;
388 }
389 /* if interrupt rate is too high then disable RSC */
390 } else if (test_bit(WX_FLAG_RSC_ENABLED, wx->flags)) {
391 clear_bit(WX_FLAG_RSC_ENABLED, wx->flags);
392 dev_info(&wx->pdev->dev,
393 "rx-usecs set too low, disabling RSC\n");
394
395 need_reset = true;
396 }
397
398 /* reset the device to apply the new RSC setting */
399 if (need_reset && wx->do_reset)
400 wx->do_reset(netdev, true);
401 }
402
wx_set_coalesce(struct net_device * netdev,struct ethtool_coalesce * ec,struct kernel_ethtool_coalesce * kernel_coal,struct netlink_ext_ack * extack)403 int wx_set_coalesce(struct net_device *netdev,
404 struct ethtool_coalesce *ec,
405 struct kernel_ethtool_coalesce *kernel_coal,
406 struct netlink_ext_ack *extack)
407 {
408 struct wx *wx = netdev_priv(netdev);
409 u16 tx_itr_param, rx_itr_param;
410 struct wx_q_vector *q_vector;
411 u16 max_eitr;
412 int i;
413
414 if (wx->q_vector[0]->tx.count && wx->q_vector[0]->rx.count) {
415 /* reject Tx specific changes in case of mixed RxTx vectors */
416 if (ec->tx_coalesce_usecs)
417 return -EOPNOTSUPP;
418 }
419
420 if (ec->tx_max_coalesced_frames_irq > U16_MAX ||
421 !ec->tx_max_coalesced_frames_irq)
422 return -EINVAL;
423
424 wx->tx_work_limit = ec->tx_max_coalesced_frames_irq;
425
426 switch (wx->mac.type) {
427 case wx_mac_sp:
428 max_eitr = WX_SP_MAX_EITR;
429 rx_itr_param = WX_20K_ITR;
430 tx_itr_param = WX_12K_ITR;
431 break;
432 case wx_mac_aml:
433 case wx_mac_aml40:
434 max_eitr = WX_AML_MAX_EITR;
435 rx_itr_param = WX_20K_ITR;
436 tx_itr_param = WX_12K_ITR;
437 break;
438 default:
439 max_eitr = WX_EM_MAX_EITR;
440 rx_itr_param = WX_7K_ITR;
441 tx_itr_param = WX_7K_ITR;
442 break;
443 }
444
445 if ((ec->rx_coalesce_usecs > (max_eitr >> 2)) ||
446 (ec->tx_coalesce_usecs > (max_eitr >> 2)))
447 return -EINVAL;
448
449 if (ec->use_adaptive_rx_coalesce) {
450 wx->adaptive_itr = true;
451 wx->rx_itr_setting = 1;
452 wx->tx_itr_setting = 1;
453 return 0;
454 }
455
456 if (ec->rx_coalesce_usecs > 1)
457 wx->rx_itr_setting = ec->rx_coalesce_usecs << 2;
458 else
459 wx->rx_itr_setting = ec->rx_coalesce_usecs;
460
461 if (ec->tx_coalesce_usecs > 1)
462 wx->tx_itr_setting = ec->tx_coalesce_usecs << 2;
463 else
464 wx->tx_itr_setting = ec->tx_coalesce_usecs;
465
466 if (wx->adaptive_itr) {
467 wx->adaptive_itr = false;
468 wx->rx_itr_setting = rx_itr_param;
469 wx->tx_itr_setting = tx_itr_param;
470 } else if (wx->rx_itr_setting == 1 || wx->tx_itr_setting == 1) {
471 wx->adaptive_itr = true;
472 }
473
474 if (wx->rx_itr_setting != 1)
475 rx_itr_param = wx->rx_itr_setting;
476
477 if (wx->tx_itr_setting != 1)
478 tx_itr_param = wx->tx_itr_setting;
479
480 /* mixed Rx/Tx */
481 if (wx->q_vector[0]->tx.count && wx->q_vector[0]->rx.count)
482 wx->tx_itr_setting = wx->rx_itr_setting;
483
484 for (i = 0; i < wx->num_q_vectors; i++) {
485 q_vector = wx->q_vector[i];
486 if (q_vector->tx.count && !q_vector->rx.count)
487 /* tx only */
488 q_vector->itr = tx_itr_param;
489 else
490 /* rx only or mixed */
491 q_vector->itr = rx_itr_param;
492 if (wx->pdev->is_virtfn)
493 wx_write_eitr_vf(q_vector);
494 else
495 wx_write_eitr(q_vector);
496 }
497
498 wx_update_rsc(wx);
499
500 return 0;
501 }
502 EXPORT_SYMBOL(wx_set_coalesce);
503
wx_max_channels(struct wx * wx)504 static unsigned int wx_max_channels(struct wx *wx)
505 {
506 unsigned int max_combined;
507
508 if (!wx->msix_q_entries) {
509 /* We only support one q_vector without MSI-X */
510 max_combined = 1;
511 } else {
512 /* support up to max allowed queues with RSS */
513 if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags))
514 max_combined = 63;
515 else
516 max_combined = 8;
517 }
518
519 return max_combined;
520 }
521
wx_get_channels(struct net_device * dev,struct ethtool_channels * ch)522 void wx_get_channels(struct net_device *dev,
523 struct ethtool_channels *ch)
524 {
525 struct wx *wx = netdev_priv(dev);
526
527 /* report maximum channels */
528 ch->max_combined = wx_max_channels(wx);
529
530 /* report info for other vector */
531 if (wx->msix_q_entries) {
532 ch->max_other = 1;
533 ch->other_count = 1;
534 }
535
536 /* record RSS queues */
537 ch->combined_count = wx->ring_feature[RING_F_RSS].indices;
538
539 if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags))
540 ch->combined_count = wx->ring_feature[RING_F_FDIR].indices;
541 }
542 EXPORT_SYMBOL(wx_get_channels);
543
wx_set_channels(struct net_device * dev,struct ethtool_channels * ch)544 int wx_set_channels(struct net_device *dev,
545 struct ethtool_channels *ch)
546 {
547 unsigned int count = ch->combined_count;
548 struct wx *wx = netdev_priv(dev);
549
550 /* verify other_count has not changed */
551 if (ch->other_count != 1)
552 return -EINVAL;
553
554 /* verify the number of channels does not exceed hardware limits */
555 if (count > wx_max_channels(wx))
556 return -EINVAL;
557
558 if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags))
559 wx->ring_feature[RING_F_FDIR].limit = count;
560
561 wx->ring_feature[RING_F_RSS].limit = count;
562
563 return wx->setup_tc(dev, netdev_get_num_tc(dev));
564 }
565 EXPORT_SYMBOL(wx_set_channels);
566
wx_rss_indir_size(struct net_device * netdev)567 u32 wx_rss_indir_size(struct net_device *netdev)
568 {
569 struct wx *wx = netdev_priv(netdev);
570
571 return wx_rss_indir_tbl_entries(wx);
572 }
573 EXPORT_SYMBOL(wx_rss_indir_size);
574
wx_get_rxfh_key_size(struct net_device * netdev)575 u32 wx_get_rxfh_key_size(struct net_device *netdev)
576 {
577 return WX_RSS_KEY_SIZE;
578 }
579 EXPORT_SYMBOL(wx_get_rxfh_key_size);
580
wx_get_reta(struct wx * wx,u32 * indir)581 static void wx_get_reta(struct wx *wx, u32 *indir)
582 {
583 u32 reta_size = wx_rss_indir_tbl_entries(wx);
584 u16 rss_m = wx->ring_feature[RING_F_RSS].mask;
585
586 if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags))
587 rss_m = wx->ring_feature[RING_F_RSS].indices - 1;
588
589 for (u32 i = 0; i < reta_size; i++)
590 indir[i] = wx->rss_indir_tbl[i] & rss_m;
591 }
592
wx_get_rxfh(struct net_device * netdev,struct ethtool_rxfh_param * rxfh)593 int wx_get_rxfh(struct net_device *netdev,
594 struct ethtool_rxfh_param *rxfh)
595 {
596 struct wx *wx = netdev_priv(netdev);
597
598 rxfh->hfunc = ETH_RSS_HASH_TOP;
599
600 if (rxfh->indir)
601 wx_get_reta(wx, rxfh->indir);
602
603 if (rxfh->key)
604 memcpy(rxfh->key, wx->rss_key, WX_RSS_KEY_SIZE);
605
606 return 0;
607 }
608 EXPORT_SYMBOL(wx_get_rxfh);
609
wx_set_rxfh(struct net_device * netdev,struct ethtool_rxfh_param * rxfh,struct netlink_ext_ack * extack)610 int wx_set_rxfh(struct net_device *netdev,
611 struct ethtool_rxfh_param *rxfh,
612 struct netlink_ext_ack *extack)
613 {
614 struct wx *wx = netdev_priv(netdev);
615 u32 reta_entries, i;
616
617 if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
618 rxfh->hfunc != ETH_RSS_HASH_TOP)
619 return -EOPNOTSUPP;
620
621 reta_entries = wx_rss_indir_tbl_entries(wx);
622 /* Fill out the redirection table */
623 if (rxfh->indir) {
624 for (i = 0; i < reta_entries; i++)
625 wx->rss_indir_tbl[i] = rxfh->indir[i];
626
627 wx_store_reta(wx);
628 }
629
630 /* Fill out the rss hash key */
631 if (rxfh->key) {
632 memcpy(wx->rss_key, rxfh->key, WX_RSS_KEY_SIZE);
633 wx_store_rsskey(wx);
634 }
635
636 return 0;
637 }
638 EXPORT_SYMBOL(wx_set_rxfh);
639
640 static const struct wx_rss_flow_map rss_flow_table[] = {
641 { TCP_V4_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV4_TCP },
642 { TCP_V6_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV6_TCP },
643 { UDP_V4_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV4_UDP },
644 { UDP_V6_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV6_UDP },
645 { SCTP_V4_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV4_SCTP },
646 { SCTP_V6_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV6_SCTP },
647 };
648
wx_get_rxfh_fields(struct net_device * dev,struct ethtool_rxfh_fields * nfc)649 int wx_get_rxfh_fields(struct net_device *dev,
650 struct ethtool_rxfh_fields *nfc)
651 {
652 struct wx *wx = netdev_priv(dev);
653
654 nfc->data = RXH_IP_SRC | RXH_IP_DST;
655
656 for (u32 i = 0; i < ARRAY_SIZE(rss_flow_table); i++) {
657 const struct wx_rss_flow_map *entry = &rss_flow_table[i];
658
659 if (entry->flow_type == nfc->flow_type) {
660 if (wx->rss_flags & entry->flag)
661 nfc->data |= entry->data;
662 break;
663 }
664 }
665
666 return 0;
667 }
668 EXPORT_SYMBOL(wx_get_rxfh_fields);
669
wx_set_rxfh_fields(struct net_device * dev,const struct ethtool_rxfh_fields * nfc,struct netlink_ext_ack * extack)670 int wx_set_rxfh_fields(struct net_device *dev,
671 const struct ethtool_rxfh_fields *nfc,
672 struct netlink_ext_ack *extack)
673 {
674 struct wx *wx = netdev_priv(dev);
675 u8 flags = wx->rss_flags;
676
677 if (!(nfc->data & RXH_IP_SRC) ||
678 !(nfc->data & RXH_IP_DST))
679 return -EINVAL;
680
681 for (u32 i = 0; i < ARRAY_SIZE(rss_flow_table); i++) {
682 const struct wx_rss_flow_map *entry = &rss_flow_table[i];
683
684 if (entry->flow_type == nfc->flow_type) {
685 if (nfc->data & entry->data)
686 flags |= entry->flag;
687 else
688 flags &= ~entry->flag;
689
690 if (flags != wx->rss_flags) {
691 wx->rss_flags = flags;
692 wx_config_rss_field(wx);
693 }
694
695 return 0;
696 }
697 }
698
699 return -EINVAL;
700 }
701 EXPORT_SYMBOL(wx_set_rxfh_fields);
702
wx_get_msglevel(struct net_device * netdev)703 u32 wx_get_msglevel(struct net_device *netdev)
704 {
705 struct wx *wx = netdev_priv(netdev);
706
707 return wx->msg_enable;
708 }
709 EXPORT_SYMBOL(wx_get_msglevel);
710
wx_set_msglevel(struct net_device * netdev,u32 data)711 void wx_set_msglevel(struct net_device *netdev, u32 data)
712 {
713 struct wx *wx = netdev_priv(netdev);
714
715 wx->msg_enable = data;
716 }
717 EXPORT_SYMBOL(wx_set_msglevel);
718
wx_get_ts_info(struct net_device * dev,struct kernel_ethtool_ts_info * info)719 int wx_get_ts_info(struct net_device *dev,
720 struct kernel_ethtool_ts_info *info)
721 {
722 struct wx *wx = netdev_priv(dev);
723
724 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
725 BIT(HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
726 BIT(HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
727 BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
728 BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
729 BIT(HWTSTAMP_FILTER_PTP_V2_SYNC) |
730 BIT(HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
731 BIT(HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
732 BIT(HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |
733 BIT(HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
734 BIT(HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
735 BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
736
737 info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
738 SOF_TIMESTAMPING_TX_HARDWARE |
739 SOF_TIMESTAMPING_RX_HARDWARE |
740 SOF_TIMESTAMPING_RAW_HARDWARE;
741
742 if (wx->ptp_clock)
743 info->phc_index = ptp_clock_index(wx->ptp_clock);
744 else
745 info->phc_index = -1;
746
747 info->tx_types = BIT(HWTSTAMP_TX_OFF) |
748 BIT(HWTSTAMP_TX_ON);
749
750 return 0;
751 }
752 EXPORT_SYMBOL(wx_get_ts_info);
753
wx_get_ptp_stats(struct net_device * dev,struct ethtool_ts_stats * ts_stats)754 void wx_get_ptp_stats(struct net_device *dev,
755 struct ethtool_ts_stats *ts_stats)
756 {
757 struct wx *wx = netdev_priv(dev);
758
759 if (wx->ptp_clock) {
760 ts_stats->pkts = wx->tx_hwtstamp_pkts;
761 ts_stats->lost = wx->tx_hwtstamp_timeouts +
762 wx->tx_hwtstamp_skipped +
763 wx->rx_hwtstamp_cleared;
764 ts_stats->err = wx->tx_hwtstamp_errors;
765 }
766 }
767 EXPORT_SYMBOL(wx_get_ptp_stats);
768
wx_get_link_ksettings_vf(struct net_device * netdev,struct ethtool_link_ksettings * cmd)769 static int wx_get_link_ksettings_vf(struct net_device *netdev,
770 struct ethtool_link_ksettings *cmd)
771 {
772 struct wx *wx = netdev_priv(netdev);
773
774 ethtool_link_ksettings_zero_link_mode(cmd, supported);
775 cmd->base.autoneg = AUTONEG_DISABLE;
776 cmd->base.port = PORT_NONE;
777 cmd->base.duplex = DUPLEX_FULL;
778 cmd->base.speed = wx->speed;
779
780 return 0;
781 }
782
wx_set_ringparam_vf(struct net_device * netdev,struct ethtool_ringparam * ring,struct kernel_ethtool_ringparam * kernel_ring,struct netlink_ext_ack * extack)783 static int wx_set_ringparam_vf(struct net_device *netdev,
784 struct ethtool_ringparam *ring,
785 struct kernel_ethtool_ringparam *kernel_ring,
786 struct netlink_ext_ack *extack)
787 {
788 struct wx *wx = netdev_priv(netdev);
789 u32 new_rx_count, new_tx_count;
790 struct wx_ring *temp_ring;
791 int i, err = 0;
792
793 new_tx_count = clamp_t(u32, ring->tx_pending, WX_MIN_TXD, WX_MAX_TXD);
794 new_tx_count = ALIGN(new_tx_count, WX_REQ_TX_DESCRIPTOR_MULTIPLE);
795
796 new_rx_count = clamp_t(u32, ring->rx_pending, WX_MIN_RXD, WX_MAX_RXD);
797 new_rx_count = ALIGN(new_rx_count, WX_REQ_RX_DESCRIPTOR_MULTIPLE);
798
799 if (new_tx_count == wx->tx_ring_count &&
800 new_rx_count == wx->rx_ring_count)
801 return 0;
802
803 mutex_lock(&wx->reset_lock);
804 set_bit(WX_STATE_RESETTING, wx->state);
805
806 if (!netif_running(wx->netdev)) {
807 for (i = 0; i < wx->num_tx_queues; i++)
808 wx->tx_ring[i]->count = new_tx_count;
809 for (i = 0; i < wx->num_rx_queues; i++)
810 wx->rx_ring[i]->count = new_rx_count;
811 wx->tx_ring_count = new_tx_count;
812 wx->rx_ring_count = new_rx_count;
813
814 goto clear_reset;
815 }
816
817 /* allocate temporary buffer to store rings in */
818 i = max_t(int, wx->num_tx_queues, wx->num_rx_queues);
819 temp_ring = kvmalloc_objs(struct wx_ring, i);
820 if (!temp_ring) {
821 err = -ENOMEM;
822 goto clear_reset;
823 }
824
825 wxvf_down(wx);
826 /* wx_set_ring() may partially apply changes before
827 * returning an error. The error indicates that not all
828 * requested ring parameters could be configured.
829 */
830 err = wx_set_ring(wx, new_tx_count, new_rx_count, temp_ring);
831 if (err)
832 wx_err(wx, "failed to set ring parameters: %d", err);
833 wx_configure_vf(wx);
834 wxvf_up_complete(wx);
835 kvfree(temp_ring);
836 clear_reset:
837 clear_bit(WX_STATE_RESETTING, wx->state);
838 mutex_unlock(&wx->reset_lock);
839 return err;
840 }
841
842 static const struct ethtool_ops wx_ethtool_ops_vf = {
843 .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
844 ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ |
845 ETHTOOL_COALESCE_USE_ADAPTIVE,
846 .get_drvinfo = wx_get_drvinfo,
847 .get_link = ethtool_op_get_link,
848 .get_ringparam = wx_get_ringparam,
849 .set_ringparam = wx_set_ringparam_vf,
850 .get_msglevel = wx_get_msglevel,
851 .get_coalesce = wx_get_coalesce,
852 .set_coalesce = wx_set_coalesce,
853 .get_ts_info = ethtool_op_get_ts_info,
854 .get_link_ksettings = wx_get_link_ksettings_vf,
855 };
856
wx_set_ethtool_ops_vf(struct net_device * netdev)857 void wx_set_ethtool_ops_vf(struct net_device *netdev)
858 {
859 netdev->ethtool_ops = &wx_ethtool_ops_vf;
860 }
861 EXPORT_SYMBOL(wx_set_ethtool_ops_vf);
862