Skip to content

Commit b3762a9

Browse files
HoratiuVulturkuba-moo
authored andcommitted
net: lan966x: Add TC filter chaining support for IS1 and IS2 VCAPs
Allow rules to be chained between IS1 VCAP and IS2 VCAP. Chaining between IS1 lookups or between IS2 lookups are not supported by the hardware. Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 135c211 commit b3762a9

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

drivers/net/ethernet/microchip/lan966x/lan966x_tc_flower.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,75 @@ static int lan966x_tc_set_actionset(struct vcap_admin *admin,
309309
return err;
310310
}
311311

312+
static int lan966x_tc_add_rule_link_target(struct vcap_admin *admin,
313+
struct vcap_rule *vrule,
314+
int target_cid)
315+
{
316+
int link_val = target_cid % VCAP_CID_LOOKUP_SIZE;
317+
int err;
318+
319+
if (!link_val)
320+
return 0;
321+
322+
switch (admin->vtype) {
323+
case VCAP_TYPE_IS1:
324+
/* Choose IS1 specific NXT_IDX key (for chaining rules from IS1) */
325+
err = vcap_rule_add_key_u32(vrule, VCAP_KF_LOOKUP_GEN_IDX_SEL,
326+
1, ~0);
327+
if (err)
328+
return err;
329+
330+
return vcap_rule_add_key_u32(vrule, VCAP_KF_LOOKUP_GEN_IDX,
331+
link_val, ~0);
332+
case VCAP_TYPE_IS2:
333+
/* Add IS2 specific PAG key (for chaining rules from IS1) */
334+
return vcap_rule_add_key_u32(vrule, VCAP_KF_LOOKUP_PAG,
335+
link_val, ~0);
336+
default:
337+
break;
338+
}
339+
return 0;
340+
}
341+
342+
static int lan966x_tc_add_rule_link(struct vcap_control *vctrl,
343+
struct vcap_admin *admin,
344+
struct vcap_rule *vrule,
345+
struct flow_cls_offload *f,
346+
int to_cid)
347+
{
348+
struct vcap_admin *to_admin = vcap_find_admin(vctrl, to_cid);
349+
int diff, err = 0;
350+
351+
if (!to_admin) {
352+
NL_SET_ERR_MSG_MOD(f->common.extack,
353+
"Unknown destination chain");
354+
return -EINVAL;
355+
}
356+
357+
diff = vcap_chain_offset(vctrl, f->common.chain_index, to_cid);
358+
if (!diff)
359+
return 0;
360+
361+
/* Between IS1 and IS2 the PAG value is used */
362+
if (admin->vtype == VCAP_TYPE_IS1 && to_admin->vtype == VCAP_TYPE_IS2) {
363+
/* This works for IS1->IS2 */
364+
err = vcap_rule_add_action_u32(vrule, VCAP_AF_PAG_VAL, diff);
365+
if (err)
366+
return err;
367+
368+
err = vcap_rule_add_action_u32(vrule, VCAP_AF_PAG_OVERRIDE_MASK,
369+
0xff);
370+
if (err)
371+
return err;
372+
} else {
373+
NL_SET_ERR_MSG_MOD(f->common.extack,
374+
"Unsupported chain destination");
375+
return -EOPNOTSUPP;
376+
}
377+
378+
return err;
379+
}
380+
312381
static int lan966x_tc_flower_add(struct lan966x_port *port,
313382
struct flow_cls_offload *f,
314383
struct vcap_admin *admin,
@@ -336,6 +405,11 @@ static int lan966x_tc_flower_add(struct lan966x_port *port,
336405
if (err)
337406
goto out;
338407

408+
err = lan966x_tc_add_rule_link_target(admin, vrule,
409+
f->common.chain_index);
410+
if (err)
411+
goto out;
412+
339413
frule = flow_cls_offload_flow_rule(f);
340414

341415
flow_action_for_each(idx, act, &frule->action) {
@@ -365,6 +439,12 @@ static int lan966x_tc_flower_add(struct lan966x_port *port,
365439
if (err)
366440
goto out;
367441

442+
err = lan966x_tc_add_rule_link(port->lan966x->vcap_ctrl,
443+
admin, vrule,
444+
f, act->chain_index);
445+
if (err)
446+
goto out;
447+
368448
break;
369449
default:
370450
NL_SET_ERR_MSG_MOD(f->common.extack,

0 commit comments

Comments
 (0)