Skip to content

Commit 2ba5999

Browse files
Arkadi Sharshevskydavem330
authored andcommitted
mlxsw: spectrum: Add Support for erif table entries access
Implement dpipe's table ops for erif table which provide: 1. Getting the entries in the table with the associate values. - match on "mlxsw_meta:erif_index" - action on "mlxsw_meta:forwared_out" 2. Synchronize the hardware in case of enabling/disabling counters which mean removing erif counters from all interfaces. Signed-off-by: Arkadi Sharshevsky <[email protected]> Signed-off-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent fd1b9d4 commit 2ba5999

File tree

1 file changed

+185
-0
lines changed

1 file changed

+185
-0
lines changed

drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
#include "spectrum.h"
3939
#include "spectrum_dpipe.h"
40+
#include "spectrum_router.h"
4041

4142
enum mlxsw_sp_field_metadata_id {
4243
MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT,
@@ -113,9 +114,193 @@ static int mlxsw_sp_dpipe_table_erif_matches_dump(void *priv,
113114
return devlink_dpipe_match_put(skb, &match);
114115
}
115116

117+
static void mlxsw_sp_erif_entry_clear(struct devlink_dpipe_entry *entry)
118+
{
119+
unsigned int value_count, value_index;
120+
struct devlink_dpipe_value *value;
121+
122+
value = entry->action_values;
123+
value_count = entry->action_values_count;
124+
for (value_index = 0; value_index < value_count; value_index++) {
125+
kfree(value[value_index].value);
126+
kfree(value[value_index].mask);
127+
}
128+
129+
value = entry->match_values;
130+
value_count = entry->match_values_count;
131+
for (value_index = 0; value_index < value_count; value_index++) {
132+
kfree(value[value_index].value);
133+
kfree(value[value_index].mask);
134+
}
135+
}
136+
137+
static void
138+
mlxsw_sp_erif_match_action_prepare(struct devlink_dpipe_match *match,
139+
struct devlink_dpipe_action *action)
140+
{
141+
action->type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
142+
action->header = &mlxsw_sp_dpipe_header_metadata;
143+
action->field_id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_FORWARD;
144+
145+
match->type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
146+
match->header = &mlxsw_sp_dpipe_header_metadata;
147+
match->field_id = MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT;
148+
}
149+
150+
static int mlxsw_sp_erif_entry_prepare(struct devlink_dpipe_entry *entry,
151+
struct devlink_dpipe_value *match_value,
152+
struct devlink_dpipe_match *match,
153+
struct devlink_dpipe_value *action_value,
154+
struct devlink_dpipe_action *action)
155+
{
156+
entry->match_values = match_value;
157+
entry->match_values_count = 1;
158+
159+
entry->action_values = action_value;
160+
entry->action_values_count = 1;
161+
162+
match_value->match = match;
163+
match_value->value_size = sizeof(u32);
164+
match_value->value = kmalloc(match_value->value_size, GFP_KERNEL);
165+
if (!match_value->value)
166+
return -ENOMEM;
167+
168+
action_value->action = action;
169+
action_value->value_size = sizeof(u32);
170+
action_value->value = kmalloc(action_value->value_size, GFP_KERNEL);
171+
if (!action_value->value)
172+
goto err_action_alloc;
173+
return 0;
174+
175+
err_action_alloc:
176+
kfree(match_value->value);
177+
return -ENOMEM;
178+
}
179+
180+
static int mlxsw_sp_erif_entry_get(struct mlxsw_sp *mlxsw_sp,
181+
struct devlink_dpipe_entry *entry,
182+
struct mlxsw_sp_rif *rif,
183+
bool counters_enabled)
184+
{
185+
u32 *action_value;
186+
u32 *rif_value;
187+
u64 cnt;
188+
int err;
189+
190+
/* Set Match RIF index */
191+
rif_value = entry->match_values->value;
192+
*rif_value = mlxsw_sp_rif_index(rif);
193+
entry->match_values->mapping_value = mlxsw_sp_rif_dev_ifindex(rif);
194+
entry->match_values->mapping_valid = true;
195+
196+
/* Set Action Forwarding */
197+
action_value = entry->action_values->value;
198+
*action_value = 1;
199+
200+
entry->counter_valid = false;
201+
entry->counter = 0;
202+
if (!counters_enabled)
203+
return 0;
204+
205+
entry->index = mlxsw_sp_rif_index(rif);
206+
err = mlxsw_sp_rif_counter_value_get(mlxsw_sp, rif,
207+
MLXSW_SP_RIF_COUNTER_EGRESS,
208+
&cnt);
209+
if (!err) {
210+
entry->counter = cnt;
211+
entry->counter_valid = true;
212+
}
213+
return 0;
214+
}
215+
216+
static int
217+
mlxsw_sp_table_erif_entries_dump(void *priv, bool counters_enabled,
218+
struct devlink_dpipe_dump_ctx *dump_ctx)
219+
{
220+
struct devlink_dpipe_value match_value = {{0}}, action_value = {{0}};
221+
struct devlink_dpipe_action action = {0};
222+
struct devlink_dpipe_match match = {0};
223+
struct devlink_dpipe_entry entry = {0};
224+
struct mlxsw_sp *mlxsw_sp = priv;
225+
unsigned int rif_count;
226+
int i, j;
227+
int err;
228+
229+
mlxsw_sp_erif_match_action_prepare(&match, &action);
230+
err = mlxsw_sp_erif_entry_prepare(&entry, &match_value, &match,
231+
&action_value, &action);
232+
if (err)
233+
return err;
234+
235+
rif_count = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
236+
rtnl_lock();
237+
i = 0;
238+
start_again:
239+
err = devlink_dpipe_entry_ctx_prepare(dump_ctx);
240+
if (err)
241+
return err;
242+
j = 0;
243+
for (; i < rif_count; i++) {
244+
if (!mlxsw_sp->rifs[i])
245+
continue;
246+
err = mlxsw_sp_erif_entry_get(mlxsw_sp, &entry,
247+
mlxsw_sp->rifs[i],
248+
counters_enabled);
249+
if (err)
250+
goto err_entry_get;
251+
err = devlink_dpipe_entry_ctx_append(dump_ctx, &entry);
252+
if (err) {
253+
if (err == -EMSGSIZE) {
254+
if (!j)
255+
goto err_entry_append;
256+
break;
257+
}
258+
goto err_entry_append;
259+
}
260+
j++;
261+
}
262+
263+
devlink_dpipe_entry_ctx_close(dump_ctx);
264+
if (i != rif_count)
265+
goto start_again;
266+
rtnl_unlock();
267+
268+
mlxsw_sp_erif_entry_clear(&entry);
269+
return 0;
270+
err_entry_append:
271+
err_entry_get:
272+
rtnl_unlock();
273+
mlxsw_sp_erif_entry_clear(&entry);
274+
return err;
275+
}
276+
277+
static int mlxsw_sp_table_erif_counters_update(void *priv, bool enable)
278+
{
279+
struct mlxsw_sp *mlxsw_sp = priv;
280+
int i;
281+
282+
rtnl_lock();
283+
for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
284+
if (!mlxsw_sp->rifs[i])
285+
continue;
286+
if (enable)
287+
mlxsw_sp_rif_counter_alloc(mlxsw_sp,
288+
mlxsw_sp->rifs[i],
289+
MLXSW_SP_RIF_COUNTER_EGRESS);
290+
else
291+
mlxsw_sp_rif_counter_free(mlxsw_sp,
292+
mlxsw_sp->rifs[i],
293+
MLXSW_SP_RIF_COUNTER_EGRESS);
294+
}
295+
rtnl_unlock();
296+
return 0;
297+
}
298+
116299
static struct devlink_dpipe_table_ops mlxsw_sp_erif_ops = {
117300
.matches_dump = mlxsw_sp_dpipe_table_erif_matches_dump,
118301
.actions_dump = mlxsw_sp_dpipe_table_erif_actions_dump,
302+
.entries_dump = mlxsw_sp_table_erif_entries_dump,
303+
.counters_set_update = mlxsw_sp_table_erif_counters_update,
119304
};
120305

121306
static int mlxsw_sp_dpipe_erif_table_init(struct mlxsw_sp *mlxsw_sp)

0 commit comments

Comments
 (0)