1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
|
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright 2021-2024 Advanced Micro Devices, Inc.
*/
#ifndef _IONIC_CRYPTO_H_
#define _IONIC_CRYPTO_H_
#include <stdint.h>
#include <stdbool.h>
#include <inttypes.h>
#include <rte_common.h>
#include <rte_dev.h>
#include <rte_cryptodev.h>
#include <cryptodev_pmd.h>
#include <rte_log.h>
#include <rte_bitmap.h>
#include "ionic_common.h"
#include "ionic_crypto_if.h"
#include "ionic_regs.h"
/* Devargs */
/* NONE */
#define IOCPT_MAX_RING_DESC 32768
#define IOCPT_MIN_RING_DESC 16
#define IOCPT_ADMINQ_LENGTH 16 /* must be a power of two */
#define IOCPT_CRYPTOQ_WAIT 10 /* 1s */
extern int iocpt_logtype;
#define RTE_LOGTYPE_IOCPT iocpt_logtype
#define IOCPT_PRINT(level, ...) \
RTE_LOG_LINE_PREFIX(level, IOCPT, "%s(): ", __func__, __VA_ARGS__)
#define IOCPT_PRINT_CALL() IOCPT_PRINT(DEBUG, " >>")
const struct rte_cryptodev_capabilities *iocpt_get_caps(uint64_t flags);
static inline void iocpt_struct_size_checks(void)
{
RTE_BUILD_BUG_ON(sizeof(struct ionic_doorbell) != 8);
RTE_BUILD_BUG_ON(sizeof(struct ionic_intr) != 32);
RTE_BUILD_BUG_ON(sizeof(struct ionic_intr_status) != 8);
RTE_BUILD_BUG_ON(sizeof(union iocpt_dev_regs) != 4096);
RTE_BUILD_BUG_ON(sizeof(union iocpt_dev_info_regs) != 2048);
RTE_BUILD_BUG_ON(sizeof(union iocpt_dev_cmd_regs) != 2048);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_admin_cmd) != 64);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_admin_comp) != 16);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_nop_cmd) != 64);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_nop_comp) != 16);
/* Device commands */
RTE_BUILD_BUG_ON(sizeof(struct iocpt_dev_identify_cmd) != 64);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_dev_identify_comp) != 16);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_dev_reset_cmd) != 64);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_dev_reset_comp) != 16);
/* LIF commands */
RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_identify_cmd) != 64);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_identify_comp) != 16);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_init_cmd) != 64);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_init_comp) != 16);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_reset_cmd) != 64);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_getattr_cmd) != 64);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_getattr_comp) != 16);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_setattr_cmd) != 64);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_setattr_comp) != 16);
/* Queue commands */
RTE_BUILD_BUG_ON(sizeof(struct iocpt_q_identify_cmd) != 64);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_q_identify_comp) != 16);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_q_init_cmd) != 64);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_q_init_comp) != 16);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_q_control_cmd) != 64);
/* Crypto */
RTE_BUILD_BUG_ON(sizeof(struct iocpt_crypto_desc) != 32);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_crypto_sg_desc) != 256);
RTE_BUILD_BUG_ON(sizeof(struct iocpt_crypto_comp) != 16);
}
struct iocpt_dev_bars {
struct ionic_dev_bar bar[IONIC_BARS_MAX];
uint32_t num_bars;
};
/* Queue watchdog */
#define IOCPT_Q_WDOG_SESS_IDX 0
#define IOCPT_Q_WDOG_KEY_LEN 16
#define IOCPT_Q_WDOG_IV_LEN 12
#define IOCPT_Q_WDOG_PLD_LEN 4
#define IOCPT_Q_WDOG_TAG_LEN 16
#define IOCPT_Q_WDOG_OP_TYPE RTE_CRYPTO_OP_TYPE_UNDEFINED
struct iocpt_qtype_info {
uint8_t version;
uint8_t supported;
uint64_t features;
uint16_t desc_sz;
uint16_t comp_sz;
uint16_t sg_desc_sz;
uint16_t max_sg_elems;
uint16_t sg_desc_stride;
};
#define IOCPT_Q_F_INITED BIT(0)
#define IOCPT_Q_F_DEFERRED BIT(1)
#define IOCPT_Q_F_SG BIT(2)
#define Q_NEXT_TO_POST(_q, _n) (((_q)->head_idx + (_n)) & ((_q)->size_mask))
#define Q_NEXT_TO_SRVC(_q, _n) (((_q)->tail_idx + (_n)) & ((_q)->size_mask))
#define IOCPT_INFO_SZ(_q) ((_q)->num_segs * sizeof(void *))
#define IOCPT_INFO_IDX(_q, _i) ((_i) * (_q)->num_segs)
#define IOCPT_INFO_PTR(_q, _i) (&(_q)->info[IOCPT_INFO_IDX((_q), _i)])
struct iocpt_queue {
uint16_t num_descs;
uint16_t num_segs;
uint16_t head_idx;
uint16_t tail_idx;
uint16_t size_mask;
uint8_t type;
uint8_t hw_type;
void *base;
void *sg_base;
struct ionic_doorbell __iomem *db;
void **info;
uint32_t index;
uint32_t hw_index;
rte_iova_t base_pa;
rte_iova_t sg_base_pa;
};
struct iocpt_cq {
uint16_t tail_idx;
uint16_t num_descs;
uint16_t size_mask;
bool done_color;
void *base;
rte_iova_t base_pa;
};
#define IOCPT_COMMON_FIELDS \
struct iocpt_queue q; \
struct iocpt_cq cq; \
struct iocpt_dev *dev; \
const struct rte_memzone *base_z; \
void *base; \
rte_iova_t base_pa
struct iocpt_common_q {
IOCPT_COMMON_FIELDS;
};
struct iocpt_admin_q {
IOCPT_COMMON_FIELDS;
uint16_t flags;
};
struct iocpt_crypto_q {
/* cacheline0, cacheline1 */
IOCPT_COMMON_FIELDS;
/* cacheline2 */
uint64_t last_wdog_cycles;
uint16_t flags;
/* cacheline3 */
struct rte_cryptodev_stats stats;
uint64_t enqueued_wdogs;
uint64_t dequeued_wdogs;
uint8_t wdog_iv[IOCPT_Q_WDOG_IV_LEN];
uint8_t wdog_pld[IOCPT_Q_WDOG_PLD_LEN];
uint8_t wdog_tag[IOCPT_Q_WDOG_TAG_LEN];
};
#define IOCPT_S_F_INITED BIT(0)
struct iocpt_session_priv {
struct iocpt_dev *dev;
uint32_t index;
uint16_t iv_offset;
uint16_t iv_length;
uint16_t digest_length;
uint16_t aad_length;
uint8_t flags;
uint8_t op;
uint8_t type;
uint16_t key_len;
uint8_t key[IOCPT_SESS_KEY_LEN_MAX_SYMM];
};
static inline uint32_t
iocpt_session_size(void)
{
return sizeof(struct iocpt_session_priv);
}
#define IOCPT_DEV_F_INITED BIT(0)
#define IOCPT_DEV_F_UP BIT(1)
#define IOCPT_DEV_F_FW_RESET BIT(2)
/* Combined dev / LIF object */
struct iocpt_dev {
const char *name;
char fw_version[IOCPT_FWVERS_BUFLEN];
struct iocpt_dev_bars bars;
struct iocpt_identity ident;
const struct iocpt_dev_intf *intf;
void *bus_dev;
struct rte_cryptodev *crypto_dev;
union iocpt_dev_info_regs __iomem *dev_info;
union iocpt_dev_cmd_regs __iomem *dev_cmd;
struct ionic_doorbell __iomem *db_pages;
struct ionic_intr __iomem *intr_ctrl;
uint32_t max_qps;
uint32_t max_sessions;
uint16_t state;
uint8_t driver_id;
uint8_t socket_id;
rte_spinlock_t adminq_lock;
rte_spinlock_t adminq_service_lock;
struct iocpt_admin_q *adminq;
struct iocpt_crypto_q **cryptoqs;
struct rte_bitmap *sess_bm; /* SET bit indicates index is free */
uint64_t features;
uint32_t hw_features;
uint32_t info_sz;
struct iocpt_lif_info *info;
rte_iova_t info_pa;
const struct rte_memzone *info_z;
struct iocpt_qtype_info qtype_info[IOCPT_QTYPE_MAX];
uint8_t qtype_ver[IOCPT_QTYPE_MAX];
struct rte_cryptodev_stats stats_base;
};
struct iocpt_dev_intf {
int (*setup_bars)(struct iocpt_dev *dev);
void (*unmap_bars)(struct iocpt_dev *dev);
};
static inline int
iocpt_setup_bars(struct iocpt_dev *dev)
{
if (dev->intf->setup_bars == NULL)
return -EINVAL;
return dev->intf->setup_bars(dev);
}
/** iocpt_admin_ctx - Admin command context.
* @pending_work: Flag that indicates a completion.
* @cmd: Admin command (64B) to be copied to the queue.
* @comp: Admin completion (16B) copied from the queue.
*/
struct iocpt_admin_ctx {
bool pending_work;
union iocpt_adminq_cmd cmd;
union iocpt_adminq_comp comp;
};
int iocpt_probe(void *bus_dev, struct rte_device *rte_dev,
struct iocpt_dev_bars *bars, const struct iocpt_dev_intf *intf,
uint8_t driver_id, uint8_t socket_id);
int iocpt_remove(struct rte_device *rte_dev);
void iocpt_configure(struct iocpt_dev *dev);
int iocpt_assign_ops(struct rte_cryptodev *cdev);
int iocpt_start(struct iocpt_dev *dev);
void iocpt_stop(struct iocpt_dev *dev);
void iocpt_deinit(struct iocpt_dev *dev);
int iocpt_dev_identify(struct iocpt_dev *dev);
int iocpt_dev_init(struct iocpt_dev *dev, rte_iova_t info_pa);
int iocpt_dev_adminq_init(struct iocpt_dev *dev);
void iocpt_dev_reset(struct iocpt_dev *dev);
int iocpt_adminq_post_wait(struct iocpt_dev *dev, struct iocpt_admin_ctx *ctx);
int iocpt_cryptoq_alloc(struct iocpt_dev *dev, uint32_t socket_id,
uint32_t index, uint16_t ndescs);
void iocpt_cryptoq_free(struct iocpt_crypto_q *cptq);
int iocpt_session_init(struct iocpt_session_priv *priv);
int iocpt_session_update(struct iocpt_session_priv *priv);
void iocpt_session_deinit(struct iocpt_session_priv *priv);
struct ionic_doorbell __iomem *iocpt_db_map(struct iocpt_dev *dev,
struct iocpt_queue *q);
typedef bool (*iocpt_cq_cb)(struct iocpt_cq *cq, uint16_t cq_desc_index,
void *cb_arg);
uint32_t iocpt_cq_service(struct iocpt_cq *cq, uint32_t work_to_do,
iocpt_cq_cb cb, void *cb_arg);
void iocpt_get_stats(const struct iocpt_dev *dev,
struct rte_cryptodev_stats *stats);
void iocpt_reset_stats(struct iocpt_dev *dev);
static inline uint16_t
iocpt_q_space_avail(struct iocpt_queue *q)
{
uint16_t avail = q->tail_idx;
if (q->head_idx >= avail)
avail += q->num_descs - q->head_idx - 1;
else
avail -= q->head_idx + 1;
return avail;
}
static inline void
iocpt_q_flush(struct iocpt_queue *q)
{
uint64_t val = IONIC_DBELL_QID(q->hw_index) | q->head_idx;
#if defined(RTE_LIBRTE_IONIC_PMD_BARRIER_ERRATA)
/* On some devices the standard 'dmb' barrier is insufficient */
asm volatile("dsb st" : : : "memory");
rte_write64_relaxed(rte_cpu_to_le_64(val), q->db);
#else
rte_write64(rte_cpu_to_le_64(val), q->db);
#endif
}
static inline bool
iocpt_is_embedded(void)
{
#if defined(RTE_LIBRTE_IONIC_PMD_EMBEDDED)
return true;
#else
return false;
#endif
}
#endif /* _IONIC_CRYPTO_H_ */
|