1
1
/* Intel(R) Ethernet Switch Host Interface Driver
2
- * Copyright(c) 2013 - 2016 Intel Corporation.
2
+ * Copyright(c) 2013 - 2017 Intel Corporation.
3
3
*
4
4
* This program is free software; you can redistribute it and/or modify it
5
5
* under the terms and conditions of the GNU General Public License,
@@ -562,7 +562,7 @@ static int fm10k_set_ringparam(struct net_device *netdev,
562
562
return 0 ;
563
563
}
564
564
565
- while (test_and_set_bit (__FM10K_RESETTING , & interface -> state ))
565
+ while (test_and_set_bit (__FM10K_RESETTING , interface -> state ))
566
566
usleep_range (1000 , 2000 );
567
567
568
568
if (!netif_running (interface -> netdev )) {
@@ -648,7 +648,7 @@ static int fm10k_set_ringparam(struct net_device *netdev,
648
648
fm10k_up (interface );
649
649
vfree (temp_ring );
650
650
clear_reset :
651
- clear_bit (__FM10K_RESETTING , & interface -> state );
651
+ clear_bit (__FM10K_RESETTING , interface -> state );
652
652
return err ;
653
653
}
654
654
@@ -716,7 +716,8 @@ static int fm10k_get_rss_hash_opts(struct fm10k_intfc *interface,
716
716
cmd -> data |= RXH_L4_B_0_1 | RXH_L4_B_2_3 ;
717
717
/* fall through */
718
718
case UDP_V4_FLOW :
719
- if (interface -> flags & FM10K_FLAG_RSS_FIELD_IPV4_UDP )
719
+ if (test_bit (FM10K_FLAG_RSS_FIELD_IPV4_UDP ,
720
+ interface -> flags ))
720
721
cmd -> data |= RXH_L4_B_0_1 | RXH_L4_B_2_3 ;
721
722
/* fall through */
722
723
case SCTP_V4_FLOW :
@@ -732,7 +733,8 @@ static int fm10k_get_rss_hash_opts(struct fm10k_intfc *interface,
732
733
cmd -> data |= RXH_IP_SRC | RXH_IP_DST ;
733
734
break ;
734
735
case UDP_V6_FLOW :
735
- if (interface -> flags & FM10K_FLAG_RSS_FIELD_IPV6_UDP )
736
+ if (test_bit (FM10K_FLAG_RSS_FIELD_IPV6_UDP ,
737
+ interface -> flags ))
736
738
cmd -> data |= RXH_L4_B_0_1 | RXH_L4_B_2_3 ;
737
739
cmd -> data |= RXH_IP_SRC | RXH_IP_DST ;
738
740
break ;
@@ -764,12 +766,13 @@ static int fm10k_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
764
766
return ret ;
765
767
}
766
768
767
- #define UDP_RSS_FLAGS (FM10K_FLAG_RSS_FIELD_IPV4_UDP | \
768
- FM10K_FLAG_RSS_FIELD_IPV6_UDP)
769
769
static int fm10k_set_rss_hash_opt (struct fm10k_intfc * interface ,
770
770
struct ethtool_rxnfc * nfc )
771
771
{
772
- u32 flags = interface -> flags ;
772
+ int rss_ipv4_udp = test_bit (FM10K_FLAG_RSS_FIELD_IPV4_UDP ,
773
+ interface -> flags );
774
+ int rss_ipv6_udp = test_bit (FM10K_FLAG_RSS_FIELD_IPV6_UDP ,
775
+ interface -> flags );
773
776
774
777
/* RSS does not support anything other than hashing
775
778
* to queues on src and dst IPs and ports
@@ -793,10 +796,12 @@ static int fm10k_set_rss_hash_opt(struct fm10k_intfc *interface,
793
796
return - EINVAL ;
794
797
switch (nfc -> data & (RXH_L4_B_0_1 | RXH_L4_B_2_3 )) {
795
798
case 0 :
796
- flags &= ~FM10K_FLAG_RSS_FIELD_IPV4_UDP ;
799
+ clear_bit (FM10K_FLAG_RSS_FIELD_IPV4_UDP ,
800
+ interface -> flags );
797
801
break ;
798
802
case (RXH_L4_B_0_1 | RXH_L4_B_2_3 ):
799
- flags |= FM10K_FLAG_RSS_FIELD_IPV4_UDP ;
803
+ set_bit (FM10K_FLAG_RSS_FIELD_IPV4_UDP ,
804
+ interface -> flags );
800
805
break ;
801
806
default :
802
807
return - EINVAL ;
@@ -808,10 +813,12 @@ static int fm10k_set_rss_hash_opt(struct fm10k_intfc *interface,
808
813
return - EINVAL ;
809
814
switch (nfc -> data & (RXH_L4_B_0_1 | RXH_L4_B_2_3 )) {
810
815
case 0 :
811
- flags &= ~FM10K_FLAG_RSS_FIELD_IPV6_UDP ;
816
+ clear_bit (FM10K_FLAG_RSS_FIELD_IPV6_UDP ,
817
+ interface -> flags );
812
818
break ;
813
819
case (RXH_L4_B_0_1 | RXH_L4_B_2_3 ):
814
- flags |= FM10K_FLAG_RSS_FIELD_IPV6_UDP ;
820
+ set_bit (FM10K_FLAG_RSS_FIELD_IPV6_UDP ,
821
+ interface -> flags );
815
822
break ;
816
823
default :
817
824
return - EINVAL ;
@@ -835,28 +842,41 @@ static int fm10k_set_rss_hash_opt(struct fm10k_intfc *interface,
835
842
return - EINVAL ;
836
843
}
837
844
838
- /* if we changed something we need to update flags */
839
- if (flags != interface -> flags ) {
845
+ /* If something changed we need to update the MRQC register. Note that
846
+ * test_bit() is guaranteed to return strictly 0 or 1, so testing for
847
+ * equality is safe.
848
+ */
849
+ if ((rss_ipv4_udp != test_bit (FM10K_FLAG_RSS_FIELD_IPV4_UDP ,
850
+ interface -> flags )) ||
851
+ (rss_ipv6_udp != test_bit (FM10K_FLAG_RSS_FIELD_IPV6_UDP ,
852
+ interface -> flags ))) {
840
853
struct fm10k_hw * hw = & interface -> hw ;
854
+ bool warn = false;
841
855
u32 mrqc ;
842
856
843
- if ((flags & UDP_RSS_FLAGS ) &&
844
- !(interface -> flags & UDP_RSS_FLAGS ))
845
- netif_warn (interface , drv , interface -> netdev ,
846
- "enabling UDP RSS: fragmented packets may arrive out of order to the stack above\n" );
847
-
848
- interface -> flags = flags ;
849
-
850
857
/* Perform hash on these packet types */
851
858
mrqc = FM10K_MRQC_IPV4 |
852
859
FM10K_MRQC_TCP_IPV4 |
853
860
FM10K_MRQC_IPV6 |
854
861
FM10K_MRQC_TCP_IPV6 ;
855
862
856
- if (flags & FM10K_FLAG_RSS_FIELD_IPV4_UDP )
863
+ if (test_bit (FM10K_FLAG_RSS_FIELD_IPV4_UDP ,
864
+ interface -> flags )) {
857
865
mrqc |= FM10K_MRQC_UDP_IPV4 ;
858
- if (flags & FM10K_FLAG_RSS_FIELD_IPV6_UDP )
866
+ warn = true;
867
+ }
868
+ if (test_bit (FM10K_FLAG_RSS_FIELD_IPV6_UDP ,
869
+ interface -> flags )) {
859
870
mrqc |= FM10K_MRQC_UDP_IPV6 ;
871
+ warn = true;
872
+ }
873
+
874
+ /* If we enable UDP RSS display a warning that this may cause
875
+ * fragmented UDP packets to arrive out of order.
876
+ */
877
+ if (warn )
878
+ netif_warn (interface , drv , interface -> netdev ,
879
+ "enabling UDP RSS: fragmented packets may arrive out of order to the stack above\n" );
860
880
861
881
fm10k_write_reg (hw , FM10K_MRQC (0 ), mrqc );
862
882
}
@@ -939,7 +959,7 @@ static void fm10k_self_test(struct net_device *dev,
939
959
940
960
memset (data , 0 , sizeof (* data ) * FM10K_TEST_LEN );
941
961
942
- if (FM10K_REMOVED (hw )) {
962
+ if (FM10K_REMOVED (hw -> hw_addr )) {
943
963
netif_err (interface , drv , dev ,
944
964
"Interface removed - test blocked\n" );
945
965
eth_test -> flags |= ETH_TEST_FL_FAILED ;
0 commit comments