net/bnxt: support action bitmap opcode
[dpdk.git] / drivers / net / i40e / i40e_fdir.c
index c346073..d59399a 100644 (file)
@@ -1007,6 +1007,36 @@ fill_ip6_head(const struct i40e_fdir_input *fdir_input, unsigned char *raw_pkt,
        return len;
 }
 
+static inline int
+fill_ip4_head(const struct i40e_fdir_input *fdir_input, unsigned char *raw_pkt,
+               uint8_t next_proto, uint8_t len, uint16_t *ether_type)
+{
+       struct rte_ipv4_hdr *ip4;
+
+       ip4 = (struct rte_ipv4_hdr *)raw_pkt;
+
+       *ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
+       ip4->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
+       /* set len to by default */
+       ip4->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
+       ip4->time_to_live = fdir_input->flow.ip4_flow.ttl ?
+               fdir_input->flow.ip4_flow.ttl :
+               I40E_FDIR_IP_DEFAULT_TTL;
+       ip4->type_of_service = fdir_input->flow.ip4_flow.tos;
+       ip4->next_proto_id = fdir_input->flow.ip4_flow.proto ?
+               fdir_input->flow.ip4_flow.proto : next_proto;
+       /**
+        * The source and destination fields in the transmitted packet
+        * need to be presented in a reversed order with respect
+        * to the expected received packets.
+        */
+       ip4->src_addr = fdir_input->flow.ip4_flow.dst_ip;
+       ip4->dst_addr = fdir_input->flow.ip4_flow.src_ip;
+       len += sizeof(struct rte_ipv4_hdr);
+
+       return len;
+}
+
 static inline int
 i40e_flow_fdir_fill_eth_ip_head(struct i40e_pf *pf,
                                const struct i40e_fdir_input *fdir_input,
@@ -1017,8 +1047,6 @@ i40e_flow_fdir_fill_eth_ip_head(struct i40e_pf *pf,
        static uint8_t vlan_frame[] = {0x81, 0, 0, 0};
        uint16_t *ether_type;
        uint8_t len = 2 * sizeof(struct rte_ether_addr);
-       struct rte_ipv4_hdr *ip;
-       struct rte_ipv6_hdr *ip6;
        uint8_t pctype = fdir_input->pctype;
        bool is_customized_pctype = fdir_input->flow_ext.customized_pctype;
        static const uint8_t next_proto[] = {
@@ -1034,7 +1062,13 @@ i40e_flow_fdir_fill_eth_ip_head(struct i40e_pf *pf,
                [I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] = IPPROTO_NONE,
        };
 
+       rte_memcpy(raw_pkt, &fdir_input->flow.l2_flow.dst,
+               sizeof(struct rte_ether_addr));
+       rte_memcpy(raw_pkt + sizeof(struct rte_ether_addr),
+               &fdir_input->flow.l2_flow.src,
+               sizeof(struct rte_ether_addr));
        raw_pkt += 2 * sizeof(struct rte_ether_addr);
+
        if (vlan && fdir_input->flow_ext.vlan_tci) {
                rte_memcpy(raw_pkt, vlan_frame, sizeof(vlan_frame));
                rte_memcpy(raw_pkt + sizeof(uint16_t),
@@ -1063,93 +1097,54 @@ i40e_flow_fdir_fill_eth_ip_head(struct i40e_pf *pf,
                 pctype == I40E_FILTER_PCTYPE_NONF_IPV4_SCTP ||
                 pctype == I40E_FILTER_PCTYPE_NONF_IPV4_OTHER ||
                 pctype == I40E_FILTER_PCTYPE_FRAG_IPV4 ||
-                ((is_customized_pctype) &&
-                 ((cus_pctype->index == I40E_CUSTOMIZED_GTPC) ||
-                  (cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV4) ||
-                  (cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV6) ||
-                  (cus_pctype->index == I40E_CUSTOMIZED_GTPU) ||
-                  (cus_pctype->index == I40E_CUSTOMIZED_IPV4_L2TPV3)))) {
-               ip = (struct rte_ipv4_hdr *)raw_pkt;
-
-               *ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
-               ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
-               /* set len to by default */
-               ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
-               ip->time_to_live = fdir_input->flow.ip4_flow.ttl ?
-                       fdir_input->flow.ip4_flow.ttl :
-                       I40E_FDIR_IP_DEFAULT_TTL;
-               ip->type_of_service = fdir_input->flow.ip4_flow.tos;
-               /**
-                * The source and destination fields in the transmitted packet
-                * need to be presented in a reversed order with respect
-                * to the expected received packets.
-                */
-               ip->src_addr = fdir_input->flow.ip4_flow.dst_ip;
-               ip->dst_addr = fdir_input->flow.ip4_flow.src_ip;
-
-               if (!is_customized_pctype) {
-                       ip->next_proto_id = fdir_input->flow.ip4_flow.proto ?
-                               fdir_input->flow.ip4_flow.proto :
-                               next_proto[fdir_input->pctype];
-                       len += sizeof(struct rte_ipv4_hdr);
+                pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP ||
+                pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP ||
+                pctype == I40E_FILTER_PCTYPE_NONF_IPV6_SCTP ||
+                pctype == I40E_FILTER_PCTYPE_NONF_IPV6_OTHER ||
+                pctype == I40E_FILTER_PCTYPE_FRAG_IPV6 ||
+                is_customized_pctype) {
+               if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_TCP ||
+                       pctype == I40E_FILTER_PCTYPE_NONF_IPV4_UDP ||
+                       pctype == I40E_FILTER_PCTYPE_NONF_IPV4_SCTP ||
+                       pctype == I40E_FILTER_PCTYPE_NONF_IPV4_OTHER ||
+                       pctype == I40E_FILTER_PCTYPE_FRAG_IPV4) {
+                       len = fill_ip4_head(fdir_input, raw_pkt,
+                                       next_proto[pctype], len, ether_type);
+               } else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP ||
+                       pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP ||
+                       pctype == I40E_FILTER_PCTYPE_NONF_IPV6_SCTP ||
+                       pctype == I40E_FILTER_PCTYPE_NONF_IPV6_OTHER ||
+                       pctype == I40E_FILTER_PCTYPE_FRAG_IPV6) {
+                       len = fill_ip6_head(fdir_input, raw_pkt,
+                                       next_proto[pctype], len,
+                                       ether_type);
                } else if (cus_pctype->index == I40E_CUSTOMIZED_GTPC ||
                         cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV4 ||
                         cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV6 ||
                         cus_pctype->index == I40E_CUSTOMIZED_GTPU) {
-                       ip->next_proto_id = IPPROTO_UDP;
-                       len += sizeof(struct rte_ipv4_hdr);
+                       len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_UDP,
+                                       len, ether_type);
                } else if (cus_pctype->index == I40E_CUSTOMIZED_IPV4_L2TPV3) {
-                       ip->next_proto_id = IPPROTO_L2TP;
-                       len += sizeof(struct rte_ipv4_hdr);
+                       len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_L2TP,
+                                       len, ether_type);
                } else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4) {
-                       ip->next_proto_id = IPPROTO_ESP;
-                       len += sizeof(struct rte_ipv4_hdr);
+                       len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_ESP,
+                                       len, ether_type);
+               } else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4_UDP) {
+                       len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_UDP,
+                                       len, ether_type);
                } else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4_UDP) {
-                       ip->next_proto_id = IPPROTO_UDP;
-                       len += sizeof(struct rte_ipv4_hdr);
+                       len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_UDP,
+                                       len, ether_type);
                } else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV6)
                        len = fill_ip6_head(fdir_input, raw_pkt, IPPROTO_ESP,
                                        len, ether_type);
                else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV6_UDP)
                        len = fill_ip6_head(fdir_input, raw_pkt, IPPROTO_UDP,
                                        len, ether_type);
-       } else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP ||
-                  pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP ||
-                  pctype == I40E_FILTER_PCTYPE_NONF_IPV6_SCTP ||
-                  pctype == I40E_FILTER_PCTYPE_NONF_IPV6_OTHER ||
-                  pctype == I40E_FILTER_PCTYPE_FRAG_IPV6 ||
-                  ((is_customized_pctype) &&
-                   (cus_pctype->index == I40E_CUSTOMIZED_IPV6_L2TPV3))) {
-               ip6 = (struct rte_ipv6_hdr *)raw_pkt;
-
-               *ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
-               ip6->vtc_flow =
-                       rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW |
-                                        (fdir_input->flow.ipv6_flow.tc <<
-                                         I40E_FDIR_IPv6_TC_OFFSET));
-               ip6->payload_len =
-                       rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN);
-               if (!is_customized_pctype)
-                       ip6->proto = fdir_input->flow.ipv6_flow.proto ?
-                               fdir_input->flow.ipv6_flow.proto :
-                               next_proto[fdir_input->pctype];
                else if (cus_pctype->index == I40E_CUSTOMIZED_IPV6_L2TPV3)
-                       ip6->proto = IPPROTO_L2TP;
-               ip6->hop_limits = fdir_input->flow.ipv6_flow.hop_limits ?
-                       fdir_input->flow.ipv6_flow.hop_limits :
-                       I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
-               /**
-                * The source and destination fields in the transmitted packet
-                * need to be presented in a reversed order with respect
-                * to the expected received packets.
-                */
-               rte_memcpy(&ip6->src_addr,
-                          &fdir_input->flow.ipv6_flow.dst_ip,
-                          IPV6_ADDR_LEN);
-               rte_memcpy(&ip6->dst_addr,
-                          &fdir_input->flow.ipv6_flow.src_ip,
-                          IPV6_ADDR_LEN);
-               len += sizeof(struct rte_ipv6_hdr);
+                       len = fill_ip6_head(fdir_input, raw_pkt, IPPROTO_L2TP,
+                                       len, ether_type);
        } else {
                PMD_DRV_LOG(ERR, "unknown pctype %u.", fdir_input->pctype);
                return -1;
@@ -1700,8 +1695,8 @@ i40e_flow_add_del_fdir_filter(struct rte_eth_dev *dev,
        struct i40e_fdir_filter check_filter; /* Check if the filter exists */
        int ret = 0;
 
-       if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_PERFECT) {
-               PMD_DRV_LOG(ERR, "FDIR is not enabled, please check the mode in fdir_conf.");
+       if (pf->fdir.fdir_vsi == NULL) {
+               PMD_DRV_LOG(ERR, "FDIR is not enabled");
                return -ENOTSUP;
        }