Skip to content

Commit 484e834

Browse files
Vimlesh KumarPaolo Abeni
authored andcommitted
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: 2c0c32c ("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>
1 parent ce8fe3f commit 484e834

4 files changed

Lines changed: 46 additions & 6 deletions

File tree

drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_cn9k.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ static void octep_vf_setup_iq_regs_cn93(struct octep_vf_device *oct, int iq_no)
196196
}
197197

198198
/* Setup registers for a hardware Rx Queue */
199-
static void octep_vf_setup_oq_regs_cn93(struct octep_vf_device *oct, int oq_no)
199+
static int octep_vf_setup_oq_regs_cn93(struct octep_vf_device *oct, int oq_no)
200200
{
201201
struct octep_vf_oq *oq = oct->oq[oq_no];
202202
u32 time_threshold = 0;
@@ -239,6 +239,7 @@ static void octep_vf_setup_oq_regs_cn93(struct octep_vf_device *oct, int oq_no)
239239
time_threshold = CFG_GET_OQ_INTR_TIME(oct->conf);
240240
reg_val = ((u64)time_threshold << 32) | CFG_GET_OQ_INTR_PKT(oct->conf);
241241
octep_vf_write_csr64(oct, CN93_VF_SDP_R_OUT_INT_LEVELS(oq_no), reg_val);
242+
return 0;
242243
}
243244

244245
/* Setup registers for a VF mailbox */

drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_cnxk.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,13 @@ static void octep_vf_setup_iq_regs_cnxk(struct octep_vf_device *oct, int iq_no)
199199
}
200200

201201
/* Setup registers for a hardware Rx Queue */
202-
static void octep_vf_setup_oq_regs_cnxk(struct octep_vf_device *oct, int oq_no)
202+
static int octep_vf_setup_oq_regs_cnxk(struct octep_vf_device *oct, int oq_no)
203203
{
204204
struct octep_vf_oq *oq = oct->oq[oq_no];
205+
unsigned long t_out_jiffies;
205206
u32 time_threshold = 0;
206207
u64 oq_ctl = ULL(0);
208+
u64 reg_ba_val;
207209
u64 reg_val;
208210

209211
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)
214216
reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_CONTROL(oq_no));
215217
} while (!(reg_val & CNXK_VF_R_OUT_CTL_IDLE));
216218
}
219+
octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_WMARK(oq_no),
220+
oq->max_count);
221+
/* Wait for WMARK to get applied */
222+
usleep_range(10, 15);
223+
224+
octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_BADDR(oq_no),
225+
oq->desc_ring_dma);
226+
octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_RSIZE(oq_no),
227+
oq->max_count);
228+
reg_ba_val = octep_vf_read_csr64(oct,
229+
CNXK_VF_SDP_R_OUT_SLIST_BADDR(oq_no));
230+
if (reg_ba_val != oq->desc_ring_dma) {
231+
t_out_jiffies = jiffies + 10 * HZ;
232+
do {
233+
if (reg_ba_val == ULLONG_MAX)
234+
return -EFAULT;
235+
octep_vf_write_csr64(oct,
236+
CNXK_VF_SDP_R_OUT_SLIST_BADDR
237+
(oq_no), oq->desc_ring_dma);
238+
octep_vf_write_csr64(oct,
239+
CNXK_VF_SDP_R_OUT_SLIST_RSIZE
240+
(oq_no), oq->max_count);
241+
reg_ba_val =
242+
octep_vf_read_csr64(oct,
243+
CNXK_VF_SDP_R_OUT_SLIST_BADDR
244+
(oq_no));
245+
} while ((reg_ba_val != oq->desc_ring_dma) &&
246+
time_before(jiffies, t_out_jiffies));
247+
248+
if (reg_ba_val != oq->desc_ring_dma)
249+
return -EAGAIN;
250+
}
217251

218252
reg_val &= ~(CNXK_VF_R_OUT_CTL_IMODE);
219253
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)
227261
reg_val |= (CNXK_VF_R_OUT_CTL_ES_P);
228262

229263
octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_CONTROL(oq_no), reg_val);
230-
octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_BADDR(oq_no), oq->desc_ring_dma);
231-
octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_RSIZE(oq_no), oq->max_count);
232264

233265
oq_ctl = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_CONTROL(oq_no));
234266
/* 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)
250282
reg_val &= ~GENMASK_ULL(31, 0);
251283
reg_val |= CFG_GET_OQ_WMARK(oct->conf);
252284
octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_WMARK(oq_no), reg_val);
285+
return 0;
253286
}
254287

255288
/* Setup registers for a VF mailbox */

drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ struct octep_vf_mmio {
5555

5656
struct octep_vf_hw_ops {
5757
void (*setup_iq_regs)(struct octep_vf_device *oct, int q);
58-
void (*setup_oq_regs)(struct octep_vf_device *oct, int q);
58+
int (*setup_oq_regs)(struct octep_vf_device *oct, int q);
5959
void (*setup_mbox_regs)(struct octep_vf_device *oct, int mbox);
6060

6161
irqreturn_t (*non_ioq_intr_handler)(void *ioq_vector);

drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include "octep_vf_config.h"
1313
#include "octep_vf_main.h"
1414

15+
static void octep_vf_oq_free_ring_buffers(struct octep_vf_oq *oq);
16+
1517
static void octep_vf_oq_reset_indices(struct octep_vf_oq *oq)
1618
{
1719
oq->host_read_idx = 0;
@@ -171,11 +173,15 @@ static int octep_vf_setup_oq(struct octep_vf_device *oct, int q_no)
171173
goto oq_fill_buff_err;
172174

173175
octep_vf_oq_reset_indices(oq);
174-
oct->hw_ops.setup_oq_regs(oct, q_no);
176+
if (oct->hw_ops.setup_oq_regs(oct, q_no))
177+
goto oq_setup_err;
178+
175179
oct->num_oqs++;
176180

177181
return 0;
178182

183+
oq_setup_err:
184+
octep_vf_oq_free_ring_buffers(oq);
179185
oq_fill_buff_err:
180186
vfree(oq->buff_info);
181187
oq->buff_info = NULL;

0 commit comments

Comments
 (0)