Commit 2e0f1eb0 authored by Edward Cree's avatar Edward Cree Committed by David S. Miller

sfc: attach an MAE counter to TC actions that need it

The only actions that expect stats (that sfc HW supports) are gact shot
 (drop), mirred redirect and mirred mirror.  Since these are 'deliverish'
 actions that end an action-set, we only require at most one counter per
 action-set.
Signed-off-by: default avatarEdward Cree <ecree.xilinx@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c4bad432
...@@ -501,8 +501,12 @@ int efx_mae_alloc_action_set(struct efx_nic *efx, struct efx_tc_action_set *act) ...@@ -501,8 +501,12 @@ int efx_mae_alloc_action_set(struct efx_nic *efx, struct efx_tc_action_set *act)
MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_MAC_ID_NULL); MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_MAC_ID_NULL);
MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_DST_MAC_ID, MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_DST_MAC_ID,
MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_MAC_ID_NULL); MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_MAC_ID_NULL);
MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_COUNTER_ID, if (act->count && !WARN_ON(!act->count->cnt))
MC_CMD_MAE_COUNTER_ALLOC_OUT_COUNTER_ID_NULL); MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_COUNTER_ID,
act->count->cnt->fw_id);
else
MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_COUNTER_ID,
MC_CMD_MAE_COUNTER_ALLOC_OUT_COUNTER_ID_NULL);
MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_COUNTER_LIST_ID, MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_COUNTER_LIST_ID,
MC_CMD_MAE_COUNTER_LIST_ALLOC_OUT_COUNTER_LIST_ID_NULL); MC_CMD_MAE_COUNTER_LIST_ALLOC_OUT_COUNTER_LIST_ID_NULL);
MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_ENCAP_HEADER_ID, MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_ENCAP_HEADER_ID,
......
...@@ -77,6 +77,8 @@ static void efx_tc_free_action_set(struct efx_nic *efx, ...@@ -77,6 +77,8 @@ static void efx_tc_free_action_set(struct efx_nic *efx,
*/ */
list_del(&act->list); list_del(&act->list);
} }
if (act->count)
efx_tc_flower_put_counter_index(efx, act->count);
kfree(act); kfree(act);
} }
...@@ -376,6 +378,28 @@ static int efx_tc_flower_replace(struct efx_nic *efx, ...@@ -376,6 +378,28 @@ static int efx_tc_flower_replace(struct efx_nic *efx,
goto release; goto release;
} }
if ((fa->id == FLOW_ACTION_REDIRECT ||
fa->id == FLOW_ACTION_MIRRED ||
fa->id == FLOW_ACTION_DROP) && fa->hw_stats) {
struct efx_tc_counter_index *ctr;
if (!(fa->hw_stats & FLOW_ACTION_HW_STATS_DELAYED)) {
NL_SET_ERR_MSG_FMT_MOD(extack, "hw_stats_type %u not supported (only 'delayed')",
fa->hw_stats);
rc = -EOPNOTSUPP;
goto release;
}
ctr = efx_tc_flower_get_counter_index(efx, tc->cookie,
EFX_TC_COUNTER_TYPE_AR);
if (IS_ERR(ctr)) {
rc = PTR_ERR(ctr);
NL_SET_ERR_MSG_MOD(extack, "Failed to obtain a counter");
goto release;
}
act->count = ctr;
}
switch (fa->id) { switch (fa->id) {
case FLOW_ACTION_DROP: case FLOW_ACTION_DROP:
rc = efx_mae_alloc_action_set(efx, act); rc = efx_mae_alloc_action_set(efx, act);
...@@ -412,6 +436,7 @@ static int efx_tc_flower_replace(struct efx_nic *efx, ...@@ -412,6 +436,7 @@ static int efx_tc_flower_replace(struct efx_nic *efx,
if (fa->id == FLOW_ACTION_REDIRECT) if (fa->id == FLOW_ACTION_REDIRECT)
break; /* end of the line */ break; /* end of the line */
/* Mirror, so continue on with saved act */ /* Mirror, so continue on with saved act */
save.count = NULL;
act = kzalloc(sizeof(*act), GFP_USER); act = kzalloc(sizeof(*act), GFP_USER);
if (!act) { if (!act) {
rc = -ENOMEM; rc = -ENOMEM;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
struct efx_tc_action_set { struct efx_tc_action_set {
u16 deliver:1; u16 deliver:1;
struct efx_tc_counter_index *count;
u32 dest_mport; u32 dest_mport;
u32 fw_id; /* index of this entry in firmware actions table */ u32 fw_id; /* index of this entry in firmware actions table */
struct list_head list; struct list_head list;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment