Commit 86cea61d authored by Tomasz Duszynski's avatar Tomasz Duszynski Committed by David S. Miller
Browse files

octeontx2-af: Add support for stripping STAG/CTAG



This works by shadowing existing UCAST MCAM entry
with a new one additionally matching either NPC_LT_LB_CTAG
or NPC_LT_LB_STAG. For this to fully work one needs to
send properly configured NIX_VTAG_CFG message afterwards i.e with
strip and capture enabled and type set to 0.

On receiving tagged packet NIX will remove outer VLAN and capture
TCI in NIX_RX_PARSE_S.

Also simplified RX Vtag configuration flow
With this setting STRIP/CAPTURE VTAG actions separately would be
possible. Following combinations are possible: STRIP,
STRIP and CAPTURE, CAPTURE or nothing (0 disables respective actions).

Signed-off-by: default avatarTomasz Duszynski <tduszynski@marvell.com>
Signed-off-by: default avatarSunil Goutham <sgoutham@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 40df309e
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -197,7 +197,8 @@ M(NIX_SET_MAC_ADDR, 0x800a, nix_set_mac_addr, nix_set_mac_addr, msg_rsp) \
M(NIX_SET_RX_MODE,	0x800b, nix_set_rx_mode, nix_rx_mode, msg_rsp)	\
M(NIX_SET_HW_FRS,	0x800c, nix_set_hw_frs, nix_frs_cfg, msg_rsp)	\
M(NIX_LF_START_RX,	0x800d, nix_lf_start_rx, msg_req, msg_rsp)	\
M(NIX_LF_STOP_RX,	0x800e, nix_lf_stop_rx, msg_req, msg_rsp)
M(NIX_LF_STOP_RX,	0x800e, nix_lf_stop_rx, msg_req, msg_rsp)	\
M(NIX_RXVLAN_ALLOC,	0x8012, nix_rxvlan_alloc, msg_req, msg_rsp)

/* Messages initiated by AF (range 0xC00 - 0xDFF) */
#define MBOX_UP_CGX_MESSAGES						\
@@ -515,6 +516,7 @@ struct nix_txschq_config {

struct nix_vtag_config {
	struct mbox_msghdr hdr;
	/* '0' for 4 octet VTAG, '1' for 8 octet VTAG */
	u8 vtag_size;
	/* cfg_type is '0' for tx vlan cfg
	 * cfg_type is '1' for rx vlan cfg
@@ -535,7 +537,7 @@ struct nix_vtag_config {

		/* valid when cfg_type is '1' */
		struct {
			/* rx vtag type index */
			/* rx vtag type index, valid values are in 0..7 range */
			u8 vtag_type;
			/* rx vtag strip */
			u8 strip_vtag :1;
+6 −0
Original line number Diff line number Diff line
@@ -259,4 +259,10 @@ struct nix_rx_action {
#endif
};

/* NIX Receive Vtag Action Structure */
#define VTAG0_VALID_BIT		BIT_ULL(15)
#define VTAG0_TYPE_MASK		GENMASK_ULL(14, 12)
#define VTAG0_LID_MASK		GENMASK_ULL(10, 8)
#define VTAG0_RELPTR_MASK	GENMASK_ULL(7, 0)

#endif /* NPC_H */
+8 −0
Original line number Diff line number Diff line
@@ -142,6 +142,11 @@ struct rvu_pfvf {
	/* Broadcast pkt replication info */
	u16			bcast_mce_idx;
	struct nix_mce_list	bcast_mce_list;

	/* VLAN offload */
	struct mcam_entry entry;
	int rxvlan_index;
	bool rxvlan;
};

struct nix_txsch {
@@ -356,6 +361,8 @@ int rvu_mbox_handler_nix_stats_rst(struct rvu *rvu, struct msg_req *req,
int rvu_mbox_handler_nix_vtag_cfg(struct rvu *rvu,
				  struct nix_vtag_config *req,
				  struct msg_rsp *rsp);
int rvu_mbox_handler_nix_rxvlan_alloc(struct rvu *rvu, struct msg_req *req,
				      struct msg_rsp *rsp);
int rvu_mbox_handler_nix_rss_flowkey_cfg(struct rvu *rvu,
					 struct nix_rss_flowkey_cfg *req,
					 struct msg_rsp *rsp);
@@ -384,6 +391,7 @@ void rvu_npc_disable_promisc_entry(struct rvu *rvu, u16 pcifunc, int nixlf);
void rvu_npc_enable_promisc_entry(struct rvu *rvu, u16 pcifunc, int nixlf);
void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc,
				       int nixlf, u64 chan);
int rvu_npc_update_rxvlan(struct rvu *rvu, u16 pcifunc, int nixlf);
void rvu_npc_disable_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
void rvu_npc_disable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
void rvu_npc_enable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
+65 −18
Original line number Diff line number Diff line
@@ -192,6 +192,7 @@ static void nix_interface_deinit(struct rvu *rvu, u16 pcifunc, u8 nixlf)

	pfvf->maxlen = 0;
	pfvf->minlen = 0;
	pfvf->rxvlan = false;

	/* Remove this PF_FUNC from bcast pkt replication list */
	err = nix_update_bcast_mce_list(rvu, pcifunc, false);
@@ -1209,28 +1210,15 @@ int rvu_mbox_handler_nix_txschq_cfg(struct rvu *rvu,
static int nix_rx_vtag_cfg(struct rvu *rvu, int nixlf, int blkaddr,
			   struct nix_vtag_config *req)
{
	u64 regval = 0;
	u64 regval = req->vtag_size;

#define NIX_VTAGTYPE_MAX 0x8ull
#define NIX_VTAGSIZE_MASK 0x7ull
#define NIX_VTAGSTRIP_CAP_MASK 0x30ull

	if (req->rx.vtag_type >= NIX_VTAGTYPE_MAX ||
	    req->vtag_size > VTAGSIZE_T8)
	if (req->rx.vtag_type > 7 || req->vtag_size > VTAGSIZE_T8)
		return -EINVAL;

	regval = rvu_read64(rvu, blkaddr,
			    NIX_AF_LFX_RX_VTAG_TYPEX(nixlf, req->rx.vtag_type));

	if (req->rx.strip_vtag && req->rx.capture_vtag)
		regval |= BIT_ULL(4) | BIT_ULL(5);
	else if (req->rx.strip_vtag)
	if (req->rx.capture_vtag)
		regval |= BIT_ULL(5);
	if (req->rx.strip_vtag)
		regval |= BIT_ULL(4);
	else
		regval &= ~(BIT_ULL(4) | BIT_ULL(5));

	regval &= ~NIX_VTAGSIZE_MASK;
	regval |= req->vtag_size & NIX_VTAGSIZE_MASK;

	rvu_write64(rvu, blkaddr,
		    NIX_AF_LFX_RX_VTAG_TYPEX(nixlf, req->rx.vtag_type), regval);
@@ -1770,6 +1758,9 @@ int rvu_mbox_handler_nix_set_mac_addr(struct rvu *rvu,

	rvu_npc_install_ucast_entry(rvu, pcifunc, nixlf,
				    pfvf->rx_chan_base, req->mac_addr);

	rvu_npc_update_rxvlan(rvu, pcifunc, nixlf);

	return 0;
}

@@ -1803,6 +1794,9 @@ int rvu_mbox_handler_nix_set_rx_mode(struct rvu *rvu, struct nix_rx_mode *req,
	else
		rvu_npc_install_promisc_entry(rvu, pcifunc, nixlf,
					      pfvf->rx_chan_base, allmulti);

	rvu_npc_update_rxvlan(rvu, pcifunc, nixlf);

	return 0;
}

@@ -1941,6 +1935,59 @@ linkcfg:
	return 0;
}

int rvu_mbox_handler_nix_rxvlan_alloc(struct rvu *rvu, struct msg_req *req,
				      struct msg_rsp *rsp)
{
	struct npc_mcam_alloc_entry_req alloc_req = { };
	struct npc_mcam_alloc_entry_rsp alloc_rsp = { };
	struct npc_mcam_free_entry_req free_req = { };
	u16 pcifunc = req->hdr.pcifunc;
	int blkaddr, nixlf, err;
	struct rvu_pfvf *pfvf;

	pfvf = rvu_get_pfvf(rvu, pcifunc);
	if (pfvf->rxvlan)
		return 0;

	/* alloc new mcam entry */
	alloc_req.hdr.pcifunc = pcifunc;
	alloc_req.count = 1;

	err = rvu_mbox_handler_npc_mcam_alloc_entry(rvu, &alloc_req,
						    &alloc_rsp);
	if (err)
		return err;

	/* update entry to enable rxvlan offload */
	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
	if (blkaddr < 0) {
		err = NIX_AF_ERR_AF_LF_INVALID;
		goto free_entry;
	}

	nixlf = rvu_get_lf(rvu, &rvu->hw->block[blkaddr], pcifunc, 0);
	if (nixlf < 0) {
		err = NIX_AF_ERR_AF_LF_INVALID;
		goto free_entry;
	}

	pfvf->rxvlan_index = alloc_rsp.entry_list[0];
	/* all it means is that rxvlan_index is valid */
	pfvf->rxvlan = true;

	err = rvu_npc_update_rxvlan(rvu, pcifunc, nixlf);
	if (err)
		goto free_entry;

	return 0;
free_entry:
	free_req.hdr.pcifunc = pcifunc;
	free_req.entry = alloc_rsp.entry_list[0];
	rvu_mbox_handler_npc_mcam_free_entry(rvu, &free_req, rsp);
	pfvf->rxvlan = false;
	return err;
}

static void nix_link_config(struct rvu *rvu, int blkaddr)
{
	struct rvu_hwinfo *hw = rvu->hw;
+42 −1
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
 * published by the Free Software Foundation.
 */

#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/pci.h>

@@ -306,6 +307,7 @@ static u64 npc_get_mcam_action(struct rvu *rvu, struct npc_mcam *mcam,
void rvu_npc_install_ucast_entry(struct rvu *rvu, u16 pcifunc,
				 int nixlf, u64 chan, u8 *mac_addr)
{
	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
	struct npc_mcam *mcam = &rvu->hw->mcam;
	struct mcam_entry entry = { {0} };
	struct nix_rx_action action;
@@ -345,6 +347,17 @@ void rvu_npc_install_ucast_entry(struct rvu *rvu, u16 pcifunc,
	entry.action = *(u64 *)&action;
	npc_config_mcam_entry(rvu, mcam, blkaddr, index,
			      NIX_INTF_RX, &entry, true);

	/* add VLAN matching, setup action and save entry back for later */
	entry.kw[0] |= (NPC_LT_LB_STAG | NPC_LT_LB_CTAG) << 20;
	entry.kw_mask[0] |= (NPC_LT_LB_STAG & NPC_LT_LB_CTAG) << 20;

	entry.vtag_action = VTAG0_VALID_BIT |
			    FIELD_PREP(VTAG0_TYPE_MASK, 0) |
			    FIELD_PREP(VTAG0_LID_MASK, NPC_LID_LA) |
			    FIELD_PREP(VTAG0_RELPTR_MASK, 12);

	memcpy(&pfvf->entry, &entry, sizeof(entry));
}

void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc,
@@ -352,7 +365,7 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc,
{
	struct npc_mcam *mcam = &rvu->hw->mcam;
	struct mcam_entry entry = { {0} };
	struct nix_rx_action action;
	struct nix_rx_action action = { };
	int blkaddr, index, kwi;

	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
@@ -521,6 +534,8 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,

	rvu_write64(rvu, blkaddr,
		    NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action);

	rvu_npc_update_rxvlan(rvu, pcifunc, nixlf);
}

static void npc_enadis_default_entries(struct rvu *rvu, u16 pcifunc,
@@ -560,6 +575,8 @@ static void npc_enadis_default_entries(struct rvu *rvu, u16 pcifunc,
		rvu_npc_enable_promisc_entry(rvu, pcifunc, nixlf);
	else
		rvu_npc_disable_promisc_entry(rvu, pcifunc, nixlf);

	rvu_npc_update_rxvlan(rvu, pcifunc, nixlf);
}

void rvu_npc_disable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf)
@@ -2018,3 +2035,27 @@ int rvu_mbox_handler_npc_get_kex_cfg(struct rvu *rvu, struct msg_req *req,
	}
	return 0;
}

int rvu_npc_update_rxvlan(struct rvu *rvu, u16 pcifunc, int nixlf)
{
	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
	struct npc_mcam *mcam = &rvu->hw->mcam;
	int blkaddr, index;
	bool enable;

	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
	if (blkaddr < 0)
		return NIX_AF_ERR_AF_LF_INVALID;

	if (!pfvf->rxvlan)
		return 0;

	index = npc_get_nixlf_mcam_index(mcam, pcifunc, nixlf,
					 NIXLF_UCAST_ENTRY);
	pfvf->entry.action = npc_get_mcam_action(rvu, mcam, blkaddr, index);
	enable = is_mcam_entry_enabled(rvu, mcam, blkaddr, index);
	npc_config_mcam_entry(rvu, mcam, blkaddr, pfvf->rxvlan_index,
			      NIX_INTF_RX, &pfvf->entry, enable);

	return 0;
}