]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: dsa: netc: initialize the group bitmap of ETT and ECT
authorWei Fang <wei.fang@nxp.com>
Thu, 11 Jun 2026 02:14:54 +0000 (10:14 +0800)
committerJakub Kicinski <kuba@kernel.org>
Mon, 15 Jun 2026 21:32:06 +0000 (14:32 -0700)
The Egress Treatment Table (ETT) and Egress Count Table (ECT) are both
index tables whose entry IDs are allocated by software. Every num_ports
entries form a group, where each entry in the group corresponds to one
port. To facilitate group allocation and management, initialize the group
index bitmaps for both tables based on hardware capabilities reported by
ETTCAPR and ECTCAPR registers.

The bitmap size per table is calculated as the total number of hardware
entries divided by the number of available ports, which gives the number
of groups available for software allocation. A set bit in the bitmap
represents a group index that has been allocated.

These bitmaps will be used by subsequent patches that add VLAN support.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
Link: https://patch.msgid.link/20260611021458.2629145-6-wei.fang@oss.nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/dsa/netc/netc_main.c
drivers/net/dsa/netc/netc_switch_hw.h
include/linux/fsl/ntmp.h

index fa7dd307ce130cc4b8fa9cdb26809a06600f4274..d4475ad7ed6c2f27c933de96c873c5a4612335e8 100644 (file)
@@ -323,16 +323,104 @@ static void netc_remove_all_cbdrs(struct netc_switch *priv)
                ntmp_free_cbdr(&ntmp->ring[i]);
 }
 
+static u32 netc_num_available_ports(struct netc_switch *priv)
+{
+       struct dsa_port *dp;
+       u32 num_ports = 0;
+
+       dsa_switch_for_each_available_port(dp, priv->ds)
+               num_ports++;
+
+       return num_ports;
+}
+
+static int netc_init_ntmp_bitmap_sizes(struct netc_switch *priv)
+{
+       u32 num_ports = netc_num_available_ports(priv);
+       struct netc_switch_regs *regs = &priv->regs;
+       struct ntmp_user *ntmp = &priv->ntmp;
+       u32 val;
+
+       if (!num_ports)
+               return -EINVAL;
+
+       val = netc_base_rd(regs, NETC_ETTCAPR);
+       ntmp->ett_bitmap_size = NETC_GET_NUM_ENTRIES(val) / num_ports;
+       if (!ntmp->ett_bitmap_size)
+               return -EINVAL;
+
+       val = netc_base_rd(regs, NETC_ECTCAPR);
+       ntmp->ect_bitmap_size = NETC_GET_NUM_ENTRIES(val) / num_ports;
+       if (!ntmp->ect_bitmap_size)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int netc_init_ntmp_bitmaps(struct netc_switch *priv)
+{
+       struct ntmp_user *ntmp = &priv->ntmp;
+
+       ntmp->ett_gid_bitmap = bitmap_zalloc(ntmp->ett_bitmap_size,
+                                            GFP_KERNEL);
+       if (!ntmp->ett_gid_bitmap)
+               return -ENOMEM;
+
+       ntmp->ect_gid_bitmap = bitmap_zalloc(ntmp->ect_bitmap_size,
+                                            GFP_KERNEL);
+       if (!ntmp->ect_gid_bitmap)
+               goto free_ett_gid_bitmap;
+
+       return 0;
+
+free_ett_gid_bitmap:
+       bitmap_free(ntmp->ett_gid_bitmap);
+       ntmp->ett_gid_bitmap = NULL;
+
+       return -ENOMEM;
+}
+
+static void netc_free_ntmp_bitmaps(struct netc_switch *priv)
+{
+       struct ntmp_user *ntmp = &priv->ntmp;
+
+       bitmap_free(ntmp->ect_gid_bitmap);
+       ntmp->ect_gid_bitmap = NULL;
+
+       bitmap_free(ntmp->ett_gid_bitmap);
+       ntmp->ett_gid_bitmap = NULL;
+}
+
 static int netc_init_ntmp_user(struct netc_switch *priv)
 {
+       int err;
+
        netc_init_ntmp_tbl_versions(priv);
 
-       return netc_init_all_cbdrs(priv);
+       err = netc_init_ntmp_bitmap_sizes(priv);
+       if (err)
+               return err;
+
+       err = netc_init_ntmp_bitmaps(priv);
+       if (err)
+               return err;
+
+       err = netc_init_all_cbdrs(priv);
+       if (err)
+               goto free_ntmp_bitmaps;
+
+       return 0;
+
+free_ntmp_bitmaps:
+       netc_free_ntmp_bitmaps(priv);
+
+       return err;
 }
 
 static void netc_free_ntmp_user(struct netc_switch *priv)
 {
        netc_remove_all_cbdrs(priv);
+       netc_free_ntmp_bitmaps(priv);
 }
 
 static void netc_switch_dos_default_config(struct netc_switch *priv)
index 1d976882a6cc3b287fd3161e7e7c07c80f740da8..1404ae41c7bcbbe1ea87bb8c4ab5d9aef74c8516 100644 (file)
 #define  DOSL3CR_SAMEADDR              BIT(0)
 #define  DOSL3CR_IPSAMCC               BIT(1)
 
+#define NETC_ETTCAPR                   0x18c4
+#define NETC_ECTCAPR                   0x18ec
+/* Index table NUM_ENTRIES mask */
+#define NETC_NUM_ENTRIES               GENMASK(15, 0)
+#define NETC_GET_NUM_ENTRIES(v)                FIELD_GET(NETC_NUM_ENTRIES, (v))
+
 /* Hash table memory capability register, the memory is shared by
  * the following tables:
  *
index 1222901f48a78a079290a60fcbee66026cadbcc1..e8b1bd802f1934adb6746113b32a139bd15dd536 100644 (file)
@@ -3,6 +3,7 @@
 #ifndef __NETC_NTMP_H
 #define __NETC_NTMP_H
 
+#include <linux/bitmap.h>
 #include <linux/bitops.h>
 #include <linux/if_ether.h>
 
@@ -70,6 +71,12 @@ struct ntmp_user {
        struct device *dev;
        struct netc_cbdr *ring;
        struct netc_tbl_vers tbl;
+
+       /* NTMP table bitmaps for resource management */
+       u32 ett_bitmap_size;
+       u32 ect_bitmap_size;
+       unsigned long *ett_gid_bitmap; /* only valid for switch */
+       unsigned long *ect_gid_bitmap; /* only valid for switch */
 };
 
 struct maft_entry_data {