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 <vikas.gupta@broadcom.com>
Reviewed-by: Bhargava Chenna Marreddy <bhargava.marreddy@broadcom.com>
Reviewed-by: Rajashekar Hudumula <rajashekar.hudumula@broadcom.com>
Link: https://patch.msgid.link/20250701143511.280702-9-vikas.gupta@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Vikas Gupta 2025-07-01 14:35:06 +00:00 committed by Jakub Kicinski
parent 627c67f038
commit 18a975389f
3 changed files with 85 additions and 0 deletions

View File

@ -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)

View File

@ -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;
}

View File

@ -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)