@@ -1525,6 +1525,7 @@ sfc_mae_rule_parse_item_port_id(const struct rte_flow_item *item,
const struct rte_flow_item_port_id *spec = NULL;
const struct rte_flow_item_port_id *mask = NULL;
efx_mport_sel_t mport_sel;
+ unsigned int type_mask;
int rc;
if (ctx_mae->match_mport_set) {
@@ -1556,8 +1557,10 @@ sfc_mae_rule_parse_item_port_id(const struct rte_flow_item *item,
"The port ID is too large");
}
+ type_mask = 1U << SFC_MAE_SWITCH_PORT_INDEPENDENT;
+
rc = sfc_mae_switch_get_ethdev_mport(ctx_mae->sa->mae.switch_domain_id,
- spec->id, &mport_sel);
+ spec->id, type_mask, &mport_sel);
if (rc != 0) {
return rte_flow_error_set(error, rc,
RTE_FLOW_ERROR_TYPE_ITEM, item,
@@ -1590,6 +1593,7 @@ sfc_mae_rule_parse_item_ethdev_based(const struct rte_flow_item *item,
const struct rte_flow_item_ethdev *spec = NULL;
const struct rte_flow_item_ethdev *mask = NULL;
efx_mport_sel_t mport_sel;
+ unsigned int type_mask;
int rc;
if (ctx_mae->match_mport_set) {
@@ -1617,9 +1621,11 @@ sfc_mae_rule_parse_item_ethdev_based(const struct rte_flow_item *item,
switch (item->type) {
case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR:
+ type_mask = 1U << SFC_MAE_SWITCH_PORT_INDEPENDENT;
+
rc = sfc_mae_switch_get_ethdev_mport(
ctx_mae->sa->mae.switch_domain_id,
- spec->port_id, &mport_sel);
+ spec->port_id, type_mask, &mport_sel);
if (rc != 0) {
return rte_flow_error_set(error, rc,
RTE_FLOW_ERROR_TYPE_ITEM, item,
@@ -3529,6 +3535,7 @@ sfc_mae_rule_parse_action_port_id(struct sfc_adapter *sa,
{
struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
struct sfc_mae *mae = &sa->mae;
+ unsigned int type_mask;
efx_mport_sel_t mport;
uint16_t port_id;
int rc;
@@ -3538,8 +3545,10 @@ sfc_mae_rule_parse_action_port_id(struct sfc_adapter *sa,
port_id = (conf->original != 0) ? sas->port_id : conf->id;
+ type_mask = 1U << SFC_MAE_SWITCH_PORT_INDEPENDENT;
+
rc = sfc_mae_switch_get_ethdev_mport(mae->switch_domain_id,
- port_id, &mport);
+ port_id, type_mask, &mport);
if (rc != 0) {
sfc_err(sa, "failed to get m-port for the given ethdev (port_id=%u): %s",
port_id, strerror(rc));
@@ -3558,14 +3567,14 @@ sfc_mae_rule_parse_action_port_id(struct sfc_adapter *sa,
static int
sfc_mae_rule_parse_action_port_representor(struct sfc_adapter *sa,
const struct rte_flow_action_ethdev *conf,
- efx_mae_actions_t *spec)
+ unsigned int type_mask, efx_mae_actions_t *spec)
{
struct sfc_mae *mae = &sa->mae;
efx_mport_sel_t mport;
int rc;
rc = sfc_mae_switch_get_ethdev_mport(mae->switch_domain_id,
- conf->port_id, &mport);
+ conf->port_id, type_mask, &mport);
if (rc != 0) {
sfc_err(sa, "failed to get m-port for the given ethdev (port_id=%u): %s",
conf->port_id, strerror(rc));
@@ -3641,6 +3650,7 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa,
const struct sfc_mae_outer_rule *outer_rule = spec_mae->outer_rule;
const uint64_t rx_metadata = sa->negotiated_rx_metadata;
efx_mae_actions_t *spec = ctx->spec;
+ unsigned int switch_port_type_mask;
bool custom_error = B_FALSE;
int rc = 0;
@@ -3757,8 +3767,11 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa,
case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR,
bundle->actions_mask);
+
+ switch_port_type_mask = 1U << SFC_MAE_SWITCH_PORT_INDEPENDENT;
+
rc = sfc_mae_rule_parse_action_port_representor(sa,
- action->conf, spec);
+ action->conf, switch_port_type_mask, spec);
break;
case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT,
@@ -933,15 +933,26 @@ sfc_repr_eth_dev_init(struct rte_eth_dev *dev, void *init_params)
struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev);
struct sfc_mae_switch_port_request switch_port_request;
efx_mport_sel_t ethdev_mport_sel;
+ efx_mport_id_t proxy_mport_id;
struct sfc_repr *sr;
int ret;
/*
- * Currently there is no mport we can use for representor's
- * ethdev. Use an invalid one for now. This way representors
- * can be instantiated.
+ * For each representor, a driver-internal flow has to be installed
+ * in order to direct traffic coming from the represented entity to
+ * the "representor proxy". Such internal flows need to find ethdev
+ * mport by ethdev ID of the representors in question to specify in
+ * delivery action. So set the representor ethdev's mport to that
+ * of the "representor proxy" in below switch port request.
*/
- efx_mae_mport_invalid(ðdev_mport_sel);
+ sfc_repr_proxy_mport_alias_get(repr_data->pf_port_id, &proxy_mport_id);
+
+ ret = efx_mae_mport_by_id(&proxy_mport_id, ðdev_mport_sel);
+ if (ret != 0) {
+ SFC_GENERIC_LOG(ERR,
+ "%s() failed to get repr proxy mport by ID", __func__);
+ goto fail_get_selector;
+ }
memset(&switch_port_request, 0, sizeof(switch_port_request));
switch_port_request.type = SFC_MAE_SWITCH_PORT_REPRESENTOR;
@@ -1033,6 +1044,7 @@ sfc_repr_eth_dev_init(struct rte_eth_dev *dev, void *init_params)
fail_create_port:
fail_mae_assign_switch_port:
+fail_get_selector:
SFC_GENERIC_LOG(ERR, "%s() failed: %s", __func__, rte_strerror(-ret));
return ret;
}
@@ -1708,3 +1708,18 @@ sfc_repr_proxy_repr_entity_mac_addr_set(uint16_t pf_port_id, uint16_t repr_id,
return rc;
}
+
+void
+sfc_repr_proxy_mport_alias_get(uint16_t pf_port_id, efx_mport_id_t *mport_alias)
+{
+ const struct sfc_repr_proxy *rp;
+ struct sfc_adapter *sa;
+
+ sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
+ sfc_adapter_lock(sa);
+ rp = sfc_repr_proxy_by_adapter(sa);
+
+ memcpy(mport_alias, &rp->mport_alias, sizeof(*mport_alias));
+
+ sfc_adapter_unlock(sa);
+}
@@ -46,6 +46,9 @@ int sfc_repr_proxy_stop_repr(uint16_t pf_port_id, uint16_t repr_id);
int sfc_repr_proxy_repr_entity_mac_addr_set(uint16_t pf_port_id,
uint16_t repr_id, const struct rte_ether_addr *mac_addr);
+void sfc_repr_proxy_mport_alias_get(uint16_t pf_port_id,
+ efx_mport_id_t *mport_alias);
+
#ifdef __cplusplus
}
#endif
@@ -551,6 +551,7 @@ sfc_mae_find_switch_port_by_ethdev(uint16_t switch_domain_id,
int
sfc_mae_switch_get_ethdev_mport(uint16_t switch_domain_id,
uint16_t ethdev_port_id,
+ unsigned int allowed_mae_switch_port_types,
efx_mport_sel_t *mport_sel)
{
struct sfc_mae_switch_port *port;
@@ -562,11 +563,7 @@ sfc_mae_switch_get_ethdev_mport(uint16_t switch_domain_id,
if (rc != 0)
goto unlock;
- if (port->type != SFC_MAE_SWITCH_PORT_INDEPENDENT) {
- /*
- * The ethdev is a "VF representor". It does not own
- * a dedicated m-port suitable for use in flow rules.
- */
+ if (((1U << port->type) & allowed_mae_switch_port_types) == 0) {
rc = ENOTSUP;
goto unlock;
}
@@ -102,8 +102,18 @@ int sfc_mae_assign_switch_port(uint16_t switch_domain_id,
int sfc_mae_clear_switch_port(uint16_t switch_domain_id,
uint16_t switch_port_id);
+/*
+ * For user flows, allowed_mae_switch_port_types can only contain bit
+ * SFC_MAE_SWITCH_PORT_INDEPENDENT, meaning that only those ethdevs
+ * that have their own MAE m-ports can be accessed by a port-based
+ * action. For driver-internal flows, this mask can also contain
+ * bit SFC_MAE_SWITCH_PORT_REPRESENTOR to allow VF traffic to be
+ * sent to the common MAE m-port of all such REPRESENTOR ports
+ * via a port-based action, for default switch interconnection.
+ */
int sfc_mae_switch_get_ethdev_mport(uint16_t switch_domain_id,
uint16_t ethdev_port_id,
+ unsigned int allowed_mae_switch_port_types,
efx_mport_sel_t *mport_sel);
int sfc_mae_switch_get_entity_mport(uint16_t switch_domain_id,