Every NIX LF has the facility to maintain a contiguous SA table that is used by NIX RX to find the exact SA context pointer associated with a particular flow. Allocate a 128-entry SA table where each entry is of 2048 bytes which is enough to hold the complete inbound SA context. Add the structure definitions for SA context (cn10k_rx_sa_s) and SA bookkeeping information (ctx_inb_ctx_info). Also, initialize the inb_sw_ctx_list to track all the SA's and their associated NPC rules and hash table related data. Signed-off-by: Tanmay Jagdale --- Changes in V5: - None Changes in V4: - None Changes in V3: - None Changes in V2: - None V1 Link: https://lore.kernel.org/netdev/20250502132005.611698-10-tanmay@marvell.com/ V2 Link: https://lore.kernel.org/netdev/20250618113020.130888-9-tanmay@marvell.com/ V3 Link: https://lore.kernel.org/netdev/20250711121317.340326-9-tanmay@marvell.com/ V4 Link: https://lore.kernel.org/netdev/20250819021507.323752-9-tanmay@marvell.com/ .../marvell/octeontx2/nic/cn10k_ipsec.c | 23 ++++- .../marvell/octeontx2/nic/cn10k_ipsec.h | 92 +++++++++++++++++++ 2 files changed, 113 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c index e2abdac27ba5..3e4cdd6bac6c 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c @@ -468,6 +468,19 @@ static int cn10k_inb_cpt_init(struct net_device *netdev) struct otx2_nic *pfvf = netdev_priv(netdev); int ret = 0, spb_cnt; + /* Set sa_tbl_entry_sz to 2048 since we are programming NIX RX + * to calculate SA index as SPI * 2048. The first 1024 bytes + * are used for SA context and the next half for bookkeeping data. + */ + pfvf->ipsec.sa_tbl_entry_sz = 2048; + ret = qmem_alloc(pfvf->dev, &pfvf->ipsec.inb_sa, CN10K_IPSEC_INB_MAX_SA, + pfvf->ipsec.sa_tbl_entry_sz); + if (ret) + return ret; + + memset(pfvf->ipsec.inb_sa->base, 0, + pfvf->ipsec.sa_tbl_entry_sz * CN10K_IPSEC_INB_MAX_SA); + /* Allocate SPB buffer count array to track the number of inbound SPB * buffers received per RX queue. This count would later be used to * refill the first pass IPsec pool. @@ -933,6 +946,9 @@ static void cn10k_ipsec_free_hw_resources(struct otx2_nic *pfvf) /* Free the per spb pool buffer counters */ devm_kfree(pfvf->dev, pfvf->ipsec.inb_spb_count); + /* Free the inbound SA table */ + qmem_free(pfvf->dev, pfvf->ipsec.inb_sa); + cn10k_ipsec_free_aura_ptrs(pfvf); } @@ -961,8 +977,8 @@ int cn10k_ipsec_ethtool_init(struct net_device *netdev, bool enable) return ret; } - /* Don't do CPT cleanup if SA installed */ - if (!pf->ipsec.outb_sa_count) { + /* Don't cleanup CPT if any inbound or outbound SA is installed */ + if (!list_empty(&pf->ipsec.inb_sw_ctx_list) && !pf->ipsec.outb_sa_count) { netdev_err(pf->netdev, "SA installed on this device\n"); return -EBUSY; } @@ -987,6 +1003,9 @@ int cn10k_ipsec_init(struct net_device *netdev) OTX2_ALIGN : sizeof(struct cn10k_tx_sa_s); pf->ipsec.sa_size = sa_size; + /* List to track all ingress SAs */ + INIT_LIST_HEAD(&pf->ipsec.inb_sw_ctx_list); + INIT_WORK(&pf->ipsec.sa_work, cn10k_ipsec_sa_wq_handler); pf->ipsec.sa_workq = alloc_workqueue("cn10k_ipsec_sa_workq", WQ_PERCPU, 0); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.h b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.h index 78baddb9ffda..8ef67f1f0e3d 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.h +++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.h @@ -52,10 +52,14 @@ DECLARE_STATIC_KEY_FALSE(cn10k_ipsec_sa_enabled); #define CN10K_CPT_LF_NQX(a) (CPT_LFBASE | 0x400 | (a) << 3) #define CN10K_CPT_LF_CTX_FLUSH (CPT_LFBASE | 0x510) +/* Maximum Inbound SAs */ +#define CN10K_IPSEC_INB_MAX_SA 2048 + /* IPSEC Instruction opcodes */ #define CN10K_IPSEC_MAJOR_OP_WRITE_SA 0x01UL #define CN10K_IPSEC_MINOR_OP_WRITE_SA 0x09UL #define CN10K_IPSEC_MAJOR_OP_OUTB_IPSEC 0x2AUL +#define CN10K_IPSEC_MAJOR_OP_INB_IPSEC 0x29UL enum cn10k_cpt_comp_e { CN10K_CPT_COMP_E_NOTDONE = 0x00, @@ -81,6 +85,19 @@ enum cn10k_cpt_hw_state_e { CN10K_CPT_HW_IN_USE }; +struct cn10k_inb_sw_ctx_info { + struct list_head list; + struct cn10k_rx_sa_s *sa_entry; + struct xfrm_state *x_state; + dma_addr_t sa_iova; + u32 npc_mcam_entry; + u32 sa_index; + __be32 spi; + u16 hash_index; /* Hash index from SPI_TO_SA match */ + u8 way; /* SPI_TO_SA match table way index */ + bool delete_npc_and_match_entry; +}; + struct cn10k_ipsec { /* Outbound CPT */ u64 io_addr; @@ -98,6 +115,11 @@ struct cn10k_ipsec { u16 inb_ipsec_pool; u16 inb_ipsec_spb_pool; atomic_t *inb_spb_count; + + u32 sa_tbl_entry_sz; + struct qmem *inb_sa; + struct list_head inb_sw_ctx_list; + DECLARE_BITMAP(inb_sa_table, CN10K_IPSEC_INB_MAX_SA); }; /* CN10K IPSEC Security Association (SA) */ @@ -152,6 +174,76 @@ struct cn10k_tx_sa_s { u64 hw_ctx[6]; /* W31 - W36 */ }; +struct cn10k_rx_sa_s { + u64 inb_ar_win_sz : 3; /* W0 */ + u64 hard_life_dec : 1; + u64 soft_life_dec : 1; + u64 count_glb_octets : 1; + u64 count_glb_pkts : 1; + u64 count_mib_bytes : 1; + u64 count_mib_pkts : 1; + u64 hw_ctx_off : 7; + u64 ctx_id : 16; + u64 orig_pkt_fabs : 1; + u64 orig_pkt_free : 1; + u64 pkind : 6; + u64 rsvd_w0_40 : 1; + u64 eth_ovrwr : 1; + u64 pkt_output : 2; + u64 pkt_format : 1; + u64 defrag_opt : 2; + u64 x2p_dst : 1; + u64 ctx_push_size : 7; + u64 rsvd_w0_55 : 1; + u64 ctx_hdr_size : 2; + u64 aop_valid : 1; + u64 rsvd_w0_59 : 1; + u64 ctx_size : 4; + + u64 rsvd_w1_31_0 : 32; /* W1 */ + u64 cookie : 32; + + u64 sa_valid : 1; /* W2 Control Word */ + u64 sa_dir : 1; + u64 rsvd_w2_2_3 : 2; + u64 ipsec_mode : 1; + u64 ipsec_protocol : 1; + u64 aes_key_len : 2; + u64 enc_type : 3; + u64 life_unit : 1; + u64 auth_type : 4; + u64 encap_type : 2; + u64 et_ovrwr_ddr_en : 1; + u64 esn_en : 1; + u64 tport_l4_incr_csum : 1; + u64 iphdr_verify : 2; + u64 udp_ports_verify : 1; + u64 l2_l3_hdr_on_error : 1; + u64 rsvd_w25_31 : 7; + u64 spi : 32; + + u64 w3; /* W3 */ + + u8 cipher_key[32]; /* W4 - W7 */ + u32 rsvd_w8_0_31; /* W8 : IV */ + u32 iv_gcm_salt; + u64 rsvd_w9; /* W9 */ + u64 rsvd_w10; /* W10 : UDP Encap */ + u32 dest_ipaddr; /* W11 - Tunnel mode: outer src and dest ipaddr */ + u32 src_ipaddr; + u64 rsvd_w12_w30[19]; /* W12 - W30 */ + + u64 ar_base; /* W31 */ + u64 ar_valid_mask; /* W32 */ + u64 hard_sa_life; /* W33 */ + u64 soft_sa_life; /* W34 */ + u64 mib_octs; /* W35 */ + u64 mib_pkts; /* W36 */ + u64 ar_winbits; /* W37 */ + + u64 rsvd_w38_w100[63]; +}; + /* CPT instruction parameter-1 */ #define CN10K_IPSEC_INST_PARAM1_DIS_L4_CSUM 0x1 #define CN10K_IPSEC_INST_PARAM1_DIS_L3_CSUM 0x2 -- 2.43.0