-
- if (!vlan_flag) {
- o_vlan_spec = vlan_spec;
- o_vlan_mask = vlan_mask;
- vlan_flag = 1;
- } else {
- i_vlan_spec = vlan_spec;
- i_vlan_mask = vlan_mask;
- vlan_flag = 0;
- }
- break;
-
- default:
- break;
- }
- }
-
- /* Get filter specification */
- if ((o_vlan_mask != NULL) && (o_vlan_mask->tci ==
- rte_cpu_to_be_16(I40E_TCI_MASK)) &&
- (i_vlan_mask != NULL) &&
- (i_vlan_mask->tci == rte_cpu_to_be_16(I40E_TCI_MASK))) {
- filter->outer_vlan = rte_be_to_cpu_16(o_vlan_spec->tci)
- & I40E_TCI_MASK;
- filter->inner_vlan = rte_be_to_cpu_16(i_vlan_spec->tci)
- & I40E_TCI_MASK;
- } else {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ITEM,
- NULL,
- "Invalid filter type");
- return -rte_errno;
- }
-
- filter->tunnel_type = I40E_TUNNEL_TYPE_QINQ;
- return 0;
-}
-
-static int
-i40e_flow_parse_qinq_filter(struct rte_eth_dev *dev,
- const struct rte_flow_attr *attr,
- const struct rte_flow_item pattern[],
- const struct rte_flow_action actions[],
- struct rte_flow_error *error,
- union i40e_filter_t *filter)
-{
- struct i40e_tunnel_filter_conf *tunnel_filter =
- &filter->consistent_tunnel_filter;
- int ret;
-
- ret = i40e_flow_parse_qinq_pattern(dev, pattern,
- error, tunnel_filter);
- if (ret)
- return ret;
-
- ret = i40e_flow_parse_tunnel_action(dev, actions, error, tunnel_filter);
- if (ret)
- return ret;
-
- ret = i40e_flow_parse_attr(attr, error);
- if (ret)
- return ret;
-
- cons_filter_type = RTE_ETH_FILTER_TUNNEL;
-
- return ret;
-}
-
-/**
- * This function is used to do configuration i40e existing RSS with rte_flow.
- * It also enable queue region configuration using flow API for i40e.
- * pattern can be used indicate what parameters will be include in flow,
- * like user_priority or flowtype for queue region or HASH function for RSS.
- * Action is used to transmit parameter like queue index and HASH
- * function for RSS, or flowtype for queue region configuration.
- * For example:
- * pattern:
- * Case 1: try to transform patterns to pctype. valid pctype will be
- * used in parse action.
- * Case 2: only ETH, indicate flowtype for queue region will be parsed.
- * Case 3: only VLAN, indicate user_priority for queue region will be parsed.
- * So, pattern choice is depened on the purpose of configuration of
- * that flow.
- * action:
- * action RSS will be used to transmit valid parameter with
- * struct rte_flow_action_rss for all the 3 case.
- */
-static int
-i40e_flow_parse_rss_pattern(__rte_unused struct rte_eth_dev *dev,
- const struct rte_flow_item *pattern,
- struct rte_flow_error *error,
- struct i40e_rss_pattern_info *p_info,
- struct i40e_queue_regions *info)
-{
- const struct rte_flow_item_vlan *vlan_spec, *vlan_mask;
- const struct rte_flow_item *item = pattern;
- enum rte_flow_item_type item_type;
- struct rte_flow_item *items;
- uint32_t item_num = 0; /* non-void item number of pattern*/
- uint32_t i = 0;
- static const struct {
- enum rte_flow_item_type *item_array;
- uint64_t type;
- } i40e_rss_pctype_patterns[] = {
- { pattern_fdir_ipv4,
- ETH_RSS_FRAG_IPV4 | ETH_RSS_NONFRAG_IPV4_OTHER },
- { pattern_fdir_ipv4_tcp, ETH_RSS_NONFRAG_IPV4_TCP },
- { pattern_fdir_ipv4_udp, ETH_RSS_NONFRAG_IPV4_UDP },
- { pattern_fdir_ipv4_sctp, ETH_RSS_NONFRAG_IPV4_SCTP },
- { pattern_fdir_ipv4_esp, ETH_RSS_ESP },
- { pattern_fdir_ipv4_udp_esp, ETH_RSS_ESP },
- { pattern_fdir_ipv6,
- ETH_RSS_FRAG_IPV6 | ETH_RSS_NONFRAG_IPV6_OTHER },
- { pattern_fdir_ipv6_tcp, ETH_RSS_NONFRAG_IPV6_TCP },
- { pattern_fdir_ipv6_udp, ETH_RSS_NONFRAG_IPV6_UDP },
- { pattern_fdir_ipv6_sctp, ETH_RSS_NONFRAG_IPV6_SCTP },
- { pattern_fdir_ipv6_esp, ETH_RSS_ESP },
- { pattern_fdir_ipv6_udp_esp, ETH_RSS_ESP },
- };
-
- p_info->types = I40E_RSS_TYPE_INVALID;
-
- if (item->type == RTE_FLOW_ITEM_TYPE_END) {
- p_info->types = I40E_RSS_TYPE_NONE;
- return 0;
- }
-
- /* Convert pattern to RSS offload types */
- while ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_END) {
- if ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_VOID)
- item_num++;
- i++;
- }
- item_num++;
-
- items = rte_zmalloc("i40e_pattern",
- item_num * sizeof(struct rte_flow_item), 0);
- if (!items) {
- rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
- NULL, "No memory for PMD internal items.");
- return -ENOMEM;
- }
-
- i40e_pattern_skip_void_item(items, pattern);
-
- for (i = 0; i < RTE_DIM(i40e_rss_pctype_patterns); i++) {
- if (i40e_match_pattern(i40e_rss_pctype_patterns[i].item_array,
- items)) {
- p_info->types = i40e_rss_pctype_patterns[i].type;
- rte_free(items);
- return 0;
- }
- }
-
- rte_free(items);
-
- for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
- if (item->last) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ITEM,
- item,
- "Not support range");
- return -rte_errno;
- }
- item_type = item->type;
- switch (item_type) {
- case RTE_FLOW_ITEM_TYPE_ETH:
- p_info->action_flag = 1;
- break;
- case RTE_FLOW_ITEM_TYPE_VLAN:
- vlan_spec = item->spec;
- vlan_mask = item->mask;
- if (vlan_spec && vlan_mask) {
- if (vlan_mask->tci ==
- rte_cpu_to_be_16(I40E_TCI_MASK)) {
- info->region[0].user_priority[0] =
- (rte_be_to_cpu_16(
- vlan_spec->tci) >> 13) & 0x7;
- info->region[0].user_priority_num = 1;
- info->queue_region_number = 1;
- p_info->action_flag = 0;
- }
- }