Skip to content

Commit

Permalink
octeontx2-af: TC flower offload support for inner VLAN
Browse files Browse the repository at this point in the history
Extend the current TC flower offload support to enable filters matching
inner VLAN, and support offload of those filters to hardware.

Signed-off-by: Suman Ghosh <[email protected]>
Reviewed-by: Simon Horman <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
Suman Ghosh authored and kuba-moo committed Aug 8, 2023
1 parent aa07a0f commit 21e7483
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 6 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/mbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -1465,6 +1465,7 @@ struct flow_msg {
u8 ip_flag;
u8 next_header;
};
__be16 vlan_itci;
};

struct npc_install_flow_req {
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/npc.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ enum key_fields {
NPC_VLAN_ETYPE_CTAG, /* 0x8100 */
NPC_VLAN_ETYPE_STAG, /* 0x88A8 */
NPC_OUTER_VID,
NPC_INNER_VID,
NPC_TOS,
NPC_IPFRAG_IPV4,
NPC_SIP_IPV4,
Expand Down Expand Up @@ -230,6 +231,8 @@ enum key_fields {
NPC_VLAN_TAG1,
/* outer vlan tci for double tagged frame */
NPC_VLAN_TAG2,
/* inner vlan tci for double tagged frame */
NPC_VLAN_TAG3,
/* other header fields programmed to extract but not of our interest */
NPC_UNKNOWN,
NPC_KEY_FIELDS_MAX,
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2787,6 +2787,11 @@ static void rvu_dbg_npc_mcam_show_flows(struct seq_file *s,
seq_printf(s, "mask 0x%x\n",
ntohs(rule->mask.vlan_tci));
break;
case NPC_INNER_VID:
seq_printf(s, "0x%x ", ntohs(rule->packet.vlan_itci));
seq_printf(s, "mask 0x%x\n",
ntohs(rule->mask.vlan_itci));
break;
case NPC_TOS:
seq_printf(s, "%d ", rule->packet.tos);
seq_printf(s, "mask 0x%x\n", rule->mask.tos);
Expand Down
13 changes: 13 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ static const char * const npc_flow_names[] = {
[NPC_VLAN_ETYPE_CTAG] = "vlan ether type ctag",
[NPC_VLAN_ETYPE_STAG] = "vlan ether type stag",
[NPC_OUTER_VID] = "outer vlan id",
[NPC_INNER_VID] = "inner vlan id",
[NPC_TOS] = "tos",
[NPC_IPFRAG_IPV4] = "fragmented IPv4 header ",
[NPC_SIP_IPV4] = "ipv4 source ip",
Expand Down Expand Up @@ -328,6 +329,8 @@ static void npc_handle_multi_layer_fields(struct rvu *rvu, int blkaddr, u8 intf)
*/
struct npc_key_field *vlan_tag1;
struct npc_key_field *vlan_tag2;
/* Inner VLAN TCI for double tagged frames */
struct npc_key_field *vlan_tag3;
u64 *features;
u8 start_lid;
int i;
Expand All @@ -350,6 +353,7 @@ static void npc_handle_multi_layer_fields(struct rvu *rvu, int blkaddr, u8 intf)
etype_tag2 = &key_fields[NPC_ETYPE_TAG2];
vlan_tag1 = &key_fields[NPC_VLAN_TAG1];
vlan_tag2 = &key_fields[NPC_VLAN_TAG2];
vlan_tag3 = &key_fields[NPC_VLAN_TAG3];

/* if key profile programmed does not extract Ethertype at all */
if (!etype_ether->nr_kws && !etype_tag1->nr_kws && !etype_tag2->nr_kws) {
Expand Down Expand Up @@ -431,6 +435,12 @@ static void npc_handle_multi_layer_fields(struct rvu *rvu, int blkaddr, u8 intf)
goto done;
}
*features |= BIT_ULL(NPC_OUTER_VID);

/* If key profile extracts inner vlan tci */
if (vlan_tag3->nr_kws) {
key_fields[NPC_INNER_VID] = *vlan_tag3;
*features |= BIT_ULL(NPC_INNER_VID);
}
done:
return;
}
Expand Down Expand Up @@ -513,6 +523,7 @@ do { \
NPC_SCAN_HDR(NPC_ETYPE_TAG2, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 8, 2);
NPC_SCAN_HDR(NPC_VLAN_TAG1, NPC_LID_LB, NPC_LT_LB_CTAG, 2, 2);
NPC_SCAN_HDR(NPC_VLAN_TAG2, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 2, 2);
NPC_SCAN_HDR(NPC_VLAN_TAG3, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 6, 2);
NPC_SCAN_HDR(NPC_DMAC, NPC_LID_LA, la_ltype, la_start, 6);

NPC_SCAN_HDR(NPC_IPSEC_SPI, NPC_LID_LD, NPC_LT_LD_AH, 4, 4);
Expand Down Expand Up @@ -943,6 +954,8 @@ do { \

NPC_WRITE_FLOW(NPC_OUTER_VID, vlan_tci, ntohs(pkt->vlan_tci), 0,
ntohs(mask->vlan_tci), 0);
NPC_WRITE_FLOW(NPC_INNER_VID, vlan_itci, ntohs(pkt->vlan_itci), 0,
ntohs(mask->vlan_itci), 0);

NPC_WRITE_FLOW(NPC_IPFRAG_IPV6, next_header, pkt->next_header, 0,
mask->next_header, 0);
Expand Down
28 changes: 22 additions & 6 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,10 +447,11 @@ static int otx2_tc_process_vlan(struct otx2_nic *nic, struct flow_msg *flow_spec
u16 vlan_tci, vlan_tci_mask;

if (is_inner)
return -EOPNOTSUPP;
flow_rule_match_cvlan(rule, &match);
else
flow_rule_match_vlan(rule, &match);

flow_rule_match_vlan(rule, &match);
if (ntohs(match.key->vlan_tpid) != ETH_P_8021Q) {
if (!eth_type_vlan(match.key->vlan_tpid)) {
netdev_err(nic->netdev, "vlan tpid 0x%x not supported\n",
ntohs(match.key->vlan_tpid));
return -EOPNOTSUPP;
Expand Down Expand Up @@ -480,9 +481,15 @@ static int otx2_tc_process_vlan(struct otx2_nic *nic, struct flow_msg *flow_spec
vlan_tci_mask = match.mask->vlan_id |
match.mask->vlan_dei << 12 |
match.mask->vlan_priority << 13;
flow_spec->vlan_tci = htons(vlan_tci);
flow_mask->vlan_tci = htons(vlan_tci_mask);
req->features |= BIT_ULL(NPC_OUTER_VID);
if (is_inner) {
flow_spec->vlan_itci = htons(vlan_tci);
flow_mask->vlan_itci = htons(vlan_tci_mask);
req->features |= BIT_ULL(NPC_INNER_VID);
} else {
flow_spec->vlan_tci = htons(vlan_tci);
flow_mask->vlan_tci = htons(vlan_tci_mask);
req->features |= BIT_ULL(NPC_OUTER_VID);
}
}

return 0;
Expand All @@ -507,6 +514,7 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node,
BIT_ULL(FLOW_DISSECTOR_KEY_BASIC) |
BIT_ULL(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
BIT_ULL(FLOW_DISSECTOR_KEY_VLAN) |
BIT(FLOW_DISSECTOR_KEY_CVLAN) |
BIT_ULL(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
BIT_ULL(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
BIT_ULL(FLOW_DISSECTOR_KEY_PORTS) |
Expand Down Expand Up @@ -647,6 +655,14 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node,
return ret;
}

if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CVLAN)) {
int ret;

ret = otx2_tc_process_vlan(nic, flow_spec, flow_mask, rule, req, true);
if (ret)
return ret;
}

if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
struct flow_match_ipv4_addrs match;

Expand Down

0 comments on commit 21e7483

Please sign in to comment.