Commit 5cfa9a61 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'add-ethtool-ntuple-filters-support'

Naveen Mamindlapalli says:

====================
Add ethtool ntuple filters support

This patch series adds support for ethtool ntuple filters, unicast
address filtering, VLAN offload and SR-IOV ndo handlers. All of the
above features are based on the Admin Function(AF) driver support to
install and delete the low level MCAM entries. Each MCAM entry is
programmed with the packet fields to match and what actions to take
if the match succeeds. The PF driver requests AF driver to allocate
set of MCAM entries to be used to install the flows by that PF. The
entries will be freed when the PF driver is unloaded.

* The patches 1 to 4 adds AF driver infrastructure to install and
  delete the low level MCAM flow entries.
* Patch 5 adds ethtool ntuple filter support.
* Patch 6 adds unicast MAC address filtering.
* Patch 7 adds support for dumping the MCAM entries via debugfs.
* Patches 8 to 10 adds support for VLAN offload.
* Patch 10 to 11 adds support for SR-IOV ndo handlers.
* Patch 12 adds support to read the MCAM entries.

Misc:
* Removed redundant mailbox NIX_RXVLAN_ALLOC.
====================

Link: https://lore.kernel.org/r/20201114195303.25967-1-naveenm@marvell.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents f7365919 5a579667
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -9,4 +9,4 @@ obj-$(CONFIG_OCTEONTX2_AF) += octeontx2_af.o

octeontx2_mbox-y := mbox.o rvu_trace.o
octeontx2_af-y := cgx.o rvu.o rvu_cgx.o rvu_npa.o rvu_nix.o \
		  rvu_reg.o rvu_npc.o rvu_debugfs.o ptp.o
		  rvu_reg.o rvu_npc.o rvu_debugfs.o ptp.o rvu_npc_fs.o
+2 −0
Original line number Diff line number Diff line
@@ -162,6 +162,8 @@ enum nix_scheduler {
#define NIX_RX_ACTIONOP_UCAST_IPSEC	(0x2ull)
#define NIX_RX_ACTIONOP_MCAST		(0x3ull)
#define NIX_RX_ACTIONOP_RSS		(0x4ull)
/* Use the RX action set in the default unicast entry */
#define NIX_RX_ACTION_DEFAULT		(0xfull)

/* NIX TX action operation*/
#define NIX_TX_ACTIONOP_DROP		(0x0ull)
+159 −11
Original line number Diff line number Diff line
@@ -188,10 +188,19 @@ M(NPC_MCAM_ALLOC_AND_WRITE_ENTRY, 0x600b, npc_mcam_alloc_and_write_entry, \
					  npc_mcam_alloc_and_write_entry_rsp)  \
M(NPC_GET_KEX_CFG,	  0x600c, npc_get_kex_cfg,			\
				   msg_req, npc_get_kex_cfg_rsp)	\
M(NPC_INSTALL_FLOW,	  0x600d, npc_install_flow,			       \
				  npc_install_flow_req, npc_install_flow_rsp)  \
M(NPC_DELETE_FLOW,	  0x600e, npc_delete_flow,			\
				  npc_delete_flow_req, msg_rsp)		\
M(NPC_MCAM_READ_ENTRY,	  0x600f, npc_mcam_read_entry,			\
				  npc_mcam_read_entry_req,		\
				  npc_mcam_read_entry_rsp)		\
M(NPC_MCAM_READ_BASE_RULE, 0x6011, npc_read_base_steer_rule,            \
				   msg_req, npc_mcam_read_base_rule_rsp)  \
/* NIX mbox IDs (range 0x8000 - 0xFFFF) */				\
M(NIX_LF_ALLOC,		0x8000, nix_lf_alloc,				\
				 nix_lf_alloc_req, nix_lf_alloc_rsp)	\
M(NIX_LF_FREE,		0x8001, nix_lf_free, msg_req, msg_rsp)		\
M(NIX_LF_FREE,		0x8001, nix_lf_free, nix_lf_free_req, msg_rsp)	\
M(NIX_AQ_ENQ,		0x8002, nix_aq_enq, nix_aq_enq_req, nix_aq_enq_rsp)  \
M(NIX_HWCTX_DISABLE,	0x8003, nix_hwctx_disable,			\
				 hwctx_disable_req, msg_rsp)		\
@@ -200,7 +209,8 @@ M(NIX_TXSCH_ALLOC, 0x8004, nix_txsch_alloc, \
M(NIX_TXSCH_FREE,	0x8005, nix_txsch_free, nix_txsch_free_req, msg_rsp) \
M(NIX_TXSCHQ_CFG,	0x8006, nix_txschq_cfg, nix_txschq_config, msg_rsp)  \
M(NIX_STATS_RST,	0x8007, nix_stats_rst, msg_req, msg_rsp)	\
M(NIX_VTAG_CFG,		0x8008, nix_vtag_cfg, nix_vtag_config, msg_rsp)	\
M(NIX_VTAG_CFG,		0x8008, nix_vtag_cfg, nix_vtag_config,		\
				 nix_vtag_config_rsp)			\
M(NIX_RSS_FLOWKEY_CFG,  0x8009, nix_rss_flowkey_cfg,			\
				 nix_rss_flowkey_cfg,			\
				 nix_rss_flowkey_cfg_rsp)		\
@@ -216,7 +226,6 @@ M(NIX_SET_RX_CFG, 0x8010, nix_set_rx_cfg, nix_rx_cfg, msg_rsp) \
M(NIX_LSO_FORMAT_CFG,	0x8011, nix_lso_format_cfg,			\
				 nix_lso_format_cfg,			\
				 nix_lso_format_cfg_rsp)		\
M(NIX_RXVLAN_ALLOC,	0x8012, nix_rxvlan_alloc, msg_req, msg_rsp)	\
M(NIX_LF_PTP_TX_ENABLE, 0x8013, nix_lf_ptp_tx_enable, msg_req, msg_rsp)	\
M(NIX_LF_PTP_TX_DISABLE, 0x8014, nix_lf_ptp_tx_disable, msg_req, msg_rsp) \
M(NIX_BP_ENABLE,	0x8016, nix_bp_enable, nix_bp_cfg_req,	\
@@ -473,6 +482,20 @@ enum nix_af_status {
	NIX_AF_ERR_LSO_CFG_FAIL     = -418,
	NIX_AF_INVAL_NPA_PF_FUNC    = -419,
	NIX_AF_INVAL_SSO_PF_FUNC    = -420,
	NIX_AF_ERR_TX_VTAG_NOSPC    = -421,
	NIX_AF_ERR_RX_VTAG_INUSE    = -422,
};

/* For NIX RX vtag action  */
enum nix_rx_vtag0_type {
	NIX_AF_LFX_RX_VTAG_TYPE0, /* reserved for rx vlan offload */
	NIX_AF_LFX_RX_VTAG_TYPE1,
	NIX_AF_LFX_RX_VTAG_TYPE2,
	NIX_AF_LFX_RX_VTAG_TYPE3,
	NIX_AF_LFX_RX_VTAG_TYPE4,
	NIX_AF_LFX_RX_VTAG_TYPE5,
	NIX_AF_LFX_RX_VTAG_TYPE6,
	NIX_AF_LFX_RX_VTAG_TYPE7,
};

/* For NIX LF context alloc and init */
@@ -510,6 +533,13 @@ struct nix_lf_alloc_rsp {
	u8	sdp_links;  /* No. of SDP links present in HW */
};

struct nix_lf_free_req {
	struct mbox_msghdr hdr;
#define NIX_LF_DISABLE_FLOWS		BIT_ULL(0)
#define NIX_LF_DONT_FREE_TX_VTAG	BIT_ULL(1)
	u64 flags;
};

/* NIX AQ enqueue msg */
struct nix_aq_enq_req {
	struct mbox_msghdr hdr;
@@ -600,14 +630,40 @@ struct nix_vtag_config {
	union {
		/* valid when cfg_type is '0' */
		struct {
			/* tx vlan0 tag(C-VLAN) */
			u64 vlan0;
			/* tx vlan1 tag(S-VLAN) */
			u64 vlan1;
			/* insert tx vlan tag */
			u8 insert_vlan :1;
			/* insert tx double vlan tag */
			u8 double_vlan :1;
			u64 vtag0;
			u64 vtag1;

			/* cfg_vtag0 & cfg_vtag1 fields are valid
			 * when free_vtag0 & free_vtag1 are '0's.
			 */
			/* cfg_vtag0 = 1 to configure vtag0 */
			u8 cfg_vtag0 :1;
			/* cfg_vtag1 = 1 to configure vtag1 */
			u8 cfg_vtag1 :1;

			/* vtag0_idx & vtag1_idx are only valid when
			 * both cfg_vtag0 & cfg_vtag1 are '0's,
			 * these fields are used along with free_vtag0
			 * & free_vtag1 to free the nix lf's tx_vlan
			 * configuration.
			 *
			 * Denotes the indices of tx_vtag def registers
			 * that needs to be cleared and freed.
			 */
			int vtag0_idx;
			int vtag1_idx;

			/* free_vtag0 & free_vtag1 fields are valid
			 * when cfg_vtag0 & cfg_vtag1 are '0's.
			 */
			/* free_vtag0 = 1 clears vtag0 configuration
			 * vtag0_idx denotes the index to be cleared.
			 */
			u8 free_vtag0 :1;
			/* free_vtag1 = 1 clears vtag1 configuration
			 * vtag1_idx denotes the index to be cleared.
			 */
			u8 free_vtag1 :1;
		} tx;

		/* valid when cfg_type is '1' */
@@ -622,6 +678,17 @@ struct nix_vtag_config {
	};
};

struct nix_vtag_config_rsp {
	struct mbox_msghdr hdr;
	int vtag0_idx;
	int vtag1_idx;
	/* Indices of tx_vtag def registers used to configure
	 * tx vtag0 & vtag1 headers, these indices are valid
	 * when nix_vtag_config mbox requested for vtag0 and/
	 * or vtag1 configuration.
	 */
};

struct nix_rss_flowkey_cfg {
	struct mbox_msghdr hdr;
	int	mcam_index;  /* MCAM entry index to modify */
@@ -882,6 +949,87 @@ struct npc_get_kex_cfg_rsp {
	u8 mkex_pfl_name[MKEX_NAME_LEN];
};

struct flow_msg {
	unsigned char dmac[6];
	unsigned char smac[6];
	__be16 etype;
	__be16 vlan_etype;
	__be16 vlan_tci;
	union {
		__be32 ip4src;
		__be32 ip6src[4];
	};
	union {
		__be32 ip4dst;
		__be32 ip6dst[4];
	};
	u8 tos;
	u8 ip_ver;
	u8 ip_proto;
	u8 tc;
	__be16 sport;
	__be16 dport;
};

struct npc_install_flow_req {
	struct mbox_msghdr hdr;
	struct flow_msg packet;
	struct flow_msg mask;
	u64 features;
	u16 entry;
	u16 channel;
	u8 intf;
	u8 set_cntr; /* If counter is available set counter for this entry ? */
	u8 default_rule;
	u8 append; /* overwrite(0) or append(1) flow to default rule? */
	u16 vf;
	/* action */
	u32 index;
	u16 match_id;
	u8 flow_key_alg;
	u8 op;
	/* vtag rx action */
	u8 vtag0_type;
	u8 vtag0_valid;
	u8 vtag1_type;
	u8 vtag1_valid;
	/* vtag tx action */
	u16 vtag0_def;
	u8  vtag0_op;
	u16 vtag1_def;
	u8  vtag1_op;
};

struct npc_install_flow_rsp {
	struct mbox_msghdr hdr;
	int counter; /* negative if no counter else counter number */
};

struct npc_delete_flow_req {
	struct mbox_msghdr hdr;
	u16 entry;
	u16 start;/*Disable range of entries */
	u16 end;
	u8 all; /* PF + VFs */
};

struct npc_mcam_read_entry_req {
	struct mbox_msghdr hdr;
	u16 entry;	 /* MCAM entry to read */
};

struct npc_mcam_read_entry_rsp {
	struct mbox_msghdr hdr;
	struct mcam_entry entry_data;
	u8 intf;
	u8 enable;
};

struct npc_mcam_read_base_rule_rsp {
	struct mbox_msghdr hdr;
	struct mcam_entry entry;
};

enum ptp_op {
	PTP_OP_ADJFINE = 0,
	PTP_OP_GET_CLOCK = 1,
+133 −4
Original line number Diff line number Diff line
@@ -140,6 +140,63 @@ enum npc_kpu_lh_ltype {
	NPC_LT_LH_CUSTOM1 = 0xF,
};

/* NPC port kind defines how the incoming or outgoing packets
 * are processed. NPC accepts packets from up to 64 pkinds.
 * Software assigns pkind for each incoming port such as CGX
 * Ethernet interfaces, LBK interfaces, etc.
 */
enum npc_pkind_type {
	NPC_TX_DEF_PKIND = 63ULL,	/* NIX-TX PKIND */
};

/* list of known and supported fields in packet header and
 * fields present in key structure.
 */
enum key_fields {
	NPC_DMAC,
	NPC_SMAC,
	NPC_ETYPE,
	NPC_OUTER_VID,
	NPC_TOS,
	NPC_SIP_IPV4,
	NPC_DIP_IPV4,
	NPC_SIP_IPV6,
	NPC_DIP_IPV6,
	NPC_SPORT_TCP,
	NPC_DPORT_TCP,
	NPC_SPORT_UDP,
	NPC_DPORT_UDP,
	NPC_SPORT_SCTP,
	NPC_DPORT_SCTP,
	NPC_HEADER_FIELDS_MAX,
	NPC_CHAN = NPC_HEADER_FIELDS_MAX, /* Valid when Rx */
	NPC_PF_FUNC, /* Valid when Tx */
	NPC_ERRLEV,
	NPC_ERRCODE,
	NPC_LXMB,
	NPC_LA,
	NPC_LB,
	NPC_LC,
	NPC_LD,
	NPC_LE,
	NPC_LF,
	NPC_LG,
	NPC_LH,
	/* Ethertype for untagged frame */
	NPC_ETYPE_ETHER,
	/* Ethertype for single tagged frame */
	NPC_ETYPE_TAG1,
	/* Ethertype for double tagged frame */
	NPC_ETYPE_TAG2,
	/* outer vlan tci for single tagged frame */
	NPC_VLAN_TAG1,
	/* outer vlan tci for double tagged frame */
	NPC_VLAN_TAG2,
	/* other header fields programmed to extract but not of our interest */
	NPC_UNKNOWN,
	NPC_KEY_FIELDS_MAX,
};

struct npc_kpu_profile_cam {
	u8 state;
	u8 state_mask;
@@ -300,11 +357,63 @@ struct nix_rx_action {
/* NPC_AF_INTFX_KEX_CFG field masks */
#define NPC_PARSE_NIBBLE		GENMASK_ULL(30, 0)

/* NPC_PARSE_KEX_S nibble definitions for each field */
#define NPC_PARSE_NIBBLE_CHAN		GENMASK_ULL(2, 0)
#define NPC_PARSE_NIBBLE_ERRLEV		BIT_ULL(3)
#define NPC_PARSE_NIBBLE_ERRCODE	GENMASK_ULL(5, 4)
#define NPC_PARSE_NIBBLE_L2L3_BCAST	BIT_ULL(6)
#define NPC_PARSE_NIBBLE_LA_FLAGS	GENMASK_ULL(8, 7)
#define NPC_PARSE_NIBBLE_LA_LTYPE	BIT_ULL(9)
#define NPC_PARSE_NIBBLE_LB_FLAGS	GENMASK_ULL(11, 10)
#define NPC_PARSE_NIBBLE_LB_LTYPE	BIT_ULL(12)
#define NPC_PARSE_NIBBLE_LC_FLAGS	GENMASK_ULL(14, 13)
#define NPC_PARSE_NIBBLE_LC_LTYPE	BIT_ULL(15)
#define NPC_PARSE_NIBBLE_LD_FLAGS	GENMASK_ULL(17, 16)
#define NPC_PARSE_NIBBLE_LD_LTYPE	BIT_ULL(18)
#define NPC_PARSE_NIBBLE_LE_FLAGS	GENMASK_ULL(20, 19)
#define NPC_PARSE_NIBBLE_LE_LTYPE	BIT_ULL(21)
#define NPC_PARSE_NIBBLE_LF_FLAGS	GENMASK_ULL(23, 22)
#define NPC_PARSE_NIBBLE_LF_LTYPE	BIT_ULL(24)
#define NPC_PARSE_NIBBLE_LG_FLAGS	GENMASK_ULL(26, 25)
#define NPC_PARSE_NIBBLE_LG_LTYPE	BIT_ULL(27)
#define NPC_PARSE_NIBBLE_LH_FLAGS	GENMASK_ULL(29, 28)
#define NPC_PARSE_NIBBLE_LH_LTYPE	BIT_ULL(30)

struct nix_tx_action {
#if defined(__BIG_ENDIAN_BITFIELD)
	u64	rsvd_63_48	:16;
	u64	match_id	:16;
	u64	index		:20;
	u64	rsvd_11_8	:8;
	u64	op		:4;
#else
	u64	op		:4;
	u64	rsvd_11_8	:8;
	u64	index		:20;
	u64	match_id	:16;
	u64	rsvd_63_48	:16;
#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)
#define RX_VTAG0_VALID_BIT		BIT_ULL(15)
#define RX_VTAG0_TYPE_MASK		GENMASK_ULL(14, 12)
#define RX_VTAG0_LID_MASK		GENMASK_ULL(10, 8)
#define RX_VTAG0_RELPTR_MASK		GENMASK_ULL(7, 0)
#define RX_VTAG1_VALID_BIT		BIT_ULL(47)
#define RX_VTAG1_TYPE_MASK		GENMASK_ULL(46, 44)
#define RX_VTAG1_LID_MASK		GENMASK_ULL(42, 40)
#define RX_VTAG1_RELPTR_MASK		GENMASK_ULL(39, 32)

/* NIX Transmit Vtag Action Structure */
#define TX_VTAG0_DEF_MASK		GENMASK_ULL(25, 16)
#define TX_VTAG0_OP_MASK		GENMASK_ULL(13, 12)
#define TX_VTAG0_LID_MASK		GENMASK_ULL(10, 8)
#define TX_VTAG0_RELPTR_MASK		GENMASK_ULL(7, 0)
#define TX_VTAG1_DEF_MASK		GENMASK_ULL(57, 48)
#define TX_VTAG1_OP_MASK		GENMASK_ULL(45, 44)
#define TX_VTAG1_LID_MASK		GENMASK_ULL(42, 40)
#define TX_VTAG1_RELPTR_MASK		GENMASK_ULL(39, 32)

struct npc_mcam_kex {
	/* MKEX Profle Header */
@@ -357,4 +466,24 @@ struct npc_lt_def_cfg {
	struct npc_lt_def	pck_iip4;
};

struct rvu_npc_mcam_rule {
	struct flow_msg packet;
	struct flow_msg mask;
	u8 intf;
	union {
		struct nix_tx_action tx_action;
		struct nix_rx_action rx_action;
	};
	u64 vtag_action;
	struct list_head list;
	u64 features;
	u16 owner;
	u16 entry;
	u16 cntr;
	bool has_cntr;
	u8 default_rule;
	bool enable;
	bool vfvlan_cfg;
};

#endif /* NPC_H */
+85 −14
Original line number Diff line number Diff line
@@ -148,6 +148,20 @@
			(((bytesm1) << 16) | ((hdr_ofs) << 8) | ((ena) << 7) | \
			 ((flags_ena) << 6) | ((key_ofs) & 0x3F))

/* Rx parse key extract nibble enable */
#define NPC_PARSE_NIBBLE_INTF_RX	(NPC_PARSE_NIBBLE_CHAN | \
					 NPC_PARSE_NIBBLE_LA_LTYPE | \
					 NPC_PARSE_NIBBLE_LB_LTYPE | \
					 NPC_PARSE_NIBBLE_LC_LTYPE | \
					 NPC_PARSE_NIBBLE_LD_LTYPE | \
					 NPC_PARSE_NIBBLE_LE_LTYPE)
/* Tx parse key extract nibble enable */
#define NPC_PARSE_NIBBLE_INTF_TX	(NPC_PARSE_NIBBLE_LA_LTYPE | \
					 NPC_PARSE_NIBBLE_LB_LTYPE | \
					 NPC_PARSE_NIBBLE_LC_LTYPE | \
					 NPC_PARSE_NIBBLE_LD_LTYPE | \
					 NPC_PARSE_NIBBLE_LE_LTYPE)

enum npc_kpu_parser_state {
	NPC_S_NA = 0,
	NPC_S_KPU1_ETHER,
@@ -13385,9 +13399,10 @@ static struct npc_mcam_kex npc_mkex_default = {
	.name = "default",
	.kpu_version = NPC_KPU_PROFILE_VER,
	.keyx_cfg = {
		/* nibble: LA..LE (ltype only) + Channel */
		[NIX_INTF_RX] = ((u64)NPC_MCAM_KEY_X2 << 32) | 0x49247,
		[NIX_INTF_TX] = ((u64)NPC_MCAM_KEY_X2 << 32) | ((1ULL << 19) - 1),
		/* nibble: LA..LE (ltype only) + channel */
		[NIX_INTF_RX] = ((u64)NPC_MCAM_KEY_X2 << 32) | NPC_PARSE_NIBBLE_INTF_RX,
		/* nibble: LA..LE (ltype only) */
		[NIX_INTF_TX] = ((u64)NPC_MCAM_KEY_X2 << 32) | NPC_PARSE_NIBBLE_INTF_TX,
	},
	.intf_lid_lt_ld = {
	/* Default RX MCAM KEX profile */
@@ -13405,12 +13420,14 @@ static struct npc_mcam_kex npc_mkex_default = {
			/* Layer B: Single VLAN (CTAG) */
			/* CTAG VLAN[2..3] + Ethertype, 4 bytes, KW0[63:32] */
			[NPC_LT_LB_CTAG] = {
				KEX_LD_CFG(0x03, 0x0, 0x1, 0x0, 0x4),
				KEX_LD_CFG(0x03, 0x2, 0x1, 0x0, 0x4),
			},
			/* Layer B: Stacked VLAN (STAG|QinQ) */
			[NPC_LT_LB_STAG_QINQ] = {
				/* CTAG VLAN[2..3] + Ethertype, 4 bytes, KW0[63:32] */
				KEX_LD_CFG(0x03, 0x4, 0x1, 0x0, 0x4),
				/* Outer VLAN: 2 bytes, KW0[63:48] */
				KEX_LD_CFG(0x01, 0x2, 0x1, 0x0, 0x6),
				/* Ethertype: 2 bytes, KW0[47:32] */
				KEX_LD_CFG(0x01, 0x8, 0x1, 0x0, 0x4),
			},
			[NPC_LT_LB_FDSA] = {
				/* SWITCH PORT: 1 byte, KW0[63:48] */
@@ -13436,17 +13453,71 @@ static struct npc_mcam_kex npc_mkex_default = {
		[NPC_LID_LD] = {
			/* Layer D:UDP */
			[NPC_LT_LD_UDP] = {
				/* SPORT: 2 bytes, KW3[15:0] */
				KEX_LD_CFG(0x1, 0x0, 0x1, 0x0, 0x18),
				/* DPORT: 2 bytes, KW3[31:16] */
				KEX_LD_CFG(0x1, 0x2, 0x1, 0x0, 0x1a),
				/* SPORT+DPORT: 4 bytes, KW3[31:0] */
				KEX_LD_CFG(0x3, 0x0, 0x1, 0x0, 0x18),
			},
			/* Layer D:TCP */
			[NPC_LT_LD_TCP] = {
				/* SPORT+DPORT: 4 bytes, KW3[31:0] */
				KEX_LD_CFG(0x3, 0x0, 0x1, 0x0, 0x18),
			},
		},
	},

	/* Default TX MCAM KEX profile */
	[NIX_INTF_TX] = {
		[NPC_LID_LA] = {
			/* Layer A: NIX_INST_HDR_S + Ethernet */
			/* NIX appends 8 bytes of NIX_INST_HDR_S at the
			 * start of each TX packet supplied to NPC.
			 */
			[NPC_LT_LA_IH_NIX_ETHER] = {
				/* PF_FUNC: 2B , KW0 [47:32] */
				KEX_LD_CFG(0x01, 0x0, 0x1, 0x0, 0x4),
				/* DMAC: 6 bytes, KW1[63:16] */
				KEX_LD_CFG(0x05, 0x8, 0x1, 0x0, 0xa),
			},
		},
		[NPC_LID_LB] = {
			/* Layer B: Single VLAN (CTAG) */
			[NPC_LT_LB_CTAG] = {
				/* CTAG VLAN[2..3] KW0[63:48] */
				KEX_LD_CFG(0x01, 0x2, 0x1, 0x0, 0x6),
				/* CTAG VLAN[2..3] KW1[15:0] */
				KEX_LD_CFG(0x01, 0x4, 0x1, 0x0, 0x8),
			},
			/* Layer B: Stacked VLAN (STAG|QinQ) */
			[NPC_LT_LB_STAG_QINQ] = {
				/* Outer VLAN: 2 bytes, KW0[63:48] */
				KEX_LD_CFG(0x01, 0x2, 0x1, 0x0, 0x6),
				/* Outer VLAN: 2 Bytes, KW1[15:0] */
				KEX_LD_CFG(0x01, 0x8, 0x1, 0x0, 0x8),
			},
		},
		[NPC_LID_LC] = {
			/* Layer C: IPv4 */
			[NPC_LT_LC_IP] = {
				/* SIP+DIP: 8 bytes, KW2[63:0] */
				KEX_LD_CFG(0x07, 0xc, 0x1, 0x0, 0x10),
				/* TOS: 1 byte, KW1[63:56] */
				KEX_LD_CFG(0x0, 0x1, 0x1, 0x0, 0xf),
			},
			/* Layer C: IPv6 */
			[NPC_LT_LC_IP6] = {
				/* Everything up to SADDR: 8 bytes, KW2[63:0] */
				KEX_LD_CFG(0x07, 0x0, 0x1, 0x0, 0x10),
			},
		},
		[NPC_LID_LD] = {
			/* Layer D:UDP */
			[NPC_LT_LD_UDP] = {
				/* SPORT+DPORT: 4 bytes, KW3[31:0] */
				KEX_LD_CFG(0x3, 0x0, 0x1, 0x0, 0x18),
			},
			/* Layer D:TCP */
			[NPC_LT_LD_TCP] = {
				/* SPORT: 2 bytes, KW3[15:0] */
				KEX_LD_CFG(0x1, 0x0, 0x1, 0x0, 0x18),
				/* DPORT: 2 bytes, KW3[31:16] */
				KEX_LD_CFG(0x1, 0x2, 0x1, 0x0, 0x1a),
				/* SPORT+DPORT: 4 bytes, KW3[31:0] */
				KEX_LD_CFG(0x3, 0x0, 0x1, 0x0, 0x18),
			},
		},
	},
Loading