This patch adds fdir config operation, including set fdir filter, normal filter, set and clear fdir tcam.
Signed-off-by: Xiaoyun wang <cloud.wangxiao...@huawei.com> --- drivers/net/hinic/base/hinic_pmd_cmd.h | 2 + drivers/net/hinic/base/hinic_pmd_niccfg.c | 205 ++++++++++++++++++++++++++++++ drivers/net/hinic/base/hinic_pmd_niccfg.h | 134 +++++++++++++++++++ 3 files changed, 341 insertions(+) diff --git a/drivers/net/hinic/base/hinic_pmd_cmd.h b/drivers/net/hinic/base/hinic_pmd_cmd.h index 5c38b5f..6b3dcf3 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 054925c..53d981b 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; +}; + /** * hinic_init_function_table - Initialize function table. * @@ -1662,3 +1679,191 @@ int hinic_vf_get_default_cos(struct hinic_hwdev *hwdev, u8 *cos_id) return 0; } + +/** + * hinic_set_fdir_filter - Set fdir filter for control path + * packet to notify firmware. + * + * @param hwdev + * The hardware interface of a nic device. + * @param filter_type + * Packet type to filter. + * @param qid + * Rx qid to filter. + * @param type_enable + * The status of pkt type filter. + * @param enable + * Fdir function Enable or Disable. + * @return + * 0 on success, + * negative error value otherwise. + */ +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; + + 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; +} + +/** + * hinic_set_normal_filter - Set fdir filter for IO path packet. + * + * @param hwdev + * The hardware interface of a nic device. + * @param qid + * Rx qid to filter. + * @param normal_type_enable + * IO path packet function Enable or Disable + * @param key + * IO path packet filter key value, such as DIP from pkt. + * @param enable + * Fdir function Enable or Disable. + * @param flag + * Filter flag, such as dip or others. + * @return + * 0 on success, + * negative error value otherwise. + */ +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; + + 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; +} + +/** + * hinic_set_fdir_tcam - Set fdir filter for control packet + * by tcam table to notify hardware. + * + * @param hwdev + * The hardware interface of a nic device. + * @param type_mask + * Index of TCAM. + * @param filter_rule + * TCAM rule for control packet, such as lacp or bgp. + * @param filter_action + * TCAM action for control packet, such as accept or drop. + * @return + * 0 on success, + * negative error value otherwise. + */ +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; + + 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; +} + +/** + * hinic_clear_fdir_tcam - Clear fdir filter TCAM table for control packet. + * + * @param hwdev + * The hardware interface of a nic device. + * @param type_mask + * Index of TCAM. + * @return + * 0 on success, + * negative error value otherwise. + */ +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 d19a834..e8ce332 100644 --- a/drivers/net/hinic/base/hinic_pmd_niccfg.h +++ b/drivers/net/hinic/base/hinic_pmd_niccfg.h @@ -609,6 +609,129 @@ 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); @@ -702,4 +825,15 @@ 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