diff --git a/drivers/net/ethernet/freescale/enetc/ntmp.c b/drivers/net/ethernet/freescale/enetc/ntmp.c index 6074eeafd5a2..db74a9107975 100644 --- a/drivers/net/ethernet/freescale/enetc/ntmp.c +++ b/drivers/net/ethernet/freescale/enetc/ntmp.c @@ -22,6 +22,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) @@ -268,6 +269,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"; } @@ -699,5 +702,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 netc_swcbd swcbd; + struct vft_req_ua *req; + struct netc_cbdr *cbdr; + union netc_cbd cbd; + u32 len; + int err; + + swcbd.size = sizeof(*req); + err = ntmp_alloc_data_mem(user->dev, &swcbd, (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(swcbd.size, NTMP_STATUS_RESP_LEN); + ntmp_fill_request_hdr(&cbd, swcbd.dma, len, NTMP_VFT_ID, + NTMP_CMD_ADD, NTMP_AM_EXACT_KEY); + + ntmp_select_and_lock_cbdr(user, &cbdr); + err = netc_xmit_ntmp_cmd(cbdr, &cbd, &swcbd); + 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_unlock_cbdr(cbdr); + + 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 b0b5805ac4f6..575ee783be47 100644 --- a/drivers/net/ethernet/freescale/enetc/ntmp_private.h +++ b/drivers/net/ethernet/freescale/enetc/ntmp_private.h @@ -156,4 +156,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 4cfff835954e..3672e0dc7726 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_swcbd { @@ -101,6 +102,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); @@ -125,6 +147,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)