From: Xiaoyun Wang <cloud.wangxiao...@huawei.com>

Add fdir config operation, including set fdir filter,
normal filter, set and clear fdir tcam.

Signed-off-by: Ziyang Xuan <xuanziya...@huawei.com>
---
 drivers/net/hinic/base/hinic_pmd_cmd.h    |   2 +
 drivers/net/hinic/base/hinic_pmd_niccfg.c | 157 ++++++++++++++++++++++++++++++
 drivers/net/hinic/base/hinic_pmd_niccfg.h | 136 ++++++++++++++++++++++++++
 3 files changed, 295 insertions(+)

diff --git a/drivers/net/hinic/base/hinic_pmd_cmd.h 
b/drivers/net/hinic/base/hinic_pmd_cmd.h
index d945694..7b5556a 100644
--- a/drivers/net/hinic/base/hinic_pmd_cmd.h
+++ b/drivers/net/hinic/base/hinic_pmd_cmd.h
@@ -140,6 +140,8 @@ enum hinic_port_cmd {
 
        HINIC_PORT_CMD_SET_VHD_CFG              = 0xF7,
        HINIC_PORT_CMD_SET_LINK_FOLLOW          = 0xF8,
+       HINIC_PORT_CMD_Q_FILTER                 = 0xFC,
+       HINIC_PORT_CMD_TCAM_FILTER              = 0xFE,
        HINIC_PORT_CMD_SET_VLAN_FILTER          = 0xFF
 };
 
diff --git a/drivers/net/hinic/base/hinic_pmd_niccfg.c 
b/drivers/net/hinic/base/hinic_pmd_niccfg.c
index 540f09a..1f504b0 100644
--- a/drivers/net/hinic/base/hinic_pmd_niccfg.c
+++ b/drivers/net/hinic/base/hinic_pmd_niccfg.c
@@ -18,6 +18,23 @@
                        buf_in, in_size,                        \
                        buf_out, out_size, 0)
 
+
+#define TCAM_SET       0x1
+#define TCAM_CLEAR     0x2
+
+struct hinic_port_qfilter_info {
+       struct hinic_mgmt_msg_head mgmt_msg_head;
+
+       u16 func_id;
+       u8 normal_type_enable;
+       u8 filter_type_enable;
+       u8 filter_enable;
+       u8 filter_type;
+       u8 qid;
+       u8 fdir_flag;
+       u32 key;
+};
+
 int hinic_init_function_table(void *hwdev, u16 rx_buf_sz)
 {
        struct hinic_function_table function_table;
@@ -1492,3 +1509,143 @@ int hinic_vf_get_default_cos(struct hinic_hwdev *hwdev, 
u8 *cos_id)
 
        return 0;
 }
+
+int hinic_set_fdir_filter(void *hwdev, u8 filter_type, u8 qid, u8 type_enable,
+                               bool enable)
+{
+       struct hinic_port_qfilter_info port_filer_cmd;
+       u16 out_size = sizeof(port_filer_cmd);
+       int err;
+
+       if (!hwdev)
+               return -EINVAL;
+
+       if (hinic_func_type(hwdev) == TYPE_VF) {
+               PMD_DRV_LOG(WARNING, "VF don't support FDIR");
+               return 0;
+       }
+
+       memset(&port_filer_cmd, 0, sizeof(port_filer_cmd));
+       port_filer_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
+       port_filer_cmd.func_id = hinic_global_func_id(hwdev);
+       port_filer_cmd.filter_enable = (u8)enable;
+       port_filer_cmd.filter_type = filter_type;
+       port_filer_cmd.qid = qid;
+       port_filer_cmd.filter_type_enable = type_enable;
+       port_filer_cmd.fdir_flag = 0;
+
+       err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_Q_FILTER,
+                       &port_filer_cmd, sizeof(port_filer_cmd),
+                       &port_filer_cmd, &out_size);
+       if (err || !out_size || port_filer_cmd.mgmt_msg_head.status) {
+               PMD_DRV_LOG(ERR, "Set port Q filter failed, err: %d, status: 
0x%x, out size: 0x%x, type: 0x%x,"
+                       " enable: 0x%x, qid: 0x%x, filter_type_enable: 0x%x\n",
+                       err, port_filer_cmd.mgmt_msg_head.status, out_size,
+                       filter_type, enable, qid, type_enable);
+               return -EFAULT;
+       }
+
+       return 0;
+}
+
+int hinic_set_normal_filter(void *hwdev, u8 qid, u8 normal_type_enable,
+                               u32 key, bool enable, u8 flag)
+{
+       struct hinic_port_qfilter_info port_filer_cmd;
+       u16 out_size = sizeof(port_filer_cmd);
+       int err;
+
+       if (!hwdev)
+               return -EINVAL;
+
+       if (hinic_func_type(hwdev) == TYPE_VF) {
+               PMD_DRV_LOG(WARNING, "VF don't support FDIR");
+               return 0;
+       }
+
+       memset(&port_filer_cmd, 0, sizeof(port_filer_cmd));
+       port_filer_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
+       port_filer_cmd.func_id = hinic_global_func_id(hwdev);
+       port_filer_cmd.filter_enable = (u8)enable;
+       port_filer_cmd.qid = qid;
+       port_filer_cmd.normal_type_enable = normal_type_enable;
+       port_filer_cmd.fdir_flag = flag; /* fdir flag: support dip */
+       port_filer_cmd.key = key;
+
+       err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_Q_FILTER,
+                       &port_filer_cmd, sizeof(port_filer_cmd),
+                       &port_filer_cmd, &out_size);
+       if (err || !out_size || port_filer_cmd.mgmt_msg_head.status) {
+               PMD_DRV_LOG(ERR, "Set normal filter failed, err: %d, status: 
0x%x, out size: 0x%x, fdir_flag: 0x%x,"
+                       " enable: 0x%x, qid: 0x%x, normal_type_enable: 0x%x, 
key:0x%x\n",
+                       err, port_filer_cmd.mgmt_msg_head.status, out_size,
+                       flag, enable, qid, normal_type_enable, key);
+               return -EFAULT;
+       }
+
+       return 0;
+}
+
+int hinic_set_fdir_tcam(void *hwdev, u16 type_mask,
+                       struct tag_pa_rule *filter_rule,
+                       struct tag_pa_action *filter_action)
+{
+       struct hinic_fdir_tcam_info port_tcam_cmd;
+       u16 out_size = sizeof(port_tcam_cmd);
+       int err;
+
+       if (!hwdev)
+               return -EINVAL;
+
+       if (hinic_func_type(hwdev) == TYPE_VF) {
+               PMD_DRV_LOG(WARNING, "VF don't support set Tcam table");
+               return 0;
+       }
+
+       memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
+       port_tcam_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
+       port_tcam_cmd.tcam_index = type_mask;
+       port_tcam_cmd.flag = TCAM_SET;
+       memcpy((void *)&port_tcam_cmd.filter_rule,
+               (void *)filter_rule, sizeof(struct tag_pa_rule));
+       memcpy((void *)&port_tcam_cmd.filter_action,
+               (void *)filter_action, sizeof(struct tag_pa_action));
+
+       err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_TCAM_FILTER,
+                       &port_tcam_cmd, sizeof(port_tcam_cmd),
+                       &port_tcam_cmd, &out_size);
+       if (err || !out_size || port_tcam_cmd.mgmt_msg_head.status) {
+               PMD_DRV_LOG(ERR, "Set tcam table failed, err: %d, status: 0x%x, 
out size: 0x%x\n",
+                       err, port_tcam_cmd.mgmt_msg_head.status, out_size);
+               return -EFAULT;
+       }
+
+       return 0;
+}
+
+int hinic_clear_fdir_tcam(void *hwdev, u16 type_mask)
+{
+       struct hinic_fdir_tcam_info port_tcam_cmd;
+       u16 out_size = sizeof(port_tcam_cmd);
+       int err;
+
+       if (!hwdev)
+               return -EINVAL;
+
+       memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
+       port_tcam_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
+       port_tcam_cmd.tcam_index = type_mask;
+       port_tcam_cmd.flag = TCAM_CLEAR;
+
+       err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_TCAM_FILTER,
+                       &port_tcam_cmd, sizeof(port_tcam_cmd),
+                       &port_tcam_cmd, &out_size);
+       if (err || !out_size || port_tcam_cmd.mgmt_msg_head.status) {
+               PMD_DRV_LOG(ERR, "Clear tcam table failed, err: %d, status: 
0x%x, out size: 0x%x\n",
+                       err, port_tcam_cmd.mgmt_msg_head.status, out_size);
+               return -EFAULT;
+       }
+
+       return 0;
+}
+
diff --git a/drivers/net/hinic/base/hinic_pmd_niccfg.h 
b/drivers/net/hinic/base/hinic_pmd_niccfg.h
index 0f0b078..18ac597 100644
--- a/drivers/net/hinic/base/hinic_pmd_niccfg.h
+++ b/drivers/net/hinic/base/hinic_pmd_niccfg.h
@@ -609,6 +609,130 @@ struct hinic_port_anti_attack_rate {
        u32     xbs;    /* eXtended Burst Size */
 };
 
+struct pa_u8_s {
+       u8   val8;
+       u8   mask8;
+};
+
+struct pa_u16_s {
+       u16  val16;
+       u16  mask16;
+};
+
+struct pa_u32_s {
+       u32  val32;
+       u32  mask32;
+};
+
+struct pa_u48_s {
+       u8   val8[6];
+       u8   mask8[6];
+};
+
+struct pa_u64_s {
+       u8   val8[8];
+       u8   mask8[8];
+};
+
+struct tag_pa_eth_ip_header {
+       struct pa_u8_s          ip_ver; /* 3bit */
+       struct pa_u8_s          ipv4_option_flag; /* 1bit */
+       /* 8bit ipv4 option or ipv6 next header */
+       struct pa_u8_s          protocol;
+       struct pa_u8_s          dscp;   /* 6bit DSCP */
+};
+
+struct tag_pa_common_l2_header {
+       struct pa_u48_s         dmac; /* dmac 48bit */
+       struct pa_u16_s         eth_type; /* ethernet type/length 16bit */
+       struct pa_u8_s          tag_flag; /* tag flag: 4bit */
+       struct pa_u8_s          np2np_hdr_qindex; /* NP2NP Header Qindex 4bit */
+       struct pa_u8_s          e_tag_pcp; /* 3bit */
+       struct pa_u8_s          vlan_layer; /* 2bit */
+       struct pa_u8_s          s_tag; /* 3bit */
+       struct pa_u8_s          c_tag; /* 3bit */
+       struct pa_u16_s         vlan_id; /* 12bit */
+};
+
+struct tag_pa_tcp {
+       struct pa_u16_s         sport; /* 16bit */
+       struct pa_u16_s         dport; /* 16bit */
+       struct pa_u16_s         tcp_flag; /* 6bit */
+};
+
+struct tag_pa_udp {
+       struct pa_u16_s         sport; /* 16bit */
+       struct pa_u16_s         dport; /* 16bit */
+       /* 8bit :
+        * 1.udp dport=67/68 && ipv4 protocol=0x11
+        * 2.udp dport=546/547 && ipv6 next header=0x11
+        * 3. do not care
+        */
+       struct pa_u8_s          dhcp_op_or_msg_type;
+};
+
+/* ICMP:
+ * ipv4 protocol = 0x1
+ * ipv6 next header = 0x3A
+ */
+struct tag_pa_icmp {
+       struct pa_u8_s          type; /* 8bit */
+       struct pa_u8_s          code; /* 8bit */
+};
+
+/* IGMP:
+ * ipv4 protocol = 0x2
+ */
+struct tag_pa_ipv4_igmp {
+       struct pa_u32_s         dip; /* 32bit */
+       struct pa_u8_s          type; /* 8bit */
+};
+
+struct tag_pa_rule {
+       struct pa_u8_s ncsi_flag; /* 1bit valid */
+       struct tag_pa_common_l2_header l2_header;
+
+       u8 eth_type;
+
+       struct pa_u64_s eth_other; /* eth_type=other 64bit */
+       struct pa_u8_s  eth_roce_opcode; /* eth_type=roce 8bit opcode */
+
+       struct tag_pa_eth_ip_header ip_header; /* eth_type=ip */
+
+       u8 ip_protocol_type;
+
+       struct tag_pa_tcp eth_ip_tcp; /* eth_type=ip && ip_protocol = tcp */
+       struct tag_pa_udp eth_ip_udp; /* eth_type=ip && ip_protocol = udp */
+       struct tag_pa_icmp eth_ip_icmp; /* eth_type=ip && ip_protocol = icmp */
+
+       /* eth_type=ip && ip_protocol = ipv4_igmp */
+       struct tag_pa_ipv4_igmp eth_ipv4_igmp;
+
+       /* eth_type=ip && ip_protocol = sctp;
+        * 16bit ipv4 protocol=0x84 or ipv6 nhr=0x84
+        */
+       struct pa_u16_s eth_ip_sctp;
+};
+
+struct tag_pa_action {
+       u16     pkt_type;
+       u8      err_type;
+       u8      pri;
+       u8      fwd_action;
+       u8      push_len;
+};
+
+struct hinic_fdir_tcam_info {
+       struct hinic_mgmt_msg_head mgmt_msg_head;
+
+       u16     tcam_index;
+       u8      flag; /* clear or set tcam table flag */
+       u8      rsvd1;
+       struct tag_pa_rule filter_rule;
+       struct tag_pa_action filter_action;
+};
+
+
 int hinic_set_mac(void *hwdev, u8 *mac_addr, u16 vlan_id, u16 func_id);
 
 int hinic_del_mac(void *hwdev, u8 *mac_addr, u16 vlan_id, u16 func_id);
@@ -704,4 +828,16 @@ int hinic_set_link_status_follow(void *hwdev,
 
 int hinic_vf_get_default_cos(struct hinic_hwdev *hwdev, u8 *cos_id);
 
+int hinic_set_fdir_filter(void *hwdev, u8 filter_type, u8 qid,
+               u8 type_enable, bool enable);
+
+int hinic_set_normal_filter(void *hwdev, u8 qid, u8 normal_type_enable,
+               u32 key, bool enable, u8 flag);
+
+int hinic_set_fdir_tcam(void *hwdev, u16 type_mask,
+       struct tag_pa_rule *filter_rule, struct tag_pa_action *filter_action);
+
+int hinic_clear_fdir_tcam(void *hwdev, u16 type_mask);
+
+
 #endif /* _HINIC_PMD_NICCFG_H_ */
-- 
1.8.3.1

Reply via email to