1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include "i40evf.h"
29
30#include <linux/uaccess.h>
31
32struct i40evf_stats {
33 char stat_string[ETH_GSTRING_LEN];
34 int stat_offset;
35};
36
37#define I40EVF_STAT(_name, _stat) { \
38 .stat_string = _name, \
39 .stat_offset = offsetof(struct i40evf_adapter, _stat) \
40}
41
42
43static const struct i40evf_stats i40evf_gstrings_stats[] = {
44 I40EVF_STAT("rx_bytes", current_stats.rx_bytes),
45 I40EVF_STAT("rx_unicast", current_stats.rx_unicast),
46 I40EVF_STAT("rx_multicast", current_stats.rx_multicast),
47 I40EVF_STAT("rx_broadcast", current_stats.rx_broadcast),
48 I40EVF_STAT("rx_discards", current_stats.rx_discards),
49 I40EVF_STAT("rx_unknown_protocol", current_stats.rx_unknown_protocol),
50 I40EVF_STAT("tx_bytes", current_stats.tx_bytes),
51 I40EVF_STAT("tx_unicast", current_stats.tx_unicast),
52 I40EVF_STAT("tx_multicast", current_stats.tx_multicast),
53 I40EVF_STAT("tx_broadcast", current_stats.tx_broadcast),
54 I40EVF_STAT("tx_discards", current_stats.tx_discards),
55 I40EVF_STAT("tx_errors", current_stats.tx_errors),
56};
57
58#define I40EVF_GLOBAL_STATS_LEN ARRAY_SIZE(i40evf_gstrings_stats)
59#define I40EVF_QUEUE_STATS_LEN(_dev) \
60 (((struct i40evf_adapter *)\
61 netdev_priv(_dev))->num_active_queues \
62 * 2 * (sizeof(struct i40e_queue_stats) / sizeof(u64)))
63#define I40EVF_STATS_LEN(_dev) \
64 (I40EVF_GLOBAL_STATS_LEN + I40EVF_QUEUE_STATS_LEN(_dev))
65
66static const char i40evf_priv_flags_strings[][ETH_GSTRING_LEN] = {
67 "packet-split",
68};
69
70#define I40EVF_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40evf_priv_flags_strings)
71
72
73
74
75
76
77
78
79
80static int i40evf_get_settings(struct net_device *netdev,
81 struct ethtool_cmd *ecmd)
82{
83
84
85
86 ecmd->supported = 0;
87 ecmd->autoneg = AUTONEG_DISABLE;
88 ecmd->transceiver = XCVR_DUMMY1;
89 ecmd->port = PORT_NONE;
90
91 return 0;
92}
93
94
95
96
97
98
99
100
101
102static int i40evf_get_sset_count(struct net_device *netdev, int sset)
103{
104 if (sset == ETH_SS_STATS)
105 return I40EVF_STATS_LEN(netdev);
106 else if (sset == ETH_SS_PRIV_FLAGS)
107 return I40EVF_PRIV_FLAGS_STR_LEN;
108 else
109 return -EINVAL;
110}
111
112
113
114
115
116
117
118
119
120static void i40evf_get_ethtool_stats(struct net_device *netdev,
121 struct ethtool_stats *stats, u64 *data)
122{
123 struct i40evf_adapter *adapter = netdev_priv(netdev);
124 int i, j;
125 char *p;
126
127 for (i = 0; i < I40EVF_GLOBAL_STATS_LEN; i++) {
128 p = (char *)adapter + i40evf_gstrings_stats[i].stat_offset;
129 data[i] = *(u64 *)p;
130 }
131 for (j = 0; j < adapter->num_active_queues; j++) {
132 data[i++] = adapter->tx_rings[j].stats.packets;
133 data[i++] = adapter->tx_rings[j].stats.bytes;
134 }
135 for (j = 0; j < adapter->num_active_queues; j++) {
136 data[i++] = adapter->rx_rings[j].stats.packets;
137 data[i++] = adapter->rx_rings[j].stats.bytes;
138 }
139}
140
141
142
143
144
145
146
147
148
149static void i40evf_get_strings(struct net_device *netdev, u32 sset, u8 *data)
150{
151 struct i40evf_adapter *adapter = netdev_priv(netdev);
152 u8 *p = data;
153 int i;
154
155 if (sset == ETH_SS_STATS) {
156 for (i = 0; i < I40EVF_GLOBAL_STATS_LEN; i++) {
157 memcpy(p, i40evf_gstrings_stats[i].stat_string,
158 ETH_GSTRING_LEN);
159 p += ETH_GSTRING_LEN;
160 }
161 for (i = 0; i < adapter->num_active_queues; i++) {
162 snprintf(p, ETH_GSTRING_LEN, "tx-%u.packets", i);
163 p += ETH_GSTRING_LEN;
164 snprintf(p, ETH_GSTRING_LEN, "tx-%u.bytes", i);
165 p += ETH_GSTRING_LEN;
166 }
167 for (i = 0; i < adapter->num_active_queues; i++) {
168 snprintf(p, ETH_GSTRING_LEN, "rx-%u.packets", i);
169 p += ETH_GSTRING_LEN;
170 snprintf(p, ETH_GSTRING_LEN, "rx-%u.bytes", i);
171 p += ETH_GSTRING_LEN;
172 }
173 } else if (sset == ETH_SS_PRIV_FLAGS) {
174 for (i = 0; i < I40EVF_PRIV_FLAGS_STR_LEN; i++) {
175 memcpy(data, i40evf_priv_flags_strings[i],
176 ETH_GSTRING_LEN);
177 data += ETH_GSTRING_LEN;
178 }
179 }
180}
181
182
183
184
185
186
187
188static u32 i40evf_get_msglevel(struct net_device *netdev)
189{
190 struct i40evf_adapter *adapter = netdev_priv(netdev);
191
192 return adapter->msg_enable;
193}
194
195
196
197
198
199
200
201
202
203static void i40evf_set_msglevel(struct net_device *netdev, u32 data)
204{
205 struct i40evf_adapter *adapter = netdev_priv(netdev);
206
207 if (I40E_DEBUG_USER & data)
208 adapter->hw.debug_mask = data;
209 adapter->msg_enable = data;
210}
211
212
213
214
215
216
217
218
219static void i40evf_get_drvinfo(struct net_device *netdev,
220 struct ethtool_drvinfo *drvinfo)
221{
222 struct i40evf_adapter *adapter = netdev_priv(netdev);
223
224 strlcpy(drvinfo->driver, i40evf_driver_name, 32);
225 strlcpy(drvinfo->version, i40evf_driver_version, 32);
226 strlcpy(drvinfo->fw_version, "N/A", 4);
227 strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
228 drvinfo->n_priv_flags = I40EVF_PRIV_FLAGS_STR_LEN;
229}
230
231
232
233
234
235
236
237
238
239static void i40evf_get_ringparam(struct net_device *netdev,
240 struct ethtool_ringparam *ring)
241{
242 struct i40evf_adapter *adapter = netdev_priv(netdev);
243
244 ring->rx_max_pending = I40EVF_MAX_RXD;
245 ring->tx_max_pending = I40EVF_MAX_TXD;
246 ring->rx_pending = adapter->rx_desc_count;
247 ring->tx_pending = adapter->tx_desc_count;
248}
249
250
251
252
253
254
255
256
257
258static int i40evf_set_ringparam(struct net_device *netdev,
259 struct ethtool_ringparam *ring)
260{
261 struct i40evf_adapter *adapter = netdev_priv(netdev);
262 u32 new_rx_count, new_tx_count;
263
264 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
265 return -EINVAL;
266
267 new_tx_count = clamp_t(u32, ring->tx_pending,
268 I40EVF_MIN_TXD,
269 I40EVF_MAX_TXD);
270 new_tx_count = ALIGN(new_tx_count, I40EVF_REQ_DESCRIPTOR_MULTIPLE);
271
272 new_rx_count = clamp_t(u32, ring->rx_pending,
273 I40EVF_MIN_RXD,
274 I40EVF_MAX_RXD);
275 new_rx_count = ALIGN(new_rx_count, I40EVF_REQ_DESCRIPTOR_MULTIPLE);
276
277
278 if ((new_tx_count == adapter->tx_desc_count) &&
279 (new_rx_count == adapter->rx_desc_count))
280 return 0;
281
282 adapter->tx_desc_count = new_tx_count;
283 adapter->rx_desc_count = new_rx_count;
284
285 if (netif_running(netdev)) {
286 adapter->flags |= I40EVF_FLAG_RESET_NEEDED;
287 schedule_work(&adapter->reset_task);
288 }
289
290 return 0;
291}
292
293
294
295
296
297
298
299
300
301
302static int i40evf_get_coalesce(struct net_device *netdev,
303 struct ethtool_coalesce *ec)
304{
305 struct i40evf_adapter *adapter = netdev_priv(netdev);
306 struct i40e_vsi *vsi = &adapter->vsi;
307
308 ec->tx_max_coalesced_frames = vsi->work_limit;
309 ec->rx_max_coalesced_frames = vsi->work_limit;
310
311 if (ITR_IS_DYNAMIC(vsi->rx_itr_setting))
312 ec->use_adaptive_rx_coalesce = 1;
313
314 if (ITR_IS_DYNAMIC(vsi->tx_itr_setting))
315 ec->use_adaptive_tx_coalesce = 1;
316
317 ec->rx_coalesce_usecs = vsi->rx_itr_setting & ~I40E_ITR_DYNAMIC;
318 ec->tx_coalesce_usecs = vsi->tx_itr_setting & ~I40E_ITR_DYNAMIC;
319
320 return 0;
321}
322
323
324
325
326
327
328
329
330static int i40evf_set_coalesce(struct net_device *netdev,
331 struct ethtool_coalesce *ec)
332{
333 struct i40evf_adapter *adapter = netdev_priv(netdev);
334 struct i40e_hw *hw = &adapter->hw;
335 struct i40e_vsi *vsi = &adapter->vsi;
336 struct i40e_q_vector *q_vector;
337 int i;
338
339 if (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq)
340 vsi->work_limit = ec->tx_max_coalesced_frames_irq;
341
342 if ((ec->rx_coalesce_usecs >= (I40E_MIN_ITR << 1)) &&
343 (ec->rx_coalesce_usecs <= (I40E_MAX_ITR << 1)))
344 vsi->rx_itr_setting = ec->rx_coalesce_usecs;
345
346 else
347 return -EINVAL;
348
349 if ((ec->tx_coalesce_usecs >= (I40E_MIN_ITR << 1)) &&
350 (ec->tx_coalesce_usecs <= (I40E_MAX_ITR << 1)))
351 vsi->tx_itr_setting = ec->tx_coalesce_usecs;
352 else if (ec->use_adaptive_tx_coalesce)
353 vsi->tx_itr_setting = (I40E_ITR_DYNAMIC |
354 ITR_REG_TO_USEC(I40E_ITR_RX_DEF));
355 else
356 return -EINVAL;
357
358 if (ec->use_adaptive_rx_coalesce)
359 vsi->rx_itr_setting |= I40E_ITR_DYNAMIC;
360 else
361 vsi->rx_itr_setting &= ~I40E_ITR_DYNAMIC;
362
363 if (ec->use_adaptive_tx_coalesce)
364 vsi->tx_itr_setting |= I40E_ITR_DYNAMIC;
365 else
366 vsi->tx_itr_setting &= ~I40E_ITR_DYNAMIC;
367
368 for (i = 0; i < adapter->num_msix_vectors - NONQ_VECS; i++) {
369 q_vector = &adapter->q_vectors[i];
370 q_vector->rx.itr = ITR_TO_REG(vsi->rx_itr_setting);
371 wr32(hw, I40E_VFINT_ITRN1(0, i), q_vector->rx.itr);
372 q_vector->tx.itr = ITR_TO_REG(vsi->tx_itr_setting);
373 wr32(hw, I40E_VFINT_ITRN1(1, i), q_vector->tx.itr);
374 i40e_flush(hw);
375 }
376
377 return 0;
378}
379
380
381
382
383
384
385
386
387static int i40evf_get_rss_hash_opts(struct i40evf_adapter *adapter,
388 struct ethtool_rxnfc *cmd)
389{
390 struct i40e_hw *hw = &adapter->hw;
391 u64 hena = (u64)rd32(hw, I40E_VFQF_HENA(0)) |
392 ((u64)rd32(hw, I40E_VFQF_HENA(1)) << 32);
393
394
395 cmd->data = RXH_IP_SRC | RXH_IP_DST;
396
397 switch (cmd->flow_type) {
398 case TCP_V4_FLOW:
399 if (hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP))
400 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
401 break;
402 case UDP_V4_FLOW:
403 if (hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP))
404 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
405 break;
406
407 case SCTP_V4_FLOW:
408 case AH_ESP_V4_FLOW:
409 case AH_V4_FLOW:
410 case ESP_V4_FLOW:
411 case IPV4_FLOW:
412 break;
413
414 case TCP_V6_FLOW:
415 if (hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP))
416 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
417 break;
418 case UDP_V6_FLOW:
419 if (hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP))
420 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
421 break;
422
423 case SCTP_V6_FLOW:
424 case AH_ESP_V6_FLOW:
425 case AH_V6_FLOW:
426 case ESP_V6_FLOW:
427 case IPV6_FLOW:
428 break;
429 default:
430 cmd->data = 0;
431 return -EINVAL;
432 }
433
434 return 0;
435}
436
437
438
439
440
441
442
443
444static int i40evf_get_rxnfc(struct net_device *netdev,
445 struct ethtool_rxnfc *cmd,
446 u32 *rule_locs)
447{
448 struct i40evf_adapter *adapter = netdev_priv(netdev);
449 int ret = -EOPNOTSUPP;
450
451 switch (cmd->cmd) {
452 case ETHTOOL_GRXRINGS:
453 cmd->data = adapter->num_active_queues;
454 ret = 0;
455 break;
456 case ETHTOOL_GRXFH:
457 ret = i40evf_get_rss_hash_opts(adapter, cmd);
458 break;
459 default:
460 break;
461 }
462
463 return ret;
464}
465
466
467
468
469
470
471
472
473static int i40evf_set_rss_hash_opt(struct i40evf_adapter *adapter,
474 struct ethtool_rxnfc *nfc)
475{
476 struct i40e_hw *hw = &adapter->hw;
477 u32 flags = adapter->vf_res->vf_offload_flags;
478
479 u64 hena = (u64)rd32(hw, I40E_VFQF_HENA(0)) |
480 ((u64)rd32(hw, I40E_VFQF_HENA(1)) << 32);
481
482
483
484
485 if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
486 RXH_L4_B_0_1 | RXH_L4_B_2_3))
487 return -EINVAL;
488
489
490 if (!(nfc->data & RXH_IP_SRC) ||
491 !(nfc->data & RXH_IP_DST))
492 return -EINVAL;
493
494 switch (nfc->flow_type) {
495 case TCP_V4_FLOW:
496 if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
497 if (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
498 hena |=
499 BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
500
501 hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
502 } else {
503 return -EINVAL;
504 }
505 break;
506 case TCP_V6_FLOW:
507 if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
508 if (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
509 hena |=
510 BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
511
512 hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
513 } else {
514 return -EINVAL;
515 }
516 break;
517 case UDP_V4_FLOW:
518 if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
519 if (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
520 hena |=
521 BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
522 BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
523
524 hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
525 BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));
526 } else {
527 return -EINVAL;
528 }
529 break;
530 case UDP_V6_FLOW:
531 if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
532 if (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
533 hena |=
534 BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
535 BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
536
537 hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
538 BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));
539 } else {
540 return -EINVAL;
541 }
542 break;
543 case AH_ESP_V4_FLOW:
544 case AH_V4_FLOW:
545 case ESP_V4_FLOW:
546 case SCTP_V4_FLOW:
547 if ((nfc->data & RXH_L4_B_0_1) ||
548 (nfc->data & RXH_L4_B_2_3))
549 return -EINVAL;
550 hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);
551 break;
552 case AH_ESP_V6_FLOW:
553 case AH_V6_FLOW:
554 case ESP_V6_FLOW:
555 case SCTP_V6_FLOW:
556 if ((nfc->data & RXH_L4_B_0_1) ||
557 (nfc->data & RXH_L4_B_2_3))
558 return -EINVAL;
559 hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);
560 break;
561 case IPV4_FLOW:
562 hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) |
563 BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));
564 break;
565 case IPV6_FLOW:
566 hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER) |
567 BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));
568 break;
569 default:
570 return -EINVAL;
571 }
572
573 wr32(hw, I40E_VFQF_HENA(0), (u32)hena);
574 wr32(hw, I40E_VFQF_HENA(1), (u32)(hena >> 32));
575 i40e_flush(hw);
576
577 return 0;
578}
579
580
581
582
583
584
585
586
587static int i40evf_set_rxnfc(struct net_device *netdev,
588 struct ethtool_rxnfc *cmd)
589{
590 struct i40evf_adapter *adapter = netdev_priv(netdev);
591 int ret = -EOPNOTSUPP;
592
593 switch (cmd->cmd) {
594 case ETHTOOL_SRXFH:
595 ret = i40evf_set_rss_hash_opt(adapter, cmd);
596 break;
597 default:
598 break;
599 }
600
601 return ret;
602}
603
604
605
606
607
608
609
610
611
612static void i40evf_get_channels(struct net_device *netdev,
613 struct ethtool_channels *ch)
614{
615 struct i40evf_adapter *adapter = netdev_priv(netdev);
616
617
618 ch->max_combined = adapter->num_active_queues;
619
620 ch->max_other = NONQ_VECS;
621 ch->other_count = NONQ_VECS;
622
623 ch->combined_count = adapter->num_active_queues;
624}
625
626
627
628
629
630
631
632static u32 i40evf_get_rxfh_indir_size(struct net_device *netdev)
633{
634 return (I40E_VFQF_HLUT_MAX_INDEX + 1) * 4;
635}
636
637
638
639
640
641
642
643
644
645static int i40evf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
646 u8 *hfunc)
647{
648 struct i40evf_adapter *adapter = netdev_priv(netdev);
649 struct i40e_vsi *vsi = &adapter->vsi;
650 u8 *seed = NULL, *lut;
651 int ret;
652 u16 i;
653
654 if (hfunc)
655 *hfunc = ETH_RSS_HASH_TOP;
656 if (!indir)
657 return 0;
658
659 seed = key;
660
661 lut = kzalloc(I40EVF_HLUT_ARRAY_SIZE, GFP_KERNEL);
662 if (!lut)
663 return -ENOMEM;
664
665 ret = i40evf_get_rss(vsi, seed, lut, I40EVF_HLUT_ARRAY_SIZE);
666 if (ret)
667 goto out;
668
669
670 for (i = 0; i < I40EVF_HLUT_ARRAY_SIZE; i++)
671 indir[i] = (u32)lut[i];
672
673out:
674 kfree(lut);
675
676 return ret;
677}
678
679
680
681
682
683
684
685
686
687
688static int i40evf_set_rxfh(struct net_device *netdev, const u32 *indir,
689 const u8 *key, const u8 hfunc)
690{
691 struct i40evf_adapter *adapter = netdev_priv(netdev);
692 struct i40e_vsi *vsi = &adapter->vsi;
693 u8 *seed = NULL;
694 u16 i;
695
696
697 if (key ||
698 (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP))
699 return -EOPNOTSUPP;
700 if (!indir)
701 return 0;
702
703 if (key) {
704 if (!vsi->rss_hkey_user) {
705 vsi->rss_hkey_user = kzalloc(I40EVF_HKEY_ARRAY_SIZE,
706 GFP_KERNEL);
707 if (!vsi->rss_hkey_user)
708 return -ENOMEM;
709 }
710 memcpy(vsi->rss_hkey_user, key, I40EVF_HKEY_ARRAY_SIZE);
711 seed = vsi->rss_hkey_user;
712 }
713 if (!vsi->rss_lut_user) {
714 vsi->rss_lut_user = kzalloc(I40EVF_HLUT_ARRAY_SIZE,
715 GFP_KERNEL);
716 if (!vsi->rss_lut_user)
717 return -ENOMEM;
718 }
719
720
721 for (i = 0; i < I40EVF_HLUT_ARRAY_SIZE; i++)
722 vsi->rss_lut_user[i] = (u8)(indir[i]);
723
724 return i40evf_config_rss(vsi, seed, vsi->rss_lut_user,
725 I40EVF_HLUT_ARRAY_SIZE);
726}
727
728
729
730
731
732
733
734
735
736
737
738static u32 i40evf_get_priv_flags(struct net_device *dev)
739{
740 struct i40evf_adapter *adapter = netdev_priv(dev);
741 u32 ret_flags = 0;
742
743 ret_flags |= adapter->flags & I40EVF_FLAG_RX_PS_ENABLED ?
744 I40EVF_PRIV_FLAGS_PS : 0;
745
746 return ret_flags;
747}
748
749
750
751
752
753
754static int i40evf_set_priv_flags(struct net_device *dev, u32 flags)
755{
756 struct i40evf_adapter *adapter = netdev_priv(dev);
757 bool reset_required = false;
758
759 if ((flags & I40EVF_PRIV_FLAGS_PS) &&
760 !(adapter->flags & I40EVF_FLAG_RX_PS_ENABLED)) {
761 adapter->flags |= I40EVF_FLAG_RX_PS_ENABLED;
762 reset_required = true;
763 } else if (!(flags & I40EVF_PRIV_FLAGS_PS) &&
764 (adapter->flags & I40EVF_FLAG_RX_PS_ENABLED)) {
765 adapter->flags &= ~I40EVF_FLAG_RX_PS_ENABLED;
766 reset_required = true;
767 }
768
769
770 if (reset_required)
771 i40evf_schedule_reset(adapter);
772
773 return 0;
774}
775
776static const struct ethtool_ops i40evf_ethtool_ops = {
777 .get_settings = i40evf_get_settings,
778 .get_drvinfo = i40evf_get_drvinfo,
779 .get_link = ethtool_op_get_link,
780 .get_ringparam = i40evf_get_ringparam,
781 .set_ringparam = i40evf_set_ringparam,
782 .get_strings = i40evf_get_strings,
783 .get_ethtool_stats = i40evf_get_ethtool_stats,
784 .get_sset_count = i40evf_get_sset_count,
785 .get_priv_flags = i40evf_get_priv_flags,
786 .set_priv_flags = i40evf_set_priv_flags,
787 .get_msglevel = i40evf_get_msglevel,
788 .set_msglevel = i40evf_set_msglevel,
789 .get_coalesce = i40evf_get_coalesce,
790 .set_coalesce = i40evf_set_coalesce,
791 .get_rxnfc = i40evf_get_rxnfc,
792 .set_rxnfc = i40evf_set_rxnfc,
793 .get_rxfh_indir_size = i40evf_get_rxfh_indir_size,
794 .get_rxfh = i40evf_get_rxfh,
795 .set_rxfh = i40evf_set_rxfh,
796 .get_channels = i40evf_get_channels,
797};
798
799
800
801
802
803
804
805
806void i40evf_set_ethtool_ops(struct net_device *netdev)
807{
808 netdev->ethtool_ops = &i40evf_ethtool_ops;
809}
810