crypto: cavium/nitrox - Configure asymmetric queue manager Hardware unit

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>
This commit is contained in:
Phani Kiran Hemadri 2019-08-08 12:17:39 +00:00 committed by Herbert Xu
parent b31c17c852
commit 5f05cdca27
5 changed files with 265 additions and 17 deletions

View File

@ -256,6 +256,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

View 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)

View 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);

View 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 */

View 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);