crypto/nitrox: add hardware queue management
authorNagadheeraj Rottela <rnagadheeraj@marvell.com>
Tue, 1 Oct 2019 06:41:27 +0000 (06:41 +0000)
committerAkhil Goyal <akhil.goyal@nxp.com>
Wed, 9 Oct 2019 09:50:12 +0000 (11:50 +0200)
Add hardware queue management code corresponding to
queue pair setup and release functions.

Signed-off-by: Nagadheeraj Rottela <rnagadheeraj@marvell.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
drivers/crypto/nitrox/nitrox_csr.h
drivers/crypto/nitrox/nitrox_hal.c
drivers/crypto/nitrox/nitrox_hal.h
drivers/crypto/nitrox/nitrox_qp.c
drivers/crypto/nitrox/nitrox_qp.h

index 8791045..8cd92e3 100644 (file)
@@ -9,6 +9,18 @@
 #include <rte_io.h>
 
 #define CSR_DELAY      30
+#define NITROX_CSR_ADDR(bar_addr, offset) (bar_addr + (offset))
+
+/* NPS packet registers */
+#define NPS_PKT_IN_INSTR_CTLX(_i)      (0x10060 + ((_i) * 0x40000))
+#define NPS_PKT_IN_INSTR_BADDRX(_i)    (0x10068 + ((_i) * 0x40000))
+#define NPS_PKT_IN_INSTR_RSIZEX(_i)    (0x10070 + ((_i) * 0x40000))
+#define NPS_PKT_IN_DONE_CNTSX(_i)      (0x10080 + ((_i) * 0x40000))
+#define NPS_PKT_IN_INSTR_BAOFF_DBELLX(_i)      (0x10078 + ((_i) * 0x40000))
+#define NPS_PKT_IN_INT_LEVELSX(_i)             (0x10088 + ((_i) * 0x40000))
+#define NPS_PKT_SLC_CTLX(_i)           (0x10000 + ((_i) * 0x40000))
+#define NPS_PKT_SLC_CNTSX(_i)          (0x10008 + ((_i) * 0x40000))
+#define NPS_PKT_SLC_INT_LEVELSX(_i)    (0x10010 + ((_i) * 0x40000))
 
 /* AQM Virtual Function Registers */
 #define AQMQ_QSZX(_i)                  (0x20008 + ((_i)*0x40000))
index ed18820..433f3ad 100644 (file)
 
 #define MAX_VF_QUEUES  8
 #define MAX_PF_QUEUES  64
+#define NITROX_TIMER_THOLD     0x3FFFFF
+#define NITROX_COUNT_THOLD      0xFFFFFFFF
+
+void
+nps_pkt_input_ring_disable(uint8_t *bar_addr, uint16_t ring)
+{
+       union nps_pkt_in_instr_ctl pkt_in_instr_ctl;
+       uint64_t reg_addr;
+       int max_retries = 5;
+
+       reg_addr = NPS_PKT_IN_INSTR_CTLX(ring);
+       pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
+       pkt_in_instr_ctl.s.enb = 0;
+       nitrox_write_csr(bar_addr, reg_addr, pkt_in_instr_ctl.u64);
+       rte_delay_us_block(100);
+
+       /* wait for enable bit to be cleared */
+       pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
+       while (pkt_in_instr_ctl.s.enb && max_retries--) {
+               rte_delay_ms(10);
+               pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
+       }
+}
+
+void
+nps_pkt_solicited_port_disable(uint8_t *bar_addr, uint16_t port)
+{
+       union nps_pkt_slc_ctl pkt_slc_ctl;
+       uint64_t reg_addr;
+       int max_retries = 5;
+
+       /* clear enable bit */
+       reg_addr = NPS_PKT_SLC_CTLX(port);
+       pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
+       pkt_slc_ctl.s.enb = 0;
+       nitrox_write_csr(bar_addr, reg_addr, pkt_slc_ctl.u64);
+       rte_delay_us_block(100);
+
+       pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
+       while (pkt_slc_ctl.s.enb && max_retries--) {
+               rte_delay_ms(10);
+               pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
+       }
+}
+
+void
+setup_nps_pkt_input_ring(uint8_t *bar_addr, uint16_t ring, uint32_t rsize,
+                        phys_addr_t raddr)
+{
+       union nps_pkt_in_instr_ctl pkt_in_instr_ctl;
+       union nps_pkt_in_instr_rsize pkt_in_instr_rsize;
+       union nps_pkt_in_instr_baoff_dbell pkt_in_instr_baoff_dbell;
+       union nps_pkt_in_done_cnts pkt_in_done_cnts;
+       uint64_t base_addr, reg_addr;
+       int max_retries = 5;
+
+       nps_pkt_input_ring_disable(bar_addr, ring);
+
+       /* write base address */
+       reg_addr = NPS_PKT_IN_INSTR_BADDRX(ring);
+       base_addr = raddr;
+       nitrox_write_csr(bar_addr, reg_addr, base_addr);
+       rte_delay_us_block(CSR_DELAY);
+
+       /* write ring size */
+       reg_addr = NPS_PKT_IN_INSTR_RSIZEX(ring);
+       pkt_in_instr_rsize.u64 = 0;
+       pkt_in_instr_rsize.s.rsize = rsize;
+       nitrox_write_csr(bar_addr, reg_addr, pkt_in_instr_rsize.u64);
+       rte_delay_us_block(CSR_DELAY);
+
+       /* clear door bell */
+       reg_addr = NPS_PKT_IN_INSTR_BAOFF_DBELLX(ring);
+       pkt_in_instr_baoff_dbell.u64 = 0;
+       pkt_in_instr_baoff_dbell.s.dbell = 0xFFFFFFFF;
+       nitrox_write_csr(bar_addr, reg_addr, pkt_in_instr_baoff_dbell.u64);
+       rte_delay_us_block(CSR_DELAY);
+
+       /* clear done count */
+       reg_addr = NPS_PKT_IN_DONE_CNTSX(ring);
+       pkt_in_done_cnts.u64 = nitrox_read_csr(bar_addr, reg_addr);
+       nitrox_write_csr(bar_addr, reg_addr, pkt_in_done_cnts.u64);
+       rte_delay_us_block(CSR_DELAY);
+
+       /* Setup PKT IN RING Interrupt Threshold */
+       reg_addr = NPS_PKT_IN_INT_LEVELSX(ring);
+       nitrox_write_csr(bar_addr, reg_addr, 0xFFFFFFFF);
+       rte_delay_us_block(CSR_DELAY);
+
+       /* enable ring */
+       reg_addr = NPS_PKT_IN_INSTR_CTLX(ring);
+       pkt_in_instr_ctl.u64 = 0;
+       pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
+       pkt_in_instr_ctl.s.is64b = 1;
+       pkt_in_instr_ctl.s.enb = 1;
+       nitrox_write_csr(bar_addr, reg_addr, pkt_in_instr_ctl.u64);
+       rte_delay_us_block(100);
+
+       pkt_in_instr_ctl.u64 = 0;
+       pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
+       /* wait for ring to be enabled */
+       while (!pkt_in_instr_ctl.s.enb && max_retries--) {
+               rte_delay_ms(10);
+               pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
+       }
+}
+
+void
+setup_nps_pkt_solicit_output_port(uint8_t *bar_addr, uint16_t port)
+{
+       union nps_pkt_slc_ctl pkt_slc_ctl;
+       union nps_pkt_slc_cnts pkt_slc_cnts;
+       union nps_pkt_slc_int_levels pkt_slc_int_levels;
+       uint64_t reg_addr;
+       int max_retries = 5;
+
+       nps_pkt_solicited_port_disable(bar_addr, port);
+
+       /* clear pkt counts */
+       reg_addr = NPS_PKT_SLC_CNTSX(port);
+       pkt_slc_cnts.u64 = nitrox_read_csr(bar_addr, reg_addr);
+       nitrox_write_csr(bar_addr, reg_addr, pkt_slc_cnts.u64);
+       rte_delay_us_block(CSR_DELAY);
+
+       /* slc interrupt levels */
+       reg_addr = NPS_PKT_SLC_INT_LEVELSX(port);
+       pkt_slc_int_levels.u64 = 0;
+       pkt_slc_int_levels.s.bmode = 0;
+       pkt_slc_int_levels.s.timet = NITROX_TIMER_THOLD;
+
+       if (NITROX_COUNT_THOLD > 0)
+               pkt_slc_int_levels.s.cnt = NITROX_COUNT_THOLD - 1;
+
+       nitrox_write_csr(bar_addr, reg_addr, pkt_slc_int_levels.u64);
+       rte_delay_us_block(CSR_DELAY);
+
+       /* enable ring */
+       reg_addr = NPS_PKT_SLC_CTLX(port);
+       pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
+       pkt_slc_ctl.s.rh = 1;
+       pkt_slc_ctl.s.z = 1;
+       pkt_slc_ctl.s.enb = 1;
+       nitrox_write_csr(bar_addr, reg_addr, pkt_slc_ctl.u64);
+       rte_delay_us_block(100);
+
+       pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
+       while (!pkt_slc_ctl.s.enb && max_retries--) {
+               rte_delay_ms(10);
+               pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
+       }
+}
 
 int
 vf_get_vf_config_mode(uint8_t *bar_addr)
index 6184211..dcfbd11 100644 (file)
 
 #include "nitrox_csr.h"
 
+union nps_pkt_slc_cnts {
+       uint64_t u64;
+       struct {
+#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+               uint64_t slc_int : 1;
+               uint64_t uns_int : 1;
+               uint64_t in_int : 1;
+               uint64_t mbox_int : 1;
+               uint64_t resend : 1;
+               uint64_t raz : 5;
+               uint64_t timer : 22;
+               uint64_t cnt : 32;
+#else
+               uint64_t cnt : 32;
+               uint64_t timer : 22;
+               uint64_t raz : 5;
+               uint64_t resend : 1;
+               uint64_t mbox_int : 1;
+               uint64_t in_int : 1;
+               uint64_t uns_int : 1;
+               uint64_t slc_int : 1;
+#endif
+       } s;
+};
+
+union nps_pkt_slc_int_levels {
+       uint64_t u64;
+       struct {
+#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+               uint64_t bmode : 1;
+               uint64_t raz : 9;
+               uint64_t timet : 22;
+               uint64_t cnt : 32;
+#else
+               uint64_t cnt : 32;
+               uint64_t timet : 22;
+               uint64_t raz : 9;
+               uint64_t bmode : 1;
+#endif
+       } s;
+};
+
+union nps_pkt_slc_ctl {
+       uint64_t u64;
+       struct {
+#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+               uint64_t raz : 61;
+               uint64_t rh : 1;
+               uint64_t z : 1;
+               uint64_t enb : 1;
+#else
+               uint64_t enb : 1;
+               uint64_t z : 1;
+               uint64_t rh : 1;
+               uint64_t raz : 61;
+#endif
+       } s;
+};
+
+union nps_pkt_in_instr_ctl {
+       uint64_t u64;
+       struct {
+#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+               uint64_t raz : 62;
+               uint64_t is64b : 1;
+               uint64_t enb : 1;
+#else
+               uint64_t enb : 1;
+               uint64_t is64b : 1;
+               uint64_t raz : 62;
+#endif
+       } s;
+};
+
+union nps_pkt_in_instr_rsize {
+       uint64_t u64;
+       struct {
+#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+               uint64_t raz : 32;
+               uint64_t rsize : 32;
+#else
+               uint64_t rsize : 32;
+               uint64_t raz : 32;
+#endif
+       } s;
+};
+
+union nps_pkt_in_instr_baoff_dbell {
+       uint64_t u64;
+       struct {
+#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+               uint64_t aoff : 32;
+               uint64_t dbell : 32;
+#else
+               uint64_t dbell : 32;
+               uint64_t aoff : 32;
+#endif
+       } s;
+};
+
+union nps_pkt_in_done_cnts {
+       uint64_t u64;
+       struct {
+#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+               uint64_t slc_int : 1;
+               uint64_t uns_int : 1;
+               uint64_t in_int : 1;
+               uint64_t mbox_int : 1;
+               uint64_t resend : 1;
+               uint64_t raz : 27;
+               uint64_t cnt : 32;
+#else
+               uint64_t cnt : 32;
+               uint64_t raz : 27;
+               uint64_t resend : 1;
+               uint64_t mbox_int : 1;
+               uint64_t in_int : 1;
+               uint64_t uns_int : 1;
+               uint64_t slc_int : 1;
+#endif
+       } s;
+};
+
 union aqmq_qsz {
        uint64_t u64;
        struct {
@@ -33,5 +156,10 @@ enum nitrox_vf_mode {
 
 int vf_get_vf_config_mode(uint8_t *bar_addr);
 int vf_config_mode_to_nr_queues(enum nitrox_vf_mode vf_mode);
+void setup_nps_pkt_input_ring(uint8_t *bar_addr, uint16_t ring, uint32_t rsize,
+                             phys_addr_t raddr);
+void setup_nps_pkt_solicit_output_port(uint8_t *bar_addr, uint16_t port);
+void nps_pkt_input_ring_disable(uint8_t *bar_addr, uint16_t ring);
+void nps_pkt_solicited_port_disable(uint8_t *bar_addr, uint16_t port);
 
 #endif /* _NITROX_HAL_H_ */
index 9673bb4..5e85ccb 100644 (file)
 #include "nitrox_logs.h"
 
 #define MAX_CMD_QLEN 16384
+#define CMDQ_PKT_IN_ALIGN 16
+
+static int
+nitrox_setup_cmdq(struct nitrox_qp *qp, uint8_t *bar_addr,
+                 const char *dev_name, uint8_t instr_size, int socket_id)
+{
+       char mz_name[RTE_MEMZONE_NAMESIZE];
+       const struct rte_memzone *mz;
+       size_t cmdq_size = qp->count * instr_size;
+       uint64_t offset;
+
+       snprintf(mz_name, sizeof(mz_name), "%s_cmdq_%d", dev_name, qp->qno);
+       mz = rte_memzone_reserve_aligned(mz_name, cmdq_size, socket_id,
+                                        RTE_MEMZONE_SIZE_HINT_ONLY |
+                                        RTE_MEMZONE_256MB,
+                                        CMDQ_PKT_IN_ALIGN);
+       if (!mz) {
+               NITROX_LOG(ERR, "cmdq memzone reserve failed for %s queue\n",
+                          mz_name);
+               return -ENOMEM;
+       }
+
+       qp->cmdq.mz = mz;
+       offset = NPS_PKT_IN_INSTR_BAOFF_DBELLX(qp->qno);
+       qp->cmdq.dbell_csr_addr = NITROX_CSR_ADDR(bar_addr, offset);
+       qp->cmdq.ring = mz->addr;
+       qp->cmdq.instr_size = instr_size;
+       setup_nps_pkt_input_ring(bar_addr, qp->qno, qp->count, mz->iova);
+       setup_nps_pkt_solicit_output_port(bar_addr, qp->qno);
+
+       return 0;
+}
 
 static int
 nitrox_setup_ridq(struct nitrox_qp *qp, int socket_id)
@@ -27,6 +59,14 @@ nitrox_setup_ridq(struct nitrox_qp *qp, int socket_id)
        return 0;
 }
 
+static int
+nitrox_release_cmdq(struct nitrox_qp *qp, uint8_t *bar_addr)
+{
+       nps_pkt_solicited_port_disable(bar_addr, qp->qno);
+       nps_pkt_input_ring_disable(bar_addr, qp->qno);
+       return rte_memzone_free(qp->cmdq.mz);
+}
+
 int
 nitrox_qp_setup(struct nitrox_qp *qp, uint8_t *bar_addr, const char *dev_name,
                uint32_t nb_descriptors, uint8_t instr_size, int socket_id)
@@ -34,8 +74,6 @@ nitrox_qp_setup(struct nitrox_qp *qp, uint8_t *bar_addr, const char *dev_name,
        int err;
        uint32_t count;
 
-       RTE_SET_USED(bar_addr);
-       RTE_SET_USED(instr_size);
        count = rte_align32pow2(nb_descriptors);
        if (count > MAX_CMD_QLEN) {
                NITROX_LOG(ERR, "%s: Number of descriptors too big %d,"
@@ -48,6 +86,10 @@ nitrox_qp_setup(struct nitrox_qp *qp, uint8_t *bar_addr, const char *dev_name,
        qp->count = count;
        qp->head = qp->tail = 0;
        rte_atomic16_init(&qp->pending_count);
+       err = nitrox_setup_cmdq(qp, bar_addr, dev_name, instr_size, socket_id);
+       if (err)
+               return err;
+
        err = nitrox_setup_ridq(qp, socket_id);
        if (err)
                goto ridq_err;
@@ -55,8 +97,8 @@ nitrox_qp_setup(struct nitrox_qp *qp, uint8_t *bar_addr, const char *dev_name,
        return 0;
 
 ridq_err:
+       nitrox_release_cmdq(qp, bar_addr);
        return err;
-
 }
 
 static void
@@ -68,7 +110,6 @@ nitrox_release_ridq(struct nitrox_qp *qp)
 int
 nitrox_qp_release(struct nitrox_qp *qp, uint8_t *bar_addr)
 {
-       RTE_SET_USED(bar_addr);
        nitrox_release_ridq(qp);
-       return 0;
+       return nitrox_release_cmdq(qp, bar_addr);
 }
index cf0102f..0244c4d 100644 (file)
 
 struct nitrox_softreq;
 
+struct command_queue {
+       const struct rte_memzone *mz;
+       uint8_t *dbell_csr_addr;
+       uint8_t *ring;
+       uint8_t instr_size;
+};
+
 struct rid {
        struct nitrox_softreq *sr;
 };
 
 struct nitrox_qp {
+       struct command_queue cmdq;
        struct rid *ridq;
        uint32_t count;
        uint32_t head;