diff options
Diffstat (limited to 'drivers/net/ethernet/marvell/octeontx2/af')
| -rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/cgx.c | 60 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/mbox.h | 89 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/npc.h | 7 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/npc_profile.h | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/rvu.c | 6 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/rvu.h | 18 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c | 18 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c | 192 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c | 61 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c | 12 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c | 198 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c | 79 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h | 21 | 
13 files changed, 569 insertions, 194 deletions
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c index 68deae529bc9..fac6474ad694 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c @@ -30,10 +30,35 @@  static LIST_HEAD(cgx_list);  /* Convert firmware speed encoding to user format(Mbps) */ -static u32 cgx_speed_mbps[CGX_LINK_SPEED_MAX]; +static const u32 cgx_speed_mbps[CGX_LINK_SPEED_MAX] = { +	[CGX_LINK_NONE] = 0, +	[CGX_LINK_10M] = 10, +	[CGX_LINK_100M] = 100, +	[CGX_LINK_1G] = 1000, +	[CGX_LINK_2HG] = 2500, +	[CGX_LINK_5G] = 5000, +	[CGX_LINK_10G] = 10000, +	[CGX_LINK_20G] = 20000, +	[CGX_LINK_25G] = 25000, +	[CGX_LINK_40G] = 40000, +	[CGX_LINK_50G] = 50000, +	[CGX_LINK_80G] = 80000, +	[CGX_LINK_100G] = 100000, +};  /* Convert firmware lmac type encoding to string */ -static char *cgx_lmactype_string[LMAC_MODE_MAX]; +static const char *cgx_lmactype_string[LMAC_MODE_MAX] = { +	[LMAC_MODE_SGMII] = "SGMII", +	[LMAC_MODE_XAUI] = "XAUI", +	[LMAC_MODE_RXAUI] = "RXAUI", +	[LMAC_MODE_10G_R] = "10G_R", +	[LMAC_MODE_40G_R] = "40G_R", +	[LMAC_MODE_QSGMII] = "QSGMII", +	[LMAC_MODE_25G_R] = "25G_R", +	[LMAC_MODE_50G_R] = "50G_R", +	[LMAC_MODE_100G_R] = "100G_R", +	[LMAC_MODE_USXGMII] = "USXGMII", +};  /* CGX PHY management internal APIs */  static int cgx_fwi_link_change(struct cgx *cgx, int lmac_id, bool en); @@ -659,34 +684,6 @@ int cgx_fwi_cmd_generic(u64 req, u64 *resp, struct cgx *cgx, int lmac_id)  	return err;  } -static inline void cgx_link_usertable_init(void) -{ -	cgx_speed_mbps[CGX_LINK_NONE] = 0; -	cgx_speed_mbps[CGX_LINK_10M] = 10; -	cgx_speed_mbps[CGX_LINK_100M] = 100; -	cgx_speed_mbps[CGX_LINK_1G] = 1000; -	cgx_speed_mbps[CGX_LINK_2HG] = 2500; -	cgx_speed_mbps[CGX_LINK_5G] = 5000; -	cgx_speed_mbps[CGX_LINK_10G] = 10000; -	cgx_speed_mbps[CGX_LINK_20G] = 20000; -	cgx_speed_mbps[CGX_LINK_25G] = 25000; -	cgx_speed_mbps[CGX_LINK_40G] = 40000; -	cgx_speed_mbps[CGX_LINK_50G] = 50000; -	cgx_speed_mbps[CGX_LINK_80G] = 80000; -	cgx_speed_mbps[CGX_LINK_100G] = 100000; - -	cgx_lmactype_string[LMAC_MODE_SGMII] = "SGMII"; -	cgx_lmactype_string[LMAC_MODE_XAUI] = "XAUI"; -	cgx_lmactype_string[LMAC_MODE_RXAUI] = "RXAUI"; -	cgx_lmactype_string[LMAC_MODE_10G_R] = "10G_R"; -	cgx_lmactype_string[LMAC_MODE_40G_R] = "40G_R"; -	cgx_lmactype_string[LMAC_MODE_QSGMII] = "QSGMII"; -	cgx_lmactype_string[LMAC_MODE_25G_R] = "25G_R"; -	cgx_lmactype_string[LMAC_MODE_50G_R] = "50G_R"; -	cgx_lmactype_string[LMAC_MODE_100G_R] = "100G_R"; -	cgx_lmactype_string[LMAC_MODE_USXGMII] = "USXGMII"; -} -  static int cgx_link_usertable_index_map(int speed)  {  	switch (speed) { @@ -828,7 +825,7 @@ static inline void link_status_user_format(u64 lstat,  					   struct cgx_link_user_info *linfo,  					   struct cgx *cgx, u8 lmac_id)  { -	char *lmac_string; +	const char *lmac_string;  	linfo->link_up = FIELD_GET(RESP_LINKSTAT_UP, lstat);  	linfo->full_duplex = FIELD_GET(RESP_LINKSTAT_FDUPLEX, lstat); @@ -1377,7 +1374,6 @@ static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id)  	list_add(&cgx->cgx_list, &cgx_list); -	cgx_link_usertable_init();  	cgx_populate_features(cgx); diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h index ea456099b33c..cedb2616c509 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h @@ -74,13 +74,13 @@ struct otx2_mbox {  	struct otx2_mbox_dev *dev;  }; -/* Header which preceeds all mbox messages */ +/* Header which precedes all mbox messages */  struct mbox_hdr {  	u64 msg_size;	/* Total msgs size embedded */  	u16  num_msgs;   /* No of msgs embedded */  }; -/* Header which preceeds every msg and is also part of it */ +/* Header which precedes every msg and is also part of it */  struct mbox_msghdr {  	u16 pcifunc;     /* Who's sending this msg */  	u16 id;          /* Mbox message ID */ @@ -177,6 +177,9 @@ M(CPT_LF_ALLOC,		0xA00, cpt_lf_alloc, cpt_lf_alloc_req_msg,	\  M(CPT_LF_FREE,		0xA01, cpt_lf_free, msg_req, msg_rsp)		\  M(CPT_RD_WR_REGISTER,	0xA02, cpt_rd_wr_register,  cpt_rd_wr_reg_msg,	\  			       cpt_rd_wr_reg_msg)			\ +M(CPT_STATS,            0xA05, cpt_sts, cpt_sts_req, cpt_sts_rsp)	\ +M(CPT_RXC_TIME_CFG,     0xA06, cpt_rxc_time_cfg, cpt_rxc_time_cfg_req,  \ +			       msg_rsp)                                 \  /* NPC mbox IDs (range 0x6000 - 0x7FFF) */				\  M(NPC_MCAM_ALLOC_ENTRY,	0x6000, npc_mcam_alloc_entry, npc_mcam_alloc_entry_req,\  				npc_mcam_alloc_entry_rsp)		\ @@ -216,6 +219,9 @@ M(NPC_MCAM_READ_ENTRY,	  0x600f, npc_mcam_read_entry,			\  				  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)  \ +M(NPC_MCAM_GET_STATS, 0x6012, npc_mcam_entry_stats,                     \ +				   npc_mcam_get_stats_req,              \ +				   npc_mcam_get_stats_rsp)              \  /* NIX mbox IDs (range 0x8000 - 0xFFFF) */				\  M(NIX_LF_ALLOC,		0x8000, nix_lf_alloc,				\  				 nix_lf_alloc_req, nix_lf_alloc_rsp)	\ @@ -277,8 +283,8 @@ struct msg_req {  	struct mbox_msghdr hdr;  }; -/* Generic rsponse msg used a ack or response for those mbox - * messages which doesn't have a specific rsp msg format. +/* Generic response msg used an ack or response for those mbox + * messages which don't have a specific rsp msg format.   */  struct msg_rsp {  	struct mbox_msghdr hdr; @@ -299,7 +305,7 @@ struct ready_msg_rsp {  /* Structure for requesting resource provisioning.   * 'modify' flag to be used when either requesting more - * or to detach partial of a cetain resource type. + * or to detach partial of a certain resource type.   * Rest of the fields specify how many of what type to   * be attached.   * To request LFs from two blocks of same type this mailbox @@ -489,7 +495,7 @@ struct cgx_set_link_mode_rsp {  };  #define RVU_LMAC_FEAT_FC		BIT_ULL(0) /* pause frames */ -#define RVU_LMAC_FEAT_PTP		BIT_ULL(1) /* precison time protocol */ +#define RVU_LMAC_FEAT_PTP		BIT_ULL(1) /* precision time protocol */  #define RVU_MAC_VERSION			BIT_ULL(2)  #define RVU_MAC_CGX			BIT_ULL(3)  #define RVU_MAC_RPM			BIT_ULL(4) @@ -605,6 +611,7 @@ enum nix_af_status {  	NIX_AF_INVAL_SSO_PF_FUNC    = -420,  	NIX_AF_ERR_TX_VTAG_NOSPC    = -421,  	NIX_AF_ERR_RX_VTAG_INUSE    = -422, +	NIX_AF_ERR_NPC_KEY_NOT_SUPP = -423,  };  /* For NIX RX vtag action  */ @@ -1141,6 +1148,7 @@ struct npc_install_flow_req {  	u64 features;  	u16 entry;  	u16 channel; +	u16 chan_mask;  	u8 intf;  	u8 set_cntr; /* If counter is available set counter for this entry ? */  	u8 default_rule; @@ -1193,6 +1201,17 @@ struct npc_mcam_read_base_rule_rsp {  	struct mcam_entry entry;  }; +struct npc_mcam_get_stats_req { +	struct mbox_msghdr hdr; +	u16 entry; /* mcam entry */ +}; + +struct npc_mcam_get_stats_rsp { +	struct mbox_msghdr hdr; +	u64 stat;  /* counter stats */ +	u8 stat_ena; /* enabled */ +}; +  enum ptp_op {  	PTP_OP_ADJFINE = 0,  	PTP_OP_GET_CLOCK = 1, @@ -1239,4 +1258,62 @@ struct cpt_lf_alloc_req_msg {  	int blkaddr;  }; +/* Mailbox message request and response format for CPT stats. */ +struct cpt_sts_req { +	struct mbox_msghdr hdr; +	u8 blkaddr; +}; + +struct cpt_sts_rsp { +	struct mbox_msghdr hdr; +	u64 inst_req_pc; +	u64 inst_lat_pc; +	u64 rd_req_pc; +	u64 rd_lat_pc; +	u64 rd_uc_pc; +	u64 active_cycles_pc; +	u64 ctx_mis_pc; +	u64 ctx_hit_pc; +	u64 ctx_aop_pc; +	u64 ctx_aop_lat_pc; +	u64 ctx_ifetch_pc; +	u64 ctx_ifetch_lat_pc; +	u64 ctx_ffetch_pc; +	u64 ctx_ffetch_lat_pc; +	u64 ctx_wback_pc; +	u64 ctx_wback_lat_pc; +	u64 ctx_psh_pc; +	u64 ctx_psh_lat_pc; +	u64 ctx_err; +	u64 ctx_enc_id; +	u64 ctx_flush_timer; +	u64 rxc_time; +	u64 rxc_time_cfg; +	u64 rxc_active_sts; +	u64 rxc_zombie_sts; +	u64 busy_sts_ae; +	u64 free_sts_ae; +	u64 busy_sts_se; +	u64 free_sts_se; +	u64 busy_sts_ie; +	u64 free_sts_ie; +	u64 exe_err_info; +	u64 cptclk_cnt; +	u64 diag; +	u64 rxc_dfrg; +	u64 x2p_link_cfg0; +	u64 x2p_link_cfg1; +}; + +/* Mailbox message request format to configure reassembly timeout. */ +struct cpt_rxc_time_cfg_req { +	struct mbox_msghdr hdr; +	int blkaddr; +	u32 step; +	u16 zombie_thres; +	u16 zombie_limit; +	u16 active_thres; +	u16 active_limit; +}; +  #endif /* MBOX_H */ diff --git a/drivers/net/ethernet/marvell/octeontx2/af/npc.h b/drivers/net/ethernet/marvell/octeontx2/af/npc.h index 3c640f6aba92..1e012e787260 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/npc.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/npc.h @@ -167,6 +167,8 @@ enum key_fields {  	NPC_IPPROTO_SCTP,  	NPC_IPPROTO_AH,  	NPC_IPPROTO_ESP, +	NPC_IPPROTO_ICMP, +	NPC_IPPROTO_ICMP6,  	NPC_SPORT_TCP,  	NPC_DPORT_TCP,  	NPC_SPORT_UDP, @@ -420,6 +422,11 @@ struct nix_tx_action {  #define TX_VTAG1_LID_MASK		GENMASK_ULL(42, 40)  #define TX_VTAG1_RELPTR_MASK		GENMASK_ULL(39, 32) +/* NPC MCAM reserved entry index per nixlf */ +#define NIXLF_UCAST_ENTRY	0 +#define NIXLF_BCAST_ENTRY	1 +#define NIXLF_PROMISC_ENTRY	2 +  struct npc_mcam_kex {  	/* MKEX Profle Header */  	u64 mkex_sign; /* "mcam-kex-profile" (8 bytes/ASCII characters) */ diff --git a/drivers/net/ethernet/marvell/octeontx2/af/npc_profile.h b/drivers/net/ethernet/marvell/octeontx2/af/npc_profile.h index b192692b4fc4..5c372d2c24a1 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/npc_profile.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/npc_profile.h @@ -13499,8 +13499,6 @@ static struct npc_mcam_kex npc_mkex_default = {  			[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] = { diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c index d9a1a71c7ccc..ab24a5e8ee8a 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c @@ -2462,8 +2462,10 @@ static void rvu_unregister_interrupts(struct rvu *rvu)  		    INTR_MASK(rvu->hw->total_pfs) & ~1ULL);  	for (irq = 0; irq < rvu->num_vec; irq++) { -		if (rvu->irq_allocated[irq]) +		if (rvu->irq_allocated[irq]) {  			free_irq(pci_irq_vector(rvu->pdev, irq), rvu); +			rvu->irq_allocated[irq] = false; +		}  	}  	pci_free_irq_vectors(rvu->pdev); @@ -2975,8 +2977,8 @@ static void rvu_remove(struct pci_dev *pdev)  	struct rvu *rvu = pci_get_drvdata(pdev);  	rvu_dbg_exit(rvu); -	rvu_unregister_interrupts(rvu);  	rvu_unregister_dl(rvu); +	rvu_unregister_interrupts(rvu);  	rvu_flr_wq_destroy(rvu);  	rvu_cgx_exit(rvu);  	rvu_fwdata_exit(rvu); diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h index fa6e46e36ae4..c2cc4806d13c 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h @@ -548,6 +548,12 @@ static inline int is_afvf(u16 pcifunc)  	return !(pcifunc & ~RVU_PFVF_FUNC_MASK);  } +/* check if PF_FUNC is AF */ +static inline bool is_pffunc_af(u16 pcifunc) +{ +	return !pcifunc; +} +  static inline bool is_rvu_fwdata_valid(struct rvu *rvu)  {  	return (rvu->fwdata->header_magic == RVU_FWDATA_HEADER_MAGIC) && @@ -640,7 +646,8 @@ int npc_config_ts_kpuaction(struct rvu *rvu, int pf, u16 pcifunc, bool en);  void rvu_npc_install_ucast_entry(struct rvu *rvu, u16 pcifunc,  				 int nixlf, u64 chan, u8 *mac_addr);  void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc, -				   int nixlf, u64 chan, bool allmulti); +				   int nixlf, u64 chan, u8 chan_cnt, +				   bool allmulti);  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, @@ -665,9 +672,6 @@ int rvu_npc_get_tx_nibble_cfg(struct rvu *rvu, u64 nibble_ena);  int npc_mcam_verify_channel(struct rvu *rvu, u16 pcifunc, u8 intf, u16 channel);  int npc_flow_steering_init(struct rvu *rvu, int blkaddr);  const char *npc_get_field_name(u8 hdr); -bool rvu_npc_write_default_rule(struct rvu *rvu, int blkaddr, int nixlf, -				u16 pcifunc, u8 intf, struct mcam_entry *entry, -				int *entry_index);  int npc_get_bank(struct npc_mcam *mcam, int index);  void npc_mcam_enable_flows(struct rvu *rvu, u16 target);  void npc_mcam_disable_flows(struct rvu *rvu, u16 target); @@ -678,6 +682,12 @@ void npc_read_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,  			 u8 *intf, u8 *ena);  bool is_mac_feature_supported(struct rvu *rvu, int pf, int feature);  u32  rvu_cgx_get_fifolen(struct rvu *rvu); +void *rvu_first_cgx_pdata(struct rvu *rvu); + +int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, u16 pcifunc, int nixlf, +			     int type); +bool is_mcam_entry_enabled(struct rvu *rvu, struct npc_mcam *mcam, int blkaddr, +			   int index);  /* CPT APIs */  int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int lf, int slot); diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c index e668e482383a..6e2bf4fcd29c 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c @@ -89,6 +89,21 @@ void *rvu_cgx_pdata(u8 cgx_id, struct rvu *rvu)  	return rvu->cgx_idmap[cgx_id];  } +/* Return first enabled CGX instance if none are enabled then return NULL */ +void *rvu_first_cgx_pdata(struct rvu *rvu) +{ +	int first_enabled_cgx = 0; +	void *cgxd = NULL; + +	for (; first_enabled_cgx < rvu->cgx_cnt_max; first_enabled_cgx++) { +		cgxd = rvu_cgx_pdata(first_enabled_cgx, rvu); +		if (cgxd) +			break; +	} + +	return cgxd; +} +  /* Based on P2X connectivity find mapped NIX block for a PF */  static void rvu_map_cgx_nix_block(struct rvu *rvu, int pf,  				  int cgx_id, int lmac_id) @@ -711,10 +726,9 @@ int rvu_mbox_handler_cgx_features_get(struct rvu *rvu,  u32 rvu_cgx_get_fifolen(struct rvu *rvu)  {  	struct mac_ops *mac_ops; -	int rvu_def_cgx_id = 0;  	u32 fifo_len; -	mac_ops = get_mac_ops(rvu_cgx_pdata(rvu_def_cgx_id, rvu)); +	mac_ops = get_mac_ops(rvu_first_cgx_pdata(rvu));  	fifo_len = mac_ops ? mac_ops->fifo_len : 0;  	return fifo_len; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c index 0945c3a3b180..89253f7bdadb 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c @@ -1,6 +1,7 @@  // SPDX-License-Identifier: GPL-2.0-only  /* Copyright (C) 2020 Marvell. */ +#include <linux/bitfield.h>  #include <linux/pci.h>  #include "rvu_struct.h"  #include "rvu_reg.h" @@ -9,6 +10,28 @@  /* CPT PF device id */  #define	PCI_DEVID_OTX2_CPT_PF	0xA0FD +#define	PCI_DEVID_OTX2_CPT10K_PF 0xA0F2 + +/* Length of initial context fetch in 128 byte words */ +#define CPT_CTX_ILEN    2 + +#define cpt_get_eng_sts(e_min, e_max, rsp, etype)                   \ +({                                                                  \ +	u64 free_sts = 0, busy_sts = 0;                             \ +	typeof(rsp) _rsp = rsp;                                     \ +	u32 e, i;                                                   \ +								    \ +	for (e = (e_min), i = 0; e < (e_max); e++, i++) {           \ +		reg = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_STS(e)); \ +		if (reg & 0x1)                                      \ +			busy_sts |= 1ULL << i;                      \ +								    \ +		if (reg & 0x2)                                      \ +			free_sts |= 1ULL << i;                      \ +	}                                                           \ +	(_rsp)->busy_sts_##etype = busy_sts;                        \ +	(_rsp)->free_sts_##etype = free_sts;                        \ +})  static int get_cpt_pf_num(struct rvu *rvu)  { @@ -21,7 +44,8 @@ static int get_cpt_pf_num(struct rvu *rvu)  		if (!pdev)  			continue; -		if (pdev->device == PCI_DEVID_OTX2_CPT_PF) { +		if (pdev->device == PCI_DEVID_OTX2_CPT_PF || +		    pdev->device == PCI_DEVID_OTX2_CPT10K_PF) {  			cpt_pf_num = i;  			put_device(&pdev->dev);  			break; @@ -55,6 +79,17 @@ static bool is_cpt_vf(struct rvu *rvu, u16 pcifunc)  	return true;  } +static int validate_and_get_cpt_blkaddr(int req_blkaddr) +{ +	int blkaddr; + +	blkaddr = req_blkaddr ? req_blkaddr : BLKADDR_CPT0; +	if (blkaddr != BLKADDR_CPT0 && blkaddr != BLKADDR_CPT1) +		return -EINVAL; + +	return blkaddr; +} +  int rvu_mbox_handler_cpt_lf_alloc(struct rvu *rvu,  				  struct cpt_lf_alloc_req_msg *req,  				  struct msg_rsp *rsp) @@ -65,9 +100,9 @@ int rvu_mbox_handler_cpt_lf_alloc(struct rvu *rvu,  	int num_lfs, slot;  	u64 val; -	blkaddr = req->blkaddr ? req->blkaddr : BLKADDR_CPT0; -	if (blkaddr != BLKADDR_CPT0 && blkaddr != BLKADDR_CPT1) -		return -ENODEV; +	blkaddr = validate_and_get_cpt_blkaddr(req->blkaddr); +	if (blkaddr < 0) +		return blkaddr;  	if (req->eng_grpmsk == 0x0)  		return CPT_AF_ERR_GRP_INVALID; @@ -103,6 +138,9 @@ int rvu_mbox_handler_cpt_lf_alloc(struct rvu *rvu,  		/* Set CPT LF group and priority */  		val = (u64)req->eng_grpmsk << 48 | 1; +		if (!is_rvu_otx2(rvu)) +			val |= (CPT_CTX_ILEN << 17); +  		rvu_write64(rvu, blkaddr, CPT_AF_LFX_CTL(cptlf), val);  		/* Set CPT LF NIX_PF_FUNC and SSO_PF_FUNC */ @@ -162,7 +200,9 @@ static bool is_valid_offset(struct rvu *rvu, struct cpt_rd_wr_reg_msg *req)  	struct rvu_block *block;  	struct rvu_pfvf *pfvf; -	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_CPT, 0); +	blkaddr = validate_and_get_cpt_blkaddr(req->blkaddr); +	if (blkaddr < 0) +		return blkaddr;  	/* Registers that can be accessed from PF/VF */  	if ((offset & 0xFF000) ==  CPT_AF_LFX_CTL(0) || @@ -192,6 +232,7 @@ static bool is_valid_offset(struct rvu *rvu, struct cpt_rd_wr_reg_msg *req)  		case CPT_AF_PF_FUNC:  		case CPT_AF_BLK_RST:  		case CPT_AF_CONSTANTS1: +		case CPT_AF_CTX_FLUSH_TIMER:  			return true;  		} @@ -217,9 +258,9 @@ int rvu_mbox_handler_cpt_rd_wr_register(struct rvu *rvu,  {  	int blkaddr; -	blkaddr = req->blkaddr ? req->blkaddr : BLKADDR_CPT0; -	if (blkaddr != BLKADDR_CPT0 && blkaddr != BLKADDR_CPT1) -		return -ENODEV; +	blkaddr = validate_and_get_cpt_blkaddr(req->blkaddr); +	if (blkaddr < 0) +		return blkaddr;  	/* This message is accepted only if sent from CPT PF/VF */  	if (!is_cpt_pf(rvu, req->hdr.pcifunc) && @@ -241,6 +282,141 @@ int rvu_mbox_handler_cpt_rd_wr_register(struct rvu *rvu,  	return 0;  } +static void get_ctx_pc(struct rvu *rvu, struct cpt_sts_rsp *rsp, int blkaddr) +{ +	if (is_rvu_otx2(rvu)) +		return; + +	rsp->ctx_mis_pc = rvu_read64(rvu, blkaddr, CPT_AF_CTX_MIS_PC); +	rsp->ctx_hit_pc = rvu_read64(rvu, blkaddr, CPT_AF_CTX_HIT_PC); +	rsp->ctx_aop_pc = rvu_read64(rvu, blkaddr, CPT_AF_CTX_AOP_PC); +	rsp->ctx_aop_lat_pc = rvu_read64(rvu, blkaddr, +					 CPT_AF_CTX_AOP_LATENCY_PC); +	rsp->ctx_ifetch_pc = rvu_read64(rvu, blkaddr, CPT_AF_CTX_IFETCH_PC); +	rsp->ctx_ifetch_lat_pc = rvu_read64(rvu, blkaddr, +					    CPT_AF_CTX_IFETCH_LATENCY_PC); +	rsp->ctx_ffetch_pc = rvu_read64(rvu, blkaddr, CPT_AF_CTX_FFETCH_PC); +	rsp->ctx_ffetch_lat_pc = rvu_read64(rvu, blkaddr, +					    CPT_AF_CTX_FFETCH_LATENCY_PC); +	rsp->ctx_wback_pc = rvu_read64(rvu, blkaddr, CPT_AF_CTX_FFETCH_PC); +	rsp->ctx_wback_lat_pc = rvu_read64(rvu, blkaddr, +					   CPT_AF_CTX_FFETCH_LATENCY_PC); +	rsp->ctx_psh_pc = rvu_read64(rvu, blkaddr, CPT_AF_CTX_FFETCH_PC); +	rsp->ctx_psh_lat_pc = rvu_read64(rvu, blkaddr, +					 CPT_AF_CTX_FFETCH_LATENCY_PC); +	rsp->ctx_err = rvu_read64(rvu, blkaddr, CPT_AF_CTX_ERR); +	rsp->ctx_enc_id = rvu_read64(rvu, blkaddr, CPT_AF_CTX_ENC_ID); +	rsp->ctx_flush_timer = rvu_read64(rvu, blkaddr, CPT_AF_CTX_FLUSH_TIMER); + +	rsp->rxc_time = rvu_read64(rvu, blkaddr, CPT_AF_RXC_TIME); +	rsp->rxc_time_cfg = rvu_read64(rvu, blkaddr, CPT_AF_RXC_TIME_CFG); +	rsp->rxc_active_sts = rvu_read64(rvu, blkaddr, CPT_AF_RXC_ACTIVE_STS); +	rsp->rxc_zombie_sts = rvu_read64(rvu, blkaddr, CPT_AF_RXC_ZOMBIE_STS); +	rsp->rxc_dfrg = rvu_read64(rvu, blkaddr, CPT_AF_RXC_DFRG); +	rsp->x2p_link_cfg0 = rvu_read64(rvu, blkaddr, CPT_AF_X2PX_LINK_CFG(0)); +	rsp->x2p_link_cfg1 = rvu_read64(rvu, blkaddr, CPT_AF_X2PX_LINK_CFG(1)); +} + +static void get_eng_sts(struct rvu *rvu, struct cpt_sts_rsp *rsp, int blkaddr) +{ +	u16 max_ses, max_ies, max_aes; +	u32 e_min = 0, e_max = 0; +	u64 reg; + +	reg = rvu_read64(rvu, blkaddr, CPT_AF_CONSTANTS1); +	max_ses = reg & 0xffff; +	max_ies = (reg >> 16) & 0xffff; +	max_aes = (reg >> 32) & 0xffff; + +	/* Get AE status */ +	e_min = max_ses + max_ies; +	e_max = max_ses + max_ies + max_aes; +	cpt_get_eng_sts(e_min, e_max, rsp, ae); +	/* Get SE status */ +	e_min = 0; +	e_max = max_ses; +	cpt_get_eng_sts(e_min, e_max, rsp, se); +	/* Get IE status */ +	e_min = max_ses; +	e_max = max_ses + max_ies; +	cpt_get_eng_sts(e_min, e_max, rsp, ie); +} + +int rvu_mbox_handler_cpt_sts(struct rvu *rvu, struct cpt_sts_req *req, +			     struct cpt_sts_rsp *rsp) +{ +	int blkaddr; + +	blkaddr = validate_and_get_cpt_blkaddr(req->blkaddr); +	if (blkaddr < 0) +		return blkaddr; + +	/* This message is accepted only if sent from CPT PF/VF */ +	if (!is_cpt_pf(rvu, req->hdr.pcifunc) && +	    !is_cpt_vf(rvu, req->hdr.pcifunc)) +		return CPT_AF_ERR_ACCESS_DENIED; + +	get_ctx_pc(rvu, rsp, blkaddr); + +	/* Get CPT engines status */ +	get_eng_sts(rvu, rsp, blkaddr); + +	/* Read CPT instruction PC registers */ +	rsp->inst_req_pc = rvu_read64(rvu, blkaddr, CPT_AF_INST_REQ_PC); +	rsp->inst_lat_pc = rvu_read64(rvu, blkaddr, CPT_AF_INST_LATENCY_PC); +	rsp->rd_req_pc = rvu_read64(rvu, blkaddr, CPT_AF_RD_REQ_PC); +	rsp->rd_lat_pc = rvu_read64(rvu, blkaddr, CPT_AF_RD_LATENCY_PC); +	rsp->rd_uc_pc = rvu_read64(rvu, blkaddr, CPT_AF_RD_UC_PC); +	rsp->active_cycles_pc = rvu_read64(rvu, blkaddr, +					   CPT_AF_ACTIVE_CYCLES_PC); +	rsp->exe_err_info = rvu_read64(rvu, blkaddr, CPT_AF_EXE_ERR_INFO); +	rsp->cptclk_cnt = rvu_read64(rvu, blkaddr, CPT_AF_CPTCLK_CNT); +	rsp->diag = rvu_read64(rvu, blkaddr, CPT_AF_DIAG); + +	return 0; +} + +#define RXC_ZOMBIE_THRES  GENMASK_ULL(59, 48) +#define RXC_ZOMBIE_LIMIT  GENMASK_ULL(43, 32) +#define RXC_ACTIVE_THRES  GENMASK_ULL(27, 16) +#define RXC_ACTIVE_LIMIT  GENMASK_ULL(11, 0) +#define RXC_ACTIVE_COUNT  GENMASK_ULL(60, 48) +#define RXC_ZOMBIE_COUNT  GENMASK_ULL(60, 48) + +static void cpt_rxc_time_cfg(struct rvu *rvu, struct cpt_rxc_time_cfg_req *req, +			     int blkaddr) +{ +	u64 dfrg_reg; + +	dfrg_reg = FIELD_PREP(RXC_ZOMBIE_THRES, req->zombie_thres); +	dfrg_reg |= FIELD_PREP(RXC_ZOMBIE_LIMIT, req->zombie_limit); +	dfrg_reg |= FIELD_PREP(RXC_ACTIVE_THRES, req->active_thres); +	dfrg_reg |= FIELD_PREP(RXC_ACTIVE_LIMIT, req->active_limit); + +	rvu_write64(rvu, blkaddr, CPT_AF_RXC_TIME_CFG, req->step); +	rvu_write64(rvu, blkaddr, CPT_AF_RXC_DFRG, dfrg_reg); +} + +int rvu_mbox_handler_cpt_rxc_time_cfg(struct rvu *rvu, +				      struct cpt_rxc_time_cfg_req *req, +				      struct msg_rsp *rsp) +{ +	int blkaddr; + +	blkaddr = validate_and_get_cpt_blkaddr(req->blkaddr); +	if (blkaddr < 0) +		return blkaddr; + +	/* This message is accepted only if sent from CPT PF/VF */ +	if (!is_cpt_pf(rvu, req->hdr.pcifunc) && +	    !is_cpt_vf(rvu, req->hdr.pcifunc)) +		return CPT_AF_ERR_ACCESS_DENIED; + +	cpt_rxc_time_cfg(rvu, req, blkaddr); + +	return 0; +} +  #define INPROG_INFLIGHT(reg)    ((reg) & 0x1FF)  #define INPROG_GRB_PARTIAL(reg) ((reg) & BIT_ULL(31))  #define INPROG_GRB(reg)         (((reg) >> 32) & 0xFF) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c index aa2ca8780b9c..9bf8eaabf9ab 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c @@ -234,12 +234,14 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp,  					  char __user *buffer,  					  size_t count, loff_t *ppos)  { -	int index, off = 0, flag = 0, go_back = 0, off_prev; +	int index, off = 0, flag = 0, go_back = 0, len = 0;  	struct rvu *rvu = filp->private_data;  	int lf, pf, vf, pcifunc;  	struct rvu_block block;  	int bytes_not_copied; +	int lf_str_size = 12;  	int buf_size = 2048; +	char *lfs;  	char *buf;  	/* don't allow partial reads */ @@ -249,12 +251,20 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp,  	buf = kzalloc(buf_size, GFP_KERNEL);  	if (!buf)  		return -ENOSPC; -	off +=	scnprintf(&buf[off], buf_size - 1 - off, "\npcifunc\t\t"); + +	lfs = kzalloc(lf_str_size, GFP_KERNEL); +	if (!lfs) { +		kfree(buf); +		return -ENOMEM; +	} +	off +=	scnprintf(&buf[off], buf_size - 1 - off, "%-*s", lf_str_size, +			  "pcifunc");  	for (index = 0; index < BLK_COUNT; index++) -		if (strlen(rvu->hw->block[index].name)) -			off +=	scnprintf(&buf[off], buf_size - 1 - off, -					  "%*s\t", (index - 1) * 2, -					  rvu->hw->block[index].name); +		if (strlen(rvu->hw->block[index].name)) { +			off += scnprintf(&buf[off], buf_size - 1 - off, +					 "%-*s", lf_str_size, +					 rvu->hw->block[index].name); +		}  	off += scnprintf(&buf[off], buf_size - 1 - off, "\n");  	for (pf = 0; pf < rvu->hw->total_pfs; pf++) {  		for (vf = 0; vf <= rvu->hw->total_vfs; vf++) { @@ -263,14 +273,15 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp,  				continue;  			if (vf) { +				sprintf(lfs, "PF%d:VF%d", pf, vf - 1);  				go_back = scnprintf(&buf[off],  						    buf_size - 1 - off, -						    "PF%d:VF%d\t\t", pf, -						    vf - 1); +						    "%-*s", lf_str_size, lfs);  			} else { +				sprintf(lfs, "PF%d", pf);  				go_back = scnprintf(&buf[off],  						    buf_size - 1 - off, -						    "PF%d\t\t", pf); +						    "%-*s", lf_str_size, lfs);  			}  			off += go_back; @@ -278,20 +289,22 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp,  				block = rvu->hw->block[index];  				if (!strlen(block.name))  					continue; -				off_prev = off; +				len = 0; +				lfs[len] = '\0';  				for (lf = 0; lf < block.lf.max; lf++) {  					if (block.fn_map[lf] != pcifunc)  						continue;  					flag = 1; -					off += scnprintf(&buf[off], buf_size - 1 -							- off, "%3d,", lf); +					len += sprintf(&lfs[len], "%d,", lf);  				} -				if (flag && off_prev != off) -					off--; -				else -					go_back++; + +				if (flag) +					len--; +				lfs[len] = '\0';  				off += scnprintf(&buf[off], buf_size - 1 - off, -						"\t"); +						 "%-*s", lf_str_size, lfs); +				if (!strlen(lfs)) +					go_back += lf_str_size;  			}  			if (!flag)  				off -= go_back; @@ -303,6 +316,7 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp,  	}  	bytes_not_copied = copy_to_user(buffer, buf, off); +	kfree(lfs);  	kfree(buf);  	if (bytes_not_copied) @@ -319,7 +333,6 @@ static int rvu_dbg_rvu_pf_cgx_map_display(struct seq_file *filp, void *unused)  	struct rvu *rvu = filp->private;  	struct pci_dev *pdev = NULL;  	struct mac_ops *mac_ops; -	int rvu_def_cgx_id = 0;  	char cgx[10], lmac[10];  	struct rvu_pfvf *pfvf;  	int pf, domain, blkid; @@ -327,7 +340,10 @@ static int rvu_dbg_rvu_pf_cgx_map_display(struct seq_file *filp, void *unused)  	u16 pcifunc;  	domain = 2; -	mac_ops = get_mac_ops(rvu_cgx_pdata(rvu_def_cgx_id, rvu)); +	mac_ops = get_mac_ops(rvu_first_cgx_pdata(rvu)); +	/* There can be no CGX devices at all */ +	if (!mac_ops) +		return 0;  	seq_printf(filp, "PCI dev\t\tRVU PF Func\tNIX block\t%s\tLMAC\n",  		   mac_ops->name);  	for (pf = 0; pf < rvu->hw->total_pfs; pf++) { @@ -1818,7 +1834,6 @@ static void rvu_dbg_cgx_init(struct rvu *rvu)  {  	struct mac_ops *mac_ops;  	unsigned long lmac_bmap; -	int rvu_def_cgx_id = 0;  	int i, lmac_id;  	char dname[20];  	void *cgx; @@ -1826,7 +1841,7 @@ static void rvu_dbg_cgx_init(struct rvu *rvu)  	if (!cgx_get_cgxcnt_max())  		return; -	mac_ops = get_mac_ops(rvu_cgx_pdata(rvu_def_cgx_id, rvu)); +	mac_ops = get_mac_ops(rvu_first_cgx_pdata(rvu));  	if (!mac_ops)  		return; @@ -2002,7 +2017,7 @@ static void rvu_dbg_npc_mcam_show_flows(struct seq_file *s,  			seq_printf(s, "mask 0x%x\n", ntohs(rule->mask.etype));  			break;  		case NPC_OUTER_VID: -			seq_printf(s, "%d ", ntohs(rule->packet.vlan_tci)); +			seq_printf(s, "0x%x ", ntohs(rule->packet.vlan_tci));  			seq_printf(s, "mask 0x%x\n",  				   ntohs(rule->mask.vlan_tci));  			break; @@ -2145,7 +2160,7 @@ static int rvu_dbg_npc_mcam_show_rules(struct seq_file *s, void *unused)  		seq_printf(s, "\tmcam entry: %d\n", iter->entry);  		rvu_dbg_npc_mcam_show_flows(s, iter); -		if (iter->intf == NIX_INTF_RX) { +		if (is_npc_intf_rx(iter->intf)) {  			target = iter->rx_action.pf_func;  			pf = (target >> RVU_PFVF_PF_SHIFT) & RVU_PFVF_PF_MASK;  			seq_printf(s, "\tForward to: PF%d ", pf); diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c index d3000194e2d3..0a8bd667cb11 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c @@ -273,7 +273,8 @@ static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf)  		pfvf->rx_chan_cnt = 1;  		pfvf->tx_chan_cnt = 1;  		rvu_npc_install_promisc_entry(rvu, pcifunc, nixlf, -					      pfvf->rx_chan_base, false); +					      pfvf->rx_chan_base, +					      pfvf->rx_chan_cnt, false);  		break;  	} @@ -2629,7 +2630,7 @@ static int set_flowkey_fields(struct nix_rx_flowkey_alg *alg, u32 flow_cfg)  	struct nix_rx_flowkey_alg *field;  	struct nix_rx_flowkey_alg tmp;  	u32 key_type, valid_key; -	int l4_key_offset; +	int l4_key_offset = 0;  	if (!alg)  		return -EINVAL; @@ -3088,7 +3089,8 @@ int rvu_mbox_handler_nix_set_rx_mode(struct rvu *rvu, struct nix_rx_mode *req,  		rvu_npc_disable_promisc_entry(rvu, pcifunc, nixlf);  	else  		rvu_npc_install_promisc_entry(rvu, pcifunc, nixlf, -					      pfvf->rx_chan_base, allmulti); +					      pfvf->rx_chan_base, +					      pfvf->rx_chan_cnt, allmulti);  	return 0;  } @@ -3635,9 +3637,7 @@ int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req,  	if (err)  		return err; -	rvu_npc_disable_default_entries(rvu, pcifunc, nixlf); - -	npc_mcam_disable_flows(rvu, pcifunc); +	rvu_npc_disable_mcam_entries(rvu, pcifunc, nixlf);  	return rvu_cgx_start_stop_io(rvu, pcifunc, false);  } diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c index 04bb0803a5c5..0bc4529691ec 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c @@ -22,10 +22,6 @@  #define RSVD_MCAM_ENTRIES_PER_PF	2 /* Bcast & Promisc */  #define RSVD_MCAM_ENTRIES_PER_NIXLF	1 /* Ucast for LFs */ -#define NIXLF_UCAST_ENTRY	0 -#define NIXLF_BCAST_ENTRY	1 -#define NIXLF_PROMISC_ENTRY	2 -  #define NPC_PARSE_RESULT_DMAC_OFFSET	8  #define NPC_HW_TSTAMP_OFFSET		8  #define NPC_KEX_CHAN_MASK		0xFFFULL @@ -96,6 +92,10 @@ int npc_mcam_verify_channel(struct rvu *rvu, u16 pcifunc, u8 intf, u16 channel)  	if (is_npc_intf_tx(intf))  		return 0; +	/* return in case of AF installed rules */ +	if (is_pffunc_af(pcifunc)) +		return 0; +  	if (is_afvf(pcifunc)) {  		end = rvu_get_num_lbk_chans();  		if (end < 0) @@ -196,8 +196,8 @@ static int npc_get_ucast_mcam_index(struct npc_mcam *mcam, u16 pcifunc,  	return mcam->nixlf_offset + (max + nixlf) * RSVD_MCAM_ENTRIES_PER_NIXLF;  } -static int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, -				    u16 pcifunc, int nixlf, int type) +int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, +			     u16 pcifunc, int nixlf, int type)  {  	int pf = rvu_get_pf(pcifunc);  	int index; @@ -230,8 +230,8 @@ int npc_get_bank(struct npc_mcam *mcam, int index)  	return bank;  } -static bool is_mcam_entry_enabled(struct rvu *rvu, struct npc_mcam *mcam, -				  int blkaddr, int index) +bool is_mcam_entry_enabled(struct rvu *rvu, struct npc_mcam *mcam, +			   int blkaddr, int index)  {  	int bank = npc_get_bank(mcam, index);  	u64 cfg; @@ -647,13 +647,17 @@ void rvu_npc_install_ucast_entry(struct rvu *rvu, u16 pcifunc,  }  void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc, -				   int nixlf, u64 chan, bool allmulti) +				   int nixlf, u64 chan, u8 chan_cnt, +				   bool allmulti)  {  	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc); +	struct npc_install_flow_req req = { 0 }; +	struct npc_install_flow_rsp rsp = { 0 };  	struct npc_mcam *mcam = &rvu->hw->mcam; -	int blkaddr, ucast_idx, index, kwi; -	struct mcam_entry entry = { {0} }; -	struct nix_rx_action action = { }; +	int blkaddr, ucast_idx, index; +	u8 mac_addr[ETH_ALEN] = { 0 }; +	struct nix_rx_action action; +	u64 relaxed_mask;  	/* Only PF or AF VF can add a promiscuous entry */  	if ((pcifunc & RVU_PFVF_FUNC_MASK) && !is_afvf(pcifunc)) @@ -663,24 +667,15 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc,  	if (blkaddr < 0)  		return; +	*(u64 *)&action = 0x00;  	index = npc_get_nixlf_mcam_index(mcam, pcifunc,  					 nixlf, NIXLF_PROMISC_ENTRY); -	entry.kw[0] = chan; -	entry.kw_mask[0] = 0xFFFULL; - -	if (allmulti) { -		kwi = NPC_KEXOF_DMAC / sizeof(u64); -		entry.kw[kwi] = BIT_ULL(40); /* LSB bit of 1st byte in DMAC */ -		entry.kw_mask[kwi] = BIT_ULL(40); -	} - -	ucast_idx = npc_get_nixlf_mcam_index(mcam, pcifunc, -					     nixlf, NIXLF_UCAST_ENTRY); -  	/* If the corresponding PF's ucast action is RSS,  	 * use the same action for promisc also  	 */ +	ucast_idx = npc_get_nixlf_mcam_index(mcam, pcifunc, +					     nixlf, NIXLF_UCAST_ENTRY);  	if (is_mcam_entry_enabled(rvu, mcam, blkaddr, ucast_idx))  		*(u64 *)&action = npc_get_mcam_action(rvu, mcam,  							blkaddr, ucast_idx); @@ -691,9 +686,36 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc,  		action.pf_func = pcifunc;  	} -	entry.action = *(u64 *)&action; -	npc_config_mcam_entry(rvu, mcam, blkaddr, index, -			      pfvf->nix_rx_intf, &entry, true); +	if (allmulti) { +		mac_addr[0] = 0x01;	/* LSB bit of 1st byte in DMAC */ +		ether_addr_copy(req.packet.dmac, mac_addr); +		ether_addr_copy(req.mask.dmac, mac_addr); +		req.features = BIT_ULL(NPC_DMAC); +	} + +	req.chan_mask = 0xFFFU; +	if (chan_cnt > 1) { +		if (!is_power_of_2(chan_cnt)) { +			dev_err(rvu->dev, +				"%s: channel count more than 1, must be power of 2\n", __func__); +			return; +		} +		relaxed_mask = GENMASK_ULL(BITS_PER_LONG_LONG - 1, +					   ilog2(chan_cnt)); +		req.chan_mask &= relaxed_mask; +	} + +	req.channel = chan; +	req.intf = pfvf->nix_rx_intf; +	req.entry = index; +	req.op = action.op; +	req.hdr.pcifunc = 0; /* AF is requester */ +	req.vf = pcifunc; +	req.index = action.index; +	req.match_id = action.match_id; +	req.flow_key_alg = action.flow_key_alg; + +	rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp);  }  static void npc_enadis_promisc_entry(struct rvu *rvu, u16 pcifunc, @@ -728,12 +750,14 @@ 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)  { +	struct rvu_pfvf *pfvf; +	struct npc_install_flow_req req = { 0 }; +	struct npc_install_flow_rsp rsp = { 0 };  	struct npc_mcam *mcam = &rvu->hw->mcam; -	struct mcam_entry entry = { {0} };  	struct rvu_hwinfo *hw = rvu->hw; -	struct nix_rx_action action; -	struct rvu_pfvf *pfvf;  	int blkaddr, index; +	u32 req_index = 0; +	u8 op;  	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);  	if (blkaddr < 0) @@ -755,32 +779,29 @@ void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc,  	index = npc_get_nixlf_mcam_index(mcam, pcifunc,  					 nixlf, NIXLF_BCAST_ENTRY); -	/* Match ingress channel */ -	entry.kw[0] = chan; -	entry.kw_mask[0] = 0xfffull; - -	/* Match broadcast MAC address. -	 * DMAC is extracted at 0th bit of PARSE_KEX::KW1 -	 */ -	entry.kw[1] = 0xffffffffffffull; -	entry.kw_mask[1] = 0xffffffffffffull; - -	*(u64 *)&action = 0x00;  	if (!hw->cap.nix_rx_multicast) {  		/* Early silicon doesn't support pkt replication,  		 * so install entry with UCAST action, so that PF  		 * receives all broadcast packets.  		 */ -		action.op = NIX_RX_ACTIONOP_UCAST; -		action.pf_func = pcifunc; +		op = NIX_RX_ACTIONOP_UCAST;  	} else { -		action.index = pfvf->bcast_mce_idx; -		action.op = NIX_RX_ACTIONOP_MCAST; +		op = NIX_RX_ACTIONOP_MCAST; +		req_index = pfvf->bcast_mce_idx;  	} -	entry.action = *(u64 *)&action; -	npc_config_mcam_entry(rvu, mcam, blkaddr, index, -			      pfvf->nix_rx_intf, &entry, true); +	eth_broadcast_addr((u8 *)&req.packet.dmac); +	eth_broadcast_addr((u8 *)&req.mask.dmac); +	req.features = BIT_ULL(NPC_DMAC); +	req.channel = chan; +	req.intf = pfvf->nix_rx_intf; +	req.entry = index; +	req.op = op; +	req.hdr.pcifunc = 0; /* AF is requester */ +	req.vf = pcifunc; +	req.index = req_index; + +	rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp);  }  void rvu_npc_enable_bcast_entry(struct rvu *rvu, u16 pcifunc, bool enable) @@ -967,7 +988,7 @@ void rvu_npc_disable_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf)  {  	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);  	struct npc_mcam *mcam = &rvu->hw->mcam; -	struct rvu_npc_mcam_rule *rule; +	struct rvu_npc_mcam_rule *rule, *tmp;  	int blkaddr;  	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); @@ -977,15 +998,18 @@ void rvu_npc_disable_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf)  	mutex_lock(&mcam->lock);  	/* Disable MCAM entries directing traffic to this 'pcifunc' */ -	list_for_each_entry(rule, &mcam->mcam_rules, list) { +	list_for_each_entry_safe(rule, tmp, &mcam->mcam_rules, list) {  		if (is_npc_intf_rx(rule->intf) &&  		    rule->rx_action.pf_func == pcifunc) {  			npc_enable_mcam_entry(rvu, mcam, blkaddr,  					      rule->entry, false);  			rule->enable = false;  			/* Indicate that default rule is disabled */ -			if (rule->default_rule) +			if (rule->default_rule) {  				pfvf->def_ucast_rule = NULL; +				list_del(&rule->list); +				kfree(rule); +			}  		}  	} @@ -1674,6 +1698,9 @@ void rvu_npc_get_mcam_counter_alloc_info(struct rvu *rvu, u16 pcifunc,  static int npc_mcam_verify_entry(struct npc_mcam *mcam,  				 u16 pcifunc, int entry)  { +	/* verify AF installed entries */ +	if (is_pffunc_af(pcifunc)) +		return 0;  	/* Verify if entry is valid and if it is indeed  	 * allocated to the requesting PFFUNC.  	 */ @@ -2268,6 +2295,10 @@ int rvu_mbox_handler_npc_mcam_write_entry(struct rvu *rvu,  		goto exit;  	} +	/* For AF installed rules, the nix_intf should be set to target NIX */ +	if (is_pffunc_af(req->hdr.pcifunc)) +		nix_intf = req->intf; +  	npc_config_mcam_entry(rvu, mcam, blkaddr, req->entry, nix_intf,  			      &req->entry_data, req->enable_entry); @@ -2490,10 +2521,10 @@ int rvu_mbox_handler_npc_mcam_free_counter(struct rvu *rvu,  		index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry);  		if (index >= mcam->bmap_entries)  			break; +		entry = index + 1;  		if (mcam->entry2cntr_map[index] != req->cntr)  			continue; -		entry = index + 1;  		npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr,  					      index, req->cntr);  	} @@ -2730,30 +2761,6 @@ int rvu_mbox_handler_npc_get_kex_cfg(struct rvu *rvu, struct msg_req *req,  	return 0;  } -bool rvu_npc_write_default_rule(struct rvu *rvu, int blkaddr, int nixlf, -				u16 pcifunc, u8 intf, struct mcam_entry *entry, -				int *index) -{ -	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc); -	struct npc_mcam *mcam = &rvu->hw->mcam; -	bool enable; -	u8 nix_intf; - -	if (is_npc_intf_tx(intf)) -		nix_intf = pfvf->nix_tx_intf; -	else -		nix_intf = pfvf->nix_rx_intf; - -	*index = npc_get_nixlf_mcam_index(mcam, pcifunc, -					  nixlf, NIXLF_UCAST_ENTRY); -	/* dont force enable unicast entry  */ -	enable = is_mcam_entry_enabled(rvu, mcam, blkaddr, *index); -	npc_config_mcam_entry(rvu, mcam, blkaddr, *index, nix_intf, -			      entry, enable); - -	return enable; -} -  int rvu_mbox_handler_npc_read_base_steer_rule(struct rvu *rvu,  					      struct msg_req *req,  					      struct npc_mcam_read_base_rule_rsp *rsp) @@ -2799,3 +2806,42 @@ read_entry:  out:  	return rc;  } + +int rvu_mbox_handler_npc_mcam_entry_stats(struct rvu *rvu, +					  struct npc_mcam_get_stats_req *req, +					  struct npc_mcam_get_stats_rsp *rsp) +{ +	struct npc_mcam *mcam = &rvu->hw->mcam; +	u16 index, cntr; +	int blkaddr; +	u64 regval; +	u32 bank; + +	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); +	if (blkaddr < 0) +		return NPC_MCAM_INVALID_REQ; + +	mutex_lock(&mcam->lock); + +	index = req->entry & (mcam->banksize - 1); +	bank = npc_get_bank(mcam, req->entry); + +	/* read MCAM entry STAT_ACT register */ +	regval = rvu_read64(rvu, blkaddr, NPC_AF_MCAMEX_BANKX_STAT_ACT(index, bank)); + +	if (!(regval & BIT_ULL(9))) { +		rsp->stat_ena = 0; +		mutex_unlock(&mcam->lock); +		return 0; +	} + +	cntr = regval & 0x1FF; + +	rsp->stat_ena = 1; +	rsp->stat = rvu_read64(rvu, blkaddr, NPC_AF_MATCH_STATX(cntr)); +	rsp->stat &= BIT_ULL(48) - 1; + +	mutex_unlock(&mcam->lock); + +	return 0; +} diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c index 4ba9d54ce4e3..7f35b62eea13 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c @@ -29,6 +29,8 @@ static const char * const npc_flow_names[] = {  	[NPC_IPPROTO_TCP] = "ip proto tcp",  	[NPC_IPPROTO_UDP] = "ip proto udp",  	[NPC_IPPROTO_SCTP] = "ip proto sctp", +	[NPC_IPPROTO_ICMP] = "ip proto icmp", +	[NPC_IPPROTO_ICMP6] = "ip proto icmp6",  	[NPC_IPPROTO_AH] = "ip proto AH",  	[NPC_IPPROTO_ESP] = "ip proto ESP",  	[NPC_SPORT_TCP]	= "tcp source port", @@ -427,6 +429,7 @@ do {									       \  	 * packet header fields below.  	 * Example: Source IP is 4 bytes and starts at 12th byte of IP header  	 */ +	NPC_SCAN_HDR(NPC_TOS, NPC_LID_LC, NPC_LT_LC_IP, 1, 1);  	NPC_SCAN_HDR(NPC_SIP_IPV4, NPC_LID_LC, NPC_LT_LC_IP, 12, 4);  	NPC_SCAN_HDR(NPC_DIP_IPV4, NPC_LID_LC, NPC_LT_LC_IP, 16, 4);  	NPC_SCAN_HDR(NPC_SIP_IPV6, NPC_LID_LC, NPC_LT_LC_IP6, 8, 16); @@ -477,9 +480,12 @@ static void npc_set_features(struct rvu *rvu, int blkaddr, u8 intf)  				     BIT_ULL(NPC_IPPROTO_SCTP);  	} -	/* for AH, check if corresponding layer type is present in the key */ -	if (npc_check_field(rvu, blkaddr, NPC_LD, intf)) +	/* for AH/ICMP/ICMPv6/, check if corresponding layer type is present in the key */ +	if (npc_check_field(rvu, blkaddr, NPC_LD, intf)) {  		*features |= BIT_ULL(NPC_IPPROTO_AH); +		*features |= BIT_ULL(NPC_IPPROTO_ICMP); +		*features |= BIT_ULL(NPC_IPPROTO_ICMP6); +	}  	/* for ESP, check if corresponding layer type is present in the key */  	if (npc_check_field(rvu, blkaddr, NPC_LE, intf)) @@ -597,7 +603,7 @@ static int npc_check_unsupported_flows(struct rvu *rvu, u64 features, u8 intf)  		dev_info(rvu->dev, "Unsupported flow(s):\n");  		for_each_set_bit(bit, (unsigned long *)&unsupported, 64)  			dev_info(rvu->dev, "%s ", npc_get_field_name(bit)); -		return -EOPNOTSUPP; +		return NIX_AF_ERR_NPC_KEY_NOT_SUPP;  	}  	return 0; @@ -769,6 +775,12 @@ static void npc_update_flow(struct rvu *rvu, struct mcam_entry *entry,  	if (features & BIT_ULL(NPC_IPPROTO_SCTP))  		npc_update_entry(rvu, NPC_LD, entry, NPC_LT_LD_SCTP,  				 0, ~0ULL, 0, intf); +	if (features & BIT_ULL(NPC_IPPROTO_ICMP)) +		npc_update_entry(rvu, NPC_LD, entry, NPC_LT_LD_ICMP, +				 0, ~0ULL, 0, intf); +	if (features & BIT_ULL(NPC_IPPROTO_ICMP6)) +		npc_update_entry(rvu, NPC_LD, entry, NPC_LT_LD_ICMP6, +				 0, ~0ULL, 0, intf);  	if (features & BIT_ULL(NPC_OUTER_VID))  		npc_update_entry(rvu, NPC_LB, entry, @@ -798,6 +810,7 @@ do {									      \  	NPC_WRITE_FLOW(NPC_SMAC, smac, smac_val, 0, smac_mask, 0);  	NPC_WRITE_FLOW(NPC_ETYPE, etype, ntohs(pkt->etype), 0,  		       ntohs(mask->etype), 0); +	NPC_WRITE_FLOW(NPC_TOS, tos, pkt->tos, 0, mask->tos, 0);  	NPC_WRITE_FLOW(NPC_SIP_IPV4, ip4src, ntohl(pkt->ip4src), 0,  		       ntohl(mask->ip4src), 0);  	NPC_WRITE_FLOW(NPC_DIP_IPV4, ip4dst, ntohl(pkt->ip4dst), 0, @@ -903,9 +916,11 @@ static void npc_update_rx_entry(struct rvu *rvu, struct rvu_pfvf *pfvf,  				struct npc_install_flow_req *req, u16 target)  {  	struct nix_rx_action action; +	u64 chan_mask; -	npc_update_entry(rvu, NPC_CHAN, entry, req->channel, 0, -			 ~0ULL, 0, NIX_INTF_RX); +	chan_mask = req->chan_mask ? req->chan_mask : ~0ULL; +	npc_update_entry(rvu, NPC_CHAN, entry, req->channel, 0, chan_mask, 0, +			 NIX_INTF_RX);  	*(u64 *)&action = 0x00;  	action.pf_func = target; @@ -998,33 +1013,21 @@ static int npc_install_flow(struct rvu *rvu, int blkaddr, u16 target,  	if (is_npc_intf_tx(req->intf))  		goto find_rule; -	if (def_ucast_rule) +	if (req->default_rule) { +		entry_index = npc_get_nixlf_mcam_index(mcam, target, nixlf, +						       NIXLF_UCAST_ENTRY); +		enable = is_mcam_entry_enabled(rvu, mcam, blkaddr, entry_index); +	} + +	/* update mcam entry with default unicast rule attributes */ +	if (def_ucast_rule && (msg_from_vf || (req->default_rule && req->append))) {  		missing_features = (def_ucast_rule->features ^ features) &  					def_ucast_rule->features; - -	if (req->default_rule && req->append) { -		/* add to default rule */  		if (missing_features)  			npc_update_flow(rvu, entry, missing_features,  					&def_ucast_rule->packet,  					&def_ucast_rule->mask,  					&dummy, req->intf); -		enable = rvu_npc_write_default_rule(rvu, blkaddr, -						    nixlf, target, -						    pfvf->nix_rx_intf, entry, -						    &entry_index); -		installed_features = req->features | missing_features; -	} else if (req->default_rule && !req->append) { -		/* overwrite default rule */ -		enable = rvu_npc_write_default_rule(rvu, blkaddr, -						    nixlf, target, -						    pfvf->nix_rx_intf, entry, -						    &entry_index); -	} else if (msg_from_vf) { -		/* normal rule - include default rule also to it for VF */ -		npc_update_flow(rvu, entry, missing_features, -				&def_ucast_rule->packet, &def_ucast_rule->mask, -				&dummy, req->intf);  		installed_features = req->features | missing_features;  	} @@ -1036,12 +1039,9 @@ find_rule:  			return -ENOMEM;  		new = true;  	} -	/* no counter for default rule */ -	if (req->default_rule) -		goto update_rule;  	/* allocate new counter if rule has no counter */ -	if (req->set_cntr && !rule->has_cntr) +	if (!req->default_rule && req->set_cntr && !rule->has_cntr)  		rvu_mcam_add_counter_to_rule(rvu, owner, rule, rsp);  	/* if user wants to delete an existing counter for a rule then @@ -1051,7 +1051,14 @@ find_rule:  		rvu_mcam_remove_counter_from_rule(rvu, owner, rule);  	write_req.hdr.pcifunc = owner; -	write_req.entry = req->entry; + +	/* AF owns the default rules so change the owner just to relax +	 * the checks in rvu_mbox_handler_npc_mcam_write_entry +	 */ +	if (req->default_rule) +		write_req.hdr.pcifunc = 0; + +	write_req.entry = entry_index;  	write_req.intf = req->intf;  	write_req.enable_entry = (u8)enable;  	/* if counter is available then clear and use it */ @@ -1069,7 +1076,7 @@ find_rule:  			kfree(rule);  		return err;  	} -update_rule: +	/* update rule */  	memcpy(&rule->packet, &dummy.packet, sizeof(rule->packet));  	memcpy(&rule->mask, &dummy.mask, sizeof(rule->mask));  	rule->entry = entry_index; @@ -1145,8 +1152,13 @@ int rvu_mbox_handler_npc_install_flow(struct rvu *rvu,  	else  		target = req->hdr.pcifunc; -	if (npc_check_unsupported_flows(rvu, req->features, req->intf)) -		return -EOPNOTSUPP; +	/* ignore chan_mask in case pf func is not AF, revisit later */ +	if (!is_pffunc_af(req->hdr.pcifunc)) +		req->chan_mask = 0xFFF; + +	err = npc_check_unsupported_flows(rvu, req->features, req->intf); +	if (err) +		return err;  	if (npc_mcam_verify_channel(rvu, target, req->intf, req->channel))  		return -EINVAL; @@ -1278,6 +1290,7 @@ static int npc_update_dmac_value(struct rvu *rvu, int npcblkaddr,  	write_req.hdr.pcifunc = rule->owner;  	write_req.entry = rule->entry; +	write_req.intf = pfvf->nix_rx_intf;  	mutex_unlock(&mcam->lock);  	err = rvu_mbox_handler_npc_mcam_write_entry(rvu, &write_req, &rsp); diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h index 3e401fd8ac63..ac71c0f2f960 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h @@ -494,6 +494,27 @@  #define CPT_AF_RAS_INT_W1S              (0x47028)  #define CPT_AF_RAS_INT_ENA_W1S          (0x47030)  #define CPT_AF_RAS_INT_ENA_W1C          (0x47038) +#define CPT_AF_CTX_FLUSH_TIMER          (0x48000ull) +#define CPT_AF_CTX_ERR                  (0x48008ull) +#define CPT_AF_CTX_ENC_ID               (0x48010ull) +#define CPT_AF_CTX_MIS_PC		(0x49400ull) +#define CPT_AF_CTX_HIT_PC		(0x49408ull) +#define CPT_AF_CTX_AOP_PC		(0x49410ull) +#define CPT_AF_CTX_AOP_LATENCY_PC       (0x49418ull) +#define CPT_AF_CTX_IFETCH_PC            (0x49420ull) +#define CPT_AF_CTX_IFETCH_LATENCY_PC    (0x49428ull) +#define CPT_AF_CTX_FFETCH_PC            (0x49430ull) +#define CPT_AF_CTX_FFETCH_LATENCY_PC    (0x49438ull) +#define CPT_AF_CTX_WBACK_PC             (0x49440ull) +#define CPT_AF_CTX_WBACK_LATENCY_PC     (0x49448ull) +#define CPT_AF_CTX_PSH_PC               (0x49450ull) +#define CPT_AF_CTX_PSH_LATENCY_PC       (0x49458ull) +#define CPT_AF_RXC_TIME                 (0x50010ull) +#define CPT_AF_RXC_TIME_CFG             (0x50018ull) +#define CPT_AF_RXC_DFRG                 (0x50020ull) +#define CPT_AF_RXC_ACTIVE_STS           (0x50028ull) +#define CPT_AF_RXC_ZOMBIE_STS           (0x50030ull) +#define CPT_AF_X2PX_LINK_CFG(a)         (0x51000ull | (u64)(a) << 3)  #define AF_BAR2_ALIASX(a, b)            (0x9100000ull | (a) << 12 | (b))  #define CPT_AF_BAR2_SEL                 0x9000000  | 
