Skip to content

Commit ce8fe3f

Browse files
Vimlesh KumarPaolo Abeni
authored andcommitted
octeon_ep: 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: 0807dc7 ("octeon_ep: support Octeon CN10K devices") 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-3-vimleshk@marvell.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 73e6ffa commit ce8fe3f

4 files changed

Lines changed: 48 additions & 11 deletions

File tree

drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ static void octep_setup_iq_regs_cn93_pf(struct octep_device *oct, int iq_no)
307307
}
308308

309309
/* Setup registers for a hardware Rx Queue */
310-
static void octep_setup_oq_regs_cn93_pf(struct octep_device *oct, int oq_no)
310+
static int octep_setup_oq_regs_cn93_pf(struct octep_device *oct, int oq_no)
311311
{
312312
u64 reg_val;
313313
u64 oq_ctl = 0ULL;
@@ -355,6 +355,7 @@ static void octep_setup_oq_regs_cn93_pf(struct octep_device *oct, int oq_no)
355355
reg_val = ((u64)time_threshold << 32) |
356356
CFG_GET_OQ_INTR_PKT(oct->conf);
357357
octep_write_csr64(oct, CN93_SDP_R_OUT_INT_LEVELS(oq_no), reg_val);
358+
return 0;
358359
}
359360

360361
/* Setup registers for a PF mailbox */

drivers/net/ethernet/marvell/octeon_ep/octep_cnxk_pf.c

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/pci.h>
99
#include <linux/netdevice.h>
1010
#include <linux/etherdevice.h>
11+
#include <linux/jiffies.h>
1112

1213
#include "octep_config.h"
1314
#include "octep_main.h"
@@ -327,12 +328,14 @@ static void octep_setup_iq_regs_cnxk_pf(struct octep_device *oct, int iq_no)
327328
}
328329

329330
/* Setup registers for a hardware Rx Queue */
330-
static void octep_setup_oq_regs_cnxk_pf(struct octep_device *oct, int oq_no)
331+
static int octep_setup_oq_regs_cnxk_pf(struct octep_device *oct, int oq_no)
331332
{
332-
u64 reg_val;
333-
u64 oq_ctl = 0ULL;
334-
u32 time_threshold = 0;
335333
struct octep_oq *oq = oct->oq[oq_no];
334+
unsigned long t_out_jiffies;
335+
u32 time_threshold = 0;
336+
u64 oq_ctl = 0ULL;
337+
u64 reg_ba_val;
338+
u64 reg_val;
336339

337340
oq_no += CFG_GET_PORTS_PF_SRN(oct->conf);
338341
reg_val = octep_read_csr64(oct, CNXK_SDP_R_OUT_CONTROL(oq_no));
@@ -343,6 +346,36 @@ static void octep_setup_oq_regs_cnxk_pf(struct octep_device *oct, int oq_no)
343346
reg_val = octep_read_csr64(oct, CNXK_SDP_R_OUT_CONTROL(oq_no));
344347
} while (!(reg_val & CNXK_R_OUT_CTL_IDLE));
345348
}
349+
octep_write_csr64(oct, CNXK_SDP_R_OUT_WMARK(oq_no), oq->max_count);
350+
/* Wait for WMARK to get applied */
351+
usleep_range(10, 15);
352+
353+
octep_write_csr64(oct, CNXK_SDP_R_OUT_SLIST_BADDR(oq_no),
354+
oq->desc_ring_dma);
355+
octep_write_csr64(oct, CNXK_SDP_R_OUT_SLIST_RSIZE(oq_no),
356+
oq->max_count);
357+
reg_ba_val = octep_read_csr64(oct, CNXK_SDP_R_OUT_SLIST_BADDR(oq_no));
358+
359+
if (reg_ba_val != oq->desc_ring_dma) {
360+
t_out_jiffies = jiffies + 10 * HZ;
361+
do {
362+
if (reg_ba_val == ULLONG_MAX)
363+
return -EFAULT;
364+
octep_write_csr64(oct,
365+
CNXK_SDP_R_OUT_SLIST_BADDR(oq_no),
366+
oq->desc_ring_dma);
367+
octep_write_csr64(oct,
368+
CNXK_SDP_R_OUT_SLIST_RSIZE(oq_no),
369+
oq->max_count);
370+
reg_ba_val =
371+
octep_read_csr64(oct,
372+
CNXK_SDP_R_OUT_SLIST_BADDR(oq_no));
373+
} while ((reg_ba_val != oq->desc_ring_dma) &&
374+
time_before(jiffies, t_out_jiffies));
375+
376+
if (reg_ba_val != oq->desc_ring_dma)
377+
return -EAGAIN;
378+
}
346379

347380
reg_val &= ~(CNXK_R_OUT_CTL_IMODE);
348381
reg_val &= ~(CNXK_R_OUT_CTL_ROR_P);
@@ -356,10 +389,6 @@ static void octep_setup_oq_regs_cnxk_pf(struct octep_device *oct, int oq_no)
356389
reg_val |= (CNXK_R_OUT_CTL_ES_P);
357390

358391
octep_write_csr64(oct, CNXK_SDP_R_OUT_CONTROL(oq_no), reg_val);
359-
octep_write_csr64(oct, CNXK_SDP_R_OUT_SLIST_BADDR(oq_no),
360-
oq->desc_ring_dma);
361-
octep_write_csr64(oct, CNXK_SDP_R_OUT_SLIST_RSIZE(oq_no),
362-
oq->max_count);
363392

364393
oq_ctl = octep_read_csr64(oct, CNXK_SDP_R_OUT_CONTROL(oq_no));
365394

@@ -385,6 +414,7 @@ static void octep_setup_oq_regs_cnxk_pf(struct octep_device *oct, int oq_no)
385414
reg_val &= ~0xFFFFFFFFULL;
386415
reg_val |= CFG_GET_OQ_WMARK(oct->conf);
387416
octep_write_csr64(oct, CNXK_SDP_R_OUT_WMARK(oq_no), reg_val);
417+
return 0;
388418
}
389419

390420
/* Setup registers for a PF mailbox */

drivers/net/ethernet/marvell/octeon_ep/octep_main.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ struct octep_pci_win_regs {
7777

7878
struct octep_hw_ops {
7979
void (*setup_iq_regs)(struct octep_device *oct, int q);
80-
void (*setup_oq_regs)(struct octep_device *oct, int q);
80+
int (*setup_oq_regs)(struct octep_device *oct, int q);
8181
void (*setup_mbox_regs)(struct octep_device *oct, int mbox);
8282

8383
irqreturn_t (*mbox_intr_handler)(void *ioq_vector);

drivers/net/ethernet/marvell/octeon_ep/octep_rx.c

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

15+
static void octep_oq_free_ring_buffers(struct octep_oq *oq);
16+
1517
static void octep_oq_reset_indices(struct octep_oq *oq)
1618
{
1719
oq->host_read_idx = 0;
@@ -170,11 +172,15 @@ static int octep_setup_oq(struct octep_device *oct, int q_no)
170172
goto oq_fill_buff_err;
171173

172174
octep_oq_reset_indices(oq);
173-
oct->hw_ops.setup_oq_regs(oct, q_no);
175+
if (oct->hw_ops.setup_oq_regs(oct, q_no))
176+
goto oq_setup_err;
177+
174178
oct->num_oqs++;
175179

176180
return 0;
177181

182+
oq_setup_err:
183+
octep_oq_free_ring_buffers(oq);
178184
oq_fill_buff_err:
179185
vfree(oq->buff_info);
180186
oq->buff_info = NULL;

0 commit comments

Comments
 (0)