Skip to content

Commit

Permalink
common/sfc_efx/base: add MAE action rule provisioning APIs
Browse files Browse the repository at this point in the history
Add APIs for action rule insert / remove operations.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
  • Loading branch information
ol-ivanmal authored and Ferruh Yigit committed Nov 3, 2020
1 parent e61baa8 commit b4fac34
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 0 deletions.
29 changes: 29 additions & 0 deletions drivers/common/sfc_efx/base/efx.h
Original file line number Diff line number Diff line change
Expand Up @@ -4193,6 +4193,11 @@ efx_mae_match_specs_class_cmp(

#define EFX_MAE_RSRC_ID_INVALID UINT32_MAX

/* Rule ID */
typedef struct efx_mae_rule_id_s {
uint32_t id;
} efx_mae_rule_id_t;

/* Action set ID */
typedef struct efx_mae_aset_id_s {
uint32_t id;
Expand All @@ -4211,6 +4216,30 @@ efx_mae_action_set_free(
__in efx_nic_t *enp,
__in const efx_mae_aset_id_t *aset_idp);

/* Action set list ID */
typedef struct efx_mae_aset_list_id_s {
uint32_t id;
} efx_mae_aset_list_id_t;

/*
* Either action set list ID or action set ID must be passed to this API,
* but not both.
*/
LIBEFX_API
extern __checkReturn efx_rc_t
efx_mae_action_rule_insert(
__in efx_nic_t *enp,
__in const efx_mae_match_spec_t *spec,
__in const efx_mae_aset_list_id_t *asl_idp,
__in const efx_mae_aset_id_t *as_idp,
__out efx_mae_rule_id_t *ar_idp);

LIBEFX_API
extern __checkReturn efx_rc_t
efx_mae_action_rule_remove(
__in efx_nic_t *enp,
__in const efx_mae_rule_id_t *ar_idp);

#endif /* EFSYS_OPT_MAE */

#ifdef __cplusplus
Expand Down
150 changes: 150 additions & 0 deletions drivers/common/sfc_efx/base/efx_mae.c
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,156 @@ efx_mae_action_set_free(

return (0);

fail3:
EFSYS_PROBE(fail3);
fail2:
EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}

__checkReturn efx_rc_t
efx_mae_action_rule_insert(
__in efx_nic_t *enp,
__in const efx_mae_match_spec_t *spec,
__in const efx_mae_aset_list_id_t *asl_idp,
__in const efx_mae_aset_id_t *as_idp,
__out efx_mae_rule_id_t *ar_idp)
{
const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
efx_mcdi_req_t req;
EFX_MCDI_DECLARE_BUF(payload,
MC_CMD_MAE_ACTION_RULE_INSERT_IN_LENMAX_MCDI2,
MC_CMD_MAE_ACTION_RULE_INSERT_OUT_LEN);
efx_oword_t *rule_response;
efx_mae_rule_id_t ar_id;
size_t offset;
efx_rc_t rc;

EFX_STATIC_ASSERT(sizeof (ar_idp->id) ==
MC_CMD_MAE_ACTION_RULE_INSERT_OUT_AR_ID_LEN);

EFX_STATIC_ASSERT(EFX_MAE_RSRC_ID_INVALID ==
MC_CMD_MAE_ACTION_RULE_INSERT_OUT_ACTION_RULE_ID_NULL);

if (encp->enc_mae_supported == B_FALSE) {
rc = ENOTSUP;
goto fail1;
}

if (spec->emms_type != EFX_MAE_RULE_ACTION ||
(asl_idp != NULL && as_idp != NULL) ||
(asl_idp == NULL && as_idp == NULL)) {
rc = EINVAL;
goto fail2;
}

req.emr_cmd = MC_CMD_MAE_ACTION_RULE_INSERT;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_MAE_ACTION_RULE_INSERT_IN_LENMAX_MCDI2;
req.emr_out_buf = payload;
req.emr_out_length = MC_CMD_MAE_ACTION_RULE_INSERT_OUT_LEN;

EFX_STATIC_ASSERT(sizeof (*rule_response) <=
MC_CMD_MAE_ACTION_RULE_INSERT_IN_RESPONSE_LEN);
offset = MC_CMD_MAE_ACTION_RULE_INSERT_IN_RESPONSE_OFST;
rule_response = (efx_oword_t *)(payload + offset);
EFX_POPULATE_OWORD_3(*rule_response,
MAE_ACTION_RULE_RESPONSE_ASL_ID,
(asl_idp != NULL) ? asl_idp->id : EFX_MAE_RSRC_ID_INVALID,
MAE_ACTION_RULE_RESPONSE_AS_ID,
(as_idp != NULL) ? as_idp->id : EFX_MAE_RSRC_ID_INVALID,
MAE_ACTION_RULE_RESPONSE_COUNTER_ID, EFX_MAE_RSRC_ID_INVALID);

MCDI_IN_SET_DWORD(req, MAE_ACTION_RULE_INSERT_IN_PRIO, spec->emms_prio);

/*
* Mask-value pairs have been stored in the byte order needed for the
* MCDI request and are thus safe to be copied directly to the buffer.
*/
EFX_STATIC_ASSERT(sizeof (spec->emms_mask_value_pairs.action) >=
MAE_FIELD_MASK_VALUE_PAIRS_LEN);
offset = MC_CMD_MAE_ACTION_RULE_INSERT_IN_MATCH_CRITERIA_OFST;
memcpy(payload + offset, spec->emms_mask_value_pairs.action,
MAE_FIELD_MASK_VALUE_PAIRS_LEN);

efx_mcdi_execute(enp, &req);

if (req.emr_rc != 0) {
rc = req.emr_rc;
goto fail3;
}

if (req.emr_out_length_used < MC_CMD_MAE_ACTION_RULE_INSERT_OUT_LEN) {
rc = EMSGSIZE;
goto fail4;
}

ar_id.id = MCDI_OUT_DWORD(req, MAE_ACTION_RULE_INSERT_OUT_AR_ID);
if (ar_id.id == EFX_MAE_RSRC_ID_INVALID) {
rc = ENOENT;
goto fail5;
}

ar_idp->id = ar_id.id;

return (0);

fail5:
EFSYS_PROBE(fail5);
fail4:
EFSYS_PROBE(fail4);
fail3:
EFSYS_PROBE(fail3);
fail2:
EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}

__checkReturn efx_rc_t
efx_mae_action_rule_remove(
__in efx_nic_t *enp,
__in const efx_mae_rule_id_t *ar_idp)
{
const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
efx_mcdi_req_t req;
EFX_MCDI_DECLARE_BUF(payload,
MC_CMD_MAE_ACTION_RULE_DELETE_IN_LEN(1),
MC_CMD_MAE_ACTION_RULE_DELETE_OUT_LEN(1));
efx_rc_t rc;

if (encp->enc_mae_supported == B_FALSE) {
rc = ENOTSUP;
goto fail1;
}

req.emr_cmd = MC_CMD_MAE_ACTION_RULE_DELETE;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_MAE_ACTION_RULE_DELETE_IN_LEN(1);
req.emr_out_buf = payload;
req.emr_out_length = MC_CMD_MAE_ACTION_RULE_DELETE_OUT_LEN(1);

MCDI_IN_SET_DWORD(req, MAE_ACTION_RULE_DELETE_IN_AR_ID, ar_idp->id);

efx_mcdi_execute(enp, &req);

if (req.emr_rc != 0) {
rc = req.emr_rc;
goto fail2;
}

if (MCDI_OUT_DWORD(req, MAE_ACTION_RULE_DELETE_OUT_DELETED_AR_ID) !=
ar_idp->id) {
/* Firmware failed to delete the action rule. */
rc = EAGAIN;
goto fail3;
}

return (0);

fail3:
EFSYS_PROBE(fail3);
fail2:
Expand Down
2 changes: 2 additions & 0 deletions drivers/common/sfc_efx/version.map
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ INTERNAL {
efx_mac_stats_upload;
efx_mac_up;

efx_mae_action_rule_insert;
efx_mae_action_rule_remove;
efx_mae_action_set_alloc;
efx_mae_action_set_free;
efx_mae_action_set_populate_deliver;
Expand Down

0 comments on commit b4fac34

Please sign in to comment.