X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fsfc%2Fsfc_mae.c;h=6a1385283b578548f2cbbe586320b9ac6698ea44;hb=2f577f0ea1a3;hp=ca91627d2fb483659f98be4731ea74cd003a6bee;hpb=0ead09838370e2813ed2aaa54c94d0d2c2011b94;p=dpdk.git diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c index ca91627d2f..6a1385283b 100644 --- a/drivers/net/sfc/sfc_mae.c +++ b/drivers/net/sfc/sfc_mae.c @@ -197,23 +197,25 @@ sfc_mae_attach(struct sfc_adapter *sa) return 0; } - sfc_log_init(sa, "init MAE"); - rc = efx_mae_init(sa->nic); - if (rc != 0) - goto fail_mae_init; + if (encp->enc_mae_admin) { + sfc_log_init(sa, "init MAE"); + rc = efx_mae_init(sa->nic); + if (rc != 0) + goto fail_mae_init; - sfc_log_init(sa, "get MAE limits"); - rc = efx_mae_get_limits(sa->nic, &limits); - if (rc != 0) - goto fail_mae_get_limits; + sfc_log_init(sa, "get MAE limits"); + rc = efx_mae_get_limits(sa->nic, &limits); + if (rc != 0) + goto fail_mae_get_limits; - sfc_log_init(sa, "init MAE counter registry"); - rc = sfc_mae_counter_registry_init(&mae->counter_registry, - limits.eml_max_n_counters); - if (rc != 0) { - sfc_err(sa, "failed to init MAE counters registry for %u entries: %s", - limits.eml_max_n_counters, rte_strerror(rc)); - goto fail_counter_registry_init; + sfc_log_init(sa, "init MAE counter registry"); + rc = sfc_mae_counter_registry_init(&mae->counter_registry, + limits.eml_max_n_counters); + if (rc != 0) { + sfc_err(sa, "failed to init MAE counters registry for %u entries: %s", + limits.eml_max_n_counters, rte_strerror(rc)); + goto fail_counter_registry_init; + } } sfc_log_init(sa, "assign entity MPORT"); @@ -238,21 +240,28 @@ sfc_mae_attach(struct sfc_adapter *sa) if (rc != 0) goto fail_mae_assign_switch_port; - sfc_log_init(sa, "allocate encap. header bounce buffer"); - bounce_eh->buf_size = limits.eml_encap_header_size_limit; - bounce_eh->buf = rte_malloc("sfc_mae_bounce_eh", - bounce_eh->buf_size, 0); - if (bounce_eh->buf == NULL) - goto fail_mae_alloc_bounce_eh; - - mae->status = SFC_MAE_STATUS_SUPPORTED; - mae->nb_outer_rule_prios_max = limits.eml_max_n_outer_prios; - mae->nb_action_rule_prios_max = limits.eml_max_n_action_prios; - mae->encap_types_supported = limits.eml_encap_types_supported; + if (encp->enc_mae_admin) { + sfc_log_init(sa, "allocate encap. header bounce buffer"); + bounce_eh->buf_size = limits.eml_encap_header_size_limit; + bounce_eh->buf = rte_malloc("sfc_mae_bounce_eh", + bounce_eh->buf_size, 0); + if (bounce_eh->buf == NULL) + goto fail_mae_alloc_bounce_eh; + + mae->nb_outer_rule_prios_max = limits.eml_max_n_outer_prios; + mae->nb_action_rule_prios_max = limits.eml_max_n_action_prios; + mae->encap_types_supported = limits.eml_encap_types_supported; + } + TAILQ_INIT(&mae->outer_rules); TAILQ_INIT(&mae->encap_headers); TAILQ_INIT(&mae->action_sets); + if (encp->enc_mae_admin) + mae->status = SFC_MAE_STATUS_ADMIN; + else + mae->status = SFC_MAE_STATUS_SUPPORTED; + sfc_log_init(sa, "done"); return 0; @@ -261,11 +270,13 @@ fail_mae_alloc_bounce_eh: fail_mae_assign_switch_port: fail_mae_assign_switch_domain: fail_mae_assign_entity_mport: - sfc_mae_counter_registry_fini(&mae->counter_registry); + if (encp->enc_mae_admin) + sfc_mae_counter_registry_fini(&mae->counter_registry); fail_counter_registry_init: fail_mae_get_limits: - efx_mae_fini(sa->nic); + if (encp->enc_mae_admin) + efx_mae_fini(sa->nic); fail_mae_init: sfc_log_init(sa, "failed %d", rc); @@ -284,7 +295,7 @@ sfc_mae_detach(struct sfc_adapter *sa) mae->nb_action_rule_prios_max = 0; mae->status = SFC_MAE_STATUS_UNKNOWN; - if (status_prev != SFC_MAE_STATUS_SUPPORTED) + if (status_prev != SFC_MAE_STATUS_ADMIN) return; rte_free(mae->bounce_eh.buf); @@ -1284,6 +1295,66 @@ sfc_mae_rule_parse_item_port_id(const struct rte_flow_item *item, return 0; } +static int +sfc_mae_rule_parse_item_port_representor(const struct rte_flow_item *item, + struct sfc_flow_parse_ctx *ctx, + struct rte_flow_error *error) +{ + struct sfc_mae_parse_ctx *ctx_mae = ctx->mae; + const struct rte_flow_item_ethdev supp_mask = { + .port_id = 0xffff, + }; + const void *def_mask = &rte_flow_item_ethdev_mask; + const struct rte_flow_item_ethdev *spec = NULL; + const struct rte_flow_item_ethdev *mask = NULL; + efx_mport_sel_t mport_sel; + int rc; + + if (ctx_mae->match_mport_set) { + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Can't handle multiple traffic source items"); + } + + rc = sfc_flow_parse_init(item, + (const void **)&spec, (const void **)&mask, + (const void *)&supp_mask, def_mask, + sizeof(struct rte_flow_item_ethdev), error); + if (rc != 0) + return rc; + + if (mask->port_id != supp_mask.port_id) { + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Bad mask in the PORT_REPRESENTOR pattern item"); + } + + /* If "spec" is not set, could be any port ID */ + if (spec == NULL) + return 0; + + rc = sfc_mae_switch_port_by_ethdev( + ctx_mae->sa->mae.switch_domain_id, + spec->port_id, &mport_sel); + if (rc != 0) { + return rte_flow_error_set(error, rc, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Can't find RTE ethdev by the port ID"); + } + + rc = efx_mae_match_spec_mport_set(ctx_mae->match_spec, + &mport_sel, NULL); + if (rc != 0) { + return rte_flow_error_set(error, rc, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Failed to set MPORT for the port ID"); + } + + ctx_mae->match_mport_set = B_TRUE; + + return 0; +} + static int sfc_mae_rule_parse_item_phy_port(const struct rte_flow_item *item, struct sfc_flow_parse_ctx *ctx, @@ -2211,6 +2282,18 @@ static const struct sfc_flow_item sfc_flow_items[] = { .ctx_type = SFC_FLOW_PARSE_CTX_MAE, .parse = sfc_mae_rule_parse_item_port_id, }, + { + .type = RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR, + .name = "PORT_REPRESENTOR", + /* + * In terms of RTE flow, this item is a META one, + * and its position in the pattern is don't care. + */ + .prev_layer = SFC_FLOW_ITEM_ANY_LAYER, + .layer = SFC_FLOW_ITEM_ANY_LAYER, + .ctx_type = SFC_FLOW_PARSE_CTX_MAE, + .parse = sfc_mae_rule_parse_item_port_representor, + }, { .type = RTE_FLOW_ITEM_TYPE_PHY_PORT, .name = "PHY_PORT", @@ -3964,9 +4047,9 @@ sfc_mae_switchdev_init(struct sfc_adapter *sa) return 0; } - if (mae->status != SFC_MAE_STATUS_SUPPORTED) { + if (mae->status != SFC_MAE_STATUS_ADMIN) { rc = ENOTSUP; - sfc_err(sa, "failed to init switchdev - no MAE support"); + sfc_err(sa, "failed to init switchdev - no admin MAE privilege"); goto fail_no_mae; }