OSDN Git Service

crypto: cavium/nitrox - Configure asymmetric queue manager Hardware unit
authorPhani Kiran Hemadri <phemadri@marvell.com>
Thu, 8 Aug 2019 12:17:39 +0000 (12:17 +0000)
committerHerbert Xu <herbert@gondor.apana.org.au>
Thu, 15 Aug 2019 11:52:14 +0000 (21:52 +1000)
This patch configures and initializes CNN55XX device AQM hardware unit.

Signed-off-by: Phani Kiran Hemadri <phemadri@marvell.com>
Reviewed-by: Srikanth Jampala <jsrikanth@marvell.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/cavium/nitrox/nitrox_csr.h
drivers/crypto/cavium/nitrox/nitrox_hal.c
drivers/crypto/cavium/nitrox/nitrox_hal.h
drivers/crypto/cavium/nitrox/nitrox_main.c
drivers/crypto/cavium/nitrox/nitrox_sriov.c

index da1d733..1c8715a 100644 (file)
@@ -257,6 +257,117 @@ union aqm_grp_execmsk_hi {
 };
 
 /**
+ * struct aqmq_drbl - AQM Queue Doorbell Counter Registers
+ * @dbell_count: Doorbell Counter
+ */
+union aqmq_drbl {
+       u64 value;
+       struct {
+#if (defined(__BIG_ENDIAN_BITFIELD))
+               u64 raz_32_63 : 32;
+               u64 dbell_count : 32;
+#else
+               u64 dbell_count : 32;
+               u64 raz_32_63 : 32;
+#endif
+       };
+};
+
+/**
+ * struct aqmq_qsz - AQM Queue Host Queue Size Registers
+ * @host_queue_size: Size, in numbers of 'aqmq_command_s' command
+ * of the Host Ring.
+ */
+union aqmq_qsz {
+       u64 value;
+       struct {
+#if (defined(__BIG_ENDIAN_BITFIELD))
+               u64 raz_32_63 : 32;
+               u64 host_queue_size : 32;
+#else
+               u64 host_queue_size : 32;
+               u64 raz_32_63 : 32;
+#endif
+       };
+};
+
+/**
+ * struct aqmq_cmp_thr - AQM Queue Commands Completed Threshold Registers
+ * @commands_completed_threshold: Count of 'aqmq_command_s' commands executed
+ * by AE engines for which completion interrupt is asserted.
+ */
+union aqmq_cmp_thr {
+       u64 value;
+       struct {
+#if (defined(__BIG_ENDIAN_BITFIELD))
+               u64 raz_32_63 : 32;
+               u64 commands_completed_threshold : 32;
+#else
+               u64 commands_completed_threshold : 32;
+               u64 raz_32_63 : 32;
+#endif
+       };
+};
+
+/**
+ * struct aqmq_cmp_cnt - AQM Queue Commands Completed Count Registers
+ * @resend: Bit to request completion interrupt Resend.
+ * @completion_status: Command completion status of the ring.
+ * @commands_completed_count: Count of 'aqmq_command_s' commands executed by
+ * AE engines.
+ */
+union aqmq_cmp_cnt {
+       u64 value;
+       struct {
+#if (defined(__BIG_ENDIAN_BITFIELD))
+               u64 raz_34_63 : 30;
+               u64 resend : 1;
+               u64 completion_status : 1;
+               u64 commands_completed_count : 32;
+#else
+               u64 commands_completed_count : 32;
+               u64 completion_status : 1;
+               u64 resend : 1;
+               u64 raz_34_63 : 30;
+#endif
+       };
+};
+
+/**
+ * struct aqmq_en - AQM Queue Enable Registers
+ * @queue_status: 1 = AQMQ is enabled, 0 = AQMQ is disabled
+ */
+union aqmq_en {
+       u64 value;
+       struct {
+#if (defined(__BIG_ENDIAN_BITFIELD))
+               u64 raz_1_63 : 63;
+               u64 queue_enable : 1;
+#else
+               u64 queue_enable : 1;
+               u64 raz_1_63 : 63;
+#endif
+       };
+};
+
+/**
+ * struct aqmq_activity_stat - AQM Queue Activity Status Registers
+ * @queue_active: 1 = AQMQ is active, 0 = AQMQ is quiescent
+ */
+union aqmq_activity_stat {
+       u64 value;
+       struct {
+#if (defined(__BIG_ENDIAN_BITFIELD))
+               u64 raz_1_63 : 63;
+               u64 queue_active : 1;
+#else
+               u64 queue_active : 1;
+               u64 raz_1_63 : 63;
+#endif
+       };
+};
+
+/**
  * struct emu_fuse_map - EMU Fuse Map Registers
  * @ae_fuse: Fuse settings for AE 19..0
  * @se_fuse: Fuse settings for SE 15..0
index 3f0df60..34a2f4f 100644 (file)
@@ -241,12 +241,12 @@ void nitrox_config_pkt_solicit_ports(struct nitrox_device *ndev)
 }
 
 /**
- * enable_nps_interrupts - enable NPS interrutps
+ * enable_nps_core_interrupts - enable NPS core interrutps
  * @ndev: NITROX device.
  *
- * This includes NPS core, packet in and slc interrupts.
+ * This includes NPS core interrupts.
  */
-static void enable_nps_interrupts(struct nitrox_device *ndev)
+static void enable_nps_core_interrupts(struct nitrox_device *ndev)
 {
        union nps_core_int_ena_w1s core_int;
 
@@ -258,18 +258,9 @@ static void enable_nps_interrupts(struct nitrox_device *ndev)
        core_int.s.npco_dma_malform = 1;
        core_int.s.host_nps_wr_err = 1;
        nitrox_write_csr(ndev, NPS_CORE_INT_ENA_W1S, core_int.value);
-
-       /* NPS packet in ring interrupts */
-       nitrox_write_csr(ndev, NPS_PKT_IN_RERR_LO_ENA_W1S, (~0ULL));
-       nitrox_write_csr(ndev, NPS_PKT_IN_RERR_HI_ENA_W1S, (~0ULL));
-       nitrox_write_csr(ndev, NPS_PKT_IN_ERR_TYPE_ENA_W1S, (~0ULL));
-       /* NPS packet slc port interrupts */
-       nitrox_write_csr(ndev, NPS_PKT_SLC_RERR_HI_ENA_W1S, (~0ULL));
-       nitrox_write_csr(ndev, NPS_PKT_SLC_RERR_LO_ENA_W1S, (~0ULL));
-       nitrox_write_csr(ndev, NPS_PKT_SLC_ERR_TYPE_ENA_W1S, (~0uLL));
 }
 
-void nitrox_config_nps_unit(struct nitrox_device *ndev)
+void nitrox_config_nps_core_unit(struct nitrox_device *ndev)
 {
        union nps_core_gbl_vfcfg core_gbl_vfcfg;
 
@@ -281,12 +272,149 @@ void nitrox_config_nps_unit(struct nitrox_device *ndev)
        core_gbl_vfcfg.s.ilk_disable = 1;
        core_gbl_vfcfg.s.cfg = __NDEV_MODE_PF;
        nitrox_write_csr(ndev, NPS_CORE_GBL_VFCFG, core_gbl_vfcfg.value);
+
+       /* enable nps core interrupts */
+       enable_nps_core_interrupts(ndev);
+}
+
+/**
+ * enable_nps_pkt_interrupts - enable NPS packet interrutps
+ * @ndev: NITROX device.
+ *
+ * This includes NPS packet in and slc interrupts.
+ */
+static void enable_nps_pkt_interrupts(struct nitrox_device *ndev)
+{
+       /* NPS packet in ring interrupts */
+       nitrox_write_csr(ndev, NPS_PKT_IN_RERR_LO_ENA_W1S, (~0ULL));
+       nitrox_write_csr(ndev, NPS_PKT_IN_RERR_HI_ENA_W1S, (~0ULL));
+       nitrox_write_csr(ndev, NPS_PKT_IN_ERR_TYPE_ENA_W1S, (~0ULL));
+       /* NPS packet slc port interrupts */
+       nitrox_write_csr(ndev, NPS_PKT_SLC_RERR_HI_ENA_W1S, (~0ULL));
+       nitrox_write_csr(ndev, NPS_PKT_SLC_RERR_LO_ENA_W1S, (~0ULL));
+       nitrox_write_csr(ndev, NPS_PKT_SLC_ERR_TYPE_ENA_W1S, (~0uLL));
+}
+
+void nitrox_config_nps_pkt_unit(struct nitrox_device *ndev)
+{
        /* config input and solicit ports */
        nitrox_config_pkt_input_rings(ndev);
        nitrox_config_pkt_solicit_ports(ndev);
 
-       /* enable interrupts */
-       enable_nps_interrupts(ndev);
+       /* enable nps packet interrupts */
+       enable_nps_pkt_interrupts(ndev);
+}
+
+static void reset_aqm_ring(struct nitrox_device *ndev, int ring)
+{
+       union aqmq_en aqmq_en_reg;
+       union aqmq_activity_stat activity_stat;
+       union aqmq_cmp_cnt cmp_cnt;
+       int max_retries = MAX_CSR_RETRIES;
+       u64 offset;
+
+       /* step 1: disable the queue */
+       offset = AQMQ_ENX(ring);
+       aqmq_en_reg.value = 0;
+       aqmq_en_reg.queue_enable = 0;
+       nitrox_write_csr(ndev, offset, aqmq_en_reg.value);
+
+       /* step 2: wait for AQMQ_ACTIVITY_STATX[QUEUE_ACTIVE] to clear */
+       usleep_range(100, 150);
+       offset = AQMQ_ACTIVITY_STATX(ring);
+       do {
+               activity_stat.value = nitrox_read_csr(ndev, offset);
+               if (!activity_stat.queue_active)
+                       break;
+               udelay(50);
+       } while (max_retries--);
+
+       /* step 3: clear commands completed count */
+       offset = AQMQ_CMP_CNTX(ring);
+       cmp_cnt.value = nitrox_read_csr(ndev, offset);
+       nitrox_write_csr(ndev, offset, cmp_cnt.value);
+       usleep_range(50, 100);
+}
+
+void enable_aqm_ring(struct nitrox_device *ndev, int ring)
+{
+       union aqmq_en aqmq_en_reg;
+       u64 offset;
+
+       offset = AQMQ_ENX(ring);
+       aqmq_en_reg.value = 0;
+       aqmq_en_reg.queue_enable = 1;
+       nitrox_write_csr(ndev, offset, aqmq_en_reg.value);
+       usleep_range(50, 100);
+}
+
+void nitrox_config_aqm_rings(struct nitrox_device *ndev)
+{
+       int ring;
+
+       for (ring = 0; ring < ndev->nr_queues; ring++) {
+               struct nitrox_cmdq *cmdq = ndev->aqmq[ring];
+               union aqmq_drbl drbl;
+               union aqmq_qsz qsize;
+               union aqmq_cmp_thr cmp_thr;
+               u64 offset;
+
+               /* steps 1 - 3 */
+               reset_aqm_ring(ndev, ring);
+
+               /* step 4: clear doorbell count of ring */
+               offset = AQMQ_DRBLX(ring);
+               drbl.value = 0;
+               drbl.dbell_count = 0xFFFFFFFF;
+               nitrox_write_csr(ndev, offset, drbl.value);
+
+               /* step 5: configure host ring details */
+
+               /* set host address for next command of ring */
+               offset = AQMQ_NXT_CMDX(ring);
+               nitrox_write_csr(ndev, offset, 0ULL);
+
+               /* set host address of ring base */
+               offset = AQMQ_BADRX(ring);
+               nitrox_write_csr(ndev, offset, cmdq->dma);
+
+               /* set ring size */
+               offset = AQMQ_QSZX(ring);
+               qsize.value = 0;
+               qsize.host_queue_size = ndev->qlen;
+               nitrox_write_csr(ndev, offset, qsize.value);
+
+               /* set command completion threshold */
+               offset = AQMQ_CMP_THRX(ring);
+               cmp_thr.value = 0;
+               cmp_thr.commands_completed_threshold = 1;
+               nitrox_write_csr(ndev, offset, cmp_thr.value);
+
+               /* step 6: enable the queue */
+               enable_aqm_ring(ndev, ring);
+       }
+}
+
+static void enable_aqm_interrupts(struct nitrox_device *ndev)
+{
+       /* clear interrupt enable bits */
+       nitrox_write_csr(ndev, AQM_DBELL_OVF_LO_ENA_W1S, (~0ULL));
+       nitrox_write_csr(ndev, AQM_DBELL_OVF_HI_ENA_W1S, (~0ULL));
+       nitrox_write_csr(ndev, AQM_DMA_RD_ERR_LO_ENA_W1S, (~0ULL));
+       nitrox_write_csr(ndev, AQM_DMA_RD_ERR_HI_ENA_W1S, (~0ULL));
+       nitrox_write_csr(ndev, AQM_EXEC_NA_LO_ENA_W1S, (~0ULL));
+       nitrox_write_csr(ndev, AQM_EXEC_NA_HI_ENA_W1S, (~0ULL));
+       nitrox_write_csr(ndev, AQM_EXEC_ERR_LO_ENA_W1S, (~0ULL));
+       nitrox_write_csr(ndev, AQM_EXEC_ERR_HI_ENA_W1S, (~0ULL));
+}
+
+void nitrox_config_aqm_unit(struct nitrox_device *ndev)
+{
+       /* config aqm command queues */
+       nitrox_config_aqm_rings(ndev);
+
+       /* enable aqm interrupts */
+       enable_aqm_interrupts(ndev);
 }
 
 void nitrox_config_pom_unit(struct nitrox_device *ndev)
index d660641..48b0af0 100644 (file)
@@ -4,10 +4,13 @@
 
 #include "nitrox_dev.h"
 
+void nitrox_config_aqm_rings(struct nitrox_device *ndev);
+void nitrox_config_aqm_unit(struct nitrox_device *ndev);
 void nitrox_config_emu_unit(struct nitrox_device *ndev);
 void nitrox_config_pkt_input_rings(struct nitrox_device *ndev);
 void nitrox_config_pkt_solicit_ports(struct nitrox_device *ndev);
-void nitrox_config_nps_unit(struct nitrox_device *ndev);
+void nitrox_config_nps_core_unit(struct nitrox_device *ndev);
+void nitrox_config_nps_pkt_unit(struct nitrox_device *ndev);
 void nitrox_config_pom_unit(struct nitrox_device *ndev);
 void nitrox_config_rand_unit(struct nitrox_device *ndev);
 void nitrox_config_efl_unit(struct nitrox_device *ndev);
@@ -15,6 +18,7 @@ void nitrox_config_bmi_unit(struct nitrox_device *ndev);
 void nitrox_config_bmo_unit(struct nitrox_device *ndev);
 void nitrox_config_lbc_unit(struct nitrox_device *ndev);
 void invalidate_lbc(struct nitrox_device *ndev);
+void enable_aqm_ring(struct nitrox_device *ndev, int qno);
 void enable_pkt_input_ring(struct nitrox_device *ndev, int ring);
 void enable_pkt_solicit_port(struct nitrox_device *ndev, int port);
 void config_nps_core_vfcfg_mode(struct nitrox_device *ndev, enum vf_mode mode);
index 345d3ea..bc92498 100644 (file)
@@ -387,7 +387,9 @@ static int nitrox_pf_hw_init(struct nitrox_device *ndev)
        /* get cores information */
        nitrox_get_hwinfo(ndev);
 
-       nitrox_config_nps_unit(ndev);
+       nitrox_config_nps_core_unit(ndev);
+       nitrox_config_aqm_unit(ndev);
+       nitrox_config_nps_pkt_unit(ndev);
        nitrox_config_pom_unit(ndev);
        nitrox_config_efl_unit(ndev);
        /* configure IO units */
index bf439d8..43287f8 100644 (file)
@@ -109,6 +109,9 @@ static int nitrox_pf_reinit(struct nitrox_device *ndev)
                return err;
        }
 
+       /* configure the AQM queues */
+       nitrox_config_aqm_rings(ndev);
+
        /* configure the packet queues */
        nitrox_config_pkt_input_rings(ndev);
        nitrox_config_pkt_solicit_ports(ndev);