The ingress port filter table (IPFT )contains a set of filters each
capable of classifying incoming traffic using a mix of L2, L3, and L4
parsed and arbitrary field data. As a result of a filter match, several
actions can be specified such as on whether to deny or allow a frame,
overriding internal QoS attributes associated with the frame and setting
parameters for the subsequent frame processing functions, such as stream
identification, policing, ingress mirroring. Each entry corresponds to a
filter. The ingress port filter entries are added using a precedence
value. If a frame matches multiple entries, the entry with the higher
precedence is used. Currently, this patch only adds "Add" and "Delete"
operations to the ingress port filter table. These two interfaces will
be used by both ENETC driver and NETC switch driver.

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

diff --git a/drivers/net/ethernet/freescale/enetc/ntmp.c 
b/drivers/net/ethernet/freescale/enetc/ntmp.c
index ef38ebe94da8..9fc3422137fc 100644
--- a/drivers/net/ethernet/freescale/enetc/ntmp.c
+++ b/drivers/net/ethernet/freescale/enetc/ntmp.c
@@ -20,6 +20,7 @@
 /* Define NTMP Table ID */
 #define NTMP_MAFT_ID                   1
 #define NTMP_RSST_ID                   3
+#define NTMP_IPFT_ID                   13
 #define NTMP_FDBT_ID                   15
 #define NTMP_VFT_ID                    18
 #define NTMP_BPT_ID                    41
@@ -234,6 +235,8 @@ static const char *ntmp_table_name(int tbl_id)
                return "MAC Address Filter Table";
        case NTMP_RSST_ID:
                return "RSS Table";
+       case NTMP_IPFT_ID:
+               return "Ingress Port Filter Table";
        case NTMP_FDBT_ID:
                return "FDB Table";
        case NTMP_VFT_ID:
@@ -468,6 +471,79 @@ int ntmp_rsst_query_entry(struct ntmp_user *user, u32 
*table, int count)
 }
 EXPORT_SYMBOL_GPL(ntmp_rsst_query_entry);
 
+/**
+ * ntmp_ipft_add_entry - add an entry into the ingress port filter table
+ * @user: target ntmp_user struct
+ * @entry: the entry data, entry->cfge (configuration element data) and
+ * entry->keye (key element data) are used as input. Since the entry ID
+ * is assigned by the hardware, so entry->entry_id is a returned value
+ * for the driver to use, the driver can update/delete/query the entry
+ * based on the entry_id.
+ *
+ * Return: 0 on success, otherwise a negative error code
+ */
+int ntmp_ipft_add_entry(struct ntmp_user *user,
+                       struct ipft_entry_data *entry)
+{
+       struct ntmp_dma_buf data = {
+               .dev = user->dev,
+               .size = sizeof(struct ipft_resp_query),
+       };
+       struct ipft_resp_query *resp;
+       struct ipft_req_ua *req;
+       union netc_cbd cbd;
+       u32 len;
+       int err;
+
+       err = ntmp_alloc_data_mem(&data, (void **)&req);
+       if (err)
+               return err;
+
+       ntmp_fill_crd(&req->crd, user->tbl.ipft_ver, NTMP_QA_ENTRY_ID,
+                     NTMP_GEN_UA_CFGEU | NTMP_GEN_UA_STSEU);
+       req->ak.keye = entry->keye;
+       req->cfge = entry->cfge;
+
+       len = NTMP_LEN(sizeof(*req), data.size);
+       ntmp_fill_request_hdr(&cbd, data.dma, len, NTMP_IPFT_ID,
+                             NTMP_CMD_AQ, NTMP_AM_TERNARY_KEY);
+
+       err = netc_xmit_ntmp_cmd(user, &cbd);
+       if (err) {
+               dev_err(user->dev, "Failed to add %s entry, err: %pe\n",
+                       ntmp_table_name(NTMP_IPFT_ID), ERR_PTR(err));
+
+               goto end;
+       }
+
+       resp = (struct ipft_resp_query *)req;
+       entry->entry_id = le32_to_cpu(resp->entry_id);
+
+end:
+       ntmp_free_data_mem(&data);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(ntmp_ipft_add_entry);
+
+/**
+ * ntmp_ipft_delete_entry - delete a specified ingress port filter table entry
+ * @user: target ntmp_user struct
+ * @entry_id: the specified ID of the ingress port filter table entry
+ *
+ * Return: 0 on success, otherwise a negative error code
+ */
+int ntmp_ipft_delete_entry(struct ntmp_user *user, u32 entry_id)
+{
+       u32 req_len = sizeof(struct ipft_req_qd);
+
+       return ntmp_delete_entry_by_id(user, NTMP_IPFT_ID,
+                                      user->tbl.ipft_ver,
+                                      entry_id, req_len,
+                                      NTMP_STATUS_RESP_LEN);
+}
+EXPORT_SYMBOL_GPL(ntmp_ipft_delete_entry);
+
 /**
  * ntmp_fdbt_add_entry - add an entry into the FDB table
  * @user: target ntmp_user struct
diff --git a/drivers/net/ethernet/freescale/enetc/ntmp_private.h 
b/drivers/net/ethernet/freescale/enetc/ntmp_private.h
index c5f6dca7b660..9411ec9f1777 100644
--- a/drivers/net/ethernet/freescale/enetc/ntmp_private.h
+++ b/drivers/net/ethernet/freescale/enetc/ntmp_private.h
@@ -103,6 +103,42 @@ struct rsst_req_update {
        u8 groups[];
 };
 
+/* Ingress Port Filter Table Response Data Buffer Format of Query action */
+struct ipft_resp_query {
+       __le32 status;
+       __le32 entry_id;
+       struct ipft_keye_data keye;
+       __le64 match_count; /* STSE_DATA */
+       struct ipft_cfge_data cfge;
+} __packed;
+
+struct ipft_ak_eid {
+       __le32 entry_id;
+       __le32 resv[52];
+};
+
+union ipft_access_key {
+       struct ipft_ak_eid eid;
+       struct ipft_keye_data keye;
+};
+
+/* Ingress Port Filter Table Request Data Buffer Format of Update and
+ * Add actions
+ */
+struct ipft_req_ua {
+       struct ntmp_cmn_req_data crd;
+       union ipft_access_key ak;
+       struct ipft_cfge_data cfge;
+};
+
+/* Ingress Port Filter Table Request Data Buffer Format of Query and
+ * Delete actions
+ */
+struct ipft_req_qd {
+       struct ntmp_req_by_eid rbe;
+       __le32 resv[52];
+};
+
 /* Access Key Format of FDB Table */
 struct fdbt_ak_eid {
        __le32 entry_id;
diff --git a/include/linux/fsl/ntmp.h b/include/linux/fsl/ntmp.h
index 925a455935b0..f6d3bb2e318d 100644
--- a/include/linux/fsl/ntmp.h
+++ b/include/linux/fsl/ntmp.h
@@ -7,6 +7,7 @@
 #include <linux/if_ether.h>
 
 #define NTMP_NULL_ENTRY_ID             0xffffffffU
+#define IPFT_MAX_PLD_LEN               24
 
 struct maft_keye_data {
        u8 mac_addr[ETH_ALEN];
@@ -34,6 +35,7 @@ struct netc_tbl_vers {
        u8 fdbt_ver;
        u8 vft_ver;
        u8 bpt_ver;
+       u8 ipft_ver;
 };
 
 struct netc_cbdr {
@@ -66,6 +68,94 @@ struct maft_entry_data {
        struct maft_cfge_data cfge;
 };
 
+struct ipft_pld_byte {
+       u8 data;
+       u8 mask;
+};
+
+struct ipft_keye_data {
+       __le16 precedence;
+       __le16 resv0[3];
+       __le16 frm_attr_flags;
+#define IPFT_FAF_OVLAN         BIT(2)
+#define IPFT_FAF_IVLAN         BIT(3)
+#define IPFT_FAF_IP_HDR                BIT(7)
+#define IPFT_FAF_IP_VER6       BIT(8)
+#define IPFT_FAF_L4_CODE       GENMASK(11, 10)
+#define  IPFT_FAF_TCP_HDR      1
+#define  IPFT_FAF_UDP_HDR      2
+#define  IPFT_FAF_SCTP_HDR     3
+#define IPFT_FAF_WOL_MAGIC     BIT(12)
+       __le16 frm_attr_flags_mask;
+       __le16 dscp;
+#define IPFT_DSCP              GENMASK(5, 0)
+#define IPFT_DSCP_MASK         GENMASK(11, 0)
+#define IPFT_DSCP_MASK_ALL     0x3f
+       __le16 src_port; /* This field is reserved for ENETC */
+#define IPFT_SRC_PORT          GENMASK(4, 0)
+#define IPFT_SRC_PORT_MASK     GENMASK(9, 5)
+#define IPFT_SRC_PORT_MASK_ALL 0x1f
+       __be16 outer_vlan_tci;
+       __be16 outer_vlan_tci_mask;
+       u8 dmac[ETH_ALEN];
+       u8 dmac_mask[ETH_ALEN];
+       u8 smac[ETH_ALEN];
+       u8 smac_mask[ETH_ALEN];
+       __be16 inner_vlan_tci;
+       __be16 inner_vlan_tci_mask;
+       __be16 ethertype;
+       __be16 ethertype_mask;
+       u8 ip_protocol;
+       u8 ip_protocol_mask;
+       __le16 resv1[7];
+       __be32 ip_src[4];
+       __le32 resv2[2];
+       __be32 ip_src_mask[4];
+       __be16 l4_src_port;
+       __be16 l4_src_port_mask;
+       __le32 resv3;
+       __be32 ip_dst[4];
+       __le32 resv4[2];
+       __be32 ip_dst_mask[4];
+       __be16 l4_dst_port;
+       __be16 l4_dst_port_mask;
+       __le32 resv5;
+       struct ipft_pld_byte byte[IPFT_MAX_PLD_LEN];
+};
+
+struct ipft_cfge_data {
+       __le32 cfg;
+#define IPFT_IPV               GENMASK(3, 0)
+#define IPFT_OIPV              BIT(4)
+#define IPFT_DR                        GENMASK(6, 5)
+#define IPFT_ODR               BIT(7)
+#define IPFT_FLTFA             GENMASK(10, 8)
+#define  IPFT_FLTFA_DISCARD    0
+#define  IPFT_FLTFA_PERMIT     1
+/* Redirect is only for switch */
+#define  IPFT_FLTFA_REDIRECT   2
+#define IPFT_IMIRE             BIT(11)
+#define IPFT_WOLTE             BIT(12)
+#define IPFT_FLTA              GENMASK(14, 13)
+#define  IPFT_FLTA_RP          1
+#define  IPFT_FLTA_IS          2
+#define  IPFT_FLTA_SI_BITMAP   3
+#define IPFT_RPR               GENMASK(16, 15)
+#define IPFT_CTD               BIT(17)
+#define IPFT_HR                        GENMASK(21, 18)
+#define IPFT_TIMECAPE          BIT(22)
+#define IPFT_RRT               BIT(23)
+#define IPFT_BL2F              BIT(24)
+#define IPFT_EVMEID            GENMASK(31, 28)
+       __le32 flta_tgt;
+};
+
+struct ipft_entry_data {
+       u32 entry_id; /* hardware assigns entry ID */
+       struct ipft_keye_data keye;
+       struct ipft_cfge_data cfge;
+};
+
 struct fdbt_keye_data {
        u8 mac_addr[ETH_ALEN]; /* big-endian */
        __le16 resv0;
@@ -155,6 +245,9 @@ int ntmp_rsst_update_entry(struct ntmp_user *user, const 
u32 *table,
                           int count);
 int ntmp_rsst_query_entry(struct ntmp_user *user,
                          u32 *table, int count);
+int ntmp_ipft_add_entry(struct ntmp_user *user,
+                       struct ipft_entry_data *entry);
+int ntmp_ipft_delete_entry(struct ntmp_user *user, u32 entry_id);
 int ntmp_fdbt_add_entry(struct ntmp_user *user, u32 *entry_id,
                        const struct fdbt_keye_data *keye,
                        const struct fdbt_cfge_data *cfge);
@@ -208,6 +301,17 @@ static inline int ntmp_rsst_query_entry(struct ntmp_user 
*user,
        return 0;
 }
 
+static inline int ntmp_ipft_add_entry(struct ntmp_user *user,
+                                     struct ipft_entry_data *entry)
+{
+       return 0;
+}
+
+static inline int ntmp_ipft_delete_entry(struct ntmp_user *user, u32 entry_id)
+{
+       return 0;
+}
+
 static inline int ntmp_fdbt_add_entry(struct ntmp_user *user, u32 *entry_id,
                                      const struct fdbt_keye_data *keye,
                                      const struct fdbt_cfge_data *data)
-- 
2.34.1


Reply via email to