Commit 3a23b80d authored by Paolo Abeni's avatar Paolo Abeni
Browse files

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: default avatarPaolo Abeni <pabeni@redhat.com>
parents 36bd7d5d 484e834d
Loading
Loading
Loading
Loading
+17 −4
Original line number Diff line number Diff line
@@ -307,7 +307,7 @@ static void octep_setup_iq_regs_cn93_pf(struct octep_device *oct, int iq_no)
}

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

/* Setup registers for a PF mailbox */
@@ -696,14 +697,26 @@ static void octep_enable_interrupts_cn93_pf(struct octep_device *oct)
/* Disable all interrupts */
static void octep_disable_interrupts_cn93_pf(struct octep_device *oct)
{
	u64 intr_mask = 0ULL;
	u64 reg_val, intr_mask = 0ULL;
	int srn, num_rings, i;

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

	for (i = 0; i < num_rings; i++)
		intr_mask |= (0x1ULL << (srn + i));
	for (i = 0; i < num_rings; i++) {
		intr_mask |= BIT_ULL(srn + i);
		reg_val = octep_read_csr64(oct,
					   CN93_SDP_R_IN_INT_LEVELS(srn + i));
		reg_val &= ~CN93_INT_ENA_BIT;
		octep_write_csr64(oct,
				  CN93_SDP_R_IN_INT_LEVELS(srn + i), reg_val);

		reg_val = octep_read_csr64(oct,
					   CN93_SDP_R_OUT_INT_LEVELS(srn + i));
		reg_val &= ~CN93_INT_ENA_BIT;
		octep_write_csr64(oct,
				  CN93_SDP_R_OUT_INT_LEVELS(srn + i), reg_val);
	}

	octep_write_csr64(oct, CN93_SDP_EPF_IRERR_RINT_ENA_W1C, intr_mask);
	octep_write_csr64(oct, CN93_SDP_EPF_ORERR_RINT_ENA_W1C, intr_mask);
+53 −11
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/jiffies.h>

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

/* Setup registers for a hardware Rx Queue  */
static void octep_setup_oq_regs_cnxk_pf(struct octep_device *oct, int oq_no)
static int octep_setup_oq_regs_cnxk_pf(struct octep_device *oct, int oq_no)
{
	u64 reg_val;
	u64 oq_ctl = 0ULL;
	u32 time_threshold = 0;
	struct octep_oq *oq = oct->oq[oq_no];
	unsigned long t_out_jiffies;
	u32 time_threshold = 0;
	u64 oq_ctl = 0ULL;
	u64 reg_ba_val;
	u64 reg_val;

	oq_no += CFG_GET_PORTS_PF_SRN(oct->conf);
	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)
			reg_val = octep_read_csr64(oct, CNXK_SDP_R_OUT_CONTROL(oq_no));
		} while (!(reg_val & CNXK_R_OUT_CTL_IDLE));
	}
	octep_write_csr64(oct, CNXK_SDP_R_OUT_WMARK(oq_no),  oq->max_count);
	/* Wait for WMARK to get applied */
	usleep_range(10, 15);

	octep_write_csr64(oct, CNXK_SDP_R_OUT_SLIST_BADDR(oq_no),
			  oq->desc_ring_dma);
	octep_write_csr64(oct, CNXK_SDP_R_OUT_SLIST_RSIZE(oq_no),
			  oq->max_count);
	reg_ba_val = octep_read_csr64(oct, CNXK_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_write_csr64(oct,
					  CNXK_SDP_R_OUT_SLIST_BADDR(oq_no),
					  oq->desc_ring_dma);
			octep_write_csr64(oct,
					  CNXK_SDP_R_OUT_SLIST_RSIZE(oq_no),
					  oq->max_count);
			reg_ba_val =
			octep_read_csr64(oct,
					 CNXK_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_R_OUT_CTL_IMODE);
	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)
	reg_val |= (CNXK_R_OUT_CTL_ES_P);

	octep_write_csr64(oct, CNXK_SDP_R_OUT_CONTROL(oq_no), reg_val);
	octep_write_csr64(oct, CNXK_SDP_R_OUT_SLIST_BADDR(oq_no),
			  oq->desc_ring_dma);
	octep_write_csr64(oct, CNXK_SDP_R_OUT_SLIST_RSIZE(oq_no),
			  oq->max_count);

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

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

/* Setup registers for a PF mailbox */
@@ -720,14 +750,26 @@ static void octep_enable_interrupts_cnxk_pf(struct octep_device *oct)
/* Disable all interrupts */
static void octep_disable_interrupts_cnxk_pf(struct octep_device *oct)
{
	u64 intr_mask = 0ULL;
	u64 reg_val, intr_mask = 0ULL;
	int srn, num_rings, i;

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

	for (i = 0; i < num_rings; i++)
		intr_mask |= (0x1ULL << (srn + i));
	for (i = 0; i < num_rings; i++) {
		intr_mask |= BIT_ULL(srn + i);
		reg_val = octep_read_csr64(oct,
					   CNXK_SDP_R_IN_INT_LEVELS(srn + i));
		reg_val &= ~CNXK_INT_ENA_BIT;
		octep_write_csr64(oct,
				  CNXK_SDP_R_IN_INT_LEVELS(srn + i), reg_val);

		reg_val = octep_read_csr64(oct,
					   CNXK_SDP_R_OUT_INT_LEVELS(srn + i));
		reg_val &= ~CNXK_INT_ENA_BIT;
		octep_write_csr64(oct,
				  CNXK_SDP_R_OUT_INT_LEVELS(srn + i), reg_val);
	}

	octep_write_csr64(oct, CNXK_SDP_EPF_IRERR_RINT_ENA_W1C, intr_mask);
	octep_write_csr64(oct, CNXK_SDP_EPF_ORERR_RINT_ENA_W1C, intr_mask);
+1 −1
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ struct octep_pci_win_regs {

struct octep_hw_ops {
	void (*setup_iq_regs)(struct octep_device *oct, int q);
	void (*setup_oq_regs)(struct octep_device *oct, int q);
	int (*setup_oq_regs)(struct octep_device *oct, int q);
	void (*setup_mbox_regs)(struct octep_device *oct, int mbox);

	irqreturn_t (*mbox_intr_handler)(void *ioq_vector);
+1 −0
Original line number Diff line number Diff line
@@ -386,5 +386,6 @@
#define CN93_PEM_BAR4_INDEX            7
#define CN93_PEM_BAR4_INDEX_SIZE       0x400000ULL
#define CN93_PEM_BAR4_INDEX_OFFSET     (CN93_PEM_BAR4_INDEX * CN93_PEM_BAR4_INDEX_SIZE)
#define CN93_INT_ENA_BIT	BIT_ULL(62)

#endif /* _OCTEP_REGS_CN9K_PF_H_ */
+1 −0
Original line number Diff line number Diff line
@@ -412,5 +412,6 @@
#define CNXK_PEM_BAR4_INDEX		7
#define CNXK_PEM_BAR4_INDEX_SIZE	0x400000ULL
#define CNXK_PEM_BAR4_INDEX_OFFSET	(CNXK_PEM_BAR4_INDEX * CNXK_PEM_BAR4_INDEX_SIZE)
#define CNXK_INT_ENA_BIT	BIT_ULL(62)

#endif /* _OCTEP_REGS_CNXK_PF_H_ */
Loading