]> www.infradead.org Git - users/hch/misc.git/commitdiff
bng_en: Introduce VNIC
authorBhargava Marreddy <bhargava.marreddy@broadcom.com>
Fri, 19 Sep 2025 17:47:35 +0000 (23:17 +0530)
committerJakub Kicinski <kuba@kernel.org>
Tue, 23 Sep 2025 00:51:27 +0000 (17:51 -0700)
Add the VNIC-specific structures and DMA memory necessary to support
UC/MC and RSS functionality.

Signed-off-by: Bhargava Marreddy <bhargava.marreddy@broadcom.com>
Reviewed-by: Vikas Gupta <vikas.gupta@broadcom.com>
Reviewed-by: Rajashekar Hudumula <rajashekar.hudumula@broadcom.com>
Link: https://patch.msgid.link/20250919174742.24969-5-bhargava.marreddy@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/broadcom/bnge/bnge_netdev.c
drivers/net/ethernet/broadcom/bnge/bnge_netdev.h

index 67da7001427abb8d96497cc213d22f214c46ccb6..df05e6ea27110b0eed0b3805a97139f884af45c5 100644 (file)
@@ -439,12 +439,122 @@ err_free_tx_rings:
        return rc;
 }
 
+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, 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;
+
+                       vnic->uc_list = kmalloc(mem_size, GFP_KERNEL);
+                       if (!vnic->uc_list)
+                               goto err_free_vnic_attributes;
+               }
+
+               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)
+                               goto err_free_vnic_attributes;
+               }
+
+               /* Allocate rss table and hash key */
+               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)
+                       goto err_free_vnic_attributes;
+
+               vnic->rss_hash_key = ((void *)vnic->rss_table) + size;
+               vnic->rss_hash_key_dma_addr = vnic->rss_table_dma_addr + size;
+       }
+       return 0;
+
+err_free_vnic_attributes:
+       bnge_free_vnic_attributes(bn);
+       return -ENOMEM;
+}
+
+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_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_vnics(bn);
        kfree(bn->tx_ring_map);
        bn->tx_ring_map = NULL;
        kfree(bn->tx_ring);
@@ -531,6 +641,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;
@@ -546,6 +660,13 @@ static int bnge_alloc_core(struct bnge_net *bn)
                goto err_free_core;
 
        rc = bnge_alloc_nq_tree(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;
index bccddae09fa7037aa15aca5a5a52f90d0c2104a6..115297dd82c1d4b881ef9985f25e68bd4eb0a75f 100644 (file)
@@ -176,6 +176,8 @@ struct bnge_net {
        u16                             *tx_ring_map;
        enum dma_data_direction         rx_dir;
 
+       struct bnge_vnic_info           *vnic_info;
+       int                             nr_vnics;
        int                             total_irqs;
 };
 
@@ -300,4 +302,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_ */