From: Vidya Sagar Velumuri <vvelum...@marvell.com>

Add support for multi segmented packet in Rx inject.

Signed-off-by: Vidya Sagar Velumuri <vvelum...@marvell.com>
---
 drivers/crypto/cnxk/cn10k_cryptodev_ops.c | 53 ++++++++++++++++++-----
 drivers/crypto/cnxk/cnxk_cryptodev_ops.h  |  9 +++-
 2 files changed, 50 insertions(+), 12 deletions(-)

diff --git a/drivers/crypto/cnxk/cn10k_cryptodev_ops.c 
b/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
index 780785d656..64d015aba2 100644
--- a/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
@@ -1366,8 +1366,8 @@ cn10k_cryptodev_sec_inb_rx_inject(void *dev, struct 
rte_mbuf **pkts,
        union cpt_fc_write_s fc;
        struct cnxk_cpt_vf *vf;
        struct rte_mbuf *m;
+       uint64_t u64_dptr;
        uint64_t *fc_addr;
-       uint64_t dptr;
        int i;
 
        vf = cdev->data->dev_private;
@@ -1401,11 +1401,6 @@ cn10k_cryptodev_sec_inb_rx_inject(void *dev, struct 
rte_mbuf **pkts,
                        break;
                }
 
-               if (unlikely(!rte_pktmbuf_is_contiguous(m))) {
-                       plt_dp_err("Multi seg is not supported");
-                       break;
-               }
-
                l2_len = m->l2_len;
 
                *rte_security_dynfield(m) = (uint64_t)sec_sess->userdata;
@@ -1415,6 +1410,46 @@ cn10k_cryptodev_sec_inb_rx_inject(void *dev, struct 
rte_mbuf **pkts,
                hw_res = RTE_PTR_ALIGN_CEIL(hw_res, 16);
 
                /* Prepare CPT instruction */
+               if (m->nb_segs > 1) {
+                       struct rte_mbuf *last = rte_pktmbuf_lastseg(m);
+                       uintptr_t dptr, rxphdr, wqe_hdr;
+                       uint16_t i;
+
+                       if ((m->nb_segs > CNXK_CPT_MAX_SG_SEGS) ||
+                           (rte_pktmbuf_tailroom(m) < 
CNXK_CPT_MIN_TAILROOM_REQ))
+                               goto exit;
+
+                       wqe_hdr = rte_pktmbuf_mtod_offset(last, uintptr_t, 
last->data_len);
+                       wqe_hdr += BIT_ULL(7);
+                       wqe_hdr = (wqe_hdr - 1) & ~(BIT_ULL(7) - 1);
+
+                       /* Pointer to WQE header */
+                       *(uint64_t *)(m + 1) = wqe_hdr;
+
+                       /* Reserve SG list after end of last mbuf data 
location. */
+                       rxphdr = wqe_hdr + 8;
+                       dptr = rxphdr + 7 * 8;
+
+                       /* Prepare Multiseg SG list */
+                       i = fill_sg2_comp_from_pkt((struct roc_sg2list_comp 
*)dptr, 0, m);
+                       u64_dptr = dptr | ((uint64_t)(i) << 60);
+               } else {
+                       struct roc_sg2list_comp *sg2;
+                       uintptr_t dptr, wqe_hdr;
+
+                       /* Reserve space for WQE, NIX_RX_PARSE_S and SG_S.
+                        * Populate SG_S with num segs and seg length
+                        */
+                       wqe_hdr = (uintptr_t)(m + 1);
+                       *(uint64_t *)(m + 1) = wqe_hdr;
+
+                       sg2 = (struct roc_sg2list_comp *)(wqe_hdr + 8 * 8);
+                       sg2->u.s.len[0] = rte_pktmbuf_pkt_len(m);
+                       sg2->u.s.valid_segs = 1;
+
+                       dptr = (uint64_t)rte_pktmbuf_iova(m);
+                       u64_dptr = dptr;
+               }
 
                /* Word 0 and 1 */
                inst_01 = vdupq_n_u64(0);
@@ -1434,16 +1469,12 @@ cn10k_cryptodev_sec_inb_rx_inject(void *dev, struct 
rte_mbuf **pkts,
                inst_45 = vdupq_n_u64(0);
                u64_0 = sec_sess->inst.w4 | (rte_pktmbuf_pkt_len(m));
                inst_45 = vsetq_lane_u64(u64_0, inst_45, 0);
-               dptr = (uint64_t)rte_pktmbuf_iova(m);
-               u64_1 = dptr;
-               inst_45 = vsetq_lane_u64(u64_1, inst_45, 1);
+               inst_45 = vsetq_lane_u64(u64_dptr, inst_45, 1);
                vst1q_u64(&inst->w4.u64, inst_45);
 
                /* Word 6 and 7 */
                inst_67 = vdupq_n_u64(0);
-               u64_0 = dptr;
                u64_1 = sec_sess->inst.w7;
-               inst_67 = vsetq_lane_u64(u64_0, inst_67, 0);
                inst_67 = vsetq_lane_u64(u64_1, inst_67, 1);
                vst1q_u64(&inst->w6.u64, inst_67);
 
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h 
b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
index caf6ac35e5..460e4803d3 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
@@ -18,7 +18,14 @@
 
 /* Space for ctrl_word(8B), IV(48B), passthrough alignment(8B) */
 #define CNXK_CPT_MIN_HEADROOM_REQ 64
-#define CNXK_CPT_MIN_TAILROOM_REQ 102
+/* Tailroom required for RX-inject path.
+ * In RX-inject path, space is required for below entities:
+ * WQE header and NIX_RX_PARSE_S
+ * SG list format for 6 IOVA pointers
+ * Space for 128 byte alignment.
+ */
+#define CNXK_CPT_MIN_TAILROOM_REQ 256
+#define CNXK_CPT_MAX_SG_SEGS     6
 
 /* Default command timeout in seconds */
 #define DEFAULT_COMMAND_TIMEOUT 4
-- 
2.25.1

Reply via email to