forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/net/vmxnet3/vmxnet3_ethtool.c
....@@ -1,7 +1,7 @@
11 /*
22 * Linux driver for VMware's vmxnet3 ethernet NIC.
33 *
4
- * Copyright (C) 2008-2016, VMware, Inc. All Rights Reserved.
4
+ * Copyright (C) 2008-2021, VMware, Inc. All Rights Reserved.
55 *
66 * This program is free software; you can redistribute it and/or modify it
77 * under the terms of the GNU General Public License as published by the
....@@ -26,6 +26,10 @@
2626
2727
2828 #include "vmxnet3_int.h"
29
+#include <net/vxlan.h>
30
+#include <net/geneve.h>
31
+
32
+#define VXLAN_UDP_PORT 8472
2933
3034 struct vmxnet3_stat_desc {
3135 char desc[ETH_GSTRING_LEN];
....@@ -257,14 +261,95 @@
257261 }
258262 }
259263
264
+netdev_features_t vmxnet3_fix_features(struct net_device *netdev,
265
+ netdev_features_t features)
266
+{
267
+ /* If Rx checksum is disabled, then LRO should also be disabled */
268
+ if (!(features & NETIF_F_RXCSUM))
269
+ features &= ~NETIF_F_LRO;
270
+
271
+ return features;
272
+}
273
+
274
+netdev_features_t vmxnet3_features_check(struct sk_buff *skb,
275
+ struct net_device *netdev,
276
+ netdev_features_t features)
277
+{
278
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
279
+
280
+ /* Validate if the tunneled packet is being offloaded by the device */
281
+ if (VMXNET3_VERSION_GE_4(adapter) &&
282
+ skb->encapsulation && skb->ip_summed == CHECKSUM_PARTIAL) {
283
+ u8 l4_proto = 0;
284
+ u16 port;
285
+ struct udphdr *udph;
286
+
287
+ switch (vlan_get_protocol(skb)) {
288
+ case htons(ETH_P_IP):
289
+ l4_proto = ip_hdr(skb)->protocol;
290
+ break;
291
+ case htons(ETH_P_IPV6):
292
+ l4_proto = ipv6_hdr(skb)->nexthdr;
293
+ break;
294
+ default:
295
+ return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
296
+ }
297
+
298
+ switch (l4_proto) {
299
+ case IPPROTO_UDP:
300
+ udph = udp_hdr(skb);
301
+ port = be16_to_cpu(udph->dest);
302
+ /* Check if offloaded port is supported */
303
+ if (port != GENEVE_UDP_PORT &&
304
+ port != IANA_VXLAN_UDP_PORT &&
305
+ port != VXLAN_UDP_PORT) {
306
+ return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
307
+ }
308
+ break;
309
+ default:
310
+ return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
311
+ }
312
+ }
313
+ return features;
314
+}
315
+
316
+static void vmxnet3_enable_encap_offloads(struct net_device *netdev)
317
+{
318
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
319
+
320
+ if (VMXNET3_VERSION_GE_4(adapter)) {
321
+ netdev->hw_enc_features |= NETIF_F_SG | NETIF_F_RXCSUM |
322
+ NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_TX |
323
+ NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_TSO | NETIF_F_TSO6 |
324
+ NETIF_F_LRO | NETIF_F_GSO_UDP_TUNNEL |
325
+ NETIF_F_GSO_UDP_TUNNEL_CSUM;
326
+ }
327
+}
328
+
329
+static void vmxnet3_disable_encap_offloads(struct net_device *netdev)
330
+{
331
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
332
+
333
+ if (VMXNET3_VERSION_GE_4(adapter)) {
334
+ netdev->hw_enc_features &= ~(NETIF_F_SG | NETIF_F_RXCSUM |
335
+ NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_TX |
336
+ NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_TSO | NETIF_F_TSO6 |
337
+ NETIF_F_LRO | NETIF_F_GSO_UDP_TUNNEL |
338
+ NETIF_F_GSO_UDP_TUNNEL_CSUM);
339
+ }
340
+}
341
+
260342 int vmxnet3_set_features(struct net_device *netdev, netdev_features_t features)
261343 {
262344 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
263345 unsigned long flags;
264346 netdev_features_t changed = features ^ netdev->features;
347
+ netdev_features_t tun_offload_mask = NETIF_F_GSO_UDP_TUNNEL |
348
+ NETIF_F_GSO_UDP_TUNNEL_CSUM;
349
+ u8 udp_tun_enabled = (netdev->features & tun_offload_mask) != 0;
265350
266351 if (changed & (NETIF_F_RXCSUM | NETIF_F_LRO |
267
- NETIF_F_HW_VLAN_CTAG_RX)) {
352
+ NETIF_F_HW_VLAN_CTAG_RX | tun_offload_mask)) {
268353 if (features & NETIF_F_RXCSUM)
269354 adapter->shared->devRead.misc.uptFeatures |=
270355 UPT1_F_RXCSUM;
....@@ -286,6 +371,17 @@
286371 else
287372 adapter->shared->devRead.misc.uptFeatures &=
288373 ~UPT1_F_RXVLAN;
374
+
375
+ if ((features & tun_offload_mask) != 0 && !udp_tun_enabled) {
376
+ vmxnet3_enable_encap_offloads(netdev);
377
+ adapter->shared->devRead.misc.uptFeatures |=
378
+ UPT1_F_RXINNEROFLD;
379
+ } else if ((features & tun_offload_mask) == 0 &&
380
+ udp_tun_enabled) {
381
+ vmxnet3_disable_encap_offloads(netdev);
382
+ adapter->shared->devRead.misc.uptFeatures &=
383
+ ~UPT1_F_RXINNEROFLD;
384
+ }
289385
290386 spin_lock_irqsave(&adapter->cmd_lock, flags);
291387 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
....@@ -545,10 +641,8 @@
545641 }
546642
547643 if (VMXNET3_VERSION_GE_3(adapter)) {
548
- if (param->rx_mini_pending < 0 ||
549
- param->rx_mini_pending > VMXNET3_RXDATA_DESC_MAX_SIZE) {
644
+ if (param->rx_mini_pending > VMXNET3_RXDATA_DESC_MAX_SIZE)
550645 return -EINVAL;
551
- }
552646 } else if (param->rx_mini_pending != 0) {
553647 return -EINVAL;
554648 }
....@@ -657,18 +751,244 @@
657751 return err;
658752 }
659753
754
+static int
755
+vmxnet3_get_rss_hash_opts(struct vmxnet3_adapter *adapter,
756
+ struct ethtool_rxnfc *info)
757
+{
758
+ enum Vmxnet3_RSSField rss_fields;
759
+
760
+ if (netif_running(adapter->netdev)) {
761
+ unsigned long flags;
762
+
763
+ spin_lock_irqsave(&adapter->cmd_lock, flags);
764
+
765
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
766
+ VMXNET3_CMD_GET_RSS_FIELDS);
767
+ rss_fields = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
768
+ spin_unlock_irqrestore(&adapter->cmd_lock, flags);
769
+ } else {
770
+ rss_fields = adapter->rss_fields;
771
+ }
772
+
773
+ info->data = 0;
774
+
775
+ /* Report default options for RSS on vmxnet3 */
776
+ switch (info->flow_type) {
777
+ case TCP_V4_FLOW:
778
+ case TCP_V6_FLOW:
779
+ info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3 |
780
+ RXH_IP_SRC | RXH_IP_DST;
781
+ break;
782
+ case UDP_V4_FLOW:
783
+ if (rss_fields & VMXNET3_RSS_FIELDS_UDPIP4)
784
+ info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
785
+ info->data |= RXH_IP_SRC | RXH_IP_DST;
786
+ break;
787
+ case AH_ESP_V4_FLOW:
788
+ case AH_V4_FLOW:
789
+ case ESP_V4_FLOW:
790
+ if (rss_fields & VMXNET3_RSS_FIELDS_ESPIP4)
791
+ info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
792
+ fallthrough;
793
+ case SCTP_V4_FLOW:
794
+ case IPV4_FLOW:
795
+ info->data |= RXH_IP_SRC | RXH_IP_DST;
796
+ break;
797
+ case UDP_V6_FLOW:
798
+ if (rss_fields & VMXNET3_RSS_FIELDS_UDPIP6)
799
+ info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
800
+ info->data |= RXH_IP_SRC | RXH_IP_DST;
801
+ break;
802
+ case AH_ESP_V6_FLOW:
803
+ case AH_V6_FLOW:
804
+ case ESP_V6_FLOW:
805
+ case SCTP_V6_FLOW:
806
+ case IPV6_FLOW:
807
+ info->data |= RXH_IP_SRC | RXH_IP_DST;
808
+ break;
809
+ default:
810
+ return -EINVAL;
811
+ }
812
+
813
+ return 0;
814
+}
815
+
816
+static int
817
+vmxnet3_set_rss_hash_opt(struct net_device *netdev,
818
+ struct vmxnet3_adapter *adapter,
819
+ struct ethtool_rxnfc *nfc)
820
+{
821
+ enum Vmxnet3_RSSField rss_fields = adapter->rss_fields;
822
+
823
+ /* RSS does not support anything other than hashing
824
+ * to queues on src and dst IPs and ports
825
+ */
826
+ if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
827
+ RXH_L4_B_0_1 | RXH_L4_B_2_3))
828
+ return -EINVAL;
829
+
830
+ switch (nfc->flow_type) {
831
+ case TCP_V4_FLOW:
832
+ case TCP_V6_FLOW:
833
+ if (!(nfc->data & RXH_IP_SRC) ||
834
+ !(nfc->data & RXH_IP_DST) ||
835
+ !(nfc->data & RXH_L4_B_0_1) ||
836
+ !(nfc->data & RXH_L4_B_2_3))
837
+ return -EINVAL;
838
+ break;
839
+ case UDP_V4_FLOW:
840
+ if (!(nfc->data & RXH_IP_SRC) ||
841
+ !(nfc->data & RXH_IP_DST))
842
+ return -EINVAL;
843
+ switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
844
+ case 0:
845
+ rss_fields &= ~VMXNET3_RSS_FIELDS_UDPIP4;
846
+ break;
847
+ case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
848
+ rss_fields |= VMXNET3_RSS_FIELDS_UDPIP4;
849
+ break;
850
+ default:
851
+ return -EINVAL;
852
+ }
853
+ break;
854
+ case UDP_V6_FLOW:
855
+ if (!(nfc->data & RXH_IP_SRC) ||
856
+ !(nfc->data & RXH_IP_DST))
857
+ return -EINVAL;
858
+ switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
859
+ case 0:
860
+ rss_fields &= ~VMXNET3_RSS_FIELDS_UDPIP6;
861
+ break;
862
+ case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
863
+ rss_fields |= VMXNET3_RSS_FIELDS_UDPIP6;
864
+ break;
865
+ default:
866
+ return -EINVAL;
867
+ }
868
+ break;
869
+ case ESP_V4_FLOW:
870
+ case AH_V4_FLOW:
871
+ case AH_ESP_V4_FLOW:
872
+ if (!(nfc->data & RXH_IP_SRC) ||
873
+ !(nfc->data & RXH_IP_DST))
874
+ return -EINVAL;
875
+ switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
876
+ case 0:
877
+ rss_fields &= ~VMXNET3_RSS_FIELDS_ESPIP4;
878
+ break;
879
+ case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
880
+ rss_fields |= VMXNET3_RSS_FIELDS_ESPIP4;
881
+ break;
882
+ default:
883
+ return -EINVAL;
884
+ }
885
+ break;
886
+ case ESP_V6_FLOW:
887
+ case AH_V6_FLOW:
888
+ case AH_ESP_V6_FLOW:
889
+ case SCTP_V4_FLOW:
890
+ case SCTP_V6_FLOW:
891
+ if (!(nfc->data & RXH_IP_SRC) ||
892
+ !(nfc->data & RXH_IP_DST) ||
893
+ (nfc->data & RXH_L4_B_0_1) ||
894
+ (nfc->data & RXH_L4_B_2_3))
895
+ return -EINVAL;
896
+ break;
897
+ default:
898
+ return -EINVAL;
899
+ }
900
+
901
+ /* if we changed something we need to update flags */
902
+ if (rss_fields != adapter->rss_fields) {
903
+ adapter->default_rss_fields = false;
904
+ if (netif_running(netdev)) {
905
+ struct Vmxnet3_DriverShared *shared = adapter->shared;
906
+ union Vmxnet3_CmdInfo *cmdInfo = &shared->cu.cmdInfo;
907
+ unsigned long flags;
908
+
909
+ spin_lock_irqsave(&adapter->cmd_lock, flags);
910
+ cmdInfo->setRssFields = rss_fields;
911
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
912
+ VMXNET3_CMD_SET_RSS_FIELDS);
913
+
914
+ /* Not all requested RSS may get applied, so get and
915
+ * cache what was actually applied.
916
+ */
917
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
918
+ VMXNET3_CMD_GET_RSS_FIELDS);
919
+ adapter->rss_fields =
920
+ VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
921
+ spin_unlock_irqrestore(&adapter->cmd_lock, flags);
922
+ } else {
923
+ /* When the device is activated, we will try to apply
924
+ * these rules and cache the applied value later.
925
+ */
926
+ adapter->rss_fields = rss_fields;
927
+ }
928
+ }
929
+ return 0;
930
+}
660931
661932 static int
662933 vmxnet3_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *info,
663934 u32 *rules)
664935 {
665936 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
937
+ int err = 0;
938
+
666939 switch (info->cmd) {
667940 case ETHTOOL_GRXRINGS:
668941 info->data = adapter->num_rx_queues;
669
- return 0;
942
+ break;
943
+ case ETHTOOL_GRXFH:
944
+ if (!VMXNET3_VERSION_GE_4(adapter)) {
945
+ err = -EOPNOTSUPP;
946
+ break;
947
+ }
948
+#ifdef VMXNET3_RSS
949
+ if (!adapter->rss) {
950
+ err = -EOPNOTSUPP;
951
+ break;
952
+ }
953
+#endif
954
+ err = vmxnet3_get_rss_hash_opts(adapter, info);
955
+ break;
956
+ default:
957
+ err = -EOPNOTSUPP;
958
+ break;
670959 }
671
- return -EOPNOTSUPP;
960
+
961
+ return err;
962
+}
963
+
964
+static int
965
+vmxnet3_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *info)
966
+{
967
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
968
+ int err = 0;
969
+
970
+ if (!VMXNET3_VERSION_GE_4(adapter)) {
971
+ err = -EOPNOTSUPP;
972
+ goto done;
973
+ }
974
+#ifdef VMXNET3_RSS
975
+ if (!adapter->rss) {
976
+ err = -EOPNOTSUPP;
977
+ goto done;
978
+ }
979
+#endif
980
+
981
+ switch (info->cmd) {
982
+ case ETHTOOL_SRXFH:
983
+ err = vmxnet3_set_rss_hash_opt(netdev, adapter, info);
984
+ break;
985
+ default:
986
+ err = -EOPNOTSUPP;
987
+ break;
988
+ }
989
+
990
+done:
991
+ return err;
672992 }
673993
674994 #ifdef VMXNET3_RSS
....@@ -774,27 +1094,6 @@
7741094 if (!VMXNET3_VERSION_GE_3(adapter))
7751095 return -EOPNOTSUPP;
7761096
777
- if (ec->rx_coalesce_usecs_irq ||
778
- ec->rx_max_coalesced_frames_irq ||
779
- ec->tx_coalesce_usecs ||
780
- ec->tx_coalesce_usecs_irq ||
781
- ec->tx_max_coalesced_frames_irq ||
782
- ec->stats_block_coalesce_usecs ||
783
- ec->use_adaptive_tx_coalesce ||
784
- ec->pkt_rate_low ||
785
- ec->rx_coalesce_usecs_low ||
786
- ec->rx_max_coalesced_frames_low ||
787
- ec->tx_coalesce_usecs_low ||
788
- ec->tx_max_coalesced_frames_low ||
789
- ec->pkt_rate_high ||
790
- ec->rx_coalesce_usecs_high ||
791
- ec->rx_max_coalesced_frames_high ||
792
- ec->tx_coalesce_usecs_high ||
793
- ec->tx_max_coalesced_frames_high ||
794
- ec->rate_sample_interval) {
795
- return -EINVAL;
796
- }
797
-
7981097 if ((ec->rx_coalesce_usecs == 0) &&
7991098 (ec->use_adaptive_rx_coalesce == 0) &&
8001099 (ec->tx_max_coalesced_frames == 0) &&
....@@ -885,6 +1184,9 @@
8851184 }
8861185
8871186 static const struct ethtool_ops vmxnet3_ethtool_ops = {
1187
+ .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS |
1188
+ ETHTOOL_COALESCE_MAX_FRAMES |
1189
+ ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
8881190 .get_drvinfo = vmxnet3_get_drvinfo,
8891191 .get_regs_len = vmxnet3_get_regs_len,
8901192 .get_regs = vmxnet3_get_regs,
....@@ -899,6 +1201,7 @@
8991201 .get_ringparam = vmxnet3_get_ringparam,
9001202 .set_ringparam = vmxnet3_set_ringparam,
9011203 .get_rxnfc = vmxnet3_get_rxnfc,
1204
+ .set_rxnfc = vmxnet3_set_rxnfc,
9021205 #ifdef VMXNET3_RSS
9031206 .get_rxfh_indir_size = vmxnet3_get_rss_indir_size,
9041207 .get_rxfh = vmxnet3_get_rss,