199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright(c) 2018 Intel Corporation 399a2dd95SBruce Richardson */ 499a2dd95SBruce Richardson #include <string.h> 599a2dd95SBruce Richardson 699a2dd95SBruce Richardson #include <rte_common.h> 799a2dd95SBruce Richardson #include <rte_malloc.h> 899a2dd95SBruce Richardson 999a2dd95SBruce Richardson #include "rte_port_sym_crypto.h" 1099a2dd95SBruce Richardson 1199a2dd95SBruce Richardson /* 1299a2dd95SBruce Richardson * Port Crypto Reader 1399a2dd95SBruce Richardson */ 1499a2dd95SBruce Richardson #ifdef RTE_PORT_STATS_COLLECT 1599a2dd95SBruce Richardson 1699a2dd95SBruce Richardson #define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_IN_ADD(port, val) \ 1799a2dd95SBruce Richardson (port)->stats.n_pkts_in += (val) 1899a2dd95SBruce Richardson #define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_DROP_ADD(port, val) \ 1999a2dd95SBruce Richardson (port)->stats.n_pkts_drop += (val) 2099a2dd95SBruce Richardson 2199a2dd95SBruce Richardson #else 2299a2dd95SBruce Richardson 2399a2dd95SBruce Richardson #define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_IN_ADD(port, val) 2499a2dd95SBruce Richardson #define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_DROP_ADD(port, val) 2599a2dd95SBruce Richardson 2699a2dd95SBruce Richardson #endif 2799a2dd95SBruce Richardson 2899a2dd95SBruce Richardson struct rte_port_sym_crypto_reader { 2999a2dd95SBruce Richardson struct rte_port_in_stats stats; 3099a2dd95SBruce Richardson 3199a2dd95SBruce Richardson uint8_t cryptodev_id; 3299a2dd95SBruce Richardson uint16_t queue_id; 3399a2dd95SBruce Richardson struct rte_crypto_op *ops[RTE_PORT_IN_BURST_SIZE_MAX]; 3499a2dd95SBruce Richardson rte_port_sym_crypto_reader_callback_fn f_callback; 3599a2dd95SBruce Richardson void *arg_callback; 3699a2dd95SBruce Richardson }; 3799a2dd95SBruce Richardson 3899a2dd95SBruce Richardson static void * 3999a2dd95SBruce Richardson rte_port_sym_crypto_reader_create(void *params, int socket_id) 4099a2dd95SBruce Richardson { 4199a2dd95SBruce Richardson struct rte_port_sym_crypto_reader_params *conf = 4299a2dd95SBruce Richardson params; 4399a2dd95SBruce Richardson struct rte_port_sym_crypto_reader *port; 4499a2dd95SBruce Richardson 4599a2dd95SBruce Richardson /* Check input parameters */ 4699a2dd95SBruce Richardson if (conf == NULL) { 4799a2dd95SBruce Richardson RTE_LOG(ERR, PORT, "%s: params is NULL\n", __func__); 4899a2dd95SBruce Richardson return NULL; 4999a2dd95SBruce Richardson } 5099a2dd95SBruce Richardson 5199a2dd95SBruce Richardson /* Memory allocation */ 5299a2dd95SBruce Richardson port = rte_zmalloc_socket("PORT", sizeof(*port), 5399a2dd95SBruce Richardson RTE_CACHE_LINE_SIZE, socket_id); 5499a2dd95SBruce Richardson if (port == NULL) { 5599a2dd95SBruce Richardson RTE_LOG(ERR, PORT, "%s: Failed to allocate port\n", __func__); 5699a2dd95SBruce Richardson return NULL; 5799a2dd95SBruce Richardson } 5899a2dd95SBruce Richardson 5999a2dd95SBruce Richardson /* Initialization */ 6099a2dd95SBruce Richardson port->cryptodev_id = conf->cryptodev_id; 6199a2dd95SBruce Richardson port->queue_id = conf->queue_id; 6299a2dd95SBruce Richardson port->f_callback = conf->f_callback; 6399a2dd95SBruce Richardson port->arg_callback = conf->arg_callback; 6499a2dd95SBruce Richardson 6599a2dd95SBruce Richardson return port; 6699a2dd95SBruce Richardson } 6799a2dd95SBruce Richardson 6899a2dd95SBruce Richardson static int 6999a2dd95SBruce Richardson rte_port_sym_crypto_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts) 7099a2dd95SBruce Richardson { 7199a2dd95SBruce Richardson struct rte_port_sym_crypto_reader *p = 7299a2dd95SBruce Richardson port; 7399a2dd95SBruce Richardson uint16_t rx_ops_cnt, i, n = 0; 7499a2dd95SBruce Richardson 7599a2dd95SBruce Richardson rx_ops_cnt = rte_cryptodev_dequeue_burst(p->cryptodev_id, p->queue_id, 7699a2dd95SBruce Richardson p->ops, n_pkts); 7799a2dd95SBruce Richardson 7899a2dd95SBruce Richardson for (i = 0; i < rx_ops_cnt; i++) { 7999a2dd95SBruce Richardson struct rte_crypto_op *op = p->ops[i]; 8099a2dd95SBruce Richardson 8199a2dd95SBruce Richardson /** Drop failed pkts */ 8299a2dd95SBruce Richardson if (unlikely(op->status != RTE_CRYPTO_OP_STATUS_SUCCESS)) { 8399a2dd95SBruce Richardson rte_pktmbuf_free(op->sym->m_src); 8499a2dd95SBruce Richardson continue; 8599a2dd95SBruce Richardson } 8699a2dd95SBruce Richardson 8799a2dd95SBruce Richardson pkts[n++] = op->sym->m_src; 8899a2dd95SBruce Richardson } 8999a2dd95SBruce Richardson 9099a2dd95SBruce Richardson if (p->f_callback) 9199a2dd95SBruce Richardson (*p->f_callback)(pkts, n, p->arg_callback); 9299a2dd95SBruce Richardson 9399a2dd95SBruce Richardson RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_IN_ADD(p, n); 9499a2dd95SBruce Richardson RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_DROP_ADD(p, rx_ops_cnt - n); 9599a2dd95SBruce Richardson 9699a2dd95SBruce Richardson return n; 9799a2dd95SBruce Richardson } 9899a2dd95SBruce Richardson 9999a2dd95SBruce Richardson static int 10099a2dd95SBruce Richardson rte_port_sym_crypto_reader_free(void *port) 10199a2dd95SBruce Richardson { 10299a2dd95SBruce Richardson if (port == NULL) { 10399a2dd95SBruce Richardson RTE_LOG(ERR, PORT, "%s: port is NULL\n", __func__); 10499a2dd95SBruce Richardson return -EINVAL; 10599a2dd95SBruce Richardson } 10699a2dd95SBruce Richardson 10799a2dd95SBruce Richardson rte_free(port); 10899a2dd95SBruce Richardson 10999a2dd95SBruce Richardson return 0; 11099a2dd95SBruce Richardson } 11199a2dd95SBruce Richardson 11299a2dd95SBruce Richardson static int rte_port_sym_crypto_reader_stats_read(void *port, 11399a2dd95SBruce Richardson struct rte_port_in_stats *stats, int clear) 11499a2dd95SBruce Richardson { 11599a2dd95SBruce Richardson struct rte_port_sym_crypto_reader *p = 11699a2dd95SBruce Richardson port; 11799a2dd95SBruce Richardson 11899a2dd95SBruce Richardson if (stats != NULL) 11999a2dd95SBruce Richardson memcpy(stats, &p->stats, sizeof(p->stats)); 12099a2dd95SBruce Richardson 12199a2dd95SBruce Richardson if (clear) 12299a2dd95SBruce Richardson memset(&p->stats, 0, sizeof(p->stats)); 12399a2dd95SBruce Richardson 12499a2dd95SBruce Richardson return 0; 12599a2dd95SBruce Richardson } 12699a2dd95SBruce Richardson 12799a2dd95SBruce Richardson /* 12899a2dd95SBruce Richardson * Port crypto Writer 12999a2dd95SBruce Richardson */ 13099a2dd95SBruce Richardson #ifdef RTE_PORT_STATS_COLLECT 13199a2dd95SBruce Richardson 13299a2dd95SBruce Richardson #define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(port, val) \ 13399a2dd95SBruce Richardson (port)->stats.n_pkts_in += (val) 13499a2dd95SBruce Richardson #define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_DROP_ADD(port, val) \ 13599a2dd95SBruce Richardson (port)->stats.n_pkts_drop += (val) 13699a2dd95SBruce Richardson 13799a2dd95SBruce Richardson #else 13899a2dd95SBruce Richardson 13999a2dd95SBruce Richardson #define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(port, val) 14099a2dd95SBruce Richardson #define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_DROP_ADD(port, val) 14199a2dd95SBruce Richardson 14299a2dd95SBruce Richardson #endif 14399a2dd95SBruce Richardson 14499a2dd95SBruce Richardson struct rte_port_sym_crypto_writer { 14599a2dd95SBruce Richardson struct rte_port_out_stats stats; 14699a2dd95SBruce Richardson 14799a2dd95SBruce Richardson struct rte_crypto_op *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX]; 14899a2dd95SBruce Richardson 14999a2dd95SBruce Richardson uint32_t tx_burst_sz; 15099a2dd95SBruce Richardson uint32_t tx_buf_count; 15199a2dd95SBruce Richardson uint64_t bsz_mask; 15299a2dd95SBruce Richardson 15399a2dd95SBruce Richardson uint8_t cryptodev_id; 15499a2dd95SBruce Richardson uint16_t queue_id; 15599a2dd95SBruce Richardson uint16_t crypto_op_offset; 15699a2dd95SBruce Richardson }; 15799a2dd95SBruce Richardson 15899a2dd95SBruce Richardson static void * 15999a2dd95SBruce Richardson rte_port_sym_crypto_writer_create(void *params, int socket_id) 16099a2dd95SBruce Richardson { 16199a2dd95SBruce Richardson struct rte_port_sym_crypto_writer_params *conf = 16299a2dd95SBruce Richardson params; 16399a2dd95SBruce Richardson struct rte_port_sym_crypto_writer *port; 16499a2dd95SBruce Richardson 16599a2dd95SBruce Richardson /* Check input parameters */ 16699a2dd95SBruce Richardson if ((conf == NULL) || 16799a2dd95SBruce Richardson (conf->tx_burst_sz == 0) || 16899a2dd95SBruce Richardson (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) || 16999a2dd95SBruce Richardson (!rte_is_power_of_2(conf->tx_burst_sz))) { 17099a2dd95SBruce Richardson RTE_LOG(ERR, PORT, "%s: Invalid input parameters\n", __func__); 17199a2dd95SBruce Richardson return NULL; 17299a2dd95SBruce Richardson } 17399a2dd95SBruce Richardson 17499a2dd95SBruce Richardson /* Memory allocation */ 17599a2dd95SBruce Richardson port = rte_zmalloc_socket("PORT", sizeof(*port), 17699a2dd95SBruce Richardson RTE_CACHE_LINE_SIZE, socket_id); 17799a2dd95SBruce Richardson if (port == NULL) { 17899a2dd95SBruce Richardson RTE_LOG(ERR, PORT, "%s: Failed to allocate port\n", __func__); 17999a2dd95SBruce Richardson return NULL; 18099a2dd95SBruce Richardson } 18199a2dd95SBruce Richardson 18299a2dd95SBruce Richardson /* Initialization */ 18399a2dd95SBruce Richardson port->tx_burst_sz = conf->tx_burst_sz; 18499a2dd95SBruce Richardson port->tx_buf_count = 0; 18599a2dd95SBruce Richardson port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1); 18699a2dd95SBruce Richardson 18799a2dd95SBruce Richardson port->cryptodev_id = conf->cryptodev_id; 18899a2dd95SBruce Richardson port->queue_id = conf->queue_id; 18999a2dd95SBruce Richardson port->crypto_op_offset = conf->crypto_op_offset; 19099a2dd95SBruce Richardson 19199a2dd95SBruce Richardson return port; 19299a2dd95SBruce Richardson } 19399a2dd95SBruce Richardson 19499a2dd95SBruce Richardson static inline void 19599a2dd95SBruce Richardson send_burst(struct rte_port_sym_crypto_writer *p) 19699a2dd95SBruce Richardson { 19799a2dd95SBruce Richardson uint32_t nb_tx; 19899a2dd95SBruce Richardson 19999a2dd95SBruce Richardson nb_tx = rte_cryptodev_enqueue_burst(p->cryptodev_id, p->queue_id, 20099a2dd95SBruce Richardson p->tx_buf, p->tx_buf_count); 20199a2dd95SBruce Richardson 20299a2dd95SBruce Richardson RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - 20399a2dd95SBruce Richardson nb_tx); 20499a2dd95SBruce Richardson for (; nb_tx < p->tx_buf_count; nb_tx++) 20599a2dd95SBruce Richardson rte_pktmbuf_free(p->tx_buf[nb_tx]->sym->m_src); 20699a2dd95SBruce Richardson 20799a2dd95SBruce Richardson p->tx_buf_count = 0; 20899a2dd95SBruce Richardson } 20999a2dd95SBruce Richardson 21099a2dd95SBruce Richardson static int 21199a2dd95SBruce Richardson rte_port_sym_crypto_writer_tx(void *port, struct rte_mbuf *pkt) 21299a2dd95SBruce Richardson { 21399a2dd95SBruce Richardson struct rte_port_sym_crypto_writer *p = 21499a2dd95SBruce Richardson port; 21599a2dd95SBruce Richardson 21699a2dd95SBruce Richardson p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *) 21799a2dd95SBruce Richardson RTE_MBUF_METADATA_UINT8_PTR(pkt, p->crypto_op_offset); 21899a2dd95SBruce Richardson RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, 1); 21999a2dd95SBruce Richardson if (p->tx_buf_count >= p->tx_burst_sz) 22099a2dd95SBruce Richardson send_burst(p); 22199a2dd95SBruce Richardson 22299a2dd95SBruce Richardson return 0; 22399a2dd95SBruce Richardson } 22499a2dd95SBruce Richardson 22599a2dd95SBruce Richardson static int 22699a2dd95SBruce Richardson rte_port_sym_crypto_writer_tx_bulk(void *port, 22799a2dd95SBruce Richardson struct rte_mbuf **pkts, 22899a2dd95SBruce Richardson uint64_t pkts_mask) 22999a2dd95SBruce Richardson { 23099a2dd95SBruce Richardson struct rte_port_sym_crypto_writer *p = 23199a2dd95SBruce Richardson port; 23299a2dd95SBruce Richardson uint64_t bsz_mask = p->bsz_mask; 23399a2dd95SBruce Richardson uint32_t tx_buf_count = p->tx_buf_count; 23499a2dd95SBruce Richardson uint64_t expr = (pkts_mask & (pkts_mask + 1)) | 23599a2dd95SBruce Richardson ((pkts_mask & bsz_mask) ^ bsz_mask); 23699a2dd95SBruce Richardson 23799a2dd95SBruce Richardson if (expr == 0) { 238*3d4e27fdSDavid Marchand uint64_t n_pkts = rte_popcount64(pkts_mask); 23999a2dd95SBruce Richardson uint32_t i; 24099a2dd95SBruce Richardson 24199a2dd95SBruce Richardson RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, n_pkts); 24299a2dd95SBruce Richardson 24399a2dd95SBruce Richardson for (i = 0; i < n_pkts; i++) 24499a2dd95SBruce Richardson p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *) 24599a2dd95SBruce Richardson RTE_MBUF_METADATA_UINT8_PTR(pkts[i], 24699a2dd95SBruce Richardson p->crypto_op_offset); 24799a2dd95SBruce Richardson 24899a2dd95SBruce Richardson if (p->tx_buf_count >= p->tx_burst_sz) 24999a2dd95SBruce Richardson send_burst(p); 25099a2dd95SBruce Richardson } else { 25199a2dd95SBruce Richardson for (; pkts_mask;) { 252*3d4e27fdSDavid Marchand uint32_t pkt_index = rte_ctz64(pkts_mask); 25399a2dd95SBruce Richardson uint64_t pkt_mask = 1LLU << pkt_index; 25499a2dd95SBruce Richardson struct rte_mbuf *pkt = pkts[pkt_index]; 25599a2dd95SBruce Richardson 25699a2dd95SBruce Richardson p->tx_buf[tx_buf_count++] = (struct rte_crypto_op *) 25799a2dd95SBruce Richardson RTE_MBUF_METADATA_UINT8_PTR(pkt, 25899a2dd95SBruce Richardson p->crypto_op_offset); 25999a2dd95SBruce Richardson 26099a2dd95SBruce Richardson RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, 1); 26199a2dd95SBruce Richardson pkts_mask &= ~pkt_mask; 26299a2dd95SBruce Richardson } 26399a2dd95SBruce Richardson 26499a2dd95SBruce Richardson p->tx_buf_count = tx_buf_count; 26599a2dd95SBruce Richardson if (tx_buf_count >= p->tx_burst_sz) 26699a2dd95SBruce Richardson send_burst(p); 26799a2dd95SBruce Richardson } 26899a2dd95SBruce Richardson 26999a2dd95SBruce Richardson return 0; 27099a2dd95SBruce Richardson } 27199a2dd95SBruce Richardson 27299a2dd95SBruce Richardson static int 27399a2dd95SBruce Richardson rte_port_sym_crypto_writer_flush(void *port) 27499a2dd95SBruce Richardson { 27599a2dd95SBruce Richardson struct rte_port_sym_crypto_writer *p = 27699a2dd95SBruce Richardson port; 27799a2dd95SBruce Richardson 27899a2dd95SBruce Richardson if (p->tx_buf_count > 0) 27999a2dd95SBruce Richardson send_burst(p); 28099a2dd95SBruce Richardson 28199a2dd95SBruce Richardson return 0; 28299a2dd95SBruce Richardson } 28399a2dd95SBruce Richardson 28499a2dd95SBruce Richardson static int 28599a2dd95SBruce Richardson rte_port_sym_crypto_writer_free(void *port) 28699a2dd95SBruce Richardson { 28799a2dd95SBruce Richardson if (port == NULL) { 28899a2dd95SBruce Richardson RTE_LOG(ERR, PORT, "%s: Port is NULL\n", __func__); 28999a2dd95SBruce Richardson return -EINVAL; 29099a2dd95SBruce Richardson } 29199a2dd95SBruce Richardson 29299a2dd95SBruce Richardson rte_port_sym_crypto_writer_flush(port); 29399a2dd95SBruce Richardson rte_free(port); 29499a2dd95SBruce Richardson 29599a2dd95SBruce Richardson return 0; 29699a2dd95SBruce Richardson } 29799a2dd95SBruce Richardson 29899a2dd95SBruce Richardson static int rte_port_sym_crypto_writer_stats_read(void *port, 29999a2dd95SBruce Richardson struct rte_port_out_stats *stats, int clear) 30099a2dd95SBruce Richardson { 30199a2dd95SBruce Richardson struct rte_port_sym_crypto_writer *p = 30299a2dd95SBruce Richardson port; 30399a2dd95SBruce Richardson 30499a2dd95SBruce Richardson if (stats != NULL) 30599a2dd95SBruce Richardson memcpy(stats, &p->stats, sizeof(p->stats)); 30699a2dd95SBruce Richardson 30799a2dd95SBruce Richardson if (clear) 30899a2dd95SBruce Richardson memset(&p->stats, 0, sizeof(p->stats)); 30999a2dd95SBruce Richardson 31099a2dd95SBruce Richardson return 0; 31199a2dd95SBruce Richardson } 31299a2dd95SBruce Richardson 31399a2dd95SBruce Richardson /* 31499a2dd95SBruce Richardson * Port crypto Writer Nodrop 31599a2dd95SBruce Richardson */ 31699a2dd95SBruce Richardson #ifdef RTE_PORT_STATS_COLLECT 31799a2dd95SBruce Richardson 31899a2dd95SBruce Richardson #define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \ 31999a2dd95SBruce Richardson (port)->stats.n_pkts_in += (val) 32099a2dd95SBruce Richardson #define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \ 32199a2dd95SBruce Richardson (port)->stats.n_pkts_drop += (val) 32299a2dd95SBruce Richardson 32399a2dd95SBruce Richardson #else 32499a2dd95SBruce Richardson 32599a2dd95SBruce Richardson #define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) 32699a2dd95SBruce Richardson #define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) 32799a2dd95SBruce Richardson 32899a2dd95SBruce Richardson #endif 32999a2dd95SBruce Richardson 33099a2dd95SBruce Richardson struct rte_port_sym_crypto_writer_nodrop { 33199a2dd95SBruce Richardson struct rte_port_out_stats stats; 33299a2dd95SBruce Richardson 33399a2dd95SBruce Richardson struct rte_crypto_op *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX]; 33499a2dd95SBruce Richardson uint32_t tx_burst_sz; 33599a2dd95SBruce Richardson uint32_t tx_buf_count; 33699a2dd95SBruce Richardson uint64_t bsz_mask; 33799a2dd95SBruce Richardson uint64_t n_retries; 33899a2dd95SBruce Richardson 33999a2dd95SBruce Richardson uint8_t cryptodev_id; 34099a2dd95SBruce Richardson uint16_t queue_id; 34199a2dd95SBruce Richardson uint16_t crypto_op_offset; 34299a2dd95SBruce Richardson }; 34399a2dd95SBruce Richardson 34499a2dd95SBruce Richardson static void * 34599a2dd95SBruce Richardson rte_port_sym_crypto_writer_nodrop_create(void *params, int socket_id) 34699a2dd95SBruce Richardson { 34799a2dd95SBruce Richardson struct rte_port_sym_crypto_writer_nodrop_params *conf = 34899a2dd95SBruce Richardson params; 34999a2dd95SBruce Richardson struct rte_port_sym_crypto_writer_nodrop *port; 35099a2dd95SBruce Richardson 35199a2dd95SBruce Richardson /* Check input parameters */ 35299a2dd95SBruce Richardson if ((conf == NULL) || 35399a2dd95SBruce Richardson (conf->tx_burst_sz == 0) || 35499a2dd95SBruce Richardson (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) || 35599a2dd95SBruce Richardson (!rte_is_power_of_2(conf->tx_burst_sz))) { 35699a2dd95SBruce Richardson RTE_LOG(ERR, PORT, "%s: Invalid input parameters\n", __func__); 35799a2dd95SBruce Richardson return NULL; 35899a2dd95SBruce Richardson } 35999a2dd95SBruce Richardson 36099a2dd95SBruce Richardson /* Memory allocation */ 36199a2dd95SBruce Richardson port = rte_zmalloc_socket("PORT", sizeof(*port), 36299a2dd95SBruce Richardson RTE_CACHE_LINE_SIZE, socket_id); 36399a2dd95SBruce Richardson if (port == NULL) { 36499a2dd95SBruce Richardson RTE_LOG(ERR, PORT, "%s: Failed to allocate port\n", __func__); 36599a2dd95SBruce Richardson return NULL; 36699a2dd95SBruce Richardson } 36799a2dd95SBruce Richardson 36899a2dd95SBruce Richardson /* Initialization */ 36999a2dd95SBruce Richardson port->cryptodev_id = conf->cryptodev_id; 37099a2dd95SBruce Richardson port->queue_id = conf->queue_id; 37199a2dd95SBruce Richardson port->crypto_op_offset = conf->crypto_op_offset; 37299a2dd95SBruce Richardson port->tx_burst_sz = conf->tx_burst_sz; 37399a2dd95SBruce Richardson port->tx_buf_count = 0; 37499a2dd95SBruce Richardson port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1); 37599a2dd95SBruce Richardson 37699a2dd95SBruce Richardson /* 37799a2dd95SBruce Richardson * When n_retries is 0 it means that we should wait for every packet to 37899a2dd95SBruce Richardson * send no matter how many retries should it take. To limit number of 37999a2dd95SBruce Richardson * branches in fast path, we use UINT64_MAX instead of branching. 38099a2dd95SBruce Richardson */ 38199a2dd95SBruce Richardson port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries; 38299a2dd95SBruce Richardson 38399a2dd95SBruce Richardson return port; 38499a2dd95SBruce Richardson } 38599a2dd95SBruce Richardson 38699a2dd95SBruce Richardson static inline void 38799a2dd95SBruce Richardson send_burst_nodrop(struct rte_port_sym_crypto_writer_nodrop *p) 38899a2dd95SBruce Richardson { 38999a2dd95SBruce Richardson uint32_t nb_tx = 0, i; 39099a2dd95SBruce Richardson 39199a2dd95SBruce Richardson nb_tx = rte_cryptodev_enqueue_burst(p->cryptodev_id, p->queue_id, 39299a2dd95SBruce Richardson p->tx_buf, p->tx_buf_count); 39399a2dd95SBruce Richardson 39499a2dd95SBruce Richardson /* We sent all the packets in a first try */ 39599a2dd95SBruce Richardson if (nb_tx >= p->tx_buf_count) { 39699a2dd95SBruce Richardson p->tx_buf_count = 0; 39799a2dd95SBruce Richardson return; 39899a2dd95SBruce Richardson } 39999a2dd95SBruce Richardson 40099a2dd95SBruce Richardson for (i = 0; i < p->n_retries; i++) { 40199a2dd95SBruce Richardson nb_tx += rte_cryptodev_enqueue_burst(p->cryptodev_id, 40299a2dd95SBruce Richardson p->queue_id, p->tx_buf + nb_tx, 40399a2dd95SBruce Richardson p->tx_buf_count - nb_tx); 40499a2dd95SBruce Richardson 40599a2dd95SBruce Richardson /* We sent all the packets in more than one try */ 40699a2dd95SBruce Richardson if (nb_tx >= p->tx_buf_count) { 40799a2dd95SBruce Richardson p->tx_buf_count = 0; 40899a2dd95SBruce Richardson return; 40999a2dd95SBruce Richardson } 41099a2dd95SBruce Richardson } 41199a2dd95SBruce Richardson 41299a2dd95SBruce Richardson /* We didn't send the packets in maximum allowed attempts */ 41399a2dd95SBruce Richardson RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, 41499a2dd95SBruce Richardson p->tx_buf_count - nb_tx); 41599a2dd95SBruce Richardson for ( ; nb_tx < p->tx_buf_count; nb_tx++) 41699a2dd95SBruce Richardson rte_pktmbuf_free(p->tx_buf[nb_tx]->sym->m_src); 41799a2dd95SBruce Richardson 41899a2dd95SBruce Richardson p->tx_buf_count = 0; 41999a2dd95SBruce Richardson } 42099a2dd95SBruce Richardson 42199a2dd95SBruce Richardson static int 42299a2dd95SBruce Richardson rte_port_sym_crypto_writer_nodrop_tx(void *port, struct rte_mbuf *pkt) 42399a2dd95SBruce Richardson { 42499a2dd95SBruce Richardson struct rte_port_sym_crypto_writer_nodrop *p = 42599a2dd95SBruce Richardson port; 42699a2dd95SBruce Richardson 42799a2dd95SBruce Richardson p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *) 42899a2dd95SBruce Richardson RTE_MBUF_METADATA_UINT8_PTR(pkt, p->crypto_op_offset); 42999a2dd95SBruce Richardson RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, 1); 43099a2dd95SBruce Richardson if (p->tx_buf_count >= p->tx_burst_sz) 43199a2dd95SBruce Richardson send_burst_nodrop(p); 43299a2dd95SBruce Richardson 43399a2dd95SBruce Richardson return 0; 43499a2dd95SBruce Richardson } 43599a2dd95SBruce Richardson 43699a2dd95SBruce Richardson static int 43799a2dd95SBruce Richardson rte_port_sym_crypto_writer_nodrop_tx_bulk(void *port, 43899a2dd95SBruce Richardson struct rte_mbuf **pkts, 43999a2dd95SBruce Richardson uint64_t pkts_mask) 44099a2dd95SBruce Richardson { 44199a2dd95SBruce Richardson struct rte_port_sym_crypto_writer_nodrop *p = 44299a2dd95SBruce Richardson port; 44399a2dd95SBruce Richardson 44499a2dd95SBruce Richardson uint64_t bsz_mask = p->bsz_mask; 44599a2dd95SBruce Richardson uint32_t tx_buf_count = p->tx_buf_count; 44699a2dd95SBruce Richardson uint64_t expr = (pkts_mask & (pkts_mask + 1)) | 44799a2dd95SBruce Richardson ((pkts_mask & bsz_mask) ^ bsz_mask); 44899a2dd95SBruce Richardson 44999a2dd95SBruce Richardson if (expr == 0) { 450*3d4e27fdSDavid Marchand uint64_t n_pkts = rte_popcount64(pkts_mask); 45199a2dd95SBruce Richardson uint32_t i; 45299a2dd95SBruce Richardson 45399a2dd95SBruce Richardson RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts); 45499a2dd95SBruce Richardson 45599a2dd95SBruce Richardson for (i = 0; i < n_pkts; i++) 45699a2dd95SBruce Richardson p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *) 45799a2dd95SBruce Richardson RTE_MBUF_METADATA_UINT8_PTR(pkts[i], 45899a2dd95SBruce Richardson p->crypto_op_offset); 45999a2dd95SBruce Richardson 46099a2dd95SBruce Richardson if (p->tx_buf_count >= p->tx_burst_sz) 46199a2dd95SBruce Richardson send_burst_nodrop(p); 46299a2dd95SBruce Richardson } else { 46399a2dd95SBruce Richardson for ( ; pkts_mask; ) { 464*3d4e27fdSDavid Marchand uint32_t pkt_index = rte_ctz64(pkts_mask); 46599a2dd95SBruce Richardson uint64_t pkt_mask = 1LLU << pkt_index; 46699a2dd95SBruce Richardson struct rte_mbuf *pkt = pkts[pkt_index]; 46799a2dd95SBruce Richardson 46899a2dd95SBruce Richardson p->tx_buf[tx_buf_count++] = (struct rte_crypto_op *) 46999a2dd95SBruce Richardson RTE_MBUF_METADATA_UINT8_PTR(pkt, 47099a2dd95SBruce Richardson p->crypto_op_offset); 47199a2dd95SBruce Richardson RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 47299a2dd95SBruce Richardson 1); 47399a2dd95SBruce Richardson pkts_mask &= ~pkt_mask; 47499a2dd95SBruce Richardson } 47599a2dd95SBruce Richardson 47699a2dd95SBruce Richardson p->tx_buf_count = tx_buf_count; 47799a2dd95SBruce Richardson if (tx_buf_count >= p->tx_burst_sz) 47899a2dd95SBruce Richardson send_burst_nodrop(p); 47999a2dd95SBruce Richardson } 48099a2dd95SBruce Richardson 48199a2dd95SBruce Richardson return 0; 48299a2dd95SBruce Richardson } 48399a2dd95SBruce Richardson 48499a2dd95SBruce Richardson static int 48599a2dd95SBruce Richardson rte_port_sym_crypto_writer_nodrop_flush(void *port) 48699a2dd95SBruce Richardson { 48799a2dd95SBruce Richardson struct rte_port_sym_crypto_writer_nodrop *p = 48899a2dd95SBruce Richardson port; 48999a2dd95SBruce Richardson 49099a2dd95SBruce Richardson if (p->tx_buf_count > 0) 49199a2dd95SBruce Richardson send_burst_nodrop(p); 49299a2dd95SBruce Richardson 49399a2dd95SBruce Richardson return 0; 49499a2dd95SBruce Richardson } 49599a2dd95SBruce Richardson 49699a2dd95SBruce Richardson static int 49799a2dd95SBruce Richardson rte_port_sym_crypto_writer_nodrop_free(void *port) 49899a2dd95SBruce Richardson { 49999a2dd95SBruce Richardson if (port == NULL) { 50099a2dd95SBruce Richardson RTE_LOG(ERR, PORT, "%s: Port is NULL\n", __func__); 50199a2dd95SBruce Richardson return -EINVAL; 50299a2dd95SBruce Richardson } 50399a2dd95SBruce Richardson 50499a2dd95SBruce Richardson rte_port_sym_crypto_writer_nodrop_flush(port); 50599a2dd95SBruce Richardson rte_free(port); 50699a2dd95SBruce Richardson 50799a2dd95SBruce Richardson return 0; 50899a2dd95SBruce Richardson } 50999a2dd95SBruce Richardson 51099a2dd95SBruce Richardson static int rte_port_sym_crypto_writer_nodrop_stats_read(void *port, 51199a2dd95SBruce Richardson struct rte_port_out_stats *stats, int clear) 51299a2dd95SBruce Richardson { 51399a2dd95SBruce Richardson struct rte_port_sym_crypto_writer_nodrop *p = 51499a2dd95SBruce Richardson port; 51599a2dd95SBruce Richardson 51699a2dd95SBruce Richardson if (stats != NULL) 51799a2dd95SBruce Richardson memcpy(stats, &p->stats, sizeof(p->stats)); 51899a2dd95SBruce Richardson 51999a2dd95SBruce Richardson if (clear) 52099a2dd95SBruce Richardson memset(&p->stats, 0, sizeof(p->stats)); 52199a2dd95SBruce Richardson 52299a2dd95SBruce Richardson return 0; 52399a2dd95SBruce Richardson } 52499a2dd95SBruce Richardson 52599a2dd95SBruce Richardson 52699a2dd95SBruce Richardson /* 52799a2dd95SBruce Richardson * Summary of port operations 52899a2dd95SBruce Richardson */ 52999a2dd95SBruce Richardson struct rte_port_in_ops rte_port_sym_crypto_reader_ops = { 53099a2dd95SBruce Richardson .f_create = rte_port_sym_crypto_reader_create, 53199a2dd95SBruce Richardson .f_free = rte_port_sym_crypto_reader_free, 53299a2dd95SBruce Richardson .f_rx = rte_port_sym_crypto_reader_rx, 53399a2dd95SBruce Richardson .f_stats = rte_port_sym_crypto_reader_stats_read, 53499a2dd95SBruce Richardson }; 53599a2dd95SBruce Richardson 53699a2dd95SBruce Richardson struct rte_port_out_ops rte_port_sym_crypto_writer_ops = { 53799a2dd95SBruce Richardson .f_create = rte_port_sym_crypto_writer_create, 53899a2dd95SBruce Richardson .f_free = rte_port_sym_crypto_writer_free, 53999a2dd95SBruce Richardson .f_tx = rte_port_sym_crypto_writer_tx, 54099a2dd95SBruce Richardson .f_tx_bulk = rte_port_sym_crypto_writer_tx_bulk, 54199a2dd95SBruce Richardson .f_flush = rte_port_sym_crypto_writer_flush, 54299a2dd95SBruce Richardson .f_stats = rte_port_sym_crypto_writer_stats_read, 54399a2dd95SBruce Richardson }; 54499a2dd95SBruce Richardson 54599a2dd95SBruce Richardson struct rte_port_out_ops rte_port_sym_crypto_writer_nodrop_ops = { 54699a2dd95SBruce Richardson .f_create = rte_port_sym_crypto_writer_nodrop_create, 54799a2dd95SBruce Richardson .f_free = rte_port_sym_crypto_writer_nodrop_free, 54899a2dd95SBruce Richardson .f_tx = rte_port_sym_crypto_writer_nodrop_tx, 54999a2dd95SBruce Richardson .f_tx_bulk = rte_port_sym_crypto_writer_nodrop_tx_bulk, 55099a2dd95SBruce Richardson .f_flush = rte_port_sym_crypto_writer_nodrop_flush, 55199a2dd95SBruce Richardson .f_stats = rte_port_sym_crypto_writer_nodrop_stats_read, 55299a2dd95SBruce Richardson }; 553