mirror of
https://github.com/torvalds/linux.git
synced 2026-07-30 03:01:41 +02:00
octeon_ep_vf: ensure dbell BADDR updation
Make sure the OUT DBELL base address reflects the
latest values written to it.
Fix:
Add a wait until the OUT DBELL base address register
is updated with the DMA ring descriptor address,
and modify the setup_oq function to properly
handle failures.
Fixes: 2c0c32c72b ("octeon_ep_vf: add hardware configuration APIs")
Signed-off-by: Sathesh Edara <sedara@marvell.com>
Signed-off-by: Shinas Rasheed <srasheed@marvell.com>
Signed-off-by: Vimlesh Kumar <vimleshk@marvell.com>
Link: https://patch.msgid.link/20260206111510.1045092-4-vimleshk@marvell.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
ce8fe3fc4f
commit
484e834d53
|
|
@ -196,7 +196,7 @@ static void octep_vf_setup_iq_regs_cn93(struct octep_vf_device *oct, int iq_no)
|
|||
}
|
||||
|
||||
/* Setup registers for a hardware Rx Queue */
|
||||
static void octep_vf_setup_oq_regs_cn93(struct octep_vf_device *oct, int oq_no)
|
||||
static int octep_vf_setup_oq_regs_cn93(struct octep_vf_device *oct, int oq_no)
|
||||
{
|
||||
struct octep_vf_oq *oq = oct->oq[oq_no];
|
||||
u32 time_threshold = 0;
|
||||
|
|
@ -239,6 +239,7 @@ static void octep_vf_setup_oq_regs_cn93(struct octep_vf_device *oct, int oq_no)
|
|||
time_threshold = CFG_GET_OQ_INTR_TIME(oct->conf);
|
||||
reg_val = ((u64)time_threshold << 32) | CFG_GET_OQ_INTR_PKT(oct->conf);
|
||||
octep_vf_write_csr64(oct, CN93_VF_SDP_R_OUT_INT_LEVELS(oq_no), reg_val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Setup registers for a VF mailbox */
|
||||
|
|
|
|||
|
|
@ -199,11 +199,13 @@ static void octep_vf_setup_iq_regs_cnxk(struct octep_vf_device *oct, int iq_no)
|
|||
}
|
||||
|
||||
/* Setup registers for a hardware Rx Queue */
|
||||
static void octep_vf_setup_oq_regs_cnxk(struct octep_vf_device *oct, int oq_no)
|
||||
static int octep_vf_setup_oq_regs_cnxk(struct octep_vf_device *oct, int oq_no)
|
||||
{
|
||||
struct octep_vf_oq *oq = oct->oq[oq_no];
|
||||
unsigned long t_out_jiffies;
|
||||
u32 time_threshold = 0;
|
||||
u64 oq_ctl = ULL(0);
|
||||
u64 reg_ba_val;
|
||||
u64 reg_val;
|
||||
|
||||
reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_CONTROL(oq_no));
|
||||
|
|
@ -214,6 +216,38 @@ static void octep_vf_setup_oq_regs_cnxk(struct octep_vf_device *oct, int oq_no)
|
|||
reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_CONTROL(oq_no));
|
||||
} while (!(reg_val & CNXK_VF_R_OUT_CTL_IDLE));
|
||||
}
|
||||
octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_WMARK(oq_no),
|
||||
oq->max_count);
|
||||
/* Wait for WMARK to get applied */
|
||||
usleep_range(10, 15);
|
||||
|
||||
octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_BADDR(oq_no),
|
||||
oq->desc_ring_dma);
|
||||
octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_RSIZE(oq_no),
|
||||
oq->max_count);
|
||||
reg_ba_val = octep_vf_read_csr64(oct,
|
||||
CNXK_VF_SDP_R_OUT_SLIST_BADDR(oq_no));
|
||||
if (reg_ba_val != oq->desc_ring_dma) {
|
||||
t_out_jiffies = jiffies + 10 * HZ;
|
||||
do {
|
||||
if (reg_ba_val == ULLONG_MAX)
|
||||
return -EFAULT;
|
||||
octep_vf_write_csr64(oct,
|
||||
CNXK_VF_SDP_R_OUT_SLIST_BADDR
|
||||
(oq_no), oq->desc_ring_dma);
|
||||
octep_vf_write_csr64(oct,
|
||||
CNXK_VF_SDP_R_OUT_SLIST_RSIZE
|
||||
(oq_no), oq->max_count);
|
||||
reg_ba_val =
|
||||
octep_vf_read_csr64(oct,
|
||||
CNXK_VF_SDP_R_OUT_SLIST_BADDR
|
||||
(oq_no));
|
||||
} while ((reg_ba_val != oq->desc_ring_dma) &&
|
||||
time_before(jiffies, t_out_jiffies));
|
||||
|
||||
if (reg_ba_val != oq->desc_ring_dma)
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
reg_val &= ~(CNXK_VF_R_OUT_CTL_IMODE);
|
||||
reg_val &= ~(CNXK_VF_R_OUT_CTL_ROR_P);
|
||||
|
|
@ -227,8 +261,6 @@ static void octep_vf_setup_oq_regs_cnxk(struct octep_vf_device *oct, int oq_no)
|
|||
reg_val |= (CNXK_VF_R_OUT_CTL_ES_P);
|
||||
|
||||
octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_CONTROL(oq_no), reg_val);
|
||||
octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_BADDR(oq_no), oq->desc_ring_dma);
|
||||
octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_RSIZE(oq_no), oq->max_count);
|
||||
|
||||
oq_ctl = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_CONTROL(oq_no));
|
||||
/* Clear the ISIZE and BSIZE (22-0) */
|
||||
|
|
@ -250,6 +282,7 @@ static void octep_vf_setup_oq_regs_cnxk(struct octep_vf_device *oct, int oq_no)
|
|||
reg_val &= ~GENMASK_ULL(31, 0);
|
||||
reg_val |= CFG_GET_OQ_WMARK(oct->conf);
|
||||
octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_WMARK(oq_no), reg_val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Setup registers for a VF mailbox */
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ struct octep_vf_mmio {
|
|||
|
||||
struct octep_vf_hw_ops {
|
||||
void (*setup_iq_regs)(struct octep_vf_device *oct, int q);
|
||||
void (*setup_oq_regs)(struct octep_vf_device *oct, int q);
|
||||
int (*setup_oq_regs)(struct octep_vf_device *oct, int q);
|
||||
void (*setup_mbox_regs)(struct octep_vf_device *oct, int mbox);
|
||||
|
||||
irqreturn_t (*non_ioq_intr_handler)(void *ioq_vector);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
#include "octep_vf_config.h"
|
||||
#include "octep_vf_main.h"
|
||||
|
||||
static void octep_vf_oq_free_ring_buffers(struct octep_vf_oq *oq);
|
||||
|
||||
static void octep_vf_oq_reset_indices(struct octep_vf_oq *oq)
|
||||
{
|
||||
oq->host_read_idx = 0;
|
||||
|
|
@ -171,11 +173,15 @@ static int octep_vf_setup_oq(struct octep_vf_device *oct, int q_no)
|
|||
goto oq_fill_buff_err;
|
||||
|
||||
octep_vf_oq_reset_indices(oq);
|
||||
oct->hw_ops.setup_oq_regs(oct, q_no);
|
||||
if (oct->hw_ops.setup_oq_regs(oct, q_no))
|
||||
goto oq_setup_err;
|
||||
|
||||
oct->num_oqs++;
|
||||
|
||||
return 0;
|
||||
|
||||
oq_setup_err:
|
||||
octep_vf_oq_free_ring_buffers(oq);
|
||||
oq_fill_buff_err:
|
||||
vfree(oq->buff_info);
|
||||
oq->buff_info = NULL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user