From 18a975389fcc810143c5e62294f52192f942b665 Mon Sep 17 00:00:00 2001 From: Vikas Gupta Date: Tue, 1 Jul 2025 14:35:06 +0000 Subject: [PATCH] bng_en: Add irq allocation support Add irq allocation functions. This will help to allocate IRQs to both netdev and RoCE aux devices. Signed-off-by: Vikas Gupta Reviewed-by: Bhargava Chenna Marreddy Reviewed-by: Rajashekar Hudumula Link: https://patch.msgid.link/20250701143511.280702-9-vikas.gupta@broadcom.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/broadcom/bnge/bnge.h | 3 + .../net/ethernet/broadcom/bnge/bnge_resc.c | 69 +++++++++++++++++++ .../net/ethernet/broadcom/bnge/bnge_resc.h | 13 ++++ 3 files changed, 85 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge.h b/drivers/net/ethernet/broadcom/bnge/bnge.h index b58d8fc6f258c..3c161b1a9b62c 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge.h @@ -172,6 +172,9 @@ struct bnge_dev { #define BNGE_SUPPORTS_TPA(bd) ((bd)->max_tpa_v2) u8 num_tc; + + struct bnge_irq *irq_tbl; + u16 irqs_acquired; }; static inline bool bnge_is_roce_en(struct bnge_dev *bd) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_resc.c b/drivers/net/ethernet/broadcom/bnge/bnge_resc.c index 68e0944748221..0e67a00016779 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_resc.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_resc.c @@ -326,3 +326,72 @@ int bnge_reserve_rings(struct bnge_dev *bd) return rc; } + +int bnge_alloc_irqs(struct bnge_dev *bd) +{ + u16 aux_msix, tx_cp, num_entries; + int i, irqs_demand, rc; + u16 max, min = 1; + + irqs_demand = bnge_nqs_demand(bd); + max = bnge_get_max_func_irqs(bd); + if (irqs_demand > max) + irqs_demand = max; + + if (!(bd->flags & BNGE_EN_SHARED_CHNL)) + min = 2; + + irqs_demand = pci_alloc_irq_vectors(bd->pdev, min, irqs_demand, + PCI_IRQ_MSIX); + aux_msix = bnge_aux_get_msix(bd); + if (irqs_demand < 0 || irqs_demand < aux_msix) { + rc = -ENODEV; + goto err_free_irqs; + } + + num_entries = irqs_demand; + if (pci_msix_can_alloc_dyn(bd->pdev)) + num_entries = max; + bd->irq_tbl = kcalloc(num_entries, sizeof(*bd->irq_tbl), GFP_KERNEL); + if (!bd->irq_tbl) { + rc = -ENOMEM; + goto err_free_irqs; + } + + for (i = 0; i < irqs_demand; i++) + bd->irq_tbl[i].vector = pci_irq_vector(bd->pdev, i); + + bd->irqs_acquired = irqs_demand; + /* Reduce rings based upon num of vectors allocated. + * We dont need to consider NQs as they have been calculated + * and must be more than irqs_demand. + */ + rc = bnge_adjust_rings(bd, &bd->rx_nr_rings, + &bd->tx_nr_rings, + irqs_demand - aux_msix, min == 1); + if (rc) + goto err_free_irqs; + + tx_cp = bnge_num_tx_to_cp(bd, bd->tx_nr_rings); + bd->nq_nr_rings = (min == 1) ? + max_t(u16, tx_cp, bd->rx_nr_rings) : + tx_cp + bd->rx_nr_rings; + + /* Readjust tx_nr_rings_per_tc */ + if (!bd->num_tc) + bd->tx_nr_rings_per_tc = bd->tx_nr_rings; + + return 0; + +err_free_irqs: + dev_err(bd->dev, "Failed to allocate IRQs err = %d\n", rc); + bnge_free_irqs(bd); + return rc; +} + +void bnge_free_irqs(struct bnge_dev *bd) +{ + pci_free_irq_vectors(bd->pdev); + kfree(bd->irq_tbl); + bd->irq_tbl = NULL; +} diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_resc.h b/drivers/net/ethernet/broadcom/bnge/bnge_resc.h index c6cef514588f2..23db93e037875 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_resc.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_resc.h @@ -51,8 +51,21 @@ struct bnge_hw_rings { u16 rss_ctx; }; +/* "TXRX", 2 hypens, plus maximum integer */ +#define BNGE_IRQ_NAME_EXTRA 17 +struct bnge_irq { + irq_handler_t handler; + unsigned int vector; + u8 requested:1; + u8 have_cpumask:1; + char name[IFNAMSIZ + BNGE_IRQ_NAME_EXTRA]; + cpumask_var_t cpu_mask; +}; + int bnge_reserve_rings(struct bnge_dev *bd); int bnge_fix_rings_count(u16 *rx, u16 *tx, u16 max, bool shared); +int bnge_alloc_irqs(struct bnge_dev *bd); +void bnge_free_irqs(struct bnge_dev *bd); static inline u32 bnge_adjust_pow_two(u32 total_ent, u16 ent_per_blk) -- 2.47.2