summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c')
-rw-r--r--drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c84
1 files changed, 72 insertions, 12 deletions
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
index d4ee2454675b..b5805969404f 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_cn9k_pf.c
@@ -216,16 +216,21 @@ static void octep_init_config_cn93_pf(struct octep_device *oct)
conf->sriov_cfg.vf_srn = CN93_SDP_EPF_RINFO_SRN(val);
val = octep_read_csr64(oct, CN93_SDP_MAC_PF_RING_CTL(oct->pcie_port));
- conf->pf_ring_cfg.srn = CN93_SDP_MAC_PF_RING_CTL_SRN(val);
- conf->pf_ring_cfg.max_io_rings = CN93_SDP_MAC_PF_RING_CTL_RPPF(val);
- conf->pf_ring_cfg.active_io_rings = conf->pf_ring_cfg.max_io_rings;
+ if (oct->chip_id == OCTEP_PCI_DEVICE_ID_CN98_PF) {
+ conf->pf_ring_cfg.srn = CN98_SDP_MAC_PF_RING_CTL_SRN(val);
+ conf->pf_ring_cfg.max_io_rings = CN98_SDP_MAC_PF_RING_CTL_RPPF(val);
+ conf->pf_ring_cfg.active_io_rings = conf->pf_ring_cfg.max_io_rings;
+ } else {
+ conf->pf_ring_cfg.srn = CN93_SDP_MAC_PF_RING_CTL_SRN(val);
+ conf->pf_ring_cfg.max_io_rings = CN93_SDP_MAC_PF_RING_CTL_RPPF(val);
+ conf->pf_ring_cfg.active_io_rings = conf->pf_ring_cfg.max_io_rings;
+ }
dev_info(&pdev->dev, "pf_srn=%u rpvf=%u nvfs=%u rppf=%u\n",
conf->pf_ring_cfg.srn, conf->sriov_cfg.active_rings_per_vf,
conf->sriov_cfg.active_vfs, conf->pf_ring_cfg.active_io_rings);
conf->iq.num_descs = OCTEP_IQ_MAX_DESCRIPTORS;
conf->iq.instr_type = OCTEP_64BYTE_INSTR;
- conf->iq.pkind = 0;
conf->iq.db_min = OCTEP_DB_MIN;
conf->iq.intr_threshold = OCTEP_IQ_INTR_THRESHOLD;
@@ -357,16 +362,55 @@ static void octep_setup_mbox_regs_cn93_pf(struct octep_device *oct, int q_no)
{
struct octep_mbox *mbox = oct->mbox[q_no];
- mbox->q_no = q_no;
-
- /* PF mbox interrupt reg */
- mbox->mbox_int_reg = oct->mmio[0].hw_addr + CN93_SDP_EPF_MBOX_RINT(0);
-
/* PF to VF DATA reg. PF writes into this reg */
- mbox->mbox_write_reg = oct->mmio[0].hw_addr + CN93_SDP_R_MBOX_PF_VF_DATA(q_no);
+ mbox->pf_vf_data_reg = oct->mmio[0].hw_addr + CN93_SDP_MBOX_PF_VF_DATA(q_no);
/* VF to PF DATA reg. PF reads from this reg */
- mbox->mbox_read_reg = oct->mmio[0].hw_addr + CN93_SDP_R_MBOX_VF_PF_DATA(q_no);
+ mbox->vf_pf_data_reg = oct->mmio[0].hw_addr + CN93_SDP_MBOX_VF_PF_DATA(q_no);
+}
+
+/* Poll for mailbox messages from VF */
+static void octep_poll_pfvf_mailbox(struct octep_device *oct)
+{
+ u32 vf, active_vfs, active_rings_per_vf, vf_mbox_queue;
+ u64 reg0, reg1;
+
+ reg0 = octep_read_csr64(oct, CN93_SDP_EPF_MBOX_RINT(0));
+ reg1 = octep_read_csr64(oct, CN93_SDP_EPF_MBOX_RINT(1));
+ if (reg0 || reg1) {
+ active_vfs = CFG_GET_ACTIVE_VFS(oct->conf);
+ active_rings_per_vf = CFG_GET_ACTIVE_RPVF(oct->conf);
+ for (vf = 0; vf < active_vfs; vf++) {
+ vf_mbox_queue = vf * active_rings_per_vf;
+
+ if (vf_mbox_queue < 64) {
+ if (!(reg0 & (0x1UL << vf_mbox_queue)))
+ continue;
+ } else {
+ if (!(reg1 & (0x1UL << (vf_mbox_queue - 64))))
+ continue;
+ }
+
+ if (!oct->mbox[vf_mbox_queue]) {
+ dev_err(&oct->pdev->dev, "bad mbox vf %d\n", vf);
+ continue;
+ }
+ schedule_work(&oct->mbox[vf_mbox_queue]->wk.work);
+ }
+ if (reg0)
+ octep_write_csr64(oct, CN93_SDP_EPF_MBOX_RINT(0), reg0);
+ if (reg1)
+ octep_write_csr64(oct, CN93_SDP_EPF_MBOX_RINT(1), reg1);
+ }
+}
+
+/* PF-VF mailbox interrupt handler */
+static irqreturn_t octep_pfvf_mbox_intr_handler_cn93_pf(void *dev)
+{
+ struct octep_device *oct = (struct octep_device *)dev;
+
+ octep_poll_pfvf_mailbox(oct);
+ return IRQ_HANDLED;
}
/* Poll OEI events like heartbeat */
@@ -398,6 +442,7 @@ static irqreturn_t octep_oei_intr_handler_cn93_pf(void *dev)
*/
static void octep_poll_non_ioq_interrupts_cn93_pf(struct octep_device *oct)
{
+ octep_poll_pfvf_mailbox(oct);
octep_poll_oei_cn93_pf(oct);
}
@@ -578,6 +623,13 @@ static irqreturn_t octep_ioq_intr_handler_cn93_pf(void *data)
return IRQ_HANDLED;
}
+/* soft reset of 98xx */
+static int octep_soft_reset_cn98_pf(struct octep_device *oct)
+{
+ dev_info(&oct->pdev->dev, "CN98XX: skip soft reset\n");
+ return 0;
+}
+
/* soft reset of 93xx */
static int octep_soft_reset_cn93_pf(struct octep_device *oct)
{
@@ -634,6 +686,8 @@ static void octep_enable_interrupts_cn93_pf(struct octep_device *oct)
octep_write_csr64(oct, CN93_SDP_EPF_MISC_RINT_ENA_W1S, intr_mask);
octep_write_csr64(oct, CN93_SDP_EPF_DMA_RINT_ENA_W1S, intr_mask);
+ octep_write_csr64(oct, CN93_SDP_EPF_MBOX_RINT_ENA_W1S(0), -1ULL);
+ octep_write_csr64(oct, CN93_SDP_EPF_MBOX_RINT_ENA_W1S(1), -1ULL);
octep_write_csr64(oct, CN93_SDP_EPF_DMA_VF_RINT_ENA_W1S(0), -1ULL);
octep_write_csr64(oct, CN93_SDP_EPF_PP_VF_RINT_ENA_W1S(0), -1ULL);
@@ -660,6 +714,8 @@ static void octep_disable_interrupts_cn93_pf(struct octep_device *oct)
octep_write_csr64(oct, CN93_SDP_EPF_MISC_RINT_ENA_W1C, intr_mask);
octep_write_csr64(oct, CN93_SDP_EPF_DMA_RINT_ENA_W1C, intr_mask);
+ octep_write_csr64(oct, CN93_SDP_EPF_MBOX_RINT_ENA_W1C(0), -1ULL);
+ octep_write_csr64(oct, CN93_SDP_EPF_MBOX_RINT_ENA_W1C(1), -1ULL);
octep_write_csr64(oct, CN93_SDP_EPF_DMA_VF_RINT_ENA_W1C(0), -1ULL);
octep_write_csr64(oct, CN93_SDP_EPF_PP_VF_RINT_ENA_W1C(0), -1ULL);
@@ -795,6 +851,7 @@ void octep_device_setup_cn93_pf(struct octep_device *oct)
oct->hw_ops.setup_oq_regs = octep_setup_oq_regs_cn93_pf;
oct->hw_ops.setup_mbox_regs = octep_setup_mbox_regs_cn93_pf;
+ oct->hw_ops.mbox_intr_handler = octep_pfvf_mbox_intr_handler_cn93_pf;
oct->hw_ops.oei_intr_handler = octep_oei_intr_handler_cn93_pf;
oct->hw_ops.ire_intr_handler = octep_ire_intr_handler_cn93_pf;
oct->hw_ops.ore_intr_handler = octep_ore_intr_handler_cn93_pf;
@@ -806,7 +863,10 @@ void octep_device_setup_cn93_pf(struct octep_device *oct)
oct->hw_ops.misc_intr_handler = octep_misc_intr_handler_cn93_pf;
oct->hw_ops.rsvd_intr_handler = octep_rsvd_intr_handler_cn93_pf;
oct->hw_ops.ioq_intr_handler = octep_ioq_intr_handler_cn93_pf;
- oct->hw_ops.soft_reset = octep_soft_reset_cn93_pf;
+ if (oct->chip_id == OCTEP_PCI_DEVICE_ID_CN98_PF)
+ oct->hw_ops.soft_reset = octep_soft_reset_cn98_pf;
+ else
+ oct->hw_ops.soft_reset = octep_soft_reset_cn93_pf;
oct->hw_ops.reinit_regs = octep_reinit_regs_cn93_pf;
oct->hw_ops.enable_interrupts = octep_enable_interrupts_cn93_pf;