From: Naveen Mamindlapalli Register and handle the NIX LF error (NIX_LF_ERR_INT) and poison/RAS (NIX_LF_RAS) interrupt vectors, The handlers acknowledge the interrupt and log the status (ratelimited) to help debug NIX LF faults. Signed-off-by: Nitin Shetty J Signed-off-by: Naveen Mamindlapalli --- .../ethernet/marvell/octeontx2/nic/otx2_pf.c | 80 ++++++++++++++++++- .../ethernet/marvell/octeontx2/nic/otx2_reg.h | 2 + .../ethernet/marvell/octeontx2/nic/otx2_vf.c | 2 +- 3 files changed, 82 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c index c995f2900859..61b0334d0b6e 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c @@ -1524,6 +1524,34 @@ irqreturn_t otx2_cq_intr_handler(int irq, void *cq_irq) } EXPORT_SYMBOL(otx2_cq_intr_handler); +static irqreturn_t otx2_nixlf_err_intr_handler(int irq, void *data) +{ + struct otx2_nic *pf = data; + u64 regval; + + /* Clear interrupt */ + regval = otx2_read64(pf, NIX_LF_ERR_INT); + otx2_write64(pf, NIX_LF_ERR_INT, regval); + + dev_err_ratelimited(pf->dev, "NIXLF Error Interrupt: 0x%llx\n", regval); + + return IRQ_HANDLED; +} + +static irqreturn_t otx2_nixlf_poison_intr_handler(int irq, void *data) +{ + struct otx2_nic *pf = data; + u64 regval; + + /* Clear interrupt */ + regval = otx2_read64(pf, NIX_LF_RAS); + otx2_write64(pf, NIX_LF_RAS, regval); + + dev_err_ratelimited(pf->dev, "NIXLF Poison Interrupt: 0x%llx\n", regval); + + return IRQ_HANDLED; +} + void otx2_disable_napi(struct otx2_nic *pf) { struct otx2_qset *qset = &pf->qset; @@ -2080,6 +2108,34 @@ int otx2_open(struct net_device *netdev) otx2_set_cints_affinity(pf); + /* Register NIXLF error IRQ handler */ + vec = pf->hw.nix_msixoff + NIX_LF_ERR_VEC; + irq_name = &pf->hw.irq_name[vec * NAME_SIZE]; + snprintf(irq_name, NAME_SIZE, "%s-nixlf-err", pf->netdev->name); + err = request_irq(pci_irq_vector(pf->pdev, vec), + otx2_nixlf_err_intr_handler, 0, irq_name, pf); + if (err) { + dev_err(pf->dev, + "RVUPF%d: IRQ registration failed for NIXLF ERR vector\n", + rvu_get_pf(pf->pdev, pf->pcifunc)); + goto err_free_cints; + } + otx2_write64(pf, NIX_LF_ERR_INT_ENA_W1S, NIX_LF_ERR_INT_MASK); + + /* Register NIXLF POISON interrupt handler */ + vec = pf->hw.nix_msixoff + NIX_LF_POISON_VEC; + irq_name = &pf->hw.irq_name[vec * NAME_SIZE]; + snprintf(irq_name, NAME_SIZE, "%s-nixlf-poison", pf->netdev->name); + err = request_irq(pci_irq_vector(pf->pdev, vec), + otx2_nixlf_poison_intr_handler, 0, irq_name, pf); + if (err) { + dev_err(pf->dev, + "RVUPF%d: IRQ registration failed for NIXLF POISON vector\n", + rvu_get_pf(pf->pdev, pf->pcifunc)); + goto err_free_errint; + } + otx2_write64(pf, NIX_LF_RAS_ENA_W1S, NIX_LF_RAS_MASK); + if (pf->flags & OTX2_FLAG_RX_VLAN_SUPPORT) otx2_enable_rxvlan(pf, true); @@ -2132,6 +2188,16 @@ int otx2_open(struct net_device *netdev) netif_tx_stop_all_queues(netdev); netif_carrier_off(netdev); pf->flags |= OTX2_FLAG_INTF_DOWN; + /* free NIXLF POISON irq */ + vec = pci_irq_vector(pf->pdev, + pf->hw.nix_msixoff + NIX_LF_POISON_VEC); + otx2_write64(pf, NIX_LF_RAS_ENA_W1C, NIX_LF_RAS_MASK); + free_irq(vec, pf); +err_free_errint: + vec = pci_irq_vector(pf->pdev, + pf->hw.nix_msixoff + NIX_LF_ERR_VEC); + otx2_write64(pf, NIX_LF_ERR_INT_ENA_W1C, NIX_LF_ERR_INT_MASK); + free_irq(vec, pf); err_free_cints: otx2_free_cints(pf, qidx); vec = pci_irq_vector(pf->pdev, @@ -2171,6 +2237,18 @@ int otx2_stop(struct net_device *netdev) /* Clear RSS enable flag */ pf->hw.rss_info.enable = false; + /* Cleanup NIXLF Poison IRQ */ + vec = pci_irq_vector(pf->pdev, + pf->hw.nix_msixoff + NIX_LF_POISON_VEC); + otx2_write64(pf, NIX_LF_RAS_ENA_W1C, NIX_LF_RAS_MASK); + free_irq(vec, pf); + + /* Cleanup NIXLF Error IRQ */ + vec = pci_irq_vector(pf->pdev, + pf->hw.nix_msixoff + NIX_LF_ERR_VEC); + otx2_write64(pf, NIX_LF_ERR_INT_ENA_W1C, NIX_LF_ERR_INT_MASK); + free_irq(vec, pf); + /* Cleanup Queue IRQ */ vec = pci_irq_vector(pf->pdev, pf->hw.nix_msixoff + NIX_LF_QINT_VEC_START); @@ -3010,7 +3088,7 @@ int otx2_realloc_msix_vectors(struct otx2_nic *pf) * upto NIX vector offset. */ num_vec = hw->nix_msixoff; - num_vec += NIX_LF_CINT_VEC_START + hw->max_queues; + num_vec += NIX_LF_POISON_VEC + 1; otx2_disable_mbox_intr(pf); pci_free_irq_vectors(hw->pdev); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_reg.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_reg.h index 1cd576fd09c5..c144fd2bbe51 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_reg.h +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_reg.h @@ -121,10 +121,12 @@ #define NIX_LF_ERR_INT_W1S (NIX_LFBASE | 0x228) #define NIX_LF_ERR_INT_ENA_W1C (NIX_LFBASE | 0x230) #define NIX_LF_ERR_INT_ENA_W1S (NIX_LFBASE | 0x238) +#define NIX_LF_ERR_INT_MASK GENMASK_ULL(31, 0) #define NIX_LF_RAS (NIX_LFBASE | 0x240) #define NIX_LF_RAS_W1S (NIX_LFBASE | 0x248) #define NIX_LF_RAS_ENA_W1C (NIX_LFBASE | 0x250) #define NIX_LF_RAS_ENA_W1S (NIX_LFBASE | 0x258) +#define NIX_LF_RAS_MASK GENMASK_ULL(10, 0) #define NIX_LF_SQ_OP_ERR_DBG (NIX_LFBASE | 0x260) #define NIX_LF_MNQ_ERR_DBG (NIX_LFBASE | 0x270) #define NIX_LF_SEND_ERR_DBG (NIX_LFBASE | 0x280) diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c index b022f52c6845..2a5630561b12 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c @@ -554,7 +554,7 @@ static int otx2vf_realloc_msix_vectors(struct otx2_nic *vf) int num_vec, err; num_vec = hw->nix_msixoff; - num_vec += NIX_LF_CINT_VEC_START + hw->max_queues; + num_vec += NIX_LF_POISON_VEC + 1; otx2vf_disable_mbox_intr(vf); pci_free_irq_vectors(hw->pdev); -- 2.48.1