X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fhns3%2Fhns3_flow.c;h=a016857aa5db2a048300304328495896840a71fd;hb=cb082f598568dd1522881111193166d4d2bbc929;hp=889fa2f521269d381f0d120d2aed5343f918b70e;hpb=0867543f8285c43b520045614e66eb0ed93e046b;p=dpdk.git diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c index 889fa2f521..a016857aa5 100644 --- a/drivers/net/hns3/hns3_flow.c +++ b/drivers/net/hns3/hns3_flow.c @@ -44,8 +44,7 @@ static enum rte_flow_item_type first_items[] = { RTE_FLOW_ITEM_TYPE_NVGRE, RTE_FLOW_ITEM_TYPE_VXLAN, RTE_FLOW_ITEM_TYPE_GENEVE, - RTE_FLOW_ITEM_TYPE_VXLAN_GPE, - RTE_FLOW_ITEM_TYPE_MPLS + RTE_FLOW_ITEM_TYPE_VXLAN_GPE }; static enum rte_flow_item_type L2_next_items[] = { @@ -65,8 +64,7 @@ static enum rte_flow_item_type L3_next_items[] = { static enum rte_flow_item_type L4_next_items[] = { RTE_FLOW_ITEM_TYPE_VXLAN, RTE_FLOW_ITEM_TYPE_GENEVE, - RTE_FLOW_ITEM_TYPE_VXLAN_GPE, - RTE_FLOW_ITEM_TYPE_MPLS + RTE_FLOW_ITEM_TYPE_VXLAN_GPE }; static enum rte_flow_item_type tunnel_next_items[] = { @@ -91,9 +89,9 @@ net_addr_to_host(uint32_t *dst, const rte_be32_t *src, size_t len) /* * This function is used to find rss general action. * 1. As we know RSS is used to spread packets among several queues, the flow - * API provide the struct rte_flow_action_rss, user could config it's field + * API provide the struct rte_flow_action_rss, user could config its field * sush as: func/level/types/key/queue to control RSS function. - * 2. The flow API also support queue region configuration for hns3. It was + * 2. The flow API also supports queue region configuration for hns3. It was * implemented by FDIR + RSS in hns3 hardware, user can create one FDIR rule * which action is RSS queues region. * 3. When action is RSS, we use the following rule to distinguish: @@ -128,11 +126,11 @@ hns3_find_rss_general_action(const struct rte_flow_item pattern[], rss = act->conf; if (have_eth && rss->conf.queue_num) { /* - * Patter have ETH and action's queue_num > 0, indicate this is + * Pattern have ETH and action's queue_num > 0, indicate this is * queue region configuration. * Because queue region is implemented by FDIR + RSS in hns3 - * hardware, it need enter FDIR process, so here return NULL to - * avoid enter RSS process. + * hardware, it needs to enter FDIR process, so here return NULL + * to avoid enter RSS process. */ return NULL; } @@ -405,7 +403,6 @@ hns3_handle_actions(struct rte_eth_dev *dev, return 0; } -/* Parse to get the attr and action info of flow director rule. */ static int hns3_check_attr(const struct rte_flow_attr *attr, struct rte_flow_error *error) { @@ -433,17 +430,12 @@ hns3_check_attr(const struct rte_flow_attr *attr, struct rte_flow_error *error) } static int -hns3_parse_eth(const struct rte_flow_item *item, - struct hns3_fdir_rule *rule, struct rte_flow_error *error) +hns3_parse_eth(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + struct rte_flow_error *error __rte_unused) { const struct rte_flow_item_eth *eth_spec; const struct rte_flow_item_eth *eth_mask; - if (item->spec == NULL && item->mask) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, - "Can't configure FDIR with mask but without spec"); - /* Only used to describe the protocol stack. */ if (item->spec == NULL && item->mask == NULL) return 0; @@ -483,11 +475,6 @@ hns3_parse_vlan(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, const struct rte_flow_item_vlan *vlan_spec; const struct rte_flow_item_vlan *vlan_mask; - if (item->spec == NULL && item->mask) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, - "Can't configure FDIR with mask but without spec"); - rule->key_conf.vlan_num++; if (rule->key_conf.vlan_num > VLAN_TAG_NUM_MAX) return rte_flow_error_set(error, EINVAL, @@ -543,14 +530,10 @@ hns3_parse_ipv4(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, const struct rte_flow_item_ipv4 *ipv4_spec; const struct rte_flow_item_ipv4 *ipv4_mask; - if (item->spec == NULL && item->mask) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, - "Can't configure FDIR with mask but without spec"); - hns3_set_bit(rule->input_set, INNER_ETH_TYPE, 1); rule->key_conf.spec.ether_type = RTE_ETHER_TYPE_IPV4; rule->key_conf.mask.ether_type = ETHER_TYPE_MASK; + /* Only used to describe the protocol stack. */ if (item->spec == NULL && item->mask == NULL) return 0; @@ -606,11 +589,6 @@ hns3_parse_ipv6(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, const struct rte_flow_item_ipv6 *ipv6_spec; const struct rte_flow_item_ipv6 *ipv6_mask; - if (item->spec == NULL && item->mask) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, - "Can't configure FDIR with mask but without spec"); - hns3_set_bit(rule->input_set, INNER_ETH_TYPE, 1); rule->key_conf.spec.ether_type = RTE_ETHER_TYPE_IPV6; rule->key_conf.mask.ether_type = ETHER_TYPE_MASK; @@ -674,11 +652,6 @@ hns3_parse_tcp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, const struct rte_flow_item_tcp *tcp_spec; const struct rte_flow_item_tcp *tcp_mask; - if (item->spec == NULL && item->mask) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, - "Can't configure FDIR with mask but without spec"); - hns3_set_bit(rule->input_set, INNER_IP_PROTO, 1); rule->key_conf.spec.ip_proto = IPPROTO_TCP; rule->key_conf.mask.ip_proto = IPPROTO_MASK; @@ -722,14 +695,10 @@ hns3_parse_udp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, const struct rte_flow_item_udp *udp_spec; const struct rte_flow_item_udp *udp_mask; - if (item->spec == NULL && item->mask) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, - "Can't configure FDIR with mask but without spec"); - hns3_set_bit(rule->input_set, INNER_IP_PROTO, 1); rule->key_conf.spec.ip_proto = IPPROTO_UDP; rule->key_conf.mask.ip_proto = IPPROTO_MASK; + /* Only used to describe the protocol stack. */ if (item->spec == NULL && item->mask == NULL) return 0; @@ -768,11 +737,6 @@ hns3_parse_sctp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, const struct rte_flow_item_sctp *sctp_spec; const struct rte_flow_item_sctp *sctp_mask; - if (item->spec == NULL && item->mask) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, - "Can't configure FDIR with mask but without spec"); - hns3_set_bit(rule->input_set, INNER_IP_PROTO, 1); rule->key_conf.spec.ip_proto = IPPROTO_SCTP; rule->key_conf.mask.ip_proto = IPPROTO_MASK; @@ -816,7 +780,7 @@ hns3_parse_sctp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, } /* - * Check items before tunnel, save inner configs to outer configs,and clear + * Check items before tunnel, save inner configs to outer configs, and clear * inner configs. * The key consists of two parts: meta_data and tuple keys. * Meta data uses 15 bits, including vlan_num(2bit), des_port(12bit) and tunnel @@ -904,15 +868,6 @@ hns3_parse_vxlan(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, const struct rte_flow_item_vxlan *vxlan_spec; const struct rte_flow_item_vxlan *vxlan_mask; - if (item->spec == NULL && item->mask) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, - "Can't configure FDIR with mask but without spec"); - else if (item->spec && (item->mask == NULL)) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, - "Tunnel packets must configure with mask"); - hns3_set_bit(rule->input_set, OUTER_DST_PORT, 1); rule->key_conf.mask.tunnel_type = TUNNEL_TYPE_MASK; if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN) @@ -955,15 +910,6 @@ hns3_parse_nvgre(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, const struct rte_flow_item_nvgre *nvgre_spec; const struct rte_flow_item_nvgre *nvgre_mask; - if (item->spec == NULL && item->mask) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, - "Can't configure FDIR with mask but without spec"); - else if (item->spec && (item->mask == NULL)) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, - "Tunnel packets must configure with mask"); - hns3_set_bit(rule->input_set, OUTER_IP_PROTO, 1); rule->key_conf.spec.outer_proto = IPPROTO_GRE; rule->key_conf.mask.outer_proto = IPPROTO_MASK; @@ -1013,15 +959,6 @@ hns3_parse_geneve(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, const struct rte_flow_item_geneve *geneve_spec; const struct rte_flow_item_geneve *geneve_mask; - if (item->spec == NULL && item->mask) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, - "Can't configure FDIR with mask but without spec"); - else if (item->spec && (item->mask == NULL)) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, - "Tunnel packets must configure with mask"); - hns3_set_bit(rule->input_set, OUTER_DST_PORT, 1); rule->key_conf.spec.tunnel_type = HNS3_TUNNEL_TYPE_GENEVE; rule->key_conf.mask.tunnel_type = TUNNEL_TYPE_MASK; @@ -1058,6 +995,17 @@ hns3_parse_tunnel(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, { int ret; + if (item->spec == NULL && item->mask) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Can't configure FDIR with mask " + "but without spec"); + else if (item->spec && (item->mask == NULL)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Tunnel packets must configure " + "with mask"); + switch (item->type) { case RTE_FLOW_ITEM_TYPE_VXLAN: case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: @@ -1086,6 +1034,12 @@ hns3_parse_normal(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, { int ret; + if (item->spec == NULL && item->mask) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Can't configure FDIR with mask " + "but without spec"); + switch (item->type) { case RTE_FLOW_ITEM_TYPE_ETH: ret = hns3_parse_eth(item, rule, error); @@ -1162,8 +1116,7 @@ is_tunnel_packet(enum rte_flow_item_type type) if (type == RTE_FLOW_ITEM_TYPE_VXLAN_GPE || type == RTE_FLOW_ITEM_TYPE_VXLAN || type == RTE_FLOW_ITEM_TYPE_NVGRE || - type == RTE_FLOW_ITEM_TYPE_GENEVE || - type == RTE_FLOW_ITEM_TYPE_MPLS) + type == RTE_FLOW_ITEM_TYPE_GENEVE) return true; return false; } @@ -1309,7 +1262,7 @@ hns3_action_rss_same(const struct rte_flow_action_rss *comp, if (comp->func == RTE_ETH_HASH_FUNCTION_MAX) func_is_same = false; else - func_is_same = (with->func ? (comp->func == with->func) : true); + func_is_same = with->func ? (comp->func == with->func) : true; return (func_is_same && comp->types == (with->types & HNS3_ETH_RSS_SUPPORT) && @@ -1491,7 +1444,7 @@ hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function *func, *hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP; break; default: - hns3_err(hw, "Invalid RSS algorithm configuration(%u)", + hns3_err(hw, "Invalid RSS algorithm configuration(%d)", algo_func); return -EINVAL; } @@ -1513,14 +1466,12 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config) if (ret) return ret; - ret = hns3_set_rss_algo_key(hw, rss_config->key); + ret = hns3_rss_set_algo_key(hw, rss_config->key); if (ret) return ret; - /* Update algorithm of hw */ hw->rss_info.conf.func = rss_config->func; - /* Set flow type supported */ tuple = &hw->rss_info.rss_tuple_sets; ret = hns3_set_rss_tuple_by_rss_hf(hw, tuple, rss_config->types); if (ret) @@ -1535,14 +1486,14 @@ hns3_update_indir_table(struct rte_eth_dev *dev, { struct hns3_adapter *hns = dev->data->dev_private; struct hns3_hw *hw = &hns->hw; - uint16_t indir_tbl[HNS3_RSS_IND_TBL_SIZE]; + uint16_t indir_tbl[HNS3_RSS_IND_TBL_SIZE_MAX]; uint16_t j; uint32_t i; /* Fill in redirection table */ memcpy(indir_tbl, hw->rss_info.rss_indirection_tbl, sizeof(hw->rss_info.rss_indirection_tbl)); - for (i = 0, j = 0; i < HNS3_RSS_IND_TBL_SIZE; i++, j++) { + for (i = 0, j = 0; i < hw->rss_ind_tbl_size; i++, j++) { j %= num; if (conf->queue[j] >= hw->alloc_rss_size) { hns3_err(hw, "queue id(%u) set to redirection table " @@ -1553,7 +1504,7 @@ hns3_update_indir_table(struct rte_eth_dev *dev, indir_tbl[i] = conf->queue[j]; } - return hns3_set_rss_indir_table(hw, indir_tbl, HNS3_RSS_IND_TBL_SIZE); + return hns3_set_rss_indir_table(hw, indir_tbl, hw->rss_ind_tbl_size); } static int @@ -1605,7 +1556,7 @@ hns3_config_rss_filter(struct rte_eth_dev *dev, if (rss_flow_conf.queue_num) { /* * Due the content of queue pointer have been reset to - * 0, the rss_info->conf.queue should be set NULL + * 0, the rss_info->conf.queue should be set to NULL */ rss_info->conf.queue = NULL; rss_info->conf.queue_num = 0; @@ -1771,7 +1722,7 @@ hns3_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, /* * Create or destroy a flow rule. * Theorically one rule can match more than one filters. - * We will let it use the filter which it hitt first. + * We will let it use the filter which it hit first. * So, the sequence matters. */ static struct rte_flow * @@ -1855,17 +1806,18 @@ hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, flow->counter_id = fdir_rule.act_cnt.id; } + + fdir_rule_ptr = rte_zmalloc("hns3 fdir rule", + sizeof(struct hns3_fdir_rule_ele), + 0); + if (fdir_rule_ptr == NULL) { + hns3_err(hw, "failed to allocate fdir_rule memory."); + ret = -ENOMEM; + goto err_fdir; + } + ret = hns3_fdir_filter_program(hns, &fdir_rule, false); if (!ret) { - fdir_rule_ptr = rte_zmalloc("hns3 fdir rule", - sizeof(struct hns3_fdir_rule_ele), - 0); - if (fdir_rule_ptr == NULL) { - hns3_err(hw, "Failed to allocate fdir_rule memory"); - ret = -ENOMEM; - goto err_fdir; - } - memcpy(&fdir_rule_ptr->fdir_conf, &fdir_rule, sizeof(struct hns3_fdir_rule)); TAILQ_INSERT_TAIL(&process_list->fdir_list, @@ -1876,10 +1828,10 @@ hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, return flow; } + rte_free(fdir_rule_ptr); err_fdir: if (fdir_rule.flags & HNS3_RULE_FLAG_COUNTER) hns3_counter_release(dev, fdir_rule.act_cnt.id); - err: rte_flow_error_set(error, -ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "Failed to create flow"); @@ -1908,6 +1860,7 @@ hns3_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, flow, "Flow is NULL"); + filter_type = flow->filter_type; switch (filter_type) { case RTE_ETH_FILTER_FDIR: