net/ionic: make minor refactorings
[dpdk.git] / drivers / net / iavf / iavf_hash.c
index 4b7f4a8..c4c73e6 100644 (file)
@@ -101,11 +101,23 @@ iavf_hash_parse_pattern_action(struct iavf_adapter *ad,
        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | \
        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST), {BUFF_NOUSED} }
 
+#define proto_hdr_ipv4_with_prot { \
+       VIRTCHNL_PROTO_HDR_IPV4, \
+       FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | \
+       FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) | \
+       FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), {BUFF_NOUSED} }
+
 #define proto_hdr_ipv6 { \
        VIRTCHNL_PROTO_HDR_IPV6, \
        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | \
        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST), {BUFF_NOUSED} }
 
+#define proto_hdr_ipv6_with_prot { \
+       VIRTCHNL_PROTO_HDR_IPV6, \
+       FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | \
+       FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) | \
+       FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), {BUFF_NOUSED} }
+
 #define proto_hdr_udp { \
        VIRTCHNL_PROTO_HDR_UDP, \
        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT) | \
@@ -151,13 +163,15 @@ struct virtchnl_proto_hdrs outer_ipv4_tmplt = {
 
 struct virtchnl_proto_hdrs outer_ipv4_udp_tmplt = {
        TUNNEL_LEVEL_OUTER, 5,
-       {proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan, proto_hdr_ipv4,
+       {proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan,
+        proto_hdr_ipv4_with_prot,
         proto_hdr_udp}
 };
 
 struct virtchnl_proto_hdrs outer_ipv4_tcp_tmplt = {
        TUNNEL_LEVEL_OUTER, 5,
-       {proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan, proto_hdr_ipv4,
+       {proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan,
+        proto_hdr_ipv4_with_prot,
         proto_hdr_tcp}
 };
 
@@ -174,13 +188,15 @@ struct virtchnl_proto_hdrs outer_ipv6_tmplt = {
 
 struct virtchnl_proto_hdrs outer_ipv6_udp_tmplt = {
        TUNNEL_LEVEL_OUTER, 5,
-       {proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan, proto_hdr_ipv6,
+       {proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan,
+        proto_hdr_ipv6_with_prot,
         proto_hdr_udp}
 };
 
 struct virtchnl_proto_hdrs outer_ipv6_tcp_tmplt = {
        TUNNEL_LEVEL_OUTER, 5,
-       {proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan, proto_hdr_ipv6,
+       {proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan,
+        proto_hdr_ipv6_with_prot,
         proto_hdr_tcp}
 };
 
@@ -195,11 +211,11 @@ struct virtchnl_proto_hdrs inner_ipv4_tmplt = {
 };
 
 struct virtchnl_proto_hdrs inner_ipv4_udp_tmplt = {
-       TUNNEL_LEVEL_INNER, 2, {proto_hdr_ipv4, proto_hdr_udp}
+       TUNNEL_LEVEL_INNER, 2, {proto_hdr_ipv4_with_prot, proto_hdr_udp}
 };
 
 struct virtchnl_proto_hdrs inner_ipv4_tcp_tmplt = {
-       TUNNEL_LEVEL_INNER, 2, {proto_hdr_ipv4, proto_hdr_tcp}
+       TUNNEL_LEVEL_INNER, 2, {proto_hdr_ipv4_with_prot, proto_hdr_tcp}
 };
 
 struct virtchnl_proto_hdrs inner_ipv4_sctp_tmplt = {
@@ -211,11 +227,11 @@ struct virtchnl_proto_hdrs inner_ipv6_tmplt = {
 };
 
 struct virtchnl_proto_hdrs inner_ipv6_udp_tmplt = {
-       TUNNEL_LEVEL_INNER, 2, {proto_hdr_ipv6, proto_hdr_udp}
+       TUNNEL_LEVEL_INNER, 2, {proto_hdr_ipv6_with_prot, proto_hdr_udp}
 };
 
 struct virtchnl_proto_hdrs inner_ipv6_tcp_tmplt = {
-       TUNNEL_LEVEL_INNER, 2, {proto_hdr_ipv6, proto_hdr_tcp}
+       TUNNEL_LEVEL_INNER, 2, {proto_hdr_ipv6_with_prot, proto_hdr_tcp}
 };
 
 struct virtchnl_proto_hdrs inner_ipv6_sctp_tmplt = {
@@ -581,14 +597,16 @@ iavf_refine_proto_hdrs_l234(struct virtchnl_proto_hdrs *proto_hdrs,
                             ETH_RSS_NONFRAG_IPV4_UDP |
                             ETH_RSS_NONFRAG_IPV4_TCP |
                             ETH_RSS_NONFRAG_IPV4_SCTP)) {
-                               if (rss_type & ETH_RSS_L3_SRC_ONLY)
+                               if (rss_type & ETH_RSS_L3_SRC_ONLY) {
                                        REFINE_PROTO_FLD(DEL, IPV4_DST);
-                               else if (rss_type & ETH_RSS_L3_DST_ONLY)
+                               } else if (rss_type & ETH_RSS_L3_DST_ONLY) {
                                        REFINE_PROTO_FLD(DEL, IPV4_SRC);
-                               else if (rss_type &
+                               else if (rss_type &
                                         (ETH_RSS_L4_SRC_ONLY |
-                                         ETH_RSS_L4_DST_ONLY))
-                                       hdr->field_selector = 0;
+                                         ETH_RSS_L4_DST_ONLY)) {
+                                       REFINE_PROTO_FLD(DEL, IPV4_DST);
+                                       REFINE_PROTO_FLD(DEL, IPV4_SRC);
+                               }
                        } else {
                                hdr->field_selector = 0;
                        }
@@ -599,14 +617,16 @@ iavf_refine_proto_hdrs_l234(struct virtchnl_proto_hdrs *proto_hdrs,
                             ETH_RSS_NONFRAG_IPV6_UDP |
                             ETH_RSS_NONFRAG_IPV6_TCP |
                             ETH_RSS_NONFRAG_IPV6_SCTP)) {
-                               if (rss_type & ETH_RSS_L3_SRC_ONLY)
+                               if (rss_type & ETH_RSS_L3_SRC_ONLY) {
                                        REFINE_PROTO_FLD(DEL, IPV6_DST);
-                               else if (rss_type & ETH_RSS_L3_DST_ONLY)
+                               } else if (rss_type & ETH_RSS_L3_DST_ONLY) {
                                        REFINE_PROTO_FLD(DEL, IPV6_SRC);
-                               else if (rss_type &
+                               else if (rss_type &
                                         (ETH_RSS_L4_SRC_ONLY |
-                                         ETH_RSS_L4_DST_ONLY))
-                                       hdr->field_selector = 0;
+                                         ETH_RSS_L4_DST_ONLY)) {
+                                       REFINE_PROTO_FLD(DEL, IPV6_DST);
+                                       REFINE_PROTO_FLD(DEL, IPV6_SRC);
+                               }
                        } else {
                                hdr->field_selector = 0;
                        }
@@ -834,10 +854,21 @@ static struct rss_attr_type rss_attr_to_valid_type[] = {
 };
 
 static bool
-iavf_any_invalid_rss_type(uint64_t rss_type, uint64_t allow_rss_type)
+iavf_any_invalid_rss_type(enum rte_eth_hash_function rss_func,
+                         uint64_t rss_type, uint64_t allow_rss_type)
 {
        uint32_t i;
 
+       /**
+        * Check if l3/l4 SRC/DST_ONLY is set for SYMMETRIC_TOEPLITZ
+        * hash function.
+        */
+       if (rss_func == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) {
+               if (rss_type & (ETH_RSS_L3_SRC_ONLY | ETH_RSS_L3_DST_ONLY |
+                   ETH_RSS_L4_SRC_ONLY | ETH_RSS_L4_DST_ONLY))
+                       return true;
+       }
+
        /* check invalid combination */
        for (i = 0; i < RTE_DIM(invalid_rss_comb); i++) {
                if (__builtin_popcountll(rss_type & invalid_rss_comb[i]) > 1)
@@ -917,7 +948,7 @@ iavf_hash_parse_action(struct iavf_pattern_match_item *match_item,
                         */
                        rss_type = rte_eth_rss_hf_refine(rss_type);
 
-                       if (iavf_any_invalid_rss_type(rss_type,
+                       if (iavf_any_invalid_rss_type(rss->func, rss_type,
                                        match_item->input_set_mask))
                                return rte_flow_error_set(error, ENOTSUP,
                                                RTE_FLOW_ERROR_TYPE_ACTION,
@@ -1034,9 +1065,13 @@ iavf_hash_destroy(__rte_unused struct iavf_adapter *ad,
                  struct rte_flow *flow,
                  __rte_unused struct rte_flow_error *error)
 {
+       struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
        struct virtchnl_rss_cfg *rss_cfg;
        int ret = 0;
 
+       if (vf->vf_reset)
+               return 0;
+
        rss_cfg = (struct virtchnl_rss_cfg *)flow->rule;
 
        ret = iavf_add_del_rss_cfg(ad, rss_cfg, false);
@@ -1058,6 +1093,12 @@ iavf_hash_uninit(struct iavf_adapter *ad)
        if (vf->vf_reset)
                return;
 
+       if (!vf->vf_res)
+               return;
+
+       if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF))
+               return;
+
        if (iavf_hash_default_set(ad, false))
                PMD_DRV_LOG(ERR, "fail to delete default RSS");