[net-next 3/9] bng_en: Introduce VNIC
From: Bhargava Marreddy <hidden>
Date: 2025-08-13 16:29:38
Also in:
lkml
Subsystem:
broadcom bng_en 800 gigabit ethernet driver, networking drivers, the rest · Maintainers:
Vikas Gupta, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Add the VNIC-specific structures and DMA memory necessary to support UC/MC and RSS functionality. Signed-off-by: Bhargava Marreddy <redacted> Reviewed-by: Vikas Gupta <vikas.gupta@broadcom.com> Reviewed-by: Rajashekar Hudumula <redacted> --- .../net/ethernet/broadcom/bnge/bnge_netdev.c | 130 ++++++++++++++++++ .../net/ethernet/broadcom/bnge/bnge_netdev.h | 30 ++++ 2 files changed, 160 insertions(+)
diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c
index 5df12bb86f8..e76a7d1f6ec 100644
--- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c
+++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c@@ -427,6 +427,123 @@ static int bnge_alloc_tx_rings(struct bnge_net *bn) return 0; } +static void bnge_free_vnic_attributes(struct bnge_net *bn) +{ + struct pci_dev *pdev = bn->bd->pdev; + struct bnge_vnic_info *vnic; + int i; + + if (!bn->vnic_info) + return; + + for (i = 0; i < bn->nr_vnics; i++) { + vnic = &bn->vnic_info[i]; + + kfree(vnic->uc_list); + vnic->uc_list = NULL; + + if (vnic->mc_list) { + dma_free_coherent(&pdev->dev, vnic->mc_list_size, + vnic->mc_list, vnic->mc_list_mapping); + vnic->mc_list = NULL; + } + + if (vnic->rss_table) { + dma_free_coherent(&pdev->dev, vnic->rss_table_size, + vnic->rss_table, + vnic->rss_table_dma_addr); + vnic->rss_table = NULL; + } + + vnic->rss_hash_key = NULL; + vnic->flags = 0; + } +} + +static int bnge_alloc_vnic_attributes(struct bnge_net *bn) +{ + struct bnge_dev *bd = bn->bd; + struct bnge_vnic_info *vnic; + int i, rc = 0, size; + + for (i = 0; i < bn->nr_vnics; i++) { + vnic = &bn->vnic_info[i]; + + if (vnic->flags & BNGE_VNIC_UCAST_FLAG) { + int mem_size = (BNGE_MAX_UC_ADDRS - 1) * ETH_ALEN; + + if (mem_size > 0) { + vnic->uc_list = kmalloc(mem_size, GFP_KERNEL); + if (!vnic->uc_list) { + rc = -ENOMEM; + goto out; + } + } + } + + if (vnic->flags & BNGE_VNIC_MCAST_FLAG) { + vnic->mc_list_size = BNGE_MAX_MC_ADDRS * ETH_ALEN; + vnic->mc_list = + dma_alloc_coherent(bd->dev, + vnic->mc_list_size, + &vnic->mc_list_mapping, + GFP_KERNEL); + if (!vnic->mc_list) { + rc = -ENOMEM; + goto out; + } + } + + /* Allocate rss table and hash key */ + size = L1_CACHE_ALIGN(HW_HASH_INDEX_SIZE * sizeof(u16)); + size = L1_CACHE_ALIGN(BNGE_MAX_RSS_TABLE_SIZE); + + vnic->rss_table_size = size + HW_HASH_KEY_SIZE; + vnic->rss_table = dma_alloc_coherent(bd->dev, + vnic->rss_table_size, + &vnic->rss_table_dma_addr, + GFP_KERNEL); + if (!vnic->rss_table) { + rc = -ENOMEM; + goto out; + } + + vnic->rss_hash_key = ((void *)vnic->rss_table) + size; + vnic->rss_hash_key_dma_addr = vnic->rss_table_dma_addr + size; + } + + return 0; + +out: + return rc; +} + +static int bnge_alloc_vnics(struct bnge_net *bn) +{ + int num_vnics; + + /* Allocate only 1 VNIC for now + * Additional VNICs will be added based on RFS/NTUPLE in future patches + */ + num_vnics = 1; + + bn->vnic_info = kcalloc(num_vnics, sizeof(struct bnge_vnic_info), + GFP_KERNEL); + if (!bn->vnic_info) + return -ENOMEM; + + bn->nr_vnics = num_vnics; + + return 0; +} + +static void bnge_free_vnics(struct bnge_net *bn) +{ + kfree(bn->vnic_info); + bn->vnic_info = NULL; + bn->nr_vnics = 0; +} + static void bnge_free_ring_grps(struct bnge_net *bn) { kfree(bn->grp_info);
@@ -435,11 +552,13 @@ static void bnge_free_ring_grps(struct bnge_net *bn) static void bnge_free_core(struct bnge_net *bn) { + bnge_free_vnic_attributes(bn); bnge_free_tx_rings(bn); bnge_free_rx_rings(bn); bnge_free_nq_tree(bn); bnge_free_nq_arrays(bn); bnge_free_ring_grps(bn); + bnge_free_vnics(bn); kfree(bn->tx_ring_map); bn->tx_ring_map = NULL; kfree(bn->tx_ring);
@@ -526,6 +645,10 @@ static int bnge_alloc_core(struct bnge_net *bn) txr->bnapi = bnapi2; } + rc = bnge_alloc_vnics(bn); + if (rc) + goto err_free_core; + rc = bnge_alloc_nq_arrays(bn); if (rc) goto err_free_core;
@@ -544,6 +667,13 @@ static int bnge_alloc_core(struct bnge_net *bn) if (rc) goto err_free_core; + bn->vnic_info[BNGE_VNIC_DEFAULT].flags |= BNGE_VNIC_RSS_FLAG | + BNGE_VNIC_MCAST_FLAG | + BNGE_VNIC_UCAST_FLAG; + rc = bnge_alloc_vnic_attributes(bn); + if (rc) + goto err_free_core; + return 0; err_free_core:
diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h
index 665a20380de..8bc0d09e041 100644
--- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h
+++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h@@ -177,6 +177,8 @@ struct bnge_net { /* grp_info indexed by napi/nq index */ struct bnge_ring_grp_info *grp_info; + struct bnge_vnic_info *vnic_info; + int nr_vnics; int total_irqs; };
@@ -301,4 +303,32 @@ struct bnge_napi { struct bnge_tx_ring_info *tx_ring[BNGE_MAX_TXR_PER_NAPI]; }; +#define INVALID_STATS_CTX_ID -1 +#define BNGE_VNIC_DEFAULT 0 +#define BNGE_MAX_UC_ADDRS 4 + +struct bnge_vnic_info { + u8 *uc_list; + dma_addr_t rss_table_dma_addr; + __le16 *rss_table; + dma_addr_t rss_hash_key_dma_addr; + u64 *rss_hash_key; + int rss_table_size; +#define BNGE_RSS_TABLE_ENTRIES 64 +#define BNGE_RSS_TABLE_SIZE (BNGE_RSS_TABLE_ENTRIES * 4) +#define BNGE_RSS_TABLE_MAX_TBL 8 +#define BNGE_MAX_RSS_TABLE_SIZE \ + (BNGE_RSS_TABLE_SIZE * BNGE_RSS_TABLE_MAX_TBL) + + u8 *mc_list; + int mc_list_size; + int mc_list_count; + dma_addr_t mc_list_mapping; +#define BNGE_MAX_MC_ADDRS 16 + + u32 flags; +#define BNGE_VNIC_RSS_FLAG 1 +#define BNGE_VNIC_MCAST_FLAG 4 +#define BNGE_VNIC_UCAST_FLAG 8 +}; #endif /* _BNGE_NETDEV_H_ */
--
2.47.3