From: Roman Zhukov Date: Thu, 19 Apr 2018 11:37:02 +0000 (+0100) Subject: net/sfc/base: support MARK and FLAG actions in filters X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=9a733758c046;p=dpdk.git net/sfc/base: support MARK and FLAG actions in filters This patch adds support for DPDK rte_flow "MARK" and "FLAG" filter actions to filters on EF10 family NICs. Signed-off-by: Roman Zhukov Signed-off-by: Andrew Rybchenko --- diff --git a/drivers/net/sfc/base/ef10_filter.c b/drivers/net/sfc/base/ef10_filter.c index bf4992e338..ae872853d8 100644 --- a/drivers/net/sfc/base/ef10_filter.c +++ b/drivers/net/sfc/base/ef10_filter.c @@ -172,7 +172,7 @@ efx_mcdi_filter_op_add( __inout ef10_filter_handle_t *handle) { efx_mcdi_req_t req; - uint8_t payload[MAX(MC_CMD_FILTER_OP_EXT_IN_LEN, + uint8_t payload[MAX(MC_CMD_FILTER_OP_V3_IN_LEN, MC_CMD_FILTER_OP_EXT_OUT_LEN)]; efx_filter_match_flags_t match_flags; efx_rc_t rc; @@ -180,7 +180,7 @@ efx_mcdi_filter_op_add( memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_FILTER_OP; req.emr_in_buf = payload; - req.emr_in_length = MC_CMD_FILTER_OP_EXT_IN_LEN; + req.emr_in_length = MC_CMD_FILTER_OP_V3_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_FILTER_OP_EXT_OUT_LEN; @@ -316,16 +316,37 @@ efx_mcdi_filter_op_add( spec->efs_ifrm_loc_mac, EFX_MAC_ADDR_LEN); } + /* + * Set the "MARK" or "FLAG" action for all packets matching this filter + * if necessary (only useful with equal stride packed stream Rx mode + * which provide the information in pseudo-header). + * These actions require MC_CMD_FILTER_OP_V3_IN msgrequest. + */ + if ((spec->efs_flags & EFX_FILTER_FLAG_ACTION_MARK) && + (spec->efs_flags & EFX_FILTER_FLAG_ACTION_FLAG)) { + rc = EINVAL; + goto fail3; + } + if (spec->efs_flags & EFX_FILTER_FLAG_ACTION_MARK) { + MCDI_IN_SET_DWORD(req, FILTER_OP_V3_IN_MATCH_ACTION, + MC_CMD_FILTER_OP_V3_IN_MATCH_ACTION_MARK); + MCDI_IN_SET_DWORD(req, FILTER_OP_V3_IN_MATCH_MARK_VALUE, + spec->efs_mark); + } else if (spec->efs_flags & EFX_FILTER_FLAG_ACTION_FLAG) { + MCDI_IN_SET_DWORD(req, FILTER_OP_V3_IN_MATCH_ACTION, + MC_CMD_FILTER_OP_V3_IN_MATCH_ACTION_FLAG); + } + efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; - goto fail3; + goto fail4; } if (req.emr_out_length_used < MC_CMD_FILTER_OP_EXT_OUT_LEN) { rc = EMSGSIZE; - goto fail4; + goto fail5; } handle->efh_lo = MCDI_OUT_DWORD(req, FILTER_OP_EXT_OUT_HANDLE_LO); @@ -333,6 +354,8 @@ efx_mcdi_filter_op_add( return (0); +fail5: + EFSYS_PROBE(fail5); fail4: EFSYS_PROBE(fail4); fail3: diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h index cd0e6f805f..f5ec568c3b 100644 --- a/drivers/net/sfc/base/efx.h +++ b/drivers/net/sfc/base/efx.h @@ -2622,6 +2622,10 @@ efx_tx_qdestroy( #define EFX_FILTER_FLAG_RX 0x08 /* Filter is for TX */ #define EFX_FILTER_FLAG_TX 0x10 +/* Set match flag on the received packet */ +#define EFX_FILTER_FLAG_ACTION_FLAG 0x20 +/* Set match mark on the received packet */ +#define EFX_FILTER_FLAG_ACTION_MARK 0x40 typedef uint8_t efx_filter_flags_t; @@ -2707,6 +2711,7 @@ typedef struct efx_filter_spec_s { efx_oword_t efs_loc_host; uint8_t efs_vni_or_vsid[EFX_VNI_OR_VSID_LEN]; uint8_t efs_ifrm_loc_mac[EFX_MAC_ADDR_LEN]; + uint32_t efs_mark; } efx_filter_spec_t; diff --git a/drivers/net/sfc/base/efx_filter.c b/drivers/net/sfc/base/efx_filter.c index 97c972c668..412298acf3 100644 --- a/drivers/net/sfc/base/efx_filter.c +++ b/drivers/net/sfc/base/efx_filter.c @@ -74,12 +74,33 @@ efx_filter_insert( __inout efx_filter_spec_t *spec) { const efx_filter_ops_t *efop = enp->en_efop; + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + efx_rc_t rc; EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER); EFSYS_ASSERT3P(spec, !=, NULL); EFSYS_ASSERT3U(spec->efs_flags, &, EFX_FILTER_FLAG_RX); + if ((spec->efs_flags & EFX_FILTER_FLAG_ACTION_MARK) && + !encp->enc_filter_action_mark_supported) { + rc = ENOTSUP; + goto fail1; + } + + if ((spec->efs_flags & EFX_FILTER_FLAG_ACTION_FLAG) && + !encp->enc_filter_action_flag_supported) { + rc = ENOTSUP; + goto fail2; + } + return (efop->efo_add(enp, spec, B_FALSE)); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); } __checkReturn efx_rc_t