Skip to content

Commit 3a23b80

Browse files
author
Paolo Abeni
committed
Merge branch 'disable-interrupts-and-ensure-dbell-updation'
Vimlesh Kumar says: ==================== disable interrupts and ensure dbell updation Disable per ring interrupts when netdev goes down and ensure dbell BADDR updation for both PFs and VFs by adding wait and check for updated value. Resending based on discussion with reviewer. ==================== Link: https://patch.msgid.link/20260206111510.1045092-1-vimleshk@marvell.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2 parents 36bd7d5 + 484e834 commit 3a23b80

10 files changed

Lines changed: 126 additions & 23 deletions

File tree

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

Lines changed: 17 additions & 4 deletions
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 */
@@ -696,14 +697,26 @@ static void octep_enable_interrupts_cn93_pf(struct octep_device *oct)
696697
/* Disable all interrupts */
697698
static void octep_disable_interrupts_cn93_pf(struct octep_device *oct)
698699
{
699-
u64 intr_mask = 0ULL;
700+
u64 reg_val, intr_mask = 0ULL;
700701
int srn, num_rings, i;
701702

702703
srn = CFG_GET_PORTS_PF_SRN(oct->conf);
703704
num_rings = CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf);
704705

705-
for (i = 0; i < num_rings; i++)
706-
intr_mask |= (0x1ULL << (srn + i));
706+
for (i = 0; i < num_rings; i++) {
707+
intr_mask |= BIT_ULL(srn + i);
708+
reg_val = octep_read_csr64(oct,
709+
CN93_SDP_R_IN_INT_LEVELS(srn + i));
710+
reg_val &= ~CN93_INT_ENA_BIT;
711+
octep_write_csr64(oct,
712+
CN93_SDP_R_IN_INT_LEVELS(srn + i), reg_val);
713+
714+
reg_val = octep_read_csr64(oct,
715+
CN93_SDP_R_OUT_INT_LEVELS(srn + i));
716+
reg_val &= ~CN93_INT_ENA_BIT;
717+
octep_write_csr64(oct,
718+
CN93_SDP_R_OUT_INT_LEVELS(srn + i), reg_val);
719+
}
707720

708721
octep_write_csr64(oct, CN93_SDP_EPF_IRERR_RINT_ENA_W1C, intr_mask);
709722
octep_write_csr64(oct, CN93_SDP_EPF_ORERR_RINT_ENA_W1C, intr_mask);

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

Lines changed: 53 additions & 11 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 */
@@ -720,14 +750,26 @@ static void octep_enable_interrupts_cnxk_pf(struct octep_device *oct)
720750
/* Disable all interrupts */
721751
static void octep_disable_interrupts_cnxk_pf(struct octep_device *oct)
722752
{
723-
u64 intr_mask = 0ULL;
753+
u64 reg_val, intr_mask = 0ULL;
724754
int srn, num_rings, i;
725755

726756
srn = CFG_GET_PORTS_PF_SRN(oct->conf);
727757
num_rings = CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf);
728758

729-
for (i = 0; i < num_rings; i++)
730-
intr_mask |= (0x1ULL << (srn + i));
759+
for (i = 0; i < num_rings; i++) {
760+
intr_mask |= BIT_ULL(srn + i);
761+
reg_val = octep_read_csr64(oct,
762+
CNXK_SDP_R_IN_INT_LEVELS(srn + i));
763+
reg_val &= ~CNXK_INT_ENA_BIT;
764+
octep_write_csr64(oct,
765+
CNXK_SDP_R_IN_INT_LEVELS(srn + i), reg_val);
766+
767+
reg_val = octep_read_csr64(oct,
768+
CNXK_SDP_R_OUT_INT_LEVELS(srn + i));
769+
reg_val &= ~CNXK_INT_ENA_BIT;
770+
octep_write_csr64(oct,
771+
CNXK_SDP_R_OUT_INT_LEVELS(srn + i), reg_val);
772+
}
731773

732774
octep_write_csr64(oct, CNXK_SDP_EPF_IRERR_RINT_ENA_W1C, intr_mask);
733775
octep_write_csr64(oct, CNXK_SDP_EPF_ORERR_RINT_ENA_W1C, intr_mask);

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_regs_cn9k_pf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,5 +386,6 @@
386386
#define CN93_PEM_BAR4_INDEX 7
387387
#define CN93_PEM_BAR4_INDEX_SIZE 0x400000ULL
388388
#define CN93_PEM_BAR4_INDEX_OFFSET (CN93_PEM_BAR4_INDEX * CN93_PEM_BAR4_INDEX_SIZE)
389+
#define CN93_INT_ENA_BIT BIT_ULL(62)
389390

390391
#endif /* _OCTEP_REGS_CN9K_PF_H_ */

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,5 +412,6 @@
412412
#define CNXK_PEM_BAR4_INDEX 7
413413
#define CNXK_PEM_BAR4_INDEX_SIZE 0x400000ULL
414414
#define CNXK_PEM_BAR4_INDEX_OFFSET (CNXK_PEM_BAR4_INDEX * CNXK_PEM_BAR4_INDEX_SIZE)
415+
#define CNXK_INT_ENA_BIT BIT_ULL(62)
415416

416417
#endif /* _OCTEP_REGS_CNXK_PF_H_ */

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;

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)