X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fsfc%2Fsfc_flow.c;h=e4a9ba0ff9b0cbd627c7b4b21713952fc10fd5b3;hb=d1c2f76b440a7468878d246332d9a6ebda5deb43;hp=e6b2ecff41bca1426c5581268d3714e12ed5e506;hpb=5f78af523912ec252094f93292bdf94586f4baee;p=dpdk.git diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index e6b2ecff41..e4a9ba0ff9 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -93,6 +92,8 @@ static sfc_flow_spec_check sfc_flow_check_unknown_dst_flags; static sfc_flow_spec_set_vals sfc_flow_set_ethertypes; static sfc_flow_spec_set_vals sfc_flow_set_ifrm_unknown_dst_flags; static sfc_flow_spec_check sfc_flow_check_ifrm_unknown_dst_flags; +static sfc_flow_spec_set_vals sfc_flow_set_outer_vid_flag; +static sfc_flow_spec_check sfc_flow_check_outer_vid_flag; static boolean_t sfc_flow_is_zero(const uint8_t *buf, unsigned int size) @@ -276,7 +277,7 @@ sfc_flow_parse_eth(const struct rte_flow_item *item, if (spec == NULL) return 0; - if (is_same_ether_addr(&mask->dst, &supp_mask.dst)) { + if (rte_is_same_ether_addr(&mask->dst, &supp_mask.dst)) { efx_spec->efs_match_flags |= is_ifrm ? EFX_FILTER_MATCH_IFRM_LOC_MAC : EFX_FILTER_MATCH_LOC_MAC; @@ -284,7 +285,7 @@ sfc_flow_parse_eth(const struct rte_flow_item *item, EFX_MAC_ADDR_LEN); } else if (memcmp(mask->dst.addr_bytes, ig_mask, EFX_MAC_ADDR_LEN) == 0) { - if (is_unicast_ether_addr(&spec->dst)) + if (rte_is_unicast_ether_addr(&spec->dst)) efx_spec->efs_match_flags |= is_ifrm ? EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST : EFX_FILTER_MATCH_UNKNOWN_UCAST_DST; @@ -292,7 +293,7 @@ sfc_flow_parse_eth(const struct rte_flow_item *item, efx_spec->efs_match_flags |= is_ifrm ? EFX_FILTER_MATCH_IFRM_UNKNOWN_MCAST_DST : EFX_FILTER_MATCH_UNKNOWN_MCAST_DST; - } else if (!is_zero_ether_addr(&mask->dst)) { + } else if (!rte_is_zero_ether_addr(&mask->dst)) { goto fail_bad_mask; } @@ -301,11 +302,11 @@ sfc_flow_parse_eth(const struct rte_flow_item *item, * ethertype masks are equal to zero in inner frame, * so these fields are filled in only for the outer frame */ - if (is_same_ether_addr(&mask->src, &supp_mask.src)) { + if (rte_is_same_ether_addr(&mask->src, &supp_mask.src)) { efx_spec->efs_match_flags |= EFX_FILTER_MATCH_REM_MAC; rte_memcpy(efx_spec->efs_rem_mac, spec->src.addr_bytes, EFX_MAC_ADDR_LEN); - } else if (!is_zero_ether_addr(&mask->src)) { + } else if (!rte_is_zero_ether_addr(&mask->src)) { goto fail_bad_mask; } @@ -371,7 +372,8 @@ sfc_flow_parse_vlan(const struct rte_flow_item *item, * the outer tag and the next matches the inner tag. */ if (mask->tci == supp_mask.tci) { - vid = rte_bswap16(spec->tci); + /* Apply mask to keep VID only */ + vid = rte_bswap16(spec->tci & mask->tci); if (!(efx_spec->efs_match_flags & EFX_FILTER_MATCH_OUTER_VID)) { @@ -949,7 +951,7 @@ sfc_flow_parse_geneve(const struct rte_flow_item *item, return 0; if (mask->protocol == supp_mask.protocol) { - if (spec->protocol != rte_cpu_to_be_16(ETHER_TYPE_TEB)) { + if (spec->protocol != rte_cpu_to_be_16(RTE_ETHER_TYPE_TEB)) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "GENEVE encap. protocol must be Ethernet " @@ -1238,10 +1240,10 @@ sfc_flow_parse_queue(struct sfc_adapter *sa, { struct sfc_rxq *rxq; - if (queue->index >= sa->rxq_count) + if (queue->index >= sfc_sa2shared(sa)->rxq_count) return -EINVAL; - rxq = sa->rxq_info[queue->index].rxq; + rxq = &sa->rxq_ctrl[queue->index]; flow->spec.template.efs_dmaq_id = (uint16_t)rxq->hw_index; return 0; @@ -1252,7 +1254,8 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, const struct rte_flow_action_rss *action_rss, struct rte_flow *flow) { - struct sfc_rss *rss = &sa->rss; + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + struct sfc_rss *rss = &sas->rss; unsigned int rxq_sw_index; struct sfc_rxq *rxq; unsigned int rxq_hw_index_min; @@ -1265,18 +1268,18 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, if (action_rss->queue_num == 0) return -EINVAL; - rxq_sw_index = sa->rxq_count - 1; - rxq = sa->rxq_info[rxq_sw_index].rxq; + rxq_sw_index = sfc_sa2shared(sa)->rxq_count - 1; + rxq = &sa->rxq_ctrl[rxq_sw_index]; rxq_hw_index_min = rxq->hw_index; rxq_hw_index_max = 0; for (i = 0; i < action_rss->queue_num; ++i) { rxq_sw_index = action_rss->queue[i]; - if (rxq_sw_index >= sa->rxq_count) + if (rxq_sw_index >= sfc_sa2shared(sa)->rxq_count) return -EINVAL; - rxq = sa->rxq_info[rxq_sw_index].rxq; + rxq = &sa->rxq_ctrl[rxq_sw_index]; if (rxq->hw_index < rxq_hw_index_min) rxq_hw_index_min = rxq->hw_index; @@ -1341,7 +1344,7 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, for (i = 0; i < RTE_DIM(sfc_rss_conf->rss_tbl); ++i) { unsigned int nb_queues = action_rss->queue_num; unsigned int rxq_sw_index = action_rss->queue[i % nb_queues]; - struct sfc_rxq *rxq = sa->rxq_info[rxq_sw_index].rxq; + struct sfc_rxq *rxq = &sa->rxq_ctrl[rxq_sw_index]; sfc_rss_conf->rss_tbl[i] = rxq->hw_index - rxq_hw_index_min; } @@ -1397,7 +1400,8 @@ static int sfc_flow_filter_insert(struct sfc_adapter *sa, struct rte_flow *flow) { - struct sfc_rss *rss = &sa->rss; + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + struct sfc_rss *rss = &sas->rss; struct sfc_flow_rss *flow_rss = &flow->rss_conf; uint32_t efs_rss_context = EFX_RSS_CONTEXT_DEFAULT; unsigned int i; @@ -1524,7 +1528,7 @@ sfc_flow_parse_actions(struct sfc_adapter *sa, struct rte_flow_error *error) { int rc; - const unsigned int dp_rx_features = sa->dp_rx->features; + const unsigned int dp_rx_features = sa->priv.dp_rx->features; uint32_t actions_set = 0; const uint32_t fate_actions_mask = (1UL << RTE_FLOW_ACTION_TYPE_QUEUE) | (1UL << RTE_FLOW_ACTION_TYPE_RSS) | @@ -1572,7 +1576,7 @@ sfc_flow_parse_actions(struct sfc_adapter *sa, rc = sfc_flow_parse_rss(sa, actions->conf, flow); if (rc != 0) { - rte_flow_error_set(error, rc, + rte_flow_error_set(error, -rc, RTE_FLOW_ERROR_TYPE_ACTION, actions, "Bad RSS action"); return -rte_errno; @@ -1779,6 +1783,43 @@ sfc_flow_set_ethertypes(struct sfc_flow_spec *spec, return 0; } +/** + * Set the EFX_FILTER_MATCH_OUTER_VID match flag with value 0 + * in the same specifications after copying. + * + * @param spec[in, out] + * SFC flow specification to update. + * @param filters_count_for_one_val[in] + * How many specifications should have the same match flag, what is the + * number of specifications before copying. + * @param error[out] + * Perform verbose error reporting if not NULL. + */ +static int +sfc_flow_set_outer_vid_flag(struct sfc_flow_spec *spec, + unsigned int filters_count_for_one_val, + struct rte_flow_error *error) +{ + unsigned int i; + + if (filters_count_for_one_val != spec->count) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "Number of specifications is incorrect " + "while copying by outer VLAN ID"); + return -rte_errno; + } + + for (i = 0; i < spec->count; i++) { + spec->filters[i].efs_match_flags |= + EFX_FILTER_MATCH_OUTER_VID; + + spec->filters[i].efs_outer_vid = 0; + } + + return 0; +} + /** * Set the EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST and * EFX_FILTER_MATCH_IFRM_UNKNOWN_MCAST_DST match flags in the same @@ -1858,6 +1899,36 @@ sfc_flow_check_ifrm_unknown_dst_flags(efx_filter_match_flags_t match, return B_FALSE; } +/** + * Check that the list of supported filters has a filter that differs + * from @p match in that it has no flag EFX_FILTER_MATCH_OUTER_VID + * in this case that filter will be used and the flag + * EFX_FILTER_MATCH_OUTER_VID is not needed. + * + * @param match[in] + * The match flags of filter. + * @param spec[in] + * Specification to be supplemented. + * @param filter[in] + * SFC filter with list of supported filters. + */ +static boolean_t +sfc_flow_check_outer_vid_flag(efx_filter_match_flags_t match, + __rte_unused efx_filter_spec_t *spec, + struct sfc_filter *filter) +{ + unsigned int i; + efx_filter_match_flags_t match_without_vid = + match & ~EFX_FILTER_MATCH_OUTER_VID; + + for (i = 0; i < filter->supported_match_num; i++) { + if (match_without_vid == filter->supported_match[i]) + return B_FALSE; + } + + return B_TRUE; +} + /* * Match flags that can be automatically added to filters. * Selecting the last minimum when searching for the copy flag ensures that the @@ -1885,6 +1956,12 @@ static const struct sfc_flow_copy_flag sfc_flow_copy_flags[] = { .set_vals = sfc_flow_set_ifrm_unknown_dst_flags, .spec_check = sfc_flow_check_ifrm_unknown_dst_flags, }, + { + .flag = EFX_FILTER_MATCH_OUTER_VID, + .vals_count = 1, + .set_vals = sfc_flow_set_outer_vid_flag, + .spec_check = sfc_flow_check_outer_vid_flag, + }, }; /* Get item from array sfc_flow_copy_flags */ @@ -2046,7 +2123,7 @@ sfc_flow_spec_filters_complete(struct sfc_adapter *sa, if (min_multiplier == UINT_MAX) { rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, - "Flow rule pattern is not supported"); + "The flow rule pattern is unsupported"); return -rte_errno; } @@ -2094,11 +2171,14 @@ sfc_flow_is_match_with_vids(efx_filter_match_flags_t match_flags, * Check whether the spec maps to a hardware filter which is known to be * ineffective despite being valid. * + * @param filter[in] + * SFC filter with list of supported filters. * @param spec[in] * SFC flow specification. */ static boolean_t -sfc_flow_is_match_flags_exception(struct sfc_flow_spec *spec) +sfc_flow_is_match_flags_exception(struct sfc_filter *filter, + struct sfc_flow_spec *spec) { unsigned int i; uint16_t ether_type; @@ -2114,8 +2194,9 @@ sfc_flow_is_match_flags_exception(struct sfc_flow_spec *spec) EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_LOC_MAC)) { ether_type = spec->filters[i].efs_ether_type; - if (ether_type == EFX_ETHER_TYPE_IPV4 || - ether_type == EFX_ETHER_TYPE_IPV6) + if (filter->supports_ip_proto_or_addr_filter && + (ether_type == EFX_ETHER_TYPE_IPV4 || + ether_type == EFX_ETHER_TYPE_IPV6)) return B_TRUE; } else if (sfc_flow_is_match_with_vids(match_flags, EFX_FILTER_MATCH_ETHER_TYPE | @@ -2125,8 +2206,9 @@ sfc_flow_is_match_flags_exception(struct sfc_flow_spec *spec) EFX_FILTER_MATCH_IP_PROTO | EFX_FILTER_MATCH_LOC_MAC)) { ip_proto = spec->filters[i].efs_ip_proto; - if (ip_proto == EFX_IPPROTO_TCP || - ip_proto == EFX_IPPROTO_UDP) + if (filter->supports_rem_or_local_port_filter && + (ip_proto == EFX_IPPROTO_TCP || + ip_proto == EFX_IPPROTO_UDP)) return B_TRUE; } } @@ -2153,7 +2235,7 @@ sfc_flow_validate_match_flags(struct sfc_adapter *sa, return rc; } - if (sfc_flow_is_match_flags_exception(&flow->spec)) { + if (sfc_flow_is_match_flags_exception(&sa->filter, &flow->spec)) { rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "The flow rule pattern is unsupported"); @@ -2171,7 +2253,7 @@ sfc_flow_parse(struct rte_eth_dev *dev, struct rte_flow *flow, struct rte_flow_error *error) { - struct sfc_adapter *sa = dev->data->dev_private; + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); int rc; rc = sfc_flow_parse_attr(attr, flow, error); @@ -2217,7 +2299,7 @@ sfc_flow_create(struct rte_eth_dev *dev, const struct rte_flow_action actions[], struct rte_flow_error *error) { - struct sfc_adapter *sa = dev->data->dev_private; + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); struct rte_flow *flow = NULL; int rc; @@ -2290,7 +2372,7 @@ sfc_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, struct rte_flow_error *error) { - struct sfc_adapter *sa = dev->data->dev_private; + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); struct rte_flow *flow_ptr; int rc = EINVAL; @@ -2319,7 +2401,7 @@ static int sfc_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error) { - struct sfc_adapter *sa = dev->data->dev_private; + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); struct rte_flow *flow; int rc = 0; int ret = 0; @@ -2341,8 +2423,7 @@ static int sfc_flow_isolate(struct rte_eth_dev *dev, int enable, struct rte_flow_error *error) { - struct sfc_adapter *sa = dev->data->dev_private; - struct sfc_port *port = &sa->port; + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); int ret = 0; sfc_adapter_lock(sa); @@ -2352,7 +2433,7 @@ sfc_flow_isolate(struct rte_eth_dev *dev, int enable, NULL, "please close the port first"); ret = -rte_errno; } else { - port->isolated = (enable) ? B_TRUE : B_FALSE; + sfc_sa2shared(sa)->isolated = (enable) ? B_TRUE : B_FALSE; } sfc_adapter_unlock(sa);