The VLAN filter table contains configuration and control information for
each VLAN configured on the switch. Each VLAN entry includes the VLAN
port membership, which FID to use in the FDB lookup, which spanning tree
group to use, the egress frame modification actions to apply to a frame
exiting form this VLAN, and various configuration and control parameters
for this VLAN.

The VLAN filter table can only be managed by the command BD ring using
table management protocol version 2.0. The table supports Add, Delete,
Update and Query operations. And the table supports 3 access methods:
Entry ID, Exact Match Key Element and Search. But currently we only add
the ntmp_vft_add_entry() helper to support the upcoming switch driver to
add an entry to the VLAN filter table. Other interfaces will be added in
the future.

Signed-off-by: Wei Fang <[email protected]>
---
 drivers/net/ethernet/freescale/enetc/ntmp.c   | 50 +++++++++++++++++++
 .../ethernet/freescale/enetc/ntmp_private.h   | 19 +++++++
 include/linux/fsl/ntmp.h                      | 30 +++++++++++
 3 files changed, 99 insertions(+)

diff --git a/drivers/net/ethernet/freescale/enetc/ntmp.c 
b/drivers/net/ethernet/freescale/enetc/ntmp.c
index f6f4316169b6..e8c94157ceb1 100644
--- a/drivers/net/ethernet/freescale/enetc/ntmp.c
+++ b/drivers/net/ethernet/freescale/enetc/ntmp.c
@@ -21,6 +21,7 @@
 #define NTMP_MAFT_ID                   1
 #define NTMP_RSST_ID                   3
 #define NTMP_FDBT_ID                   15
+#define NTMP_VFT_ID                    18
 
 /* Generic Update Actions for most tables */
 #define NTMP_GEN_UA_CFGEU              BIT(0)
@@ -231,6 +232,8 @@ static const char *ntmp_table_name(int tbl_id)
                return "RSS Table";
        case NTMP_FDBT_ID:
                return "FDB Table";
+       case NTMP_VFT_ID:
+               return "VLAN Filter Table";
        default:
                return "Unknown Table";
        }
@@ -652,5 +655,52 @@ int ntmp_fdbt_search_port_entry(struct ntmp_user *user, 
int port,
 }
 EXPORT_SYMBOL_GPL(ntmp_fdbt_search_port_entry);
 
+/**
+ * ntmp_vft_add_entry - add an entry into the VLAN filter table
+ * @user: target ntmp_user struct
+ * @vid: VLAN ID
+ * @cfge: configuration element data
+ *
+ * Return: 0 on success, otherwise a negative error code
+ */
+int ntmp_vft_add_entry(struct ntmp_user *user, u16 vid,
+                      const struct vft_cfge_data *cfge)
+{
+       struct ntmp_dma_buf data = {
+               .dev = user->dev,
+               .size = sizeof(struct vft_req_ua),
+       };
+       struct vft_req_ua *req;
+       union netc_cbd cbd;
+       u32 len;
+       int err;
+
+       err = ntmp_alloc_data_mem(&data, (void **)&req);
+       if (err)
+               return err;
+
+       /* Request data */
+       ntmp_fill_crd(&req->crd, user->tbl.vft_ver, 0,
+                     NTMP_GEN_UA_CFGEU);
+       req->ak.exact.vid = cpu_to_le16(vid);
+       req->cfge = *cfge;
+
+       /* Request header */
+       len = NTMP_LEN(data.size, NTMP_STATUS_RESP_LEN);
+       ntmp_fill_request_hdr(&cbd, data.dma, len, NTMP_VFT_ID,
+                             NTMP_CMD_ADD, NTMP_AM_EXACT_KEY);
+
+       err = netc_xmit_ntmp_cmd(user, &cbd);
+       if (err)
+               dev_err(user->dev,
+                       "Failed to add %s entry, vid: %u, err: %pe\n",
+                       ntmp_table_name(NTMP_VFT_ID), vid, ERR_PTR(err));
+
+       ntmp_free_data_mem(&data);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(ntmp_vft_add_entry);
+
 MODULE_DESCRIPTION("NXP NETC Library");
 MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/ethernet/freescale/enetc/ntmp_private.h 
b/drivers/net/ethernet/freescale/enetc/ntmp_private.h
index 9e2a18cf3507..8f94572eaf0d 100644
--- a/drivers/net/ethernet/freescale/enetc/ntmp_private.h
+++ b/drivers/net/ethernet/freescale/enetc/ntmp_private.h
@@ -160,4 +160,23 @@ struct fdbt_resp_query {
        u8 resv[3];
 };
 
+/* Access Key Format of VLAN Filter Table */
+struct vft_ak_exact {
+       __le16 vid; /* bit0~11: VLAN ID, other bits are reserved */
+       __le16 resv;
+};
+
+union vft_access_key {
+       __le32 entry_id; /* entry_id match */
+       struct vft_ak_exact exact;
+       __le32 resume_entry_id; /* search */
+};
+
+/* VLAN Filter Table Request Data Buffer Format of Update and Add actions */
+struct vft_req_ua {
+       struct ntmp_cmn_req_data crd;
+       union vft_access_key ak;
+       struct vft_cfge_data cfge;
+};
+
 #endif
diff --git a/include/linux/fsl/ntmp.h b/include/linux/fsl/ntmp.h
index ba56d4ae0ff4..6fb2c8c525de 100644
--- a/include/linux/fsl/ntmp.h
+++ b/include/linux/fsl/ntmp.h
@@ -32,6 +32,7 @@ struct netc_tbl_vers {
        u8 maft_ver;
        u8 rsst_ver;
        u8 fdbt_ver;
+       u8 vft_ver;
 };
 
 struct netc_cbdr {
@@ -94,6 +95,27 @@ struct fdbt_entry_data {
 #define FDBT_ACT_FLAG          BIT(7)
 };
 
+struct vft_cfge_data {
+       __le32 bitmap_stg;
+#define VFT_PORT_MEMBERSHIP    GENMASK(23, 0)
+#define VFT_STG_ID_MASK                GENMASK(27, 24)
+#define VFT_STG_ID(g)          FIELD_PREP(VFT_STG_ID_MASK, (g))
+       __le16 fid;
+#define VFT_FID                        GENMASK(11, 0)
+       __le16 cfg;
+#define VFT_MLO                        GENMASK(2, 0)
+#define VFT_MFO                        GENMASK(4, 3)
+#define VFT_IPMFE              BIT(6)
+#define VFT_IPMFLE             BIT(7)
+#define VFT_PGA                        BIT(8)
+#define VFT_SFDA               BIT(10)
+#define VFT_OSFDA              BIT(11)
+#define VFT_FDBAFSS            BIT(12)
+       __le32 eta_port_bitmap;
+#define VFT_ETA_PORT_BITMAP    GENMASK(23, 0)
+       __le32 et_eid;
+};
+
 #if IS_ENABLED(CONFIG_NXP_NETC_LIB)
 int ntmp_init_cbdr(struct netc_cbdr *cbdr, struct device *dev,
                   const struct netc_cbdr_regs *regs);
@@ -118,6 +140,8 @@ int ntmp_fdbt_delete_entry(struct ntmp_user *user, u32 
entry_id);
 int ntmp_fdbt_search_port_entry(struct ntmp_user *user, int port,
                                u32 *resume_entry_id,
                                struct fdbt_entry_data *entry);
+int ntmp_vft_add_entry(struct ntmp_user *user, u16 vid,
+                      const struct vft_cfge_data *cfge);
 #else
 static inline int ntmp_init_cbdr(struct netc_cbdr *cbdr, struct device *dev,
                                 const struct netc_cbdr_regs *regs)
@@ -183,6 +207,12 @@ static inline int ntmp_fdbt_search_port_entry(struct 
ntmp_user *user, int port,
        return 0;
 }
 
+static inline int ntmp_vft_add_entry(struct ntmp_user *user, u16 vid,
+                                    const struct vft_cfge_data *cfge)
+{
+       return 0;
+}
+
 #endif
 
 #endif
-- 
2.34.1


Reply via email to