+ return -EIO;
+ }
+
+ return 0;
+}
+
+/**
+ * hinic_vf_get_default_cos - Get default cos of VF.
+ *
+ * @param hwdev
+ * The hardware interface of a nic device.
+ * @param cos_id
+ * Cos value.
+ *
+ * @return
+ * 0 on success.
+ * negative error value otherwise.
+ */
+int hinic_vf_get_default_cos(struct hinic_hwdev *hwdev, u8 *cos_id)
+{
+ struct hinic_vf_default_cos vf_cos;
+ u16 out_size = sizeof(vf_cos);
+ int err;
+
+ memset(&vf_cos, 0, sizeof(vf_cos));
+ vf_cos.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
+
+ err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC,
+ HINIC_PORT_CMD_GET_VF_COS, &vf_cos,
+ sizeof(vf_cos), &vf_cos, &out_size, 0);
+ if (err || !out_size || vf_cos.mgmt_msg_head.status) {
+ PMD_DRV_LOG(ERR, "Get VF default cos failed, err: %d, status: 0x%x, out size: 0x%x",
+ err, vf_cos.mgmt_msg_head.status, out_size);
+ return -EIO;
+ }
+ *cos_id = vf_cos.state.default_cos;
+
+ 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 -EIO;
+ }
+
+ 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 -EIO;
+ }
+
+ 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",
+ err, port_tcam_cmd.mgmt_msg_head.status, out_size);
+ return -EIO;
+ }
+
+ 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",
+ err, port_tcam_cmd.mgmt_msg_head.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int hinic_add_tcam_rule(void *hwdev, struct tag_tcam_cfg_rule *tcam_rule)
+{
+ u16 out_size = sizeof(struct tag_fdir_add_rule_cmd);
+ struct tag_fdir_add_rule_cmd tcam_cmd;
+ int err;
+
+ if (!hwdev) {
+ PMD_DRV_LOG(ERR, "Hwdev is NULL");
+ return -EINVAL;
+ }
+
+ if (tcam_rule->index >= HINIC_MAX_TCAM_RULES_NUM) {
+ PMD_DRV_LOG(ERR, "Tcam rules num to add is invalid");
+ return -EINVAL;
+ }
+
+ memset(&tcam_cmd, 0, sizeof(struct tag_fdir_add_rule_cmd));
+ tcam_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
+ memcpy((void *)&tcam_cmd.rule, (void *)tcam_rule,
+ sizeof(struct tag_tcam_cfg_rule));
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_UP_TC_ADD_FLOW,
+ &tcam_cmd, sizeof(tcam_cmd),
+ &tcam_cmd, &out_size);
+ if (err || tcam_cmd.mgmt_msg_head.status || !out_size) {
+ PMD_DRV_LOG(ERR,
+ "Add tcam rule failed, err: %d, status: 0x%x, out size: 0x%x",
+ err, tcam_cmd.mgmt_msg_head.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int hinic_del_tcam_rule(void *hwdev, u32 index)
+{
+ u16 out_size = sizeof(struct tag_fdir_del_rule_cmd);
+ struct tag_fdir_del_rule_cmd tcam_cmd;
+ int err;
+
+ if (!hwdev) {
+ PMD_DRV_LOG(ERR, "Hwdev is NULL");
+ return -EINVAL;
+ }
+
+ if (index >= HINIC_MAX_TCAM_RULES_NUM) {
+ PMD_DRV_LOG(ERR, "Tcam rules num to del is invalid");
+ return -EINVAL;
+ }
+
+ memset(&tcam_cmd, 0, sizeof(struct tag_fdir_del_rule_cmd));
+ tcam_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
+ tcam_cmd.index_start = index;
+ tcam_cmd.index_num = 1;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_UP_TC_DEL_FLOW,
+ &tcam_cmd, sizeof(tcam_cmd),
+ &tcam_cmd, &out_size);
+ if (err || tcam_cmd.mgmt_msg_head.status || !out_size) {
+ PMD_DRV_LOG(ERR,
+ "Del tcam rule failed, err: %d, status: 0x%x, out size: 0x%x",
+ err, tcam_cmd.mgmt_msg_head.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int hinic_mgmt_tcam_block(void *hwdev, u8 alloc_en,
+ u8 block_type, u16 *index)
+{
+ struct hinic_cmd_ctrl_tcam_block tcam_block_info;
+ u16 out_size = sizeof(struct hinic_cmd_ctrl_tcam_block);
+ struct hinic_hwdev *nic_hwdev = (struct hinic_hwdev *)hwdev;
+ int err;
+
+ if (!hwdev) {
+ PMD_DRV_LOG(ERR, "Hwdev is NULL");