14610ac93SAndrew Boyer /* SPDX-License-Identifier: BSD-3-Clause 24610ac93SAndrew Boyer * Copyright 2021-2024 Advanced Micro Devices, Inc. 34610ac93SAndrew Boyer */ 44610ac93SAndrew Boyer 54610ac93SAndrew Boyer #ifndef _IONIC_CRYPTO_H_ 64610ac93SAndrew Boyer #define _IONIC_CRYPTO_H_ 74610ac93SAndrew Boyer 84610ac93SAndrew Boyer #include <stdint.h> 94610ac93SAndrew Boyer #include <stdbool.h> 104610ac93SAndrew Boyer #include <inttypes.h> 114610ac93SAndrew Boyer 124610ac93SAndrew Boyer #include <rte_common.h> 134610ac93SAndrew Boyer #include <rte_dev.h> 144610ac93SAndrew Boyer #include <rte_cryptodev.h> 154610ac93SAndrew Boyer #include <cryptodev_pmd.h> 164610ac93SAndrew Boyer #include <rte_log.h> 17*6bc7f2cfSAndrew Boyer #include <rte_bitmap.h> 184610ac93SAndrew Boyer 194610ac93SAndrew Boyer #include "ionic_common.h" 2025c896eaSAndrew Boyer #include "ionic_crypto_if.h" 214610ac93SAndrew Boyer #include "ionic_regs.h" 224610ac93SAndrew Boyer 234610ac93SAndrew Boyer /* Devargs */ 244610ac93SAndrew Boyer /* NONE */ 254610ac93SAndrew Boyer 262c1662bbSAndrew Boyer #define IOCPT_MAX_RING_DESC 32768 272c1662bbSAndrew Boyer #define IOCPT_MIN_RING_DESC 16 282c1662bbSAndrew Boyer #define IOCPT_ADMINQ_LENGTH 16 /* must be a power of two */ 292c1662bbSAndrew Boyer 304610ac93SAndrew Boyer extern int iocpt_logtype; 314610ac93SAndrew Boyer #define RTE_LOGTYPE_IOCPT iocpt_logtype 324610ac93SAndrew Boyer 334610ac93SAndrew Boyer #define IOCPT_PRINT(level, ...) \ 344610ac93SAndrew Boyer RTE_LOG_LINE_PREFIX(level, IOCPT, "%s(): ", __func__, __VA_ARGS__) 354610ac93SAndrew Boyer 364610ac93SAndrew Boyer #define IOCPT_PRINT_CALL() IOCPT_PRINT(DEBUG, " >>") 374610ac93SAndrew Boyer 38dddfb0d9SAndrew Boyer const struct rte_cryptodev_capabilities *iocpt_get_caps(uint64_t flags); 39dddfb0d9SAndrew Boyer 4025c896eaSAndrew Boyer static inline void iocpt_struct_size_checks(void) 4125c896eaSAndrew Boyer { 4225c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct ionic_doorbell) != 8); 4325c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct ionic_intr) != 32); 4425c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct ionic_intr_status) != 8); 4525c896eaSAndrew Boyer 4625c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(union iocpt_dev_regs) != 4096); 4725c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(union iocpt_dev_info_regs) != 2048); 4825c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(union iocpt_dev_cmd_regs) != 2048); 4925c896eaSAndrew Boyer 5025c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_admin_cmd) != 64); 5125c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_admin_comp) != 16); 5225c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_nop_cmd) != 64); 5325c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_nop_comp) != 16); 5425c896eaSAndrew Boyer 5525c896eaSAndrew Boyer /* Device commands */ 5625c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_dev_identify_cmd) != 64); 5725c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_dev_identify_comp) != 16); 5825c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_dev_reset_cmd) != 64); 5925c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_dev_reset_comp) != 16); 6025c896eaSAndrew Boyer 6125c896eaSAndrew Boyer /* LIF commands */ 6225c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_identify_cmd) != 64); 6325c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_identify_comp) != 16); 6425c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_init_cmd) != 64); 6525c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_init_comp) != 16); 6625c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_reset_cmd) != 64); 6725c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_getattr_cmd) != 64); 6825c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_getattr_comp) != 16); 6925c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_setattr_cmd) != 64); 7025c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_setattr_comp) != 16); 7125c896eaSAndrew Boyer 7225c896eaSAndrew Boyer /* Queue commands */ 7325c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_q_identify_cmd) != 64); 7425c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_q_identify_comp) != 16); 7525c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_q_init_cmd) != 64); 7625c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_q_init_comp) != 16); 7725c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_q_control_cmd) != 64); 7825c896eaSAndrew Boyer 7925c896eaSAndrew Boyer /* Crypto */ 8025c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_crypto_desc) != 32); 8125c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_crypto_sg_desc) != 256); 8225c896eaSAndrew Boyer RTE_BUILD_BUG_ON(sizeof(struct iocpt_crypto_comp) != 16); 8325c896eaSAndrew Boyer } 8425c896eaSAndrew Boyer 854610ac93SAndrew Boyer struct iocpt_dev_bars { 864610ac93SAndrew Boyer struct ionic_dev_bar bar[IONIC_BARS_MAX]; 874610ac93SAndrew Boyer uint32_t num_bars; 884610ac93SAndrew Boyer }; 894610ac93SAndrew Boyer 90a677112dSAndrew Boyer struct iocpt_qtype_info { 91a677112dSAndrew Boyer uint8_t version; 92a677112dSAndrew Boyer uint8_t supported; 93a677112dSAndrew Boyer uint64_t features; 94a677112dSAndrew Boyer uint16_t desc_sz; 95a677112dSAndrew Boyer uint16_t comp_sz; 96a677112dSAndrew Boyer uint16_t sg_desc_sz; 97a677112dSAndrew Boyer uint16_t max_sg_elems; 98a677112dSAndrew Boyer uint16_t sg_desc_stride; 99a677112dSAndrew Boyer }; 100a677112dSAndrew Boyer 1012c1662bbSAndrew Boyer #define IOCPT_Q_F_INITED BIT(0) 1022c1662bbSAndrew Boyer #define IOCPT_Q_F_DEFERRED BIT(1) 1032c1662bbSAndrew Boyer #define IOCPT_Q_F_SG BIT(2) 1042c1662bbSAndrew Boyer 1052c1662bbSAndrew Boyer #define Q_NEXT_TO_POST(_q, _n) (((_q)->head_idx + (_n)) & ((_q)->size_mask)) 1062c1662bbSAndrew Boyer #define Q_NEXT_TO_SRVC(_q, _n) (((_q)->tail_idx + (_n)) & ((_q)->size_mask)) 1072c1662bbSAndrew Boyer 1082c1662bbSAndrew Boyer #define IOCPT_INFO_SZ(_q) ((_q)->num_segs * sizeof(void *)) 1092c1662bbSAndrew Boyer #define IOCPT_INFO_IDX(_q, _i) ((_i) * (_q)->num_segs) 1102c1662bbSAndrew Boyer #define IOCPT_INFO_PTR(_q, _i) (&(_q)->info[IOCPT_INFO_IDX((_q), _i)]) 1112c1662bbSAndrew Boyer 1122c1662bbSAndrew Boyer struct iocpt_queue { 1132c1662bbSAndrew Boyer uint16_t num_descs; 1142c1662bbSAndrew Boyer uint16_t num_segs; 1152c1662bbSAndrew Boyer uint16_t head_idx; 1162c1662bbSAndrew Boyer uint16_t tail_idx; 1172c1662bbSAndrew Boyer uint16_t size_mask; 1182c1662bbSAndrew Boyer uint8_t type; 1192c1662bbSAndrew Boyer uint8_t hw_type; 1202c1662bbSAndrew Boyer void *base; 1212c1662bbSAndrew Boyer void *sg_base; 1222c1662bbSAndrew Boyer struct ionic_doorbell __iomem *db; 1232c1662bbSAndrew Boyer void **info; 1242c1662bbSAndrew Boyer 1252c1662bbSAndrew Boyer uint32_t index; 1262c1662bbSAndrew Boyer uint32_t hw_index; 1272c1662bbSAndrew Boyer rte_iova_t base_pa; 1282c1662bbSAndrew Boyer rte_iova_t sg_base_pa; 1292c1662bbSAndrew Boyer }; 1302c1662bbSAndrew Boyer 1312c1662bbSAndrew Boyer struct iocpt_cq { 1322c1662bbSAndrew Boyer uint16_t tail_idx; 1332c1662bbSAndrew Boyer uint16_t num_descs; 1342c1662bbSAndrew Boyer uint16_t size_mask; 1352c1662bbSAndrew Boyer bool done_color; 1362c1662bbSAndrew Boyer void *base; 1372c1662bbSAndrew Boyer rte_iova_t base_pa; 1382c1662bbSAndrew Boyer }; 1392c1662bbSAndrew Boyer 1402c1662bbSAndrew Boyer #define IOCPT_COMMON_FIELDS \ 1412c1662bbSAndrew Boyer struct iocpt_queue q; \ 1422c1662bbSAndrew Boyer struct iocpt_cq cq; \ 1432c1662bbSAndrew Boyer struct iocpt_dev *dev; \ 1442c1662bbSAndrew Boyer const struct rte_memzone *base_z; \ 1452c1662bbSAndrew Boyer void *base; \ 1462c1662bbSAndrew Boyer rte_iova_t base_pa 1472c1662bbSAndrew Boyer 1482c1662bbSAndrew Boyer struct iocpt_common_q { 1492c1662bbSAndrew Boyer IOCPT_COMMON_FIELDS; 1502c1662bbSAndrew Boyer }; 1512c1662bbSAndrew Boyer 1522c1662bbSAndrew Boyer struct iocpt_admin_q { 1532c1662bbSAndrew Boyer IOCPT_COMMON_FIELDS; 1542c1662bbSAndrew Boyer 1552c1662bbSAndrew Boyer uint16_t flags; 1562c1662bbSAndrew Boyer }; 1572c1662bbSAndrew Boyer 158*6bc7f2cfSAndrew Boyer #define IOCPT_S_F_INITED BIT(0) 159*6bc7f2cfSAndrew Boyer 160*6bc7f2cfSAndrew Boyer struct iocpt_session_priv { 161*6bc7f2cfSAndrew Boyer struct iocpt_dev *dev; 162*6bc7f2cfSAndrew Boyer 163*6bc7f2cfSAndrew Boyer uint32_t index; 164*6bc7f2cfSAndrew Boyer 165*6bc7f2cfSAndrew Boyer uint16_t iv_offset; 166*6bc7f2cfSAndrew Boyer uint16_t iv_length; 167*6bc7f2cfSAndrew Boyer uint16_t digest_length; 168*6bc7f2cfSAndrew Boyer uint16_t aad_length; 169*6bc7f2cfSAndrew Boyer 170*6bc7f2cfSAndrew Boyer uint8_t flags; 171*6bc7f2cfSAndrew Boyer uint8_t op; 172*6bc7f2cfSAndrew Boyer uint8_t type; 173*6bc7f2cfSAndrew Boyer 174*6bc7f2cfSAndrew Boyer uint16_t key_len; 175*6bc7f2cfSAndrew Boyer uint8_t key[IOCPT_SESS_KEY_LEN_MAX_SYMM]; 176*6bc7f2cfSAndrew Boyer }; 177*6bc7f2cfSAndrew Boyer 178*6bc7f2cfSAndrew Boyer static inline uint32_t 179*6bc7f2cfSAndrew Boyer iocpt_session_size(void) 180*6bc7f2cfSAndrew Boyer { 181*6bc7f2cfSAndrew Boyer return sizeof(struct iocpt_session_priv); 182*6bc7f2cfSAndrew Boyer } 183*6bc7f2cfSAndrew Boyer 1844610ac93SAndrew Boyer #define IOCPT_DEV_F_INITED BIT(0) 1854610ac93SAndrew Boyer #define IOCPT_DEV_F_UP BIT(1) 1864610ac93SAndrew Boyer #define IOCPT_DEV_F_FW_RESET BIT(2) 1874610ac93SAndrew Boyer 1884610ac93SAndrew Boyer /* Combined dev / LIF object */ 1894610ac93SAndrew Boyer struct iocpt_dev { 1904610ac93SAndrew Boyer const char *name; 19125c896eaSAndrew Boyer char fw_version[IOCPT_FWVERS_BUFLEN]; 1924610ac93SAndrew Boyer struct iocpt_dev_bars bars; 193a677112dSAndrew Boyer struct iocpt_identity ident; 1944610ac93SAndrew Boyer 1954610ac93SAndrew Boyer const struct iocpt_dev_intf *intf; 1964610ac93SAndrew Boyer void *bus_dev; 1974610ac93SAndrew Boyer struct rte_cryptodev *crypto_dev; 1984610ac93SAndrew Boyer 19925c896eaSAndrew Boyer union iocpt_dev_info_regs __iomem *dev_info; 20025c896eaSAndrew Boyer union iocpt_dev_cmd_regs __iomem *dev_cmd; 20125c896eaSAndrew Boyer 20225c896eaSAndrew Boyer struct ionic_doorbell __iomem *db_pages; 20325c896eaSAndrew Boyer struct ionic_intr __iomem *intr_ctrl; 20425c896eaSAndrew Boyer 2054610ac93SAndrew Boyer uint32_t max_qps; 2064610ac93SAndrew Boyer uint32_t max_sessions; 2074610ac93SAndrew Boyer uint16_t state; 2084610ac93SAndrew Boyer uint8_t driver_id; 2094610ac93SAndrew Boyer uint8_t socket_id; 2104610ac93SAndrew Boyer 2112c1662bbSAndrew Boyer rte_spinlock_t adminq_lock; 2122c1662bbSAndrew Boyer rte_spinlock_t adminq_service_lock; 2132c1662bbSAndrew Boyer 2142c1662bbSAndrew Boyer struct iocpt_admin_q *adminq; 2152c1662bbSAndrew Boyer 216*6bc7f2cfSAndrew Boyer struct rte_bitmap *sess_bm; /* SET bit indicates index is free */ 217*6bc7f2cfSAndrew Boyer 2184610ac93SAndrew Boyer uint64_t features; 2194610ac93SAndrew Boyer uint32_t hw_features; 220a677112dSAndrew Boyer 221a677112dSAndrew Boyer uint32_t info_sz; 222a677112dSAndrew Boyer struct iocpt_lif_info *info; 223a677112dSAndrew Boyer rte_iova_t info_pa; 224a677112dSAndrew Boyer const struct rte_memzone *info_z; 225a677112dSAndrew Boyer 226a677112dSAndrew Boyer struct iocpt_qtype_info qtype_info[IOCPT_QTYPE_MAX]; 227a677112dSAndrew Boyer uint8_t qtype_ver[IOCPT_QTYPE_MAX]; 2284610ac93SAndrew Boyer }; 2294610ac93SAndrew Boyer 2304610ac93SAndrew Boyer struct iocpt_dev_intf { 2314610ac93SAndrew Boyer int (*setup_bars)(struct iocpt_dev *dev); 2324610ac93SAndrew Boyer void (*unmap_bars)(struct iocpt_dev *dev); 2334610ac93SAndrew Boyer }; 2344610ac93SAndrew Boyer 2354610ac93SAndrew Boyer static inline int 2364610ac93SAndrew Boyer iocpt_setup_bars(struct iocpt_dev *dev) 2374610ac93SAndrew Boyer { 2384610ac93SAndrew Boyer if (dev->intf->setup_bars == NULL) 2394610ac93SAndrew Boyer return -EINVAL; 2404610ac93SAndrew Boyer 2414610ac93SAndrew Boyer return (*dev->intf->setup_bars)(dev); 2424610ac93SAndrew Boyer } 2434610ac93SAndrew Boyer 2442c1662bbSAndrew Boyer /** iocpt_admin_ctx - Admin command context. 2452c1662bbSAndrew Boyer * @pending_work: Flag that indicates a completion. 2462c1662bbSAndrew Boyer * @cmd: Admin command (64B) to be copied to the queue. 2472c1662bbSAndrew Boyer * @comp: Admin completion (16B) copied from the queue. 2482c1662bbSAndrew Boyer */ 2492c1662bbSAndrew Boyer struct iocpt_admin_ctx { 2502c1662bbSAndrew Boyer bool pending_work; 2512c1662bbSAndrew Boyer union iocpt_adminq_cmd cmd; 2522c1662bbSAndrew Boyer union iocpt_adminq_comp comp; 2532c1662bbSAndrew Boyer }; 2542c1662bbSAndrew Boyer 2554610ac93SAndrew Boyer int iocpt_probe(void *bus_dev, struct rte_device *rte_dev, 2564610ac93SAndrew Boyer struct iocpt_dev_bars *bars, const struct iocpt_dev_intf *intf, 2574610ac93SAndrew Boyer uint8_t driver_id, uint8_t socket_id); 2584610ac93SAndrew Boyer int iocpt_remove(struct rte_device *rte_dev); 2594610ac93SAndrew Boyer 2604610ac93SAndrew Boyer void iocpt_configure(struct iocpt_dev *dev); 261dddfb0d9SAndrew Boyer int iocpt_assign_ops(struct rte_cryptodev *cdev); 2624610ac93SAndrew Boyer void iocpt_deinit(struct iocpt_dev *dev); 2634610ac93SAndrew Boyer 264a677112dSAndrew Boyer int iocpt_dev_identify(struct iocpt_dev *dev); 265a677112dSAndrew Boyer int iocpt_dev_init(struct iocpt_dev *dev, rte_iova_t info_pa); 2662c1662bbSAndrew Boyer int iocpt_dev_adminq_init(struct iocpt_dev *dev); 267a677112dSAndrew Boyer void iocpt_dev_reset(struct iocpt_dev *dev); 268a677112dSAndrew Boyer 2692c1662bbSAndrew Boyer int iocpt_adminq_post_wait(struct iocpt_dev *dev, struct iocpt_admin_ctx *ctx); 2702c1662bbSAndrew Boyer 271*6bc7f2cfSAndrew Boyer int iocpt_session_init(struct iocpt_session_priv *priv); 272*6bc7f2cfSAndrew Boyer int iocpt_session_update(struct iocpt_session_priv *priv); 273*6bc7f2cfSAndrew Boyer void iocpt_session_deinit(struct iocpt_session_priv *priv); 274*6bc7f2cfSAndrew Boyer 2752c1662bbSAndrew Boyer struct ionic_doorbell __iomem *iocpt_db_map(struct iocpt_dev *dev, 2762c1662bbSAndrew Boyer struct iocpt_queue *q); 2772c1662bbSAndrew Boyer 2782c1662bbSAndrew Boyer typedef bool (*iocpt_cq_cb)(struct iocpt_cq *cq, uint16_t cq_desc_index, 2792c1662bbSAndrew Boyer void *cb_arg); 2802c1662bbSAndrew Boyer uint32_t iocpt_cq_service(struct iocpt_cq *cq, uint32_t work_to_do, 2812c1662bbSAndrew Boyer iocpt_cq_cb cb, void *cb_arg); 2822c1662bbSAndrew Boyer 2832c1662bbSAndrew Boyer static inline uint16_t 2842c1662bbSAndrew Boyer iocpt_q_space_avail(struct iocpt_queue *q) 2852c1662bbSAndrew Boyer { 2862c1662bbSAndrew Boyer uint16_t avail = q->tail_idx; 2872c1662bbSAndrew Boyer 2882c1662bbSAndrew Boyer if (q->head_idx >= avail) 2892c1662bbSAndrew Boyer avail += q->num_descs - q->head_idx - 1; 2902c1662bbSAndrew Boyer else 2912c1662bbSAndrew Boyer avail -= q->head_idx + 1; 2922c1662bbSAndrew Boyer 2932c1662bbSAndrew Boyer return avail; 2942c1662bbSAndrew Boyer } 2952c1662bbSAndrew Boyer 2962c1662bbSAndrew Boyer static inline void 2972c1662bbSAndrew Boyer iocpt_q_flush(struct iocpt_queue *q) 2982c1662bbSAndrew Boyer { 2992c1662bbSAndrew Boyer uint64_t val = IONIC_DBELL_QID(q->hw_index) | q->head_idx; 3002c1662bbSAndrew Boyer 3012c1662bbSAndrew Boyer #if defined(RTE_LIBRTE_IONIC_PMD_BARRIER_ERRATA) 3022c1662bbSAndrew Boyer /* On some devices the standard 'dmb' barrier is insufficient */ 3032c1662bbSAndrew Boyer asm volatile("dsb st" : : : "memory"); 3042c1662bbSAndrew Boyer rte_write64_relaxed(rte_cpu_to_le_64(val), q->db); 3052c1662bbSAndrew Boyer #else 3062c1662bbSAndrew Boyer rte_write64(rte_cpu_to_le_64(val), q->db); 3072c1662bbSAndrew Boyer #endif 3082c1662bbSAndrew Boyer } 3092c1662bbSAndrew Boyer 3104610ac93SAndrew Boyer static inline bool 3114610ac93SAndrew Boyer iocpt_is_embedded(void) 3124610ac93SAndrew Boyer { 3134610ac93SAndrew Boyer #if defined(RTE_LIBRTE_IONIC_PMD_EMBEDDED) 3144610ac93SAndrew Boyer return true; 3154610ac93SAndrew Boyer #else 3164610ac93SAndrew Boyer return false; 3174610ac93SAndrew Boyer #endif 3184610ac93SAndrew Boyer } 3194610ac93SAndrew Boyer 3204610ac93SAndrew Boyer #endif /* _IONIC_CRYPTO_H_ */ 321