| /* SPDX-License-Identifier: GPL-2.0 */ |
| /* Marvell IPSEC offload driver |
| * |
| * Copyright (C) 2024 Marvell. |
| */ |
| |
| #ifndef CN10K_IPSEC_H |
| #define CN10K_IPSEC_H |
| |
| #include <linux/types.h> |
| |
| DECLARE_STATIC_KEY_FALSE(cn10k_ipsec_sa_enabled); |
| |
| /* CPT instruction size in bytes */ |
| #define CN10K_CPT_INST_SIZE 64 |
| |
| /* CPT instruction (CPT_INST_S) queue length */ |
| #define CN10K_CPT_INST_QLEN 8200 |
| |
| /* CPT instruction queue size passed to HW is in units of |
| * 40*CPT_INST_S messages. |
| */ |
| #define CN10K_CPT_SIZE_DIV40 (CN10K_CPT_INST_QLEN / 40) |
| |
| /* CPT needs 320 free entries */ |
| #define CN10K_CPT_INST_QLEN_EXTRA_BYTES (320 * CN10K_CPT_INST_SIZE) |
| #define CN10K_CPT_EXTRA_SIZE_DIV40 (320 / 40) |
| |
| /* CPT instruction queue length in bytes */ |
| #define CN10K_CPT_INST_QLEN_BYTES \ |
| ((CN10K_CPT_SIZE_DIV40 * 40 * CN10K_CPT_INST_SIZE) + \ |
| CN10K_CPT_INST_QLEN_EXTRA_BYTES) |
| |
| /* CPT instruction group queue length in bytes */ |
| #define CN10K_CPT_INST_GRP_QLEN_BYTES \ |
| ((CN10K_CPT_SIZE_DIV40 + CN10K_CPT_EXTRA_SIZE_DIV40) * 16) |
| |
| /* CPT FC length in bytes */ |
| #define CN10K_CPT_Q_FC_LEN 128 |
| |
| /* Default CPT engine group for ipsec offload */ |
| #define CN10K_DEF_CPT_IPSEC_EGRP 1 |
| |
| /* CN10K CPT LF registers */ |
| #define CPT_LFBASE (BLKTYPE_CPT << RVU_FUNC_BLKADDR_SHIFT) |
| #define CN10K_CPT_LF_CTL (CPT_LFBASE | 0x10) |
| #define CN10K_CPT_LF_INPROG (CPT_LFBASE | 0x40) |
| #define CN10K_CPT_LF_Q_BASE (CPT_LFBASE | 0xf0) |
| #define CN10K_CPT_LF_Q_SIZE (CPT_LFBASE | 0x100) |
| #define CN10K_CPT_LF_Q_INST_PTR (CPT_LFBASE | 0x110) |
| #define CN10K_CPT_LF_Q_GRP_PTR (CPT_LFBASE | 0x120) |
| #define CN10K_CPT_LF_NQX(a) (CPT_LFBASE | 0x400 | (a) << 3) |
| #define CN10K_CPT_LF_CTX_FLUSH (CPT_LFBASE | 0x510) |
| |
| /* 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 |
| |
| enum cn10k_cpt_comp_e { |
| CN10K_CPT_COMP_E_NOTDONE = 0x00, |
| CN10K_CPT_COMP_E_GOOD = 0x01, |
| CN10K_CPT_COMP_E_FAULT = 0x02, |
| CN10K_CPT_COMP_E_HWERR = 0x04, |
| CN10K_CPT_COMP_E_INSTERR = 0x05, |
| CN10K_CPT_COMP_E_WARN = 0x06, |
| CN10K_CPT_COMP_E_MASK = 0x3F |
| }; |
| |
| struct cn10k_cpt_inst_queue { |
| u8 *vaddr; |
| u8 *real_vaddr; |
| dma_addr_t dma_addr; |
| dma_addr_t real_dma_addr; |
| u32 size; |
| }; |
| |
| enum cn10k_cpt_hw_state_e { |
| CN10K_CPT_HW_UNAVAILABLE, |
| CN10K_CPT_HW_AVAILABLE, |
| CN10K_CPT_HW_IN_USE |
| }; |
| |
| struct cn10k_ipsec { |
| /* Outbound CPT */ |
| u64 io_addr; |
| atomic_t cpt_state; |
| struct cn10k_cpt_inst_queue iq; |
| |
| /* SA info */ |
| u32 sa_size; |
| u32 outb_sa_count; |
| struct work_struct sa_work; |
| struct workqueue_struct *sa_workq; |
| }; |
| |
| /* CN10K IPSEC Security Association (SA) */ |
| /* SA direction */ |
| #define CN10K_IPSEC_SA_DIR_INB 0 |
| #define CN10K_IPSEC_SA_DIR_OUTB 1 |
| /* SA protocol */ |
| #define CN10K_IPSEC_SA_IPSEC_PROTO_AH 0 |
| #define CN10K_IPSEC_SA_IPSEC_PROTO_ESP 1 |
| /* SA Encryption Type */ |
| #define CN10K_IPSEC_SA_ENCAP_TYPE_AES_GCM 5 |
| /* SA IPSEC mode Transport/Tunnel */ |
| #define CN10K_IPSEC_SA_IPSEC_MODE_TRANSPORT 0 |
| #define CN10K_IPSEC_SA_IPSEC_MODE_TUNNEL 1 |
| /* SA AES Key Length */ |
| #define CN10K_IPSEC_SA_AES_KEY_LEN_128 1 |
| #define CN10K_IPSEC_SA_AES_KEY_LEN_192 2 |
| #define CN10K_IPSEC_SA_AES_KEY_LEN_256 3 |
| /* IV Source */ |
| #define CN10K_IPSEC_SA_IV_SRC_COUNTER 0 |
| #define CN10K_IPSEC_SA_IV_SRC_PACKET 3 |
| |
| struct cn10k_tx_sa_s { |
| u64 esn_en : 1; /* W0 */ |
| u64 rsvd_w0_1_8 : 8; |
| u64 hw_ctx_off : 7; |
| u64 ctx_id : 16; |
| u64 rsvd_w0_32_47 : 16; |
| 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 w1; /* W1 */ |
| u64 sa_valid : 1; /* W2 */ |
| 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 rsvd_w2_11_19 : 9; |
| u64 iv_src : 2; |
| u64 rsvd_w2_22_31 : 10; |
| u64 rsvd_w2_32_63 : 32; |
| u64 w3; /* W3 */ |
| u8 cipher_key[32]; /* W4 - W7 */ |
| u32 rsvd_w8_0_31; /* W8 : IV */ |
| u32 iv_gcm_salt; |
| u64 rsvd_w9_w30[22]; /* W9 - W30 */ |
| u64 hw_ctx[6]; /* W31 - W36 */ |
| }; |
| |
| /* CPT instruction parameter-1 */ |
| #define CN10K_IPSEC_INST_PARAM1_DIS_L4_CSUM 0x1 |
| #define CN10K_IPSEC_INST_PARAM1_DIS_L3_CSUM 0x2 |
| #define CN10K_IPSEC_INST_PARAM1_CRYPTO_MODE 0x20 |
| #define CN10K_IPSEC_INST_PARAM1_IV_OFFSET_SHIFT 8 |
| |
| /* CPT instruction parameter-2 */ |
| #define CN10K_IPSEC_INST_PARAM2_ENC_DATA_OFFSET_SHIFT 0 |
| #define CN10K_IPSEC_INST_PARAM2_AUTH_DATA_OFFSET_SHIFT 8 |
| |
| /* CPT Instruction Structure */ |
| struct cpt_inst_s { |
| u64 nixtxl : 3; /* W0 */ |
| u64 doneint : 1; |
| u64 rsvd_w0_4_15 : 12; |
| u64 dat_offset : 8; |
| u64 ext_param1 : 8; |
| u64 nixtx_offset : 20; |
| u64 rsvd_w0_52_63 : 12; |
| u64 res_addr; /* W1 */ |
| u64 tag : 32; /* W2 */ |
| u64 tt : 2; |
| u64 grp : 10; |
| u64 rsvd_w2_44_47 : 4; |
| u64 rvu_pf_func : 16; |
| u64 qord : 1; /* W3 */ |
| u64 rsvd_w3_1_2 : 2; |
| u64 wqe_ptr : 61; |
| u64 dlen : 16; /* W4 */ |
| u64 param2 : 16; |
| u64 param1 : 16; |
| u64 opcode_major : 8; |
| u64 opcode_minor : 8; |
| u64 dptr; /* W5 */ |
| u64 rptr; /* W6 */ |
| u64 cptr : 60; /* W7 */ |
| u64 ctx_val : 1; |
| u64 egrp : 3; |
| }; |
| |
| /* CPT Instruction Result Structure */ |
| struct cpt_res_s { |
| u64 compcode : 7; /* W0 */ |
| u64 doneint : 1; |
| u64 uc_compcode : 8; |
| u64 uc_info : 48; |
| u64 esn; /* W1 */ |
| }; |
| |
| /* CPT SG structure */ |
| struct cpt_sg_s { |
| u64 seg1_size : 16; |
| u64 seg2_size : 16; |
| u64 seg3_size : 16; |
| u64 segs : 2; |
| u64 rsvd_63_50 : 14; |
| }; |
| |
| /* CPT LF_INPROG Register */ |
| #define CPT_LF_INPROG_INFLIGHT GENMASK_ULL(8, 0) |
| #define CPT_LF_INPROG_GRB_CNT GENMASK_ULL(39, 32) |
| #define CPT_LF_INPROG_GWB_CNT GENMASK_ULL(47, 40) |
| |
| /* CPT LF_Q_GRP_PTR Register */ |
| #define CPT_LF_Q_GRP_PTR_DQ_PTR GENMASK_ULL(14, 0) |
| #define CPT_LF_Q_GRP_PTR_NQ_PTR GENMASK_ULL(46, 32) |
| |
| /* CPT LF_Q_SIZE Register */ |
| #define CPT_LF_Q_BASE_ADDR GENMASK_ULL(52, 7) |
| |
| /* CPT LF_Q_SIZE Register */ |
| #define CPT_LF_Q_SIZE_DIV40 GENMASK_ULL(14, 0) |
| |
| /* CPT LF CTX Flush Register */ |
| #define CPT_LF_CTX_FLUSH_CPTR GENMASK_ULL(45, 0) |
| |
| #ifdef CONFIG_XFRM_OFFLOAD |
| int cn10k_ipsec_init(struct net_device *netdev); |
| void cn10k_ipsec_clean(struct otx2_nic *pf); |
| int cn10k_ipsec_ethtool_init(struct net_device *netdev, bool enable); |
| bool otx2_sqe_add_sg_ipsec(struct otx2_nic *pfvf, struct otx2_snd_queue *sq, |
| struct sk_buff *skb, int num_segs, int *offset); |
| bool cn10k_ipsec_transmit(struct otx2_nic *pf, struct netdev_queue *txq, |
| struct otx2_snd_queue *sq, struct sk_buff *skb, |
| int num_segs, int size); |
| #else |
| static inline __maybe_unused int cn10k_ipsec_init(struct net_device *netdev) |
| { |
| return 0; |
| } |
| |
| static inline __maybe_unused void cn10k_ipsec_clean(struct otx2_nic *pf) |
| { |
| } |
| |
| static inline __maybe_unused |
| int cn10k_ipsec_ethtool_init(struct net_device *netdev, bool enable) |
| { |
| return 0; |
| } |
| |
| static inline bool __maybe_unused |
| otx2_sqe_add_sg_ipsec(struct otx2_nic *pfvf, struct otx2_snd_queue *sq, |
| struct sk_buff *skb, int num_segs, int *offset) |
| { |
| return true; |
| } |
| |
| static inline bool __maybe_unused |
| cn10k_ipsec_transmit(struct otx2_nic *pf, struct netdev_queue *txq, |
| struct otx2_snd_queue *sq, struct sk_buff *skb, |
| int num_segs, int size) |
| { |
| return true; |
| } |
| #endif |
| #endif // CN10K_IPSEC_H |