diff --git a/drivers/net/ethernet/huawei/hinic/hinic_api_cmd.c b/drivers/net/ethernet/huawei/hinic/hinic_api_cmd.c index de190ba060648f2d8ea368d84d71ce11215a5920..6ead68963cf8c303b6b834f36b9d05d7fbe0c1c9 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_api_cmd.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_api_cmd.c @@ -251,8 +251,8 @@ static void prepare_cell_ctrl(u64 *cell_ctrl, u16 cell_len) **/ static void prepare_api_cmd(struct hinic_api_cmd_chain *chain, struct hinic_api_cmd_cell *cell, - enum hinic_node_id dest, - void *cmd, u16 cmd_size) + enum hinic_node_id dest, + const void *cmd, u16 cmd_size) { struct hinic_api_cmd_cell_ctxt *cell_ctxt; u32 priv; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_cfg.c b/drivers/net/ethernet/huawei/hinic/hinic_cfg.c index fbacba16f35964f2791c443c1e8f6cd9b649da5c..6662119f684b0649cb0eeda85db3750d94095ac0 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_cfg.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_cfg.c @@ -34,6 +34,20 @@ #include "hinic_nic_cfg.h" #include "hinic_mgmt_interface.h" #include "hinic_multi_host_mgmt.h" + +uint g_rdma_mtts_num; +uint g_rdma_qps_num; +uint g_rdma_mpts_num; +uint g_vfs_num; +module_param(g_rdma_mtts_num, uint, 0444); +MODULE_PARM_DESC(g_rdma_mtts_num, "number of roce used mtts, use default value when pass 0"); +module_param(g_rdma_qps_num, uint, 0444); +MODULE_PARM_DESC(g_rdma_qps_num, "number of roce used qps, use default value when pass 0"); +module_param(g_rdma_mpts_num, uint, 0444); +MODULE_PARM_DESC(g_rdma_mpts_num, "number of roce used mpts, use default value when pass 0"); +module_param(g_vfs_num, uint, 0444); +MODULE_PARM_DESC(g_vfs_num, "number of used vfs, use default value when pass 0 "); + uint intr_mode; uint timer_enable = 1; @@ -149,6 +163,7 @@ static void parse_pub_res_cap(struct service_cap *cap, cap->cos_valid_bitmap = dev_cap->valid_cos_bitmap; cap->er_id = dev_cap->er_id; cap->port_id = dev_cap->port_id; + cap->force_up = dev_cap->force_up; parse_sf_en_cap(cap, dev_cap, type); @@ -253,6 +268,7 @@ static void parse_l2nic_res_cap(struct service_cap *cap, nic_cap->max_rqs = dev_cap->nic_max_rq; nic_cap->vf_max_sqs = 0; nic_cap->vf_max_rqs = 0; + nic_cap->max_queue_allowed = dev_cap->max_queue_allowed; } if (dev_cap->nic_lro_en) @@ -263,11 +279,12 @@ static void parse_l2nic_res_cap(struct service_cap *cap, nic_cap->lro_sz = dev_cap->nic_lro_sz; nic_cap->tso_sz = dev_cap->nic_tso_sz; - pr_info("L2nic resource capbility, max_sqs=0x%x, max_rqs=0x%x, vf_max_sqs=0x%x, vf_max_rqs=0x%x\n", + pr_info("L2nic resource capbility, max_sqs=0x%x, max_rqs=0x%x, vf_max_sqs=0x%x, vf_max_rqs=0x%x, max_queue_allowed=0x%x\n", nic_cap->max_sqs, nic_cap->max_rqs, nic_cap->vf_max_sqs, - nic_cap->vf_max_rqs); + nic_cap->vf_max_rqs, + nic_cap->max_queue_allowed); /* Check parameters from firmware */ if (nic_cap->max_sqs > HINIC_CFG_MAX_QP || @@ -557,7 +574,9 @@ static int get_cap_from_fw(struct hinic_hwdev *dev, enum func_type type) int err; dev_cap.version = HINIC_CMD_VER_FUNC_ID; - dev_cap.func_id = hinic_global_func_id(dev); + err = hinic_global_func_id_get(dev, &dev_cap.func_id); + if (err) + return err; sdk_info(dev->dev_hdl, "Get cap from fw, func_idx: %d\n", dev_cap.func_id); @@ -630,6 +649,14 @@ static int get_dev_cap(struct hinic_hwdev *dev) static void nic_param_fix(struct hinic_hwdev *dev) { + struct nic_service_cap *nic_cap = &dev->cfg_mgmt->svc_cap.nic_cap; + + if ((hinic_func_type(dev) == TYPE_VF) && + nic_cap->max_queue_allowed != 0) { + nic_cap->max_rqs = nic_cap->max_queue_allowed; + nic_cap->max_sqs = nic_cap->max_queue_allowed; + } + } static void rdma_param_fix(struct hinic_hwdev *dev) @@ -696,7 +723,8 @@ static void rdma_param_fix(struct hinic_hwdev *dev) * we use original 8bits directly for simpilification */ rdma_cap->max_fmr_maps = 255; - rdma_cap->num_mtts = RDMA_NUM_MTTS; + rdma_cap->num_mtts = (g_rdma_mtts_num > 0 ? + g_rdma_mtts_num : RDMA_NUM_MTTS); rdma_cap->log_mtt_seg = LOG_MTT_SEG; rdma_cap->mtt_entry_sz = MTT_ENTRY_SZ; rdma_cap->log_rdmarc_seg = LOG_RDMARC_SEG; @@ -1158,7 +1186,7 @@ int hinic_alloc_ceqs(void *hwdev, enum hinic_service_type type, int num, for (i = 0; i < num; i++) { if (eq->num_ceq_remain == 0) { sdk_warn(dev->dev_hdl, "Alloc %d ceqs, less than required %d ceqs\n", - *act_num, num); + *act_num, num); mutex_unlock(&eq->eq_mutex); return 0; } @@ -1322,15 +1350,16 @@ static int cfg_mbx_pf_proc_vf_msg(void *hwdev, u16 vf_id, u8 cmd, void *buf_in, dev_cap->nic_max_sq = dev_cap_tmp.nic_max_sq + 1; dev_cap->nic_max_rq = dev_cap_tmp.nic_max_rq + 1; - sdk_info(dev->dev_hdl, "func_id(%u) fixed qnum %u\n", - func_id, dev_cap->nic_max_sq); + dev_cap->max_queue_allowed = dev_cap_tmp.max_queue_allowed; + sdk_info(dev->dev_hdl, "func_id(%u) fixed qnum %u max_queue_allowed %u\n", + func_id, dev_cap->nic_max_sq, dev_cap->max_queue_allowed); return 0; } static int cfg_mbx_ppf_proc_msg(void *hwdev, u16 pf_id, u16 vf_id, u8 cmd, - void *buf_in, u16 in_size, void *buf_out, - u16 *out_size) + void *buf_in, u16 in_size, void *buf_out, + u16 *out_size) { struct hinic_hwdev *dev = hwdev; @@ -1343,7 +1372,7 @@ static int cfg_mbx_ppf_proc_msg(void *hwdev, u16 pf_id, u16 vf_id, u8 cmd, } static int cfg_mbx_vf_proc_msg(void *hwdev, u8 cmd, void *buf_in, u16 in_size, - void *buf_out, u16 *out_size) + void *buf_out, u16 *out_size) { struct hinic_hwdev *dev = hwdev; @@ -1734,6 +1763,32 @@ bool hinic_func_for_mgmt(void *hwdev) return true; } +bool hinic_func_for_hwpt(void *hwdev) +{ + struct hinic_hwdev *dev = hwdev; + + if (!hwdev) + return false; + + if (IS_HWPT_TYPE(dev)) + return true; + else + return false; +} + +bool hinic_func_for_pt(void *hwdev) +{ + struct hinic_hwdev *dev = hwdev; + + if (!hwdev) + return false; + + if (dev->cfg_mgmt->svc_cap.force_up) + return true; + else + return false; +} + int cfg_set_func_sf_en(void *hwdev, u32 enbits, u32 enmask) { struct hinic_hwdev *dev = hwdev; @@ -1750,10 +1805,15 @@ int cfg_set_func_sf_en(void *hwdev, u32 enbits, u32 enmask) return -ENOMEM; } - glb_func_idx = hinic_global_func_id(hwdev); - func_sf_enbits->function_id = glb_func_idx; + err = hinic_global_func_id_get(dev, &glb_func_idx); + if (err) { + kfree(func_sf_enbits); + return err; + } + func_sf_enbits->stateful_enbits = enbits; func_sf_enbits->stateful_enmask = enmask; + func_sf_enbits->function_id = glb_func_idx; err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC, HINIC_MISC_SET_FUNC_SF_ENBITS, @@ -1788,7 +1848,11 @@ int cfg_get_func_sf_en(void *hwdev, u32 *enbits) return -ENOMEM; } - glb_func_idx = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(dev, &glb_func_idx); + if (err) { + kfree(func_sf_enbits); + return err; + } func_sf_enbits->function_id = glb_func_idx; @@ -2056,7 +2120,9 @@ static int hinic_os_dep_init(struct hinic_hwdev *hwdev) static void hinic_os_dep_deinit(struct hinic_hwdev *hwdev) { destroy_work(&hwdev->fault_work); + destroy_workqueue(hwdev->workq); + down(&hwdev->fault_list_sem); up(&hwdev->fault_list_sem); @@ -2068,7 +2134,6 @@ static void hinic_os_dep_deinit(struct hinic_hwdev *hwdev) void hinic_ppf_hwdev_unreg(void *hwdev) { struct hinic_hwdev *dev = hwdev; - if (!hwdev) return; @@ -2082,7 +2147,6 @@ void hinic_ppf_hwdev_unreg(void *hwdev) void hinic_ppf_hwdev_reg(void *hwdev, void *ppf_hwdev) { struct hinic_hwdev *dev = hwdev; - if (!hwdev) return; @@ -2149,6 +2213,8 @@ int hinic_init_hwdev(struct hinic_init_para *para) hwdev->chip_node = para->chip_node; hwdev->ppf_hwdev = para->ppf_hwdev; sema_init(&hwdev->ppf_sem, 1); + sema_init(&hwdev->func_sem, 1); + hwdev->func_ref = 0; hwdev->chip_fault_stats = vzalloc(HINIC_CHIP_FAULT_SIZE); if (!hwdev->chip_fault_stats) @@ -2208,6 +2274,9 @@ int hinic_init_hwdev(struct hinic_init_para *para) goto init_cap_err; } + if (hwdev->cfg_mgmt->svc_cap.force_up) + hwdev->feature_cap |= HINIC_FUNC_FORCE_LINK_UP; + err = __vf_func_init(hwdev); if (err) goto vf_func_init_err; @@ -2244,6 +2313,7 @@ int hinic_init_hwdev(struct hinic_init_para *para) vfree(hwdev->chip_fault_stats); alloc_chip_fault_stats_err: + sema_deinit(&hwdev->func_sem); sema_deinit(&hwdev->ppf_sem); kfree(hwdev); *para->hwdev = NULL; @@ -2251,6 +2321,33 @@ int hinic_init_hwdev(struct hinic_init_para *para) return -EFAULT; } +/** + * hinic_set_vf_dev_cap - Set max queue num for VF + * @hwdev: the HW device for VF + **/ +int hinic_set_vf_dev_cap(void *hwdev) +{ + int err; + struct hinic_hwdev *dev; + enum func_type type; + + if (!hwdev) + return -EFAULT; + + dev = (struct hinic_hwdev *)hwdev; + type = HINIC_FUNC_TYPE(dev); + if (type != TYPE_VF) + return -EPERM; + + err = get_dev_cap(dev); + if (err) + return err; + + nic_param_fix(dev); + + return 0; +} + void hinic_free_hwdev(void *hwdev) { struct hinic_hwdev *dev = hwdev; @@ -2287,6 +2384,7 @@ void hinic_free_hwdev(void *hwdev) clear_bit(HINIC_HWDEV_NONE_INITED, &dev->func_state); hinic_free_hwif(dev); vfree(dev->chip_fault_stats); + sema_deinit(&dev->func_sem); sema_deinit(&dev->ppf_sem); kfree(dev); } @@ -2337,6 +2435,7 @@ enum hinic_func_mode hinic_get_func_mode(void *hwdev) return dev->func_mode; } +EXPORT_SYMBOL(hinic_get_func_mode); enum hinic_service_mode hinic_get_service_mode(void *hwdev) { diff --git a/drivers/net/ethernet/huawei/hinic/hinic_cfg.h b/drivers/net/ethernet/huawei/hinic/hinic_cfg.h index 55d038335f3c4d0f7d09a7b68a504c2046488326..8ca07640d4c0374d48a342d26089ff890a77670b 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_cfg.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_cfg.h @@ -222,6 +222,7 @@ struct service_cap { u8 er_id; /* PF/VF's ER */ u8 port_id; /* PF/VF's physical port */ u8 max_vf; /* max VF number that PF supported */ + u8 force_up; bool sf_en; /* stateful business status */ u8 timer_en; /* 0:disable, 1:enable */ u8 bloomfilter_en; /* 0:disable, 1:enable*/ @@ -363,7 +364,7 @@ struct hinic_dev_cap { u8 cfg_file_ver; u8 net_port_mode; u8 valid_cos_bitmap; /* every bit indicate cos is valid */ - u8 rsvd1; + u8 force_up; u32 pf_num; u32 pf_id_start; u32 vf_num; @@ -386,7 +387,7 @@ struct hinic_dev_cap { u8 nic_lro_en; u8 nic_lro_sz; u8 nic_tso_sz; - u8 rsvd3; + u8 max_queue_allowed; /* RoCE */ u32 roce_max_qp; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_cmdq.c b/drivers/net/ethernet/huawei/hinic/hinic_cmdq.c index e9f9f0a392abbaf957c384f0ecbf386ae34ebfc6..3f52123be4af29f2f2c5de17eefd1b2fff748397 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_cmdq.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_cmdq.c @@ -53,7 +53,7 @@ #define CMDQ_DB_INFO_SRC_TYPE_MASK 0x1FU #define CMDQ_DB_INFO_SET(val, member) \ - (((val) & CMDQ_DB_INFO_##member##_MASK) \ + ((val & CMDQ_DB_INFO_##member##_MASK) \ << CMDQ_DB_INFO_##member##_SHIFT) #define CMDQ_CTRL_PI_SHIFT 0 @@ -168,7 +168,7 @@ #define CMDQ_DB_PI_OFF(pi) (((u16)LOWER_8_BITS(pi)) << 3) #define CMDQ_DB_ADDR(db_base, pi) \ - (((u8 *)(db_base) + HINIC_DB_OFF) + CMDQ_DB_PI_OFF(pi)) + (((u8 *)db_base + HINIC_DB_OFF) + CMDQ_DB_PI_OFF(pi)) #define CMDQ_PFN_SHIFT 12 #define CMDQ_PFN(addr) ((addr) >> CMDQ_PFN_SHIFT) @@ -194,6 +194,9 @@ #define CMDQ_SEND_CMPT_CODE 10 #define CMDQ_COMPLETE_CMPT_CODE 11 +#define HINIC_GET_CMDQ_FREE_WQEBBS(cmdq_wq) \ + atomic_read(&(cmdq_wq)->delta) + enum cmdq_scmd_type { CMDQ_SET_ARM_CMD = 2, }; @@ -278,7 +281,7 @@ void hinic_free_cmd_buf(void *hwdev, struct hinic_cmd_buf *cmd_buf) struct hinic_cmdqs *cmdqs; if (!hwdev || !cmd_buf) { - pr_err("Failed to free cmd buf.\n"); + pr_err("Failed to free cmd buf\n"); return; } @@ -337,7 +340,7 @@ static void cmdq_set_lcmd_bufdesc(struct hinic_cmdq_wqe_lcmd *wqe, } static void cmdq_set_inline_wqe_data(struct hinic_cmdq_inline_wqe *wqe, - void *buf_in, u32 in_size) + const void *buf_in, u32 in_size) { struct hinic_cmdq_wqe_scmd *wqe_scmd = &wqe->wqe_scmd; @@ -368,7 +371,7 @@ static void cmdq_set_db(struct hinic_cmdq *cmdq, writel(db.db_info, CMDQ_DB_ADDR(cmdq->db_base, prod_idx)); } -static void cmdq_wqe_fill(void *dst, void *src) +static void cmdq_wqe_fill(void *dst, const void *src) { memcpy((u8 *)dst + FIRST_DATA_TO_WRITE_LAST, (u8 *)src + FIRST_DATA_TO_WRITE_LAST, @@ -541,8 +544,9 @@ static int hinic_cmdq_sync_timeout_check(struct hinic_cmdq *cmdq, return 0; } -static void __clear_cmd_info(struct hinic_cmdq_cmd_info *cmd_info, int *errcode, - struct completion *done, u64 *out_param) +static void __clear_cmd_info(struct hinic_cmdq_cmd_info *cmd_info, + const int *errcode, struct completion *done, + u64 *out_param) { if (cmd_info->errcode == errcode) cmd_info->errcode = NULL; @@ -576,10 +580,20 @@ static int cmdq_sync_cmd_direct_resp(struct hinic_cmdq *cmdq, /* Keep wrapped and doorbell index correct. bh - for tasklet(ceq) */ spin_lock_bh(&cmdq->cmdq_lock); - /* WQE_SIZE = WQEBB_SIZE, we will get the wq element and not shadow*/ + /* in order to save a wqebb for setting arm_bit when + * send cmdq commands frequently resulting in cmdq full + */ + if (HINIC_GET_CMDQ_FREE_WQEBBS(wq) < num_wqebbs + 1) { + spin_unlock_bh(&cmdq->cmdq_lock); + return -EBUSY; + } + + /* WQE_SIZE = WQEBB_SIZE, we will get the wq element and not shadow */ curr_wqe = hinic_get_wqe(cmdq->wq, num_wqebbs, &curr_prod_idx); if (!curr_wqe) { spin_unlock_bh(&cmdq->cmdq_lock); + sdk_err(cmdq->hwdev->dev_hdl, "Can not get avalible wqebb, mod: %u, cmd: 0x%x\n", + mod, cmd); return -EBUSY; } @@ -696,10 +710,20 @@ static int cmdq_sync_cmd_detail_resp(struct hinic_cmdq *cmdq, /* Keep wrapped and doorbell index correct. bh - for tasklet(ceq) */ spin_lock_bh(&cmdq->cmdq_lock); + /* in order to save a wqebb for setting arm_bit when + * send cmdq commands frequently resulting in cmdq full + */ + if (HINIC_GET_CMDQ_FREE_WQEBBS(wq) < num_wqebbs + 1) { + spin_unlock_bh(&cmdq->cmdq_lock); + return -EBUSY; + } + /* WQE_SIZE = WQEBB_SIZE, we will get the wq element and not shadow*/ curr_wqe = hinic_get_wqe(cmdq->wq, num_wqebbs, &curr_prod_idx); if (!curr_wqe) { spin_unlock_bh(&cmdq->cmdq_lock); + sdk_err(cmdq->hwdev->dev_hdl, "Can not get avalible wqebb, mod: %u, cmd: 0x%x\n", + mod, cmd); return -EBUSY; } @@ -716,6 +740,7 @@ static int cmdq_sync_cmd_detail_resp(struct hinic_cmdq *cmdq, cmd_info = &cmdq->cmd_infos[curr_prod_idx]; init_completion(&done); + cmd_info->done = &done; cmd_info->errcode = &errcode; cmd_info->cmpt_code = &cmpt_code; @@ -856,6 +881,7 @@ static int cmdq_set_arm_bit(struct hinic_cmdq *cmdq, void *buf_in, u16 in_size) curr_wqe = hinic_get_wqe(cmdq->wq, num_wqebbs, &curr_prod_idx); if (!curr_wqe) { spin_unlock_bh(&cmdq->cmdq_lock); + sdk_err(cmdq->hwdev->dev_hdl, "Can not get avalible wqebb setting arm\n"); return -EBUSY; } @@ -946,9 +972,13 @@ int hinic_cmdq_direct_resp(void *hwdev, enum hinic_ack_type ack_type, return err; } + err = hinic_func_own_get(hwdev); + if (err) + return err; + err = cmdq_sync_cmd_direct_resp(&cmdqs->cmdq[HINIC_CMDQ_SYNC], ack_type, mod, cmd, buf_in, out_param, timeout); - + hinic_func_own_free(hwdev); if (!(((struct hinic_hwdev *)hwdev)->chip_present_flag)) return -ETIMEDOUT; else @@ -1109,7 +1139,8 @@ static void cmdq_sync_cmd_handler(struct hinic_cmdq *cmdq, cmdq_update_cmd_status(cmdq, prod_idx, wqe); if (cmdq->cmd_infos[prod_idx].cmpt_code) { - *cmdq->cmd_infos[prod_idx].cmpt_code = CMDQ_COMPLETE_CMPT_CODE; + *cmdq->cmd_infos[prod_idx].cmpt_code = + CMDQ_COMPLETE_CMPT_CODE; cmdq->cmd_infos[prod_idx].cmpt_code = NULL; } @@ -1267,7 +1298,7 @@ static void cmdq_init_queue_ctxt(struct hinic_cmdq *cmdq, ctxt_info->wq_block_pfn = CMDQ_CTXT_BLOCK_INFO_SET(start_ci, CI) | CMDQ_CTXT_BLOCK_INFO_SET(pfn, WQ_BLOCK_PFN); - cmdq_ctxt->func_idx = HINIC_HWIF_GLOBAL_IDX(hwdev->hwif); + cmdq_ctxt->func_idx = hinic_global_func_id_hw(hwdev); cmdq_ctxt->ppf_idx = HINIC_HWIF_PPF_IDX(hwdev->hwif); cmdq_ctxt->cmdq_id = cmdq->cmdq_type; } @@ -1348,6 +1379,7 @@ int hinic_set_cmdq_ctxts(struct hinic_hwdev *hwdev) cmdq_type = HINIC_CMDQ_SYNC; for (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++) { cmdq_ctxt = &cmdqs->cmdq[cmdq_type].cmdq_ctxt; + cmdq_ctxt->func_idx = hinic_global_func_id_hw(hwdev); in_size = sizeof(*cmdq_ctxt); err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, HINIC_MGMT_CMD_CMDQ_CTXT_SET, diff --git a/drivers/net/ethernet/huawei/hinic/hinic_ctx_def.h b/drivers/net/ethernet/huawei/hinic/hinic_ctx_def.h index 0b61e22501b5e6740907ee138fb45566ec7e5c8f..71ccb1f17044fb990e5ffabb457336a6a38289cf 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_ctx_def.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_ctx_def.h @@ -1,8 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0*/ /****************************************************************************** - * - * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd. - * + + Copyright (C), 2001-2011, Huawei Tech. Co., Ltd. + ****************************************************************************** File Name : hinic_ctx_def.h Version : Initial Draft @@ -33,6 +33,8 @@ extern "C"{ #define HINIC_Q_CTXT_MAX 42 +#define HINIC_RQ_CQ_MAX 128 + #define MAX_WQE_SIZE(max_sge, wqebb_size) \ (((max_sge) <= 2) ? (wqebb_size) : \ ((ALIGN(((max_sge) - 2), 4) / 4 + 1) * (wqebb_size))) @@ -214,6 +216,7 @@ enum cfg_svc_type_en { CFG_SVC_OVS_BIT7 = (1 << 7), CFG_SVC_ACL_BIT8 = (1 << 8), CFG_SVC_IOE_BIT9 = (1 << 9), + CFG_SVC_HWPT_BIT10 = (1 << 10), CFG_SVC_FT_EN = (CFG_SVC_FCOE_BIT2 | CFG_SVC_TOE_BIT3 | CFG_SVC_FC_BIT5 | CFG_SVC_IOE_BIT9), @@ -244,6 +247,8 @@ enum cfg_svc_type_en { ((dev)->cfg_mgmt->svc_cap.chip_svc_type & CFG_SVC_FT_EN) #define IS_RDMA_TYPE(dev) \ ((dev)->cfg_mgmt->svc_cap.chip_svc_type & CFG_SVC_RDMA_EN) +#define IS_HWPT_TYPE(dev) \ + ((dev)->cfg_mgmt->svc_cap.chip_svc_type & CFG_SVC_HWPT_BIT10) #ifdef __cplusplus #if __cplusplus diff --git a/drivers/net/ethernet/huawei/hinic/hinic_dbg.h b/drivers/net/ethernet/huawei/hinic/hinic_dbg.h index bfc6aa4440af2e6ec3c5bd66f6841d47390b7a5f..f87bedfc113ef69bc92288331b7d3a60f56c44fc 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_dbg.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_dbg.h @@ -39,7 +39,7 @@ u64 hinic_dbg_get_rq_cla_addr(void *hwdev, u16 q_id); int hinic_dbg_get_sq_db_addr(void *hwdev, u16 q_id, u64 **map_addr, u64 *phy_addr, u32 *pg_idx); -u16 hinic_dbg_get_global_qpn(void *hwdev); +u16 hinic_dbg_get_global_qpn(const void *hwdev); int hinic_dbg_get_sq_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt, u8 *wqe, u16 *wqe_size); @@ -79,11 +79,12 @@ int hinic_api_csr_wr32(void *hwdev, u8 dest, u32 addr, u32 val); int hinic_api_csr_rd64(void *hwdev, u8 dest, u32 addr, u64 *val); -int hinic_dbg_get_hw_stats(void *hwdev, u8 *hw_stats, u16 *out_size); +int hinic_dbg_get_hw_stats(const void *hwdev, u8 *hw_stats, u16 *out_size); u16 hinic_dbg_clear_hw_stats(void *hwdev); -void hinic_get_chip_fault_stats(void *hwdev, u8 *chip_fault_stats, int offset); +void hinic_get_chip_fault_stats(const void *hwdev, + u8 *chip_fault_stats, int offset); int hinic_dbg_get_pf_bw_limit(void *hwdev, u32 *pf_bw_limit); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c b/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c index 96fb8db6665657915dfabdd59456a158753ac6c0..0cf65bfde2de9df955fa79031032e5283f34d111 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c @@ -53,13 +53,9 @@ struct ffm_intr_info { void *g_card_node_array[MAX_CARD_NUM] = {0}; void *g_card_vir_addr[MAX_CARD_NUM] = {0}; u64 g_card_phy_addr[MAX_CARD_NUM] = {0}; -/* lock for g_card_vir_addr */ +/* lock for g_card_vir_addr */ struct mutex g_addr_lock; int card_id; -unsigned long card_id_flag; -enum hinic_card_id_status { - HINIC_CARD_ID_USE = BIT(0), -}; /* dbgtool character device name, class name, dev path*/ #define CHR_DEV_DBGTOOL "dbgtool_chr_dev" @@ -111,7 +107,7 @@ static ssize_t dbgtool_knl_write(struct file *pfile, static bool is_valid_phy_addr(u64 offset) { - int i = 0; + int i; for (i = 0; i < MAX_CARD_NUM; i++) { if (offset == g_card_phy_addr[i]) @@ -129,20 +125,17 @@ int hinic_mem_mmap(struct file *filp, struct vm_area_struct *vma) if (vmsize > (PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER))) { pr_err("Map size = %lu is bigger than alloc\n", vmsize); - clear_bit(HINIC_CARD_ID_USE, &card_id_flag); return -EAGAIN; } if (offset && !is_valid_phy_addr((u64)offset) && !hinic_is_valid_bar_addr((u64)offset)) { - pr_err("offset is invalid\n"); - clear_bit(HINIC_CARD_ID_USE, &card_id_flag); + pr_err("offset is invalid"); return -EAGAIN; } /* old version of tool set vma->vm_pgoff to 0 */ phy_addr = offset ? offset : g_card_phy_addr[card_id]; - clear_bit(HINIC_CARD_ID_USE, &card_id_flag); if (!phy_addr) { pr_err("Card_id = %d physical address is 0\n", card_id); return -EAGAIN; @@ -200,9 +193,10 @@ long dbgtool_knl_api_cmd_read(struct dbgtool_param *para, ack_size = para->param.api_rd.ack_size; if (para->param.api_rd.ack_size == 0) { pr_err("Read cmd ack size is 0\n"); - ret = -EINVAL; + ret = -ENOMEM; goto alloc_ack_mem_fail; } + ack = kzalloc((unsigned long long)ack_size, GFP_KERNEL); if (!ack) { pr_err("Alloc read ack mem fail\n"); @@ -557,7 +551,7 @@ long dbgtool_knl_unlocked_ioctl(struct file *pfile, struct dbgtool_param param; struct dbgtool_k_glb_info *dbgtool_info; struct card_node *card_info = NULL; - int i, cnt = 0; + int i; (void)memset(¶m, 0, sizeof(param)); @@ -580,20 +574,7 @@ long dbgtool_knl_unlocked_ioctl(struct file *pfile, return -EFAULT; } - while (cnt < 10) { - if (!test_and_set_bit(HINIC_CARD_ID_USE, &card_id_flag)) - break; - usleep_range(500, 1000); - cnt++; - } - - if (cnt < 10) { - card_id = i; - } else { - pr_err("Card id in using!\n"); - clear_bit(HINIC_CARD_ID_USE, &card_id_flag); - return -EFAULT; - } + card_id = i; dbgtool_info = (struct dbgtool_k_glb_info *)card_info->dbgtool_info; @@ -651,6 +632,7 @@ void ffm_intr_msg_record(void *handle, void *buf_in, u16 in_size, struct timex txc; struct rtc_time rctm; struct card_node *card_info = NULL; + bool flag = false; int i, j; for (i = 0; i < MAX_CARD_NUM; i++) { @@ -659,10 +641,14 @@ void ffm_intr_msg_record(void *handle, void *buf_in, u16 in_size, continue; for (j = 0; j < MAX_FUNCTION_NUM; j++) { - if (handle == card_info->func_handle_array[j]) + if (handle == card_info->func_handle_array[j]) { + flag = true; break; + } } - break; + + if (flag) + break; } if (i == MAX_CARD_NUM || !card_info) { @@ -787,6 +773,7 @@ int dbgtool_knl_init(void *vhwdev, void *chip_node) pr_err("Failed to get hinic id\n"); goto sscanf_chdev_fail; } + g_card_node_array[id] = chip_info; chip_info->func_num++; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.h b/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.h index 833d3fd60d51b497a60a82711dff600150d5086b..33aaca1eb73450d50bf45bb0d96d00e04c36a493 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.h @@ -118,4 +118,5 @@ int hinic_mem_mmap(struct file *filp, struct vm_area_struct *vma); void chipif_get_all_pf_dev_info(struct pf_dev_info *dev_info, int card_id, void **g_func_handle_array); long dbgtool_knl_free_mem(int id); + #endif diff --git a/drivers/net/ethernet/huawei/hinic/hinic_dcb.c b/drivers/net/ethernet/huawei/hinic/hinic_dcb.c index 0d1bb2a7ed48a167df82fc643b05e6f6fbdb2cd0..8f80a8f240a389ac7247a55916c8963ef49e772f 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_dcb.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_dcb.c @@ -120,6 +120,8 @@ void hinic_init_ieee_settings(struct hinic_nic_dev *nic_dev) if (dcb_cfg->tc_cfg[i].pfc_en) pfc->pfc_en |= (u8)BIT(i); } + + return; } static int hinic_set_up_cos_map(struct hinic_nic_dev *nic_dev, @@ -330,6 +332,41 @@ int hinic_setup_tc(struct net_device *netdev, u8 tc) return 0; } +u8 hinic_setup_dcb_tool(struct net_device *netdev, u8 *dcb_en, bool wr_flag) +{ + struct hinic_nic_dev *nic_dev = netdev_priv(netdev); + int err = 0; + + if (wr_flag) { + if (nic_dev->max_qps < nic_dev->dcb_cfg.pg_tcs && *dcb_en) { + netif_err(nic_dev, drv, netdev, + "max_qps:%d is less than %d\n", + nic_dev->max_qps, nic_dev->dcb_cfg.pg_tcs); + return 1; + } + if (*dcb_en) + set_bit(HINIC_DCB_ENABLE, &nic_dev->flags); + else + clear_bit(HINIC_DCB_ENABLE, &nic_dev->flags); + /*hinic_setup_tc need get the nic_mutex lock again */ + mutex_unlock(&nic_dev->nic_mutex); + /* kill the rtnl assert warning */ + rtnl_lock(); + err = hinic_setup_tc(netdev, + *dcb_en ? nic_dev->dcb_cfg.pg_tcs : 0); + rtnl_unlock(); + mutex_lock(&nic_dev->nic_mutex); + + if (!err) + netif_info(nic_dev, drv, netdev, "%s DCB\n", + *dcb_en ? "Enable" : "Disable"); + } else { + *dcb_en = (u8)test_bit(HINIC_DCB_ENABLE, &nic_dev->flags); + } + + return !!err; +} + static u8 hinic_dcbnl_get_state(struct net_device *netdev) { struct hinic_nic_dev *nic_dev = netdev_priv(netdev); @@ -349,6 +386,13 @@ static u8 hinic_dcbnl_set_state(struct net_device *netdev, u8 state) if (state == curr_state) return 0; + if (nic_dev->max_qps < nic_dev->dcb_cfg.pg_tcs && state) { + netif_err(nic_dev, drv, netdev, + "max_qps:%d is less than %d\n", + nic_dev->max_qps, nic_dev->dcb_cfg.pg_tcs); + return 1; + } + err = hinic_setup_tc(netdev, state ? nic_dev->dcb_cfg.pg_tcs : 0); if (!err) netif_info(nic_dev, drv, netdev, "%s DCB\n", @@ -370,6 +414,58 @@ static void hinic_dcbnl_get_perm_hw_addr(struct net_device *netdev, nicif_err(nic_dev, drv, netdev, "Failed to get default mac\n"); } +void hinic_dcbnl_set_ets_tc_tool(struct net_device *netdev, u8 tc[], bool flag) +{ + struct hinic_nic_dev *nic_dev = netdev_priv(netdev); + struct hinic_tc_cfg *cfg = nic_dev->tmp_dcb_cfg.tc_cfg; + struct hinic_tc_cfg *tc_conf = nic_dev->dcb_cfg.tc_cfg; + u8 i, tc_tmp, j; + + if (flag) { + /*need to clear first */ + for (i = 0; i < HINIC_DCB_TC_MAX; i++) { + cfg[i].path[HINIC_DCB_CFG_TX].up_map = 0; + cfg[i].path[HINIC_DCB_CFG_RX].up_map = 0; + } + for (i = 0; i < HINIC_DCB_TC_MAX; i++) { + tc_tmp = tc[i]; + cfg[tc_tmp].path[HINIC_DCB_CFG_TX].up_map |= (u8)BIT(i); + cfg[tc_tmp].path[HINIC_DCB_CFG_RX].up_map |= (u8)BIT(i); + cfg[tc_tmp].path[HINIC_DCB_CFG_TX].pg_id = (u8)tc_tmp; + cfg[tc_tmp].path[HINIC_DCB_CFG_RX].pg_id = (u8)tc_tmp; + } + } else { + for (i = 0; i < HINIC_DCB_TC_MAX; i++) { + for (j = 0; j < HINIC_DCB_TC_MAX; j++) { + if (tc_conf[i].path[HINIC_DCB_CFG_TX].up_map & + (u8)BIT(j)) { + tc[j] = i; + } + } + } + } +} + +void hinic_dcbnl_set_ets_pecent_tool(struct net_device *netdev, + u8 percent[], bool flag) +{ + struct hinic_nic_dev *nic_dev = netdev_priv(netdev); + int i; + + if (flag) { + for (i = 0; i < HINIC_DCB_COS_MAX; i++) { + nic_dev->tmp_dcb_cfg.bw_pct[HINIC_DCB_CFG_TX][i] = + percent[i]; + nic_dev->tmp_dcb_cfg.bw_pct[HINIC_DCB_CFG_RX][i] = + percent[i]; + } + } else { + for (i = 0; i < HINIC_DCB_COS_MAX; i++) + percent[i] = + nic_dev->dcb_cfg.bw_pct[HINIC_DCB_CFG_TX][i]; + } +} + static void hinic_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc, u8 prio, u8 pg_id, u8 bw_pct, u8 up_map) @@ -460,6 +556,69 @@ static void hinic_dcbnl_get_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, *bw_pct = nic_dev->dcb_cfg.bw_pct[1][bwg_id]; } +void hinic_dcbnl_set_pfc_cfg_tool(struct net_device *netdev, u8 setting) +{ + struct hinic_nic_dev *nic_dev = netdev_priv(netdev); + u8 i; + + for (i = 0; i < HINIC_DCB_TC_MAX; i++) { + nic_dev->tmp_dcb_cfg.tc_cfg[i].pfc_en = !!(setting & BIT(i)); + if (nic_dev->tmp_dcb_cfg.tc_cfg[i].pfc_en != + nic_dev->dcb_cfg.tc_cfg[i].pfc_en) { + nic_dev->tmp_dcb_cfg.pfc_state = true; + } + } +} + +void hinic_dcbnl_set_ets_strict_tool(struct net_device *netdev, + u8 *setting, bool flag) +{ + struct hinic_nic_dev *nic_dev = netdev_priv(netdev); + struct hinic_tc_cfg *cfg = nic_dev->tmp_dcb_cfg.tc_cfg; + struct hinic_tc_cfg *conf = nic_dev->dcb_cfg.tc_cfg; + u8 i; + + if (flag) { + for (i = 0; i < HINIC_DCB_COS_MAX; i++) { + cfg[i].path[HINIC_DCB_CFG_TX].prio_type = + !!(*setting & BIT(i)) ? 2 : 0; + cfg[i].path[HINIC_DCB_CFG_RX].prio_type = + !!(*setting & BIT(i)) ? 2 : 0; + } + } else { + for (i = 0; i < HINIC_DCB_COS_MAX; i++) { + *setting = *setting | + (u8)((u32)(!!(conf[i].path[0].prio_type)) << i); + } + } +} + +void hinic_dcbnl_set_pfc_en_tool(struct net_device *netdev, + u8 *value, bool flag) +{ + struct hinic_nic_dev *nic_dev = netdev_priv(netdev); + + if (flag) + nic_dev->tmp_dcb_cfg.pfc_state = !!(*value); + else + *value = !!nic_dev->tmp_dcb_cfg.pfc_state; +} + +void hinic_dcbnl_set_ets_en_tool(struct net_device *netdev, + u8 *value, bool flag) +{ + struct hinic_nic_dev *nic_dev = netdev_priv(netdev); + + if (flag) { + if (*value) + set_bit(HINIC_ETS_ENABLE, &nic_dev->flags); + else + clear_bit(HINIC_ETS_ENABLE, &nic_dev->flags); + } else { + *value = (u8)test_bit(HINIC_ETS_ENABLE, &nic_dev->flags); + } +} + static void hinic_dcbnl_set_pfc_cfg(struct net_device *netdev, int prio, u8 setting) { @@ -471,6 +630,24 @@ static void hinic_dcbnl_set_pfc_cfg(struct net_device *netdev, int prio, nic_dev->tmp_dcb_cfg.pfc_state = true; } +void hinic_dcbnl_get_pfc_cfg_tool(struct net_device *netdev, u8 *setting) +{ + struct hinic_nic_dev *nic_dev = netdev_priv(netdev); + u8 i; + + for (i = 0; i < HINIC_DCB_TC_MAX; i++) { + *setting = *setting | + (u8)((u32)(nic_dev->dcb_cfg.tc_cfg[i].pfc_en) << i); + } +} + +void hinic_dcbnl_get_tc_num_tool(struct net_device *netdev, u8 *tc_num) +{ + struct hinic_nic_dev *nic_dev = netdev_priv(netdev); + + *tc_num = nic_dev->max_cos; +} + static void hinic_dcbnl_get_pfc_cfg(struct net_device *netdev, int prio, u8 *setting) { @@ -598,7 +775,7 @@ static u8 hinic_sync_dcb_cfg(struct hinic_nic_dev *nic_dev) static void hinic_dcb_get_pfc_map(struct hinic_nic_dev *nic_dev, struct hinic_dcb_config *dcb_cfg, u8 *pfc_map) { - int i, up; + u8 i, up; u8 pfc_en = 0, outof_range_pfc = 0; for (i = 0; i < dcb_cfg->pfc_tcs; i++) { @@ -624,7 +801,7 @@ static void hinic_dcb_get_pfc_map(struct hinic_nic_dev *nic_dev, static bool is_cos_in_use(u8 cos, u8 up_valid_bitmap, u8 *up_cos) { - int i; + u32 i; for (i = 0; i < HINIC_DCB_UP_MAX; i++) { if (!(up_valid_bitmap & BIT(i))) @@ -869,6 +1046,52 @@ static int __set_hw_ets(struct hinic_nic_dev *nic_dev) return 0; } +u8 hinic_dcbnl_set_ets_tool(struct net_device *netdev) +{ + struct hinic_nic_dev *nic_dev = netdev_priv(netdev); + u8 state = DCB_HW_CFG_CHG; + int err; + + nic_dev->dcb_changes |= hinic_sync_dcb_cfg(nic_dev); + if (!nic_dev->dcb_changes) + return DCB_HW_CFG_CHG; + + err = hinic_stop_port_traffic_flow(nic_dev); + if (err) + return DCB_HW_CFG_ERR; + /* wait all traffic flow stopped */ + if (netdev->reg_state == NETREG_REGISTERED) + msleep(HINIC_WAIT_PORT_IO_STOP); + + if (nic_dev->dcb_changes & DCB_CFG_CHG_UP_COS) { + err = __set_hw_cos_up_map(nic_dev); + if (err) { + hinic_info(nic_dev, drv, + "Set cos_up map to hardware failed\n"); + state = DCB_HW_CFG_ERR; + goto out; + } + + nic_dev->dcb_changes &= (~DCB_CFG_CHG_UP_COS); + } + + if (nic_dev->dcb_changes & (DCB_CFG_CHG_PG_TX | DCB_CFG_CHG_PG_RX)) { + err = __set_hw_ets(nic_dev); + if (err) { + state = DCB_HW_CFG_ERR; + goto out; + } + + nic_dev->dcb_changes &= + (~(DCB_CFG_CHG_PG_TX | DCB_CFG_CHG_PG_RX)); + } + +out: + hinic_start_port_traffic_flow(nic_dev); + + return state; +} + static int hinic_dcbnl_set_df_ieee_cfg(struct net_device *netdev) { struct hinic_nic_dev *nic_dev = netdev_priv(netdev); @@ -910,7 +1133,44 @@ static int hinic_dcbnl_set_df_ieee_cfg(struct net_device *netdev) hinic_start_port_traffic_flow(nic_dev); - return (err1 | err2) ? -EINVAL : 0; + return (err1 || err2) ? -EINVAL : 0; +} + +u8 hinic_dcbnl_set_pfc_tool(struct net_device *netdev) +{ + struct hinic_nic_dev *nic_dev = netdev_priv(netdev); + struct hinic_dcb_config *dcb_cfg = &nic_dev->dcb_cfg; + u8 state = DCB_HW_CFG_CHG; + int err; + + nic_dev->dcb_changes |= hinic_sync_dcb_cfg(nic_dev); + if (!nic_dev->dcb_changes) + return DCB_HW_CFG_CHG; + + if (nic_dev->dcb_changes & DCB_CFG_CHG_PFC) { + u8 pfc_map = 0; + + hinic_dcb_get_pfc_map(nic_dev, dcb_cfg, &pfc_map); + err = hinic_dcb_set_pfc(nic_dev->hwdev, dcb_cfg->pfc_state, + pfc_map); + if (err) { + hinic_info(nic_dev, drv, "Failed to %s PFC\n", + dcb_cfg->pfc_state ? "enable" : "disable"); + state = DCB_HW_CFG_ERR; + goto out; + } + + if (dcb_cfg->pfc_state) + hinic_info(nic_dev, drv, "Set PFC: 0x%x to hw done\n", + pfc_map); + else + hinic_info(nic_dev, drv, "Disable PFC, enable tx/rx pause\n"); + + nic_dev->dcb_changes &= (~DCB_CFG_CHG_PFC); + } +out: + + return state; } u8 hinic_dcbnl_set_all(struct net_device *netdev) @@ -986,7 +1246,7 @@ u8 hinic_dcbnl_set_all(struct net_device *netdev) } static int hinic_dcbnl_ieee_get_ets(struct net_device *netdev, - struct ieee_ets *ets) + struct ieee_ets *ets) { struct hinic_nic_dev *nic_dev = netdev_priv(netdev); struct ieee_ets *my_ets = &nic_dev->hinic_ieee_ets; @@ -1001,7 +1261,7 @@ static int hinic_dcbnl_ieee_get_ets(struct net_device *netdev, } static int hinic_dcbnl_ieee_set_ets(struct net_device *netdev, - struct ieee_ets *ets) + struct ieee_ets *ets) { struct hinic_nic_dev *nic_dev = netdev_priv(netdev); struct hinic_dcb_config *dcb_cfg = &nic_dev->dcb_cfg; @@ -1067,7 +1327,7 @@ static int hinic_dcbnl_ieee_set_ets(struct net_device *netdev, } static int hinic_dcbnl_ieee_get_pfc(struct net_device *netdev, - struct ieee_pfc *pfc) + struct ieee_pfc *pfc) { struct hinic_nic_dev *nic_dev = netdev_priv(netdev); struct ieee_pfc *my_pfc = &nic_dev->hinic_ieee_pfc; @@ -1079,7 +1339,7 @@ static int hinic_dcbnl_ieee_get_pfc(struct net_device *netdev, } static int hinic_dcbnl_ieee_set_pfc(struct net_device *netdev, - struct ieee_pfc *pfc) + struct ieee_pfc *pfc) { struct hinic_nic_dev *nic_dev = netdev_priv(netdev); struct hinic_dcb_config *dcb_cfg = &nic_dev->dcb_cfg; @@ -1206,7 +1466,6 @@ static u8 hinic_dcbnl_setdcbx(struct net_device *netdev, u8 mode) if (nic_dev->dcbx_cap == mode) return 0; - nic_dev->dcbx_cap = mode; if (mode & DCB_CAP_DCBX_VER_CEE) { @@ -1224,7 +1483,9 @@ static u8 hinic_dcbnl_setdcbx(struct net_device *netdev, u8 mode) return 1; } } + hinic_dcbnl_set_df_ieee_cfg(netdev); + hinic_force_port_relink(nic_dev->hwdev); } else { err = hinic_setup_tc(netdev, 0); if (err) { @@ -1309,7 +1570,7 @@ void hinic_configure_dcb(struct net_device *netdev) static bool __is_cos_up_map_change(struct hinic_nic_dev *nic_dev, u8 *cos_up) { - int cos, up; + u8 cos, up; for (cos = 0; cos < nic_dev->max_cos; cos++) { up = cos_up[cos]; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_dcb.h b/drivers/net/ethernet/huawei/hinic/hinic_dcb.h index 0d6c0251d8da87d95ffc6d1ce9d66d814f5564e1..056b722734c3942659a76acc0d24f077cad00b8b 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_dcb.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_dcb.h @@ -48,5 +48,20 @@ int hinic_get_num_cos(struct hinic_nic_dev *nic_dev, u8 *num_cos); int hinic_get_cos_up_map(struct hinic_nic_dev *nic_dev, u8 *num_cos, u8 *cos_up); +u8 hinic_setup_dcb_tool(struct net_device *netdev, u8 *dcb_en, bool wr_flag); +void hinic_dcbnl_set_pfc_en_tool(struct net_device *netdev, + u8 *value, bool flag); +void hinic_dcbnl_set_pfc_cfg_tool(struct net_device *netdev, u8 setting); +void hinic_dcbnl_get_pfc_cfg_tool(struct net_device *netdev, u8 *setting); +u8 hinic_dcbnl_set_pfc_tool(struct net_device *netdev); +void hinic_dcbnl_get_tc_num_tool(struct net_device *netdev, u8 *tc_num); +void hinic_dcbnl_set_ets_tc_tool(struct net_device *netdev, u8 tc[], bool flag); +void hinic_dcbnl_set_ets_pecent_tool(struct net_device *netdev, + u8 percent[], bool flag); +void hinic_dcbnl_set_ets_en_tool(struct net_device *netdev, + u8 *value, bool flag); +void hinic_dcbnl_set_ets_strict_tool(struct net_device *netdev, + u8 *setting, bool flag); +u8 hinic_dcbnl_set_ets_tool(struct net_device *netdev); #endif diff --git a/drivers/net/ethernet/huawei/hinic/hinic_dfx_def.h b/drivers/net/ethernet/huawei/hinic/hinic_dfx_def.h index ff993528ffaf0405315ba32753bfd2b40319c6fa..cb5fe472eb20b1f19c474ba672f2692984870b69 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_dfx_def.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_dfx_def.h @@ -1,8 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0*/ /****************************************************************************** - * - * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd. - * + + Copyright (C), 2001-2011, Huawei Tech. Co., Ltd. + ****************************************************************************** File Name : hinic_dfx_def.h Version : Initial Draft @@ -95,6 +95,14 @@ enum driver_cmd_type { GET_NIC_STATS_STRING, GET_NIC_STATS_INFO, GET_PF_ID, + SET_DCB_CFG, + SET_PFC_PRIORITY, + GET_PFC_INFO, + SET_PFC_CONTROL, + SET_ETS, + GET_ETS_INFO, + GET_SUPPORT_UP, + GET_SUPPORT_TC, RSS_CFG = 0x40, RSS_INDIR, @@ -121,9 +129,9 @@ enum api_chain_cmd_type { }; enum sm_cmd_type { -SM_CTR_RD32 = 1, -SM_CTR_RD64_PAIR, -SM_CTR_RD64 + SM_CTR_RD32 = 1, + SM_CTR_RD64_PAIR, + SM_CTR_RD64 }; enum hinic_show_set { diff --git a/drivers/net/ethernet/huawei/hinic/hinic_eqs.c b/drivers/net/ethernet/huawei/hinic/hinic_eqs.c index 3d6dbc700746da59d6a97d46d3955cf0acea1028..80650f8de8dad5488ad8a672b71d67afda9c4dbe 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_eqs.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_eqs.c @@ -10,6 +10,7 @@ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. + * */ #define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt @@ -35,15 +36,23 @@ #define HINIC_EQS_WQ_NAME "hinic_eqs" #define AEQ_CTRL_0_INTR_IDX_SHIFT 0 +#define AEQ_CTRL_0_FUNC_BUSY_SHIFT 10 #define AEQ_CTRL_0_DMA_ATTR_SHIFT 12 #define AEQ_CTRL_0_PCI_INTF_IDX_SHIFT 20 +#define AEQ_CTRL_0_QPS_NUM_SHIFT 22 #define AEQ_CTRL_0_INTR_MODE_SHIFT 31 #define AEQ_CTRL_0_INTR_IDX_MASK 0x3FFU +#define AEQ_CTRL_0_FUNC_BUSY_MASK 0x1U #define AEQ_CTRL_0_DMA_ATTR_MASK 0x3FU #define AEQ_CTRL_0_PCI_INTF_IDX_MASK 0x3U +#define AEQ_CTRL_0_QPS_NUM_MASK 0xFFU #define AEQ_CTRL_0_INTR_MODE_MASK 0x1U +#define AEQ_CTRL_0_GET(val, member) \ + (((val) >> AEQ_CTRL_0_##member##_SHIFT) & \ + AEQ_CTRL_0_##member##_MASK) + #define AEQ_CTRL_0_SET(val, member) \ (((val) & AEQ_CTRL_0_##member##_MASK) << \ AEQ_CTRL_0_##member##_SHIFT) @@ -53,13 +62,19 @@ << AEQ_CTRL_0_##member##_SHIFT))) #define AEQ_CTRL_1_LEN_SHIFT 0 +#define AEQ_CTRL_1_FUNC_OWN_SHIFT 21 #define AEQ_CTRL_1_ELEM_SIZE_SHIFT 24 #define AEQ_CTRL_1_PAGE_SIZE_SHIFT 28 #define AEQ_CTRL_1_LEN_MASK 0x1FFFFFU +#define AEQ_CTRL_1_FUNC_OWN_MASK 0x1U #define AEQ_CTRL_1_ELEM_SIZE_MASK 0x3U #define AEQ_CTRL_1_PAGE_SIZE_MASK 0xFU +#define AEQ_CTRL_1_GET(val, member) \ + (((val) >> AEQ_CTRL_1_##member##_SHIFT) & \ + AEQ_CTRL_1_##member##_MASK) + #define AEQ_CTRL_1_SET(val, member) \ (((val) & AEQ_CTRL_1_##member##_MASK) << \ AEQ_CTRL_1_##member##_SHIFT) @@ -213,6 +228,66 @@ MODULE_PARM_DESC(g_num_ceqe_in_tasklet, static irqreturn_t aeq_interrupt(int irq, void *data); static irqreturn_t ceq_interrupt(int irq, void *data); + +void hinic_qps_num_set(struct hinic_hwdev *hwdev, u32 num_qps) +{ + struct hinic_hwif *hwif = hwdev->hwif; + u32 addr, val, ctrl; + + addr = HINIC_CSR_AEQ_CTRL_0_ADDR(0); + val = hinic_hwif_read_reg(hwif, addr); + val = AEQ_CTRL_0_CLEAR(val, QPS_NUM); + ctrl = AEQ_CTRL_0_SET(num_qps, QPS_NUM); + val |= ctrl; + hinic_hwif_write_reg(hwif, addr, val); +} + +u32 hinic_func_busy_state_get(struct hinic_hwdev *hwdev) +{ + struct hinic_hwif *hwif = hwdev->hwif; + u32 addr, val; + + addr = HINIC_CSR_AEQ_CTRL_0_ADDR(0); + val = hinic_hwif_read_reg(hwif, addr); + return AEQ_CTRL_0_GET(val, FUNC_BUSY); +} + +void hinic_func_busy_state_set(struct hinic_hwdev *hwdev, u32 cfg) +{ + struct hinic_hwif *hwif = hwdev->hwif; + u32 addr, val, ctrl; + + addr = HINIC_CSR_AEQ_CTRL_0_ADDR(0); + val = hinic_hwif_read_reg(hwif, addr); + val = AEQ_CTRL_0_CLEAR(val, FUNC_BUSY); + ctrl = AEQ_CTRL_0_SET(cfg, FUNC_BUSY); + val |= ctrl; + hinic_hwif_write_reg(hwif, addr, val); +} + +u32 hinic_func_own_bit_get(struct hinic_hwdev *hwdev) +{ + struct hinic_hwif *hwif = hwdev->hwif; + u32 addr, val; + + addr = HINIC_CSR_AEQ_CTRL_1_ADDR(0); + val = hinic_hwif_read_reg(hwif, addr); + return AEQ_CTRL_1_GET(val, FUNC_OWN); +} + +void hinic_func_own_bit_set(struct hinic_hwdev *hwdev, u32 cfg) +{ + struct hinic_hwif *hwif = hwdev->hwif; + u32 addr, val, ctrl; + + addr = HINIC_CSR_AEQ_CTRL_1_ADDR(0); + val = hinic_hwif_read_reg(hwif, addr); + val = AEQ_CTRL_1_CLEAR(val, FUNC_OWN); + ctrl = AEQ_CTRL_1_SET(cfg, FUNC_OWN); + val |= ctrl; + hinic_hwif_write_reg(hwif, addr, val); +} + static void ceq_tasklet(ulong eq_tasklet); static u8 eq_cons_idx_checksum_set(u32 val) @@ -463,7 +538,7 @@ static bool aeq_irq_handler(struct hinic_eq *eq) &aeqs->aeq_sw_cb_state[sw_event]); if (aeqs->aeq_swe_cb[sw_event] && test_bit(HINIC_AEQ_SW_CB_REG, - &aeqs->aeq_sw_cb_state[sw_event])) { + &aeqs->aeq_sw_cb_state[sw_event])) { lev = aeqs->aeq_swe_cb[sw_event](aeqs->hwdev, ucode_event, aeqe_data); @@ -479,7 +554,7 @@ static bool aeq_irq_handler(struct hinic_eq *eq) &aeqs->aeq_hw_cb_state[event]); if (aeqs->aeq_hwe_cb[event] && test_bit(HINIC_AEQ_HW_CB_REG, - &aeqs->aeq_hw_cb_state[event])) + &aeqs->aeq_hw_cb_state[event])) aeqs->aeq_hwe_cb[event](aeqs->hwdev, aeqe_pos->aeqe_data, size); clear_bit(HINIC_AEQ_HW_CB_RUNNING, @@ -709,7 +784,10 @@ static int set_ceq_ctrl_reg(struct hinic_hwdev *hwdev, u16 q_id, u16 out_size = sizeof(ceq_ctrl); int err; - ceq_ctrl.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &ceq_ctrl.func_id); + if (err) + return err; + ceq_ctrl.q_id = q_id; ceq_ctrl.ctrl0 = ctrl0; ceq_ctrl.ctrl1 = ctrl1; @@ -751,6 +829,11 @@ static int set_eq_ctrls(struct hinic_eq *eq) AEQ_CTRL_0_CLEAR(val, PCI_INTF_IDX) & AEQ_CTRL_0_CLEAR(val, INTR_MODE); + if (HINIC_IS_VF(eq->hwdev)) { + val = AEQ_CTRL_0_CLEAR(val, FUNC_BUSY) & + AEQ_CTRL_1_CLEAR(val, FUNC_OWN); + } + ctrl0 = AEQ_CTRL_0_SET(eq_irq->msix_entry_idx, INTR_IDX) | AEQ_CTRL_0_SET(AEQ_DMA_ATTR_DEFAULT, DMA_ATTR) | AEQ_CTRL_0_SET(pci_intf_idx, PCI_INTF_IDX) | @@ -955,7 +1038,6 @@ static void free_eq_pages(struct hinic_eq *eq) kfree(eq->virt_addr); kfree(eq->dma_addr); } - static inline u32 get_page_size(struct hinic_eq *eq) { u32 total_size; @@ -979,7 +1061,6 @@ static inline u32 get_page_size(struct hinic_eq *eq) return EQ_MIN_PAGE_SIZE << n; } - /** * init_eq - initialize eq * @eq: the event queue @@ -1091,6 +1172,7 @@ static void remove_eq(struct hinic_eq *eq) hinic_set_msix_state(eq->hwdev, entry->msix_entry_idx, HINIC_MSIX_DISABLE); synchronize_irq(entry->irq_id); + free_irq(entry->irq_id, eq); if (eq->type == HINIC_AEQ) { diff --git a/drivers/net/ethernet/huawei/hinic/hinic_eqs.h b/drivers/net/ethernet/huawei/hinic/hinic_eqs.h index 102dd189bb937ff71344cc394712546ba4f1497f..5813c4b3e67c06a5a7bcf26bef28bcf8cc2c8df7 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_eqs.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_eqs.h @@ -14,11 +14,13 @@ */ #ifndef HINIC_EQS_H +#include + #define HINIC_EQS_H #define HINIC_EQ_PAGE_SIZE 0x00001000 -#define HINIC_MAX_AEQS 4 +#define HINIC_MAX_AEQS 3 #define HINIC_MAX_CEQS 32 #define HINIC_EQ_MAX_PAGES 8 @@ -65,7 +67,6 @@ struct hinic_eq_work { struct hinic_ceq_tasklet_data { void *data; }; - struct hinic_eq { struct hinic_hwdev *hwdev; u16 q_id; @@ -113,7 +114,6 @@ struct hinic_aeqs { struct hinic_hwdev *hwdev; hinic_aeq_hwe_cb aeq_hwe_cb[HINIC_MAX_AEQ_EVENTS]; - hinic_aeq_swe_cb aeq_swe_cb[HINIC_MAX_AEQ_SW_EVENTS]; unsigned long aeq_hw_cb_state[HINIC_MAX_AEQ_EVENTS]; unsigned long aeq_sw_cb_state[HINIC_MAX_AEQ_SW_EVENTS]; @@ -140,6 +140,24 @@ struct hinic_ceqs { u16 num_ceqs; }; +enum hinic_msg_pipe_state { + PIPE_STATE_IDLE, + PIPE_STATE_BUSY, + PIPE_STATE_SUSPEND, +}; + +#define PIPE_CYCLE_MAX 10000 + +u32 hinic_func_busy_state_get(struct hinic_hwdev *hwdev); + +void hinic_func_busy_state_set(struct hinic_hwdev *hwdev, u32 cfg); + +u32 hinic_func_own_bit_get(struct hinic_hwdev *hwdev); + +void hinic_func_own_bit_set(struct hinic_hwdev *hwdev, u32 cfg); + +void hinic_qps_num_set(struct hinic_hwdev *hwdev, u32 num_qps); + int hinic_aeqs_init(struct hinic_hwdev *hwdev, u16 num_aeqs, struct irq_info *msix_entries); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c b/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c index 76443f8a596d8ec46d342eda7cf363f9a244bfaa..e563d8aea67682c5a943cce1dd62ecc6ec2ecfac 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c @@ -140,7 +140,7 @@ static struct hinic_stats hinic_tx_queue_stats_extern[] = { HINIC_TXQ_STAT(alloc_cpy_frag_err), HINIC_TXQ_STAT(map_cpy_frag_err), HINIC_TXQ_STAT(map_frag_err), -}; /*lint -restore*/ +};/*lint -restore*/ #define HINIC_FUNC_STAT(_stat_item) { \ .name = #_stat_item, \ @@ -677,9 +677,9 @@ static int hinic_get_settings(struct net_device *netdev, } #ifdef ETHTOOL_GLINKSETTINGS +#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS static int hinic_get_link_ksettings(struct net_device *netdev, - struct ethtool_link_ksettings - *link_settings) + struct ethtool_link_ksettings *link_settings) { struct cmd_link_settings settings = {0}; struct ethtool_link_settings *base = &link_settings->base; @@ -707,6 +707,7 @@ static int hinic_get_link_ksettings(struct net_device *netdev, return 0; } #endif +#endif static int hinic_is_speed_legal(struct hinic_nic_dev *nic_dev, u32 speed) { @@ -852,15 +853,16 @@ static int hinic_set_settings(struct net_device *netdev, } #ifdef ETHTOOL_GLINKSETTINGS +#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS static int hinic_set_link_ksettings(struct net_device *netdev, - const struct ethtool_link_ksettings - *link_settings) + const struct ethtool_link_ksettings *link_settings) { /* Only support to set autoneg and speed */ return set_link_settings(netdev, link_settings->base.autoneg, link_settings->base.speed); } #endif +#endif static void hinic_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info) @@ -1374,27 +1376,27 @@ static int is_coalesce_legal(struct net_device *netdev, #define CHECK_COALESCE_ALIGN(coal, item, unit) \ do { \ - if ((coal)->item % (unit)) \ + if (coal->item % (unit)) \ nicif_warn(nic_dev, drv, netdev, \ "%s in %d units, change to %d\n", \ - #item, (unit), ALIGN_DOWN((coal)->item, unit));\ + #item, (unit), ALIGN_DOWN(coal->item, unit));\ } while (0) #define CHECK_COALESCE_CHANGED(coal, item, unit, ori_val, obj_str) \ do { \ - if (((coal)->item / (unit)) != (ori_val)) \ + if ((coal->item / (unit)) != (ori_val)) \ nicif_info(nic_dev, drv, netdev, \ "Change %s from %d to %d %s\n", \ #item, (ori_val) * (unit), \ - ALIGN_DOWN((coal)->item, unit), (obj_str)); \ + ALIGN_DOWN(coal->item, unit), (obj_str)); \ } while (0) #define CHECK_PKT_RATE_CHANGED(coal, item, ori_val, obj_str) \ do { \ - if ((coal)->item != (ori_val)) \ + if (coal->item != (ori_val)) \ nicif_info(nic_dev, drv, netdev, \ "Change %s from %llu to %u %s\n", \ - #item, (ori_val), (coal)->item, (obj_str)); \ + #item, (ori_val), coal->item, (obj_str)); \ } while (0) static int __hinic_set_coalesce(struct net_device *netdev, @@ -1865,7 +1867,7 @@ static int hinic_run_lp_test(struct hinic_nic_dev *nic_dev, u32 test_time) /* mark index for every pkt */ skb->data[LP_PKT_LEN - 1] = j; - if (hinic_xmit_frame(skb, netdev)) { + if (hinic_lb_xmit_frame(skb, netdev)) { dev_kfree_skb_any(skb); dev_kfree_skb_any(skb_tmp); nicif_err(nic_dev, drv, netdev, @@ -2228,7 +2230,7 @@ static int __set_rss_rxfh(struct net_device *netdev, /* We request double spaces for the hash key, * the second one holds the key of Big Edian * format. - */ + */ nic_dev->rss_hkey_user = kzalloc(HINIC_RSS_KEY_SIZE * 2, GFP_KERNEL); @@ -2448,8 +2450,10 @@ static int hinic_set_rxfh_indir(struct net_device *netdev, const u32 *indir) static const struct ethtool_ops hinic_ethtool_ops = { #ifdef ETHTOOL_GLINKSETTINGS +#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS .get_link_ksettings = hinic_get_link_ksettings, .set_link_ksettings = hinic_set_link_ksettings, +#endif #endif .get_settings = hinic_get_settings, .set_settings = hinic_set_settings, @@ -2521,7 +2525,9 @@ static const struct ethtool_ops_ext hinic_ethtool_ops_ext = { static const struct ethtool_ops hinicvf_ethtool_ops = { #ifdef ETHTOOL_GLINKSETTINGS +#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS .get_link_ksettings = hinic_get_link_ksettings, +#endif #else .get_settings = hinic_get_settings, #endif diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw.h b/drivers/net/ethernet/huawei/hinic/hinic_hw.h index 9850a8ed6e22364ecfda16bdf88545723f624b36..69b069ba0cd3ca39dd0946a218d58015c8f5ebbc 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_hw.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_hw.h @@ -84,8 +84,8 @@ int hinic_msg_to_mgmt_async(void *hwdev, enum hinic_mod_type mod, u8 cmd, void *buf_in, u16 in_size); int hinic_mbox_to_vf(void *hwdev, enum hinic_mod_type mod, - u16 vf_id, u8 cmd, void *buf_in, u16 in_size, - void *buf_out, u16 *out_size, u32 timeout); + u16 vf_id, u8 cmd, void *buf_in, u16 in_size, + void *buf_out, u16 *out_size, u32 timeout); int hinic_api_cmd_write_nack(void *hwdev, u8 dest, void *cmd, u16 size); @@ -375,11 +375,13 @@ enum hinic_func_cap { * allocation or dev_err print the parameter */ int hinic_init_hwdev(struct hinic_init_para *para); +int hinic_set_vf_dev_cap(void *hwdev); void hinic_free_hwdev(void *hwdev); void hinic_shutdown_hwdev(void *hwdev); void hinic_ppf_hwdev_unreg(void *hwdev); void hinic_ppf_hwdev_reg(void *hwdev, void *ppf_hwdev); + bool hinic_is_hwdev_mod_inited(void *hwdev, enum hinic_hwdev_init_state state); enum hinic_func_mode hinic_get_func_mode(void *hwdev); u64 hinic_get_func_feature_cap(void *hwdev); @@ -390,7 +392,6 @@ enum hinic_service_mode { HINIC_WORK_MODE_NIC, HINIC_WORK_MODE_INVALID = 0xFF, }; - enum hinic_service_mode hinic_get_service_mode(void *hwdev); int hinic_slq_init(void *dev, int num_wqs); @@ -616,6 +617,7 @@ enum hinic_event_type { HINIC_EVENT_PORT_MODULE_EVENT = 7, HINIC_EVENT_MCTP_GET_HOST_INFO, HINIC_EVENT_MULTI_HOST_MGMT, + HINIC_EVENT_INIT_MIGRATE_PF, }; struct hinic_event_info { @@ -726,14 +728,16 @@ struct hinic_hw_pf_infos { int hinic_get_hw_pf_infos(void *hwdev, struct hinic_hw_pf_infos *infos); int hinic_set_ip_check(void *hwdev, bool ip_check_ctl); int hinic_mbox_to_host_sync(void *hwdev, enum hinic_mod_type mod, - u8 cmd, void *buf_in, u16 in_size, void *buf_out, - u16 *out_size, u32 timeout); + u8 cmd, void *buf_in, u16 in_size, void *buf_out, + u16 *out_size, u32 timeout); int hinic_mbox_ppf_to_vf(void *hwdev, - enum hinic_mod_type mod, u16 func_id, u8 cmd, - void *buf_in, u16 in_size, void *buf_out, - u16 *out_size, u32 timeout); + enum hinic_mod_type mod, u16 func_id, u8 cmd, void *buf_in, + u16 in_size, void *buf_out, u16 *out_size, u32 timeout); int hinic_get_card_present_state(void *hwdev, bool *card_present_state); + +void hinic_migrate_report(void *dev); int hinic_set_vxlan_udp_dport(void *hwdev, u32 udp_port); +bool is_multi_vm_slave(void *hwdev); #endif diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h index d4bb6fab34626e4e659b9e5d54503cf03f25baae..f2143c05526ef8f026fbd0f0895c61a5e3450de9 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h @@ -1,5 +1,5 @@ -/* - * Huawei HiNIC PCI Express Linux driver +/* SPDX-License-Identifier: GPL-2.0*/ +/* Huawei HiNIC PCI Express Linux driver * Copyright(c) 2017 Huawei Technologies Co., Ltd * * This program is free software; you can redistribute it and/or modify it @@ -27,6 +27,9 @@ enum hinic_service_type { SERVICE_T_IWARP, SERVICE_T_FC, SERVICE_T_FCOE, + SERVICE_T_MIGRATE, + SERVICE_T_PT, + SERVICE_T_HWPT, SERVICE_T_MAX, /* Only used for interruption resource management, @@ -68,6 +71,8 @@ struct nic_service_cap { bool lro_en; /* LRO feature enable bit*/ u8 lro_sz; /* LRO context space: n*16B */ u8 tso_sz; /* TSO context space: n*16B */ + + u16 max_queue_allowed; }; struct dev_roce_svc_own_cap { @@ -520,7 +525,6 @@ struct hinic_micro_log_info { int (*init)(void *hwdev); void (*deinit)(void *hwdev); }; - int hinic_register_micro_log(struct hinic_micro_log_info *micro_log_info); void hinic_unregister_micro_log(struct hinic_micro_log_info *micro_log_info); @@ -544,5 +548,12 @@ struct hinic_func_nic_state { int hinic_set_func_nic_state(void *hwdev, struct hinic_func_nic_state *state); int hinic_get_func_nic_enable(void *hwdev, u16 glb_func_idx, bool *en); bool hinic_get_master_host_mbox_enable(void *hwdev); - +bool hinic_get_slave_host_enable(void *hwdev, u8 host_id); +int hinic_func_own_get(void *hwdev); +void hinic_func_own_free(void *hwdev); +int hinic_global_func_id_get(void *hwdev, u16 *func_id); +u16 hinic_pf_id_of_vf_hw(void *hwdev); +u16 hinic_global_func_id_hw(void *hwdev); +bool hinic_func_for_pt(void *hwdev); +bool hinic_func_for_hwpt(void *hwdev); #endif diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hwdev.c b/drivers/net/ethernet/huawei/hinic/hinic_hwdev.c index 86e6da167bb2c907de03800136ec62aa02d785fb..26939981877cca8df52f61b65581645c4efbbd3c 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_hwdev.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_hwdev.c @@ -10,6 +10,7 @@ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. + * */ #define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt @@ -514,30 +515,6 @@ static void hinic_set_mgmt_channel_status(void *handle, bool state); static inline void __set_heartbeat_ehd_detect_delay(struct hinic_hwdev *hwdev, u32 delay_ms); -#define HINIC_MGMT_STATUS_ERR_OK 0 /* Ok */ -#define HINIC_MGMT_STATUS_ERR_PARAM 1 /* Invalid parameter */ -#define HINIC_MGMT_STATUS_ERR_FAILED 2 /* Operation failed */ -#define HINIC_MGMT_STATUS_ERR_PORT 3 /* Invalid port */ -#define HINIC_MGMT_STATUS_ERR_TIMEOUT 4 /* Operation time out */ -#define HINIC_MGMT_STATUS_ERR_NOMATCH 5 /* Version not match */ -#define HINIC_MGMT_STATUS_ERR_EXIST 6 /* Entry exists */ -#define HINIC_MGMT_STATUS_ERR_NOMEM 7 /* Out of memory */ -#define HINIC_MGMT_STATUS_ERR_INIT 8 /* Feature not initialized */ -#define HINIC_MGMT_STATUS_ERR_FAULT 9 /* Invalid address */ -#define HINIC_MGMT_STATUS_ERR_PERM 10 /* Operation not permitted */ -#define HINIC_MGMT_STATUS_ERR_EMPTY 11 /* Table empty */ -#define HINIC_MGMT_STATUS_ERR_FULL 12 /* Table full */ -#define HINIC_MGMT_STATUS_ERR_NOT_FOUND 13 /* Not found */ -#define HINIC_MGMT_STATUS_ERR_BUSY 14 /* Device or resource busy */ -#define HINIC_MGMT_STATUS_ERR_RESOURCE 15 /* No resources for operation */ -#define HINIC_MGMT_STATUS_ERR_CONFIG 16 /* Invalid configuration */ -#define HINIC_MGMT_STATUS_ERR_UNAVAIL 17 /* Feature unavailable */ -#define HINIC_MGMT_STATUS_ERR_CRC 18 /* CRC check failed */ -#define HINIC_MGMT_STATUS_ERR_NXIO 19 /* No such device or address */ -#define HINIC_MGMT_STATUS_ERR_ROLLBACK 20 /* Chip rollback fail */ -#define HINIC_MGMT_STATUS_ERR_LEN 32 /* Length too short or too long */ -#define HINIC_MGMT_STATUS_ERR_UNSUPPORT 0xFF/* Feature not supported*/ - #define HINIC_QUEUE_MIN_DEPTH 6 #define HINIC_QUEUE_MAX_DEPTH 12 #define HINIC_MAX_RX_BUFFER_SIZE 15 @@ -692,7 +669,7 @@ static void __print_status_info(struct hinic_hwdev *dev, if (HINIC_IS_VF(dev) && (cmd == HINIC_PORT_CMD_SET_MAC || cmd == HINIC_PORT_CMD_DEL_MAC || cmd == HINIC_PORT_CMD_UPDATE_MAC) && - mgmt_status_log[index].status == HINIC_PF_SET_VF_ALREADY) + (mgmt_status_log[index].status == HINIC_PF_SET_VF_ALREADY)) return; nic_err(dev->dev_hdl, "Mgmt process mod(0x%x) cmd(0x%x) fail: %s", @@ -719,8 +696,8 @@ static bool hinic_status_need_special_handle(enum hinic_mod_type mod, return false; } -void hinic_print_status_info(void *hwdev, enum hinic_mod_type mod, u8 cmd, - void *buf_out) +static void hinic_print_status_info(void *hwdev, enum hinic_mod_type mod, + u8 cmd, const void *buf_out) { struct hinic_hwdev *dev = hwdev; int i, size; @@ -773,9 +750,15 @@ void hinic_set_chip_absent(void *hwdev) int hinic_get_chip_present_flag(void *hwdev) { - int flag = ((struct hinic_hwdev *)hwdev)->chip_present_flag; + int flag; + + if (!hwdev) + return -EINVAL; + flag = ((struct hinic_hwdev *)hwdev)->chip_present_flag; return flag; } +EXPORT_SYMBOL(hinic_get_chip_present_flag); + static void hinic_set_fast_recycle_status(void *hwdev) { @@ -843,8 +826,7 @@ static int __func_send_mbox(struct hinic_hwdev *hwdev, enum hinic_mod_type mod, out_size, timeout); else if (NEED_MBOX_FORWARD(hwdev)) err = hinic_mbox_to_host_sync(hwdev, mod, cmd, buf_in, - in_size, buf_out, out_size, - timeout); + in_size, buf_out, out_size, timeout); else err = -EFAULT; @@ -1060,8 +1042,8 @@ int hinic_mbox_to_vf(void *hwdev, EXPORT_SYMBOL(hinic_mbox_to_vf); int hinic_clp_to_mgmt(void *hwdev, enum hinic_mod_type mod, u8 cmd, - void *buf_in, u16 in_size, - void *buf_out, u16 *out_size) + void *buf_in, u16 in_size, + void *buf_out, u16 *out_size) { struct hinic_hwdev *dev = hwdev; @@ -1080,7 +1062,7 @@ int hinic_clp_to_mgmt(void *hwdev, enum hinic_mod_type mod, u8 cmd, return -EPERM; err = hinic_pf_clp_to_mgmt(dev, mod, cmd, buf_in, - in_size, buf_out, out_size); + in_size, buf_out, out_size); return err; } @@ -1162,7 +1144,9 @@ int hinic_set_ci_table(void *hwdev, u16 q_id, struct hinic_sq_attr *attr) if (!hwdev || !attr) return -EINVAL; - cons_idx_attr.func_idx = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &cons_idx_attr.func_idx); + if (err) + return err; cons_idx_attr.dma_attr_off = attr->dma_attr_off; cons_idx_attr.pending_limit = attr->pending_limit; @@ -1199,7 +1183,10 @@ static int hinic_set_cmdq_depth(struct hinic_hwdev *hwdev, u16 cmdq_depth) u16 out_size = sizeof(root_ctxt); int err; - root_ctxt.func_idx = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &root_ctxt.func_idx); + if (err) + return err; + root_ctxt.ppf_idx = hinic_ppf_idx(hwdev); root_ctxt.set_cmdq_depth = 1; @@ -1244,7 +1231,10 @@ int hinic_set_root_ctxt(void *hwdev, u16 rq_depth, u16 sq_depth, int rx_buf_sz) if (!hwdev) return -EINVAL; - root_ctxt.func_idx = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &root_ctxt.func_idx); + if (err) + return err; + root_ctxt.ppf_idx = hinic_ppf_idx(hwdev); root_ctxt.set_cmdq_depth = 0; @@ -1280,7 +1270,10 @@ int hinic_clean_root_ctxt(void *hwdev) if (!hwdev) return -EINVAL; - root_ctxt.func_idx = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &root_ctxt.func_idx); + if (err) + return err; + root_ctxt.ppf_idx = hinic_ppf_idx(hwdev); err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, @@ -1368,7 +1361,10 @@ static int hinic_vf_rx_tx_flush(struct hinic_hwdev *hwdev) if (err) sdk_warn(hwdev->dev_hdl, "Cmdq is still working, please check CMDQ timeout value is reasonable\n"); - clr_res.func_idx = HINIC_HWIF_GLOBAL_IDX(hwdev->hwif); + err = hinic_global_func_id_get(hwdev, &clr_res.func_idx); + if (err) + return err; + clr_res.ppf_idx = HINIC_HWIF_PPF_IDX(hwdev->hwif); err = hinic_mbox_to_pf_no_ack(hwdev, HINIC_MOD_COMM, HINIC_MGMT_CMD_START_FLR, &clr_res, @@ -1434,6 +1430,7 @@ static int hinic_vf_rx_tx_flush_in_pf(struct hinic_hwdev *hwdev, u16 vf_id) ret = -EFAULT; } + /* wait ucode stop I/O */ msleep(100); /* notice up begine vf flush */ @@ -1462,11 +1459,11 @@ static int hinic_pf_rx_tx_flush(struct hinic_hwdev *hwdev) struct hinic_hwif *hwif = hwdev->hwif; struct hinic_clear_doorbell clear_db = {0}; struct hinic_clear_resource clr_res = {0}; - u16 out_size; + u16 out_size, func_id; int err; int ret = 0; - /* wait ucode stop I/O */ + /* wait ucode stop I/O */ msleep(100); err = wait_cmdq_stop(hwdev); @@ -1478,7 +1475,8 @@ static int hinic_pf_rx_tx_flush(struct hinic_hwdev *hwdev) hinic_disable_doorbell(hwif); out_size = sizeof(clear_db); - clear_db.func_idx = HINIC_HWIF_GLOBAL_IDX(hwif); + func_id = hinic_global_func_id_hw(hwdev); + clear_db.func_idx = func_id; clear_db.ppf_idx = HINIC_HWIF_PPF_IDX(hwif); err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, @@ -1495,7 +1493,7 @@ static int hinic_pf_rx_tx_flush(struct hinic_hwdev *hwdev) hinic_set_pf_status(hwif, HINIC_PF_STATUS_FLR_START_FLAG); - clr_res.func_idx = HINIC_HWIF_GLOBAL_IDX(hwif); + clr_res.func_idx = func_id; clr_res.ppf_idx = HINIC_HWIF_PPF_IDX(hwif); err = hinic_msg_to_mgmt_no_ack(hwdev, HINIC_MOD_COMM, @@ -1551,7 +1549,10 @@ int hinic_get_interrupt_cfg(void *hwdev, if (!hwdev || !interrupt_info) return -EINVAL; - msix_cfg.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &msix_cfg.func_id); + if (err) + return err; + msix_cfg.msix_index = interrupt_info->msix_index; err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, @@ -1586,15 +1587,17 @@ int hinic_set_interrupt_cfg(void *hwdev, if (!hwdev) return -EINVAL; - msix_cfg.func_id = hinic_global_func_id(hwdev); - msix_cfg.msix_index = (u16)interrupt_info.msix_index; - temp_info.msix_index = interrupt_info.msix_index; err = hinic_get_interrupt_cfg(hwdev, &temp_info); if (err) return -EINVAL; + err = hinic_global_func_id_get(hwdev, &msix_cfg.func_id); + if (err) + return err; + + msix_cfg.msix_index = (u16)interrupt_info.msix_index; msix_cfg.lli_credit_cnt = temp_info.lli_credit_limit; msix_cfg.lli_tmier_cnt = temp_info.lli_timer_cfg; msix_cfg.pending_cnt = temp_info.pending_limt; @@ -1747,7 +1750,9 @@ static int set_vf_dma_attr_entry(struct hinic_hwdev *hwdev, u8 entry_idx, u16 out_size = sizeof(attr); int err; - attr.func_idx = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &attr.func_idx); + if (err) + return err; attr.func_dma_entry_num = hinic_dma_attr_entry_num(hwdev); attr.entry_idx = entry_idx; @@ -1799,12 +1804,14 @@ static int dma_attr_table_init(struct hinic_hwdev *hwdev) static int resources_state_set(struct hinic_hwdev *hwdev, enum hinic_res_state state) { - struct hinic_hwif *hwif = hwdev->hwif; struct hinic_cmd_set_res_state res_state = {0}; u16 out_size = sizeof(res_state); int err; - res_state.func_idx = HINIC_HWIF_GLOBAL_IDX(hwif); + err = hinic_global_func_id_get(hwdev, &res_state.func_idx); + if (err) + return err; + res_state.state = state; err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, @@ -2141,7 +2148,6 @@ static void hinic_comm_pf_to_mgmt_free(struct hinic_hwdev *hwdev) hinic_pf_to_mgmt_free(hwdev); } - static int hinic_comm_clp_to_mgmt_init(struct hinic_hwdev *hwdev) { int err; @@ -2225,8 +2231,8 @@ static int hinic_sync_mgmt_func_state(struct hinic_hwdev *hwdev) if (HINIC_FUNC_TYPE(hwdev) == TYPE_PPF) { /* heartbeat synchronize must be after set pf active status */ hinic_comm_recv_mgmt_self_cmd_reg(hwdev, - HINIC_MGMT_HEARTBEAT_EVENT, - mgmt_heartbeat_event_handler); + HINIC_MGMT_CMD_HEARTBEAT_EVENT, + mgmt_heartbeat_event_handler); } return 0; @@ -2244,7 +2250,7 @@ static void hinic_unsync_mgmt_func_state(struct hinic_hwdev *hwdev) hwdev->heartbeat_ehd.en = false; if (HINIC_FUNC_TYPE(hwdev) == TYPE_PPF) { hinic_comm_recv_up_self_cmd_unreg(hwdev, - HINIC_MGMT_HEARTBEAT_EVENT); + HINIC_MGMT_CMD_HEARTBEAT_EVENT); } resources_state_set(hwdev, HINIC_RES_CLEAN); @@ -2253,7 +2259,6 @@ static void hinic_unsync_mgmt_func_state(struct hinic_hwdev *hwdev) int hinic_l2nic_reset_base(struct hinic_hwdev *hwdev, u16 reset_flag) { struct hinic_l2nic_reset l2nic_reset = {0}; - struct hinic_hwif *hwif = hwdev->hwif; u16 out_size = sizeof(l2nic_reset); int err = 0; @@ -2264,7 +2269,11 @@ int hinic_l2nic_reset_base(struct hinic_hwdev *hwdev, u16 reset_flag) msleep(100); sdk_info(hwdev->dev_hdl, "L2nic reset flag 0x%x\n", reset_flag); - l2nic_reset.func_id = HINIC_HWIF_GLOBAL_IDX(hwif); + + err = hinic_global_func_id_get(hwdev, &l2nic_reset.func_id); + if (err) + return err; + l2nic_reset.reset_flag = reset_flag; err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, HINIC_MGMT_CMD_L2NIC_RESET, &l2nic_reset, @@ -2337,6 +2346,7 @@ static int __init_eqs_msix_attr(struct hinic_hwdev *hwdev) int hinic_init_comm_ch(struct hinic_hwdev *hwdev) { int err; + u16 func_id; if (IS_BMGW_SLAVE_HOST(hwdev) && (!hinic_get_master_host_mbox_enable(hwdev))) { @@ -2405,8 +2415,12 @@ int hinic_init_comm_ch(struct hinic_hwdev *hwdev) /* set default wq page_size */ hwdev->wq_page_size = HINIC_DEFAULT_WQ_PAGE_SIZE; - err = hinic_set_wq_page_size(hwdev, hinic_global_func_id(hwdev), - hwdev->wq_page_size); + + err = hinic_global_func_id_get(hwdev, &func_id); + if (err) + goto get_func_id_err; + + err = hinic_set_wq_page_size(hwdev, func_id, hwdev->wq_page_size); if (err) { sdk_err(hwdev->dev_hdl, "Failed to set wq page size\n"); goto init_wq_pg_size_err; @@ -2445,9 +2459,9 @@ int hinic_init_comm_ch(struct hinic_hwdev *hwdev) cmdq_init_err: if (HINIC_FUNC_TYPE(hwdev) != TYPE_VF) - hinic_set_wq_page_size(hwdev, hinic_global_func_id(hwdev), - HINIC_HW_WQ_PAGE_SIZE); + hinic_set_wq_page_size(hwdev, func_id, HINIC_HW_WQ_PAGE_SIZE); init_wq_pg_size_err: +get_func_id_err: init_eqs_msix_err: hinic_comm_ceqs_free(hwdev); @@ -2473,6 +2487,8 @@ int hinic_init_comm_ch(struct hinic_hwdev *hwdev) static void __uninit_comm_module(struct hinic_hwdev *hwdev, enum hinic_hwdev_init_state init_state) { + u16 func_id; + switch (init_state) { case HINIC_HWDEV_COMM_CH_INITED: hinic_aeq_unregister_swe_cb(hwdev, @@ -2485,10 +2501,12 @@ static void __uninit_comm_module(struct hinic_hwdev *hwdev, * will return error in pf, pf will set all vf's page * size to 4K when disable sriov */ - if (HINIC_FUNC_TYPE(hwdev) != TYPE_VF) - hinic_set_wq_page_size(hwdev, - hinic_global_func_id(hwdev), + if (HINIC_FUNC_TYPE(hwdev) != TYPE_VF) { + func_id = hinic_global_func_id_hw(hwdev); + hinic_set_wq_page_size(hwdev, func_id, HINIC_HW_WQ_PAGE_SIZE); + } + hinic_comm_ceqs_free(hwdev); if (IS_MULTI_HOST(hwdev)) @@ -2641,7 +2659,10 @@ int hinic_func_tmr_bitmap_set(void *hwdev, bool en) if (!hwdev) return -EINVAL; - bitmap_op.func_idx = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &bitmap_op.func_idx); + if (err) + return err; + bitmap_op.ppf_idx = hinic_ppf_idx(hwdev); if (en) bitmap_op.op_id = FUNC_TMR_BITMAP_ENABLE; @@ -2916,8 +2937,8 @@ int mqm_eqm_set_cfg_2_hw(struct hinic_hwdev *hwdev, u32 valid) u16 out_size = sizeof(info_eqm_cfg); int err; + info_eqm_cfg.ppf_id = hinic_global_func_id_hw(hwdev); info_eqm_cfg.page_size = hwdev->mqm_att.page_size; - info_eqm_cfg.ppf_id = hwdev->hwif->attr.func_global_idx; info_eqm_cfg.valid = valid; err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, @@ -2974,9 +2995,9 @@ int mqm_eqm_set_page_2_hw(struct hinic_hwdev *hwdev) info->start_idx = start_idx; out_size = send_buf_size; err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, - HINIC_MGMT_MQM_SRCH_GPA_SET, - info, (u16)send_buf_size, - info, &out_size, 0); + HINIC_MGMT_CMD_MQM_SRCH_GPA_SET, + info, (u16)send_buf_size, info, + &out_size, 0); if (err || !out_size || info->status) { sdk_err(hwdev->dev_hdl, "Set mqm srch gpa fail, err: %d, status: 0x%x, out_size: 0x%x\n", err, info->status, out_size); @@ -2997,7 +3018,7 @@ int mqm_eqm_set_page_2_hw(struct hinic_hwdev *hwdev) info->start_idx = start_idx; out_size = send_buf_size; err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, - HINIC_MGMT_MQM_SRCH_GPA_SET, + HINIC_MGMT_CMD_MQM_SRCH_GPA_SET, info, (u16)send_buf_size, info, &out_size, 0); if (err || !out_size || info->status) { @@ -3259,7 +3280,7 @@ static struct hinic_event_convert __event_convert[] = { }, { .mod = HINIC_MOD_COMM, - .cmd = HINIC_MGMT_HEARTBEAT_EVENT, + .cmd = HINIC_MGMT_CMD_HEARTBEAT_EVENT, .event = HINIC_EVENT_MGMT_HEARTBEAT_EHD, }, }; @@ -3281,7 +3302,7 @@ static enum hinic_event_cmd __get_event_type(u8 mod, u8 cmd) bool hinic_mgmt_event_ack_first(u8 mod, u8 cmd) { if ((mod == HINIC_MOD_COMM && cmd == HINIC_MGMT_CMD_GET_HOST_INFO) || - (mod == HINIC_MOD_COMM && cmd == HINIC_MGMT_HEARTBEAT_EVENT)) + (mod == HINIC_MOD_COMM && cmd == HINIC_MGMT_CMD_HEARTBEAT_EVENT)) return false; if (mod == HINIC_MOD_COMM || mod == HINIC_MOD_L2NIC || @@ -3392,7 +3413,7 @@ static void fault_report_show(struct hinic_hwdev *hwdev, } static void hinic_refresh_history_fault(struct hinic_hwdev *hwdev, - struct hinic_fault_recover_info *info) + struct hinic_fault_recover_info *info) { if (!hwdev->history_fault_flag) { hwdev->history_fault_flag = true; @@ -3405,6 +3426,20 @@ static void hinic_refresh_history_fault(struct hinic_hwdev *hwdev, } } +void hinic_migrate_report(void *dev) +{ + struct hinic_hwdev *hwdev = (struct hinic_hwdev *)dev; + struct hinic_event_info event_info = {0}; + + if (!dev) + return; + + event_info.type = HINIC_EVENT_INIT_MIGRATE_PF; + if (hwdev->event_callback) + hwdev->event_callback(hwdev->event_pri_handle, &event_info); +} +EXPORT_SYMBOL(hinic_migrate_report); + static void fault_event_handler(struct hinic_hwdev *hwdev, void *buf_in, u16 in_size, void *buf_out, u16 *out_size) { @@ -4198,7 +4233,6 @@ static int vf_nic_event_handler(void *hwdev, u8 cmd, void *buf_in, { enum hinic_event_cmd type = __get_event_type(HINIC_MOD_L2NIC, cmd); - if (type == HINIC_EVENT_MAX_TYPE) { sdk_warn(((struct hinic_hwdev *)hwdev)->dev_hdl, "Unsupport L2NIC event: cmd %d\n", cmd); @@ -4216,7 +4250,6 @@ static int vf_comm_event_handler(void *hwdev, u8 cmd, void *buf_in, { enum hinic_event_cmd type = __get_event_type(HINIC_MOD_COMM, cmd); - if (type == HINIC_EVENT_MAX_TYPE) { sdk_warn(((struct hinic_hwdev *)hwdev)->dev_hdl, "Unsupport COMM event: cmd %d\n", cmd); @@ -4235,7 +4268,6 @@ static void pf_nic_event_handler(void *hwdev, void *pri_handle, u8 cmd, void *buf_out, u16 *out_size) { enum hinic_event_cmd type = __get_event_type(HINIC_MOD_L2NIC, cmd); - if (type == HINIC_EVENT_MAX_TYPE) { sdk_warn(((struct hinic_hwdev *)hwdev)->dev_hdl, "Unsupport L2NIC event: cmd %d\n", cmd); @@ -4251,7 +4283,6 @@ static void pf_hilink_event_handler(void *hwdev, void *pri_handle, u8 cmd, void *buf_out, u16 *out_size) { enum hinic_event_cmd type = __get_event_type(HINIC_MOD_HILINK, cmd); - if (type == HINIC_EVENT_MAX_TYPE) { sdk_warn(((struct hinic_hwdev *)hwdev)->dev_hdl, "Unsupport HILINK event: cmd %d\n", cmd); @@ -4265,7 +4296,7 @@ static void pf_hilink_event_handler(void *hwdev, void *pri_handle, u8 cmd, /* pf fault report event */ void pf_fault_event_handler(void *hwdev, void *buf_in, u16 in_size, - void *buf_out, u16 *out_size) + void *buf_out, u16 *out_size) { _event_handler(hwdev, HINIC_EVENT_MGMT_FAULT, buf_in, in_size, buf_out, out_size); @@ -4286,7 +4317,7 @@ void mgmt_fmw_act_event_handler(void *hwdev, void *buf_in, u16 in_size, } void mgmt_pcie_dfx_event_handler(void *hwdev, void *buf_in, u16 in_size, - void *buf_out, u16 *out_size) + void *buf_out, u16 *out_size) { _event_handler(hwdev, HINIC_EVENT_MGMT_PCIE_DFX, buf_in, in_size, buf_out, out_size); @@ -4398,7 +4429,7 @@ static u8 hinic_get_heartbeat_status(struct hinic_hwdev *hwdev) sdk_err(hwdev->dev_hdl, "Detect pcie is link down\n"); hinic_set_chip_absent(hwdev); hinic_force_complete_all(hwdev); - /* should notify chiperr to pangea + /* :should notify chiperr to pangea * when detecting pcie link down */ return 1; @@ -4538,7 +4569,10 @@ int hinic_enable_fast_recycle(void *hwdev, bool enable) if (!hwdev) return -EINVAL; - fast_recycled_mode.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &fast_recycled_mode.func_id); + if (err) + return err; + fast_recycled_mode.fast_recycled_mode = enable ? 1 : 0; err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, @@ -4792,6 +4826,7 @@ int hinic_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit) struct hinic_hwdev *dev = hwdev; struct hinic_bios_cfg_cmd cfg = {0}; u16 out_size = sizeof(cfg); + u16 func_id; int err; if (!hwdev || !pf_bw_limit) @@ -4801,8 +4836,12 @@ int hinic_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit) !FUNC_SUPPORT_RATE_LIMIT(hwdev)) return 0; + err = hinic_global_func_id_get(hwdev, &func_id); + if (err) + return err; + cfg.func_valid = 1; - cfg.func_idx = (u8)hinic_global_func_id(hwdev); + cfg.func_idx = (u8)func_id; cfg.op_code = HINIC_BIOS_CFG_GET | HINIC_BIOS_CFG_PF_BW_LIMIT; @@ -4895,7 +4934,7 @@ int hinic_read_reg(void *hwdev, u32 reg_addr, u32 *val) } static void hinic_exec_recover_cb(struct hinic_hwdev *hwdev, - struct hinic_fault_recover_info *info) + struct hinic_fault_recover_info *info) { sdk_info(hwdev->dev_hdl, "Enter hinic_exec_recover_cb\n"); @@ -5043,8 +5082,8 @@ int hinic_set_ip_check(void *hwdev, bool ip_check_ctl) for (i = 0; i <= HINIC_IPSU_CHANNEL_NUM; i++) { ret = hinic_api_csr_rd32(hwdev, HINIC_NODE_ID_IPSU, - (HINIC_IPSU_CHANNEL0_ADDR + - i * HINIC_IPSU_CHANNEL_OFFSET), &val); + (HINIC_IPSU_CHANNEL0_ADDR + + i * HINIC_IPSU_CHANNEL_OFFSET), &val); if (ret) return ret; @@ -5056,8 +5095,8 @@ int hinic_set_ip_check(void *hwdev, bool ip_check_ctl) val = cpu_to_be32(val); ret = hinic_api_csr_wr32(hwdev, HINIC_NODE_ID_IPSU, - (HINIC_IPSU_CHANNEL0_ADDR + - i * HINIC_IPSU_CHANNEL_OFFSET), val); + (HINIC_IPSU_CHANNEL0_ADDR + + i * HINIC_IPSU_CHANNEL_OFFSET), val); if (ret) return ret; } @@ -5103,7 +5142,7 @@ int hinic_set_vxlan_udp_dport(void *hwdev, u32 udp_port) return 0; ret = hinic_api_csr_rd32(hwdev, HINIC_NODE_ID_IPSU, - HINIC_IPSURX_VXLAN_DPORT_ADDR, &val); + HINIC_IPSURX_VXLAN_DPORT_ADDR, &val); if (ret) return ret; @@ -5116,7 +5155,7 @@ int hinic_set_vxlan_udp_dport(void *hwdev, u32 udp_port) udp_port = cpu_to_be32(udp_port); ret = hinic_api_csr_wr32(hwdev, HINIC_NODE_ID_IPSU, - HINIC_IPSURX_VXLAN_DPORT_ADDR, udp_port); + HINIC_IPSURX_VXLAN_DPORT_ADDR, udp_port); if (ret) return ret; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hwdev.h b/drivers/net/ethernet/huawei/hinic/hinic_hwdev.h index e0d76b192080e2cd3cf768377ef7190cc141186b..eebd74b85f94b2cbf640b0797ee894376e05371f 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_hwdev.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_hwdev.h @@ -24,6 +24,30 @@ #define HINIC_MSG_TO_MGMT_MAX_LEN 2016 +#define HINIC_MGMT_STATUS_ERR_OK 0 /* Ok */ +#define HINIC_MGMT_STATUS_ERR_PARAM 1 /* Invalid parameter */ +#define HINIC_MGMT_STATUS_ERR_FAILED 2 /* Operation failed */ +#define HINIC_MGMT_STATUS_ERR_PORT 3 /* Invalid port */ +#define HINIC_MGMT_STATUS_ERR_TIMEOUT 4 /* Operation time out */ +#define HINIC_MGMT_STATUS_ERR_NOMATCH 5 /* Version not match */ +#define HINIC_MGMT_STATUS_ERR_EXIST 6 /* Entry exists */ +#define HINIC_MGMT_STATUS_ERR_NOMEM 7 /* Out of memory */ +#define HINIC_MGMT_STATUS_ERR_INIT 8 /* Feature not initialized */ +#define HINIC_MGMT_STATUS_ERR_FAULT 9 /* Invalid address */ +#define HINIC_MGMT_STATUS_ERR_PERM 10 /* Operation not permitted */ +#define HINIC_MGMT_STATUS_ERR_EMPTY 11 /* Table empty */ +#define HINIC_MGMT_STATUS_ERR_FULL 12 /* Table full */ +#define HINIC_MGMT_STATUS_ERR_NOT_FOUND 13 /* Not found */ +#define HINIC_MGMT_STATUS_ERR_BUSY 14 /* Device or resource busy */ +#define HINIC_MGMT_STATUS_ERR_RESOURCE 15 /* No resources for operation */ +#define HINIC_MGMT_STATUS_ERR_CONFIG 16 /* Invalid configuration */ +#define HINIC_MGMT_STATUS_ERR_UNAVAIL 17 /* Feature unavailable */ +#define HINIC_MGMT_STATUS_ERR_CRC 18 /* CRC check failed */ +#define HINIC_MGMT_STATUS_ERR_NXIO 19 /* No such device or address */ +#define HINIC_MGMT_STATUS_ERR_ROLLBACK 20 /* Chip rollback fail */ +#define HINIC_MGMT_STATUS_ERR_LEN 32 /* Length too short or too long */ +#define HINIC_MGMT_STATUS_ERR_UNSUPPORT 0xFF/* Feature not supported*/ + struct cfg_mgmt_info; struct rdma_comp_resource; @@ -193,7 +217,8 @@ struct hinic_heartbeat_enhanced { HINIC_FUNC_SUPP_DFX_REG | \ HINIC_FUNC_SRIOV_EN_DFLT | \ HINIC_FUNC_SUPP_RX_MODE | \ - HINIC_FUNC_SUPP_CHANGE_MAC) + HINIC_FUNC_SUPP_CHANGE_MAC | \ + HINIC_FUNC_OFFLOAD_OVS_UNSUPP) #define MULTI_HOST_CHIP_MODE_SHIFT 0 #define MULTI_HOST_MASTER_MBX_STS_SHIFT 0x4 @@ -294,6 +319,8 @@ struct hinic_hwdev { struct semaphore ppf_sem; void *ppf_hwdev; + struct semaphore func_sem; + int func_ref; struct hinic_board_info board_info; #define MGMT_VERSION_MAX_LEN 32 u8 mgmt_ver[MGMT_VERSION_MAX_LEN]; @@ -347,8 +374,8 @@ int hinic_pf_msg_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd, void *buf_out, u16 *out_size, u32 timeout); int hinic_pf_send_clp_cmd(void *hwdev, enum hinic_mod_type mod, u8 cmd, - void *buf_in, u16 in_size, - void *buf_out, u16 *out_size); + void *buf_in, u16 in_size, + void *buf_out, u16 *out_size); int hinic_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit); @@ -379,4 +406,5 @@ int hinic_get_sdi_mode(struct hinic_hwdev *hwdev, u16 *cur_mode); void mgmt_heartbeat_event_handler(void *hwdev, void *buf_in, u16 in_size, void *buf_out, u16 *out_size); + #endif diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hwif.c b/drivers/net/ethernet/huawei/hinic/hinic_hwif.c index fad2d6d9459d7b738aefa4e7ea4057ed94fde1f1..260c61d19242a943f6651dad87de84e0255bf318 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_hwif.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_hwif.c @@ -10,6 +10,7 @@ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. + * */ #define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt @@ -26,6 +27,7 @@ #include "hinic_csr.h" #include "hinic_hwif.h" +#include "hinic_eqs.h" #define WAIT_HWIF_READY_TIMEOUT 10000 @@ -671,6 +673,108 @@ u16 hinic_global_func_id(void *hwdev) } EXPORT_SYMBOL(hinic_global_func_id); +/*get function id from register,used by sriov hot migration process*/ +u16 hinic_global_func_id_hw(void *hwdev) +{ + u32 addr, attr0; + struct hinic_hwdev *dev; + + dev = (struct hinic_hwdev *)hwdev; + addr = HINIC_CSR_FUNC_ATTR0_ADDR; + attr0 = hinic_hwif_read_reg(dev->hwif, addr); + + return HINIC_AF0_GET(attr0, FUNC_GLOBAL_IDX); +} + +static int func_busy_state_check(struct hinic_hwdev *hwdev) +{ + u32 func_state; + int cycle; + + /*set BUSY before src vm suspend and clear it before dst vm resume*/ + cycle = PIPE_CYCLE_MAX; + func_state = hinic_func_busy_state_get(hwdev); + while (func_state && cycle) { + msleep(20); + cycle--; + if (!cycle) { + sdk_err(hwdev->dev_hdl, "busy_state suspend timeout"); + return -ETIMEDOUT; + } + + func_state = hinic_func_busy_state_get(hwdev); + } + + return 0; +} + +int hinic_func_own_get(void *hwdev) +{ + struct hinic_hwdev *dev = (struct hinic_hwdev *)hwdev; + u32 func_state; + int err; + + if (!HINIC_IS_VF(dev)) + return 0; + +restart: + down(&dev->func_sem); + + dev->func_ref++; + hinic_func_own_bit_set(dev, 1); + + func_state = hinic_func_busy_state_get(hwdev); + if (func_state) { + dev->func_ref--; + if (dev->func_ref == 0) + hinic_func_own_bit_set(dev, 0); + + up(&dev->func_sem); + err = func_busy_state_check(dev); + if (err) + return err; + goto restart; + } + + up(&dev->func_sem); + return 0; +} + +void hinic_func_own_free(void *hwdev) +{ + struct hinic_hwdev *dev = (struct hinic_hwdev *)hwdev; + + if (!HINIC_IS_VF(dev)) + return; + + down(&dev->func_sem); + dev->func_ref--; + if (dev->func_ref == 0) + hinic_func_own_bit_set(dev, 0); + + up(&dev->func_sem); +} + +/*get function id, used by sriov hot migratition process.*/ +int hinic_global_func_id_get(void *hwdev, u16 *func_id) +{ + struct hinic_hwdev *dev = (struct hinic_hwdev *)hwdev; + int err; + + /*only vf get func_id from chip reg for sriov migrate*/ + if (!HINIC_IS_VF(dev)) { + *func_id = hinic_global_func_id(hwdev); + return 0; + } + + err = func_busy_state_check(dev); + if (err) + return err; + + *func_id = hinic_global_func_id_hw(dev); + return 0; +} + u16 hinic_intr_num(void *hwdev) { struct hinic_hwif *hwif; @@ -697,6 +801,18 @@ u8 hinic_pf_id_of_vf(void *hwdev) } EXPORT_SYMBOL(hinic_pf_id_of_vf); +u16 hinic_pf_id_of_vf_hw(void *hwdev) +{ + u32 addr, attr0; + struct hinic_hwdev *dev; + + dev = (struct hinic_hwdev *)hwdev; + addr = HINIC_CSR_FUNC_ATTR0_ADDR; + attr0 = hinic_hwif_read_reg(dev->hwif, addr); + + return HINIC_AF0_GET(attr0, P2P_IDX); +} + u8 hinic_pcie_itf_id(void *hwdev) { struct hinic_hwif *hwif; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_lld.c b/drivers/net/ethernet/huawei/hinic/hinic_lld.c index 4260ed404c6576404d698a423bcd8a1b08585f71..f653694dfbd6c4c52847bf2854e2cf56ec226159 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_lld.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_lld.c @@ -134,7 +134,6 @@ struct hinic_pcidev { bool nic_cur_enable; bool nic_des_enable; }; - #define HINIC_EVENT_PROCESS_TIMEOUT 10000 #define FIND_BIT(num, n) (((num) & (1UL << (n))) ? 1 : 0) @@ -146,7 +145,7 @@ static u64 card_bit_map; LIST_HEAD(g_hinic_chip_list); struct hinic_uld_info g_uld_info[SERVICE_T_MAX] = { {0} }; static const char *s_uld_name[SERVICE_T_MAX] = { - "nic", "ovs", "roce", "toe", "iwarp", "fc", "fcoe", }; + "nic", "ovs", "roce", "toe", "iwarp", "fc", "fcoe", "migrate"}; enum hinic_lld_status { HINIC_NODE_CHANGE = BIT(0), @@ -276,7 +275,6 @@ static int attach_uld(struct hinic_pcidev *dev, enum hinic_service_type type, { void *uld_dev = NULL; int err; - mutex_lock(&dev->pdev_mutex); if (dev->init_state < HINIC_INIT_STATE_HWDEV_INITED) { @@ -702,12 +700,6 @@ struct mctp_hdr { u8 spc_field; }; -struct mctp_drv_info { - struct mctp_hdr hdr; /* spc_field: driver is valid, alway 0 */ - u8 drv_name[32]; - u8 drv_ver[MAX_VER_SPLIT_NUM]; -}; - struct mctp_bdf_info { struct mctp_hdr hdr; /* spc_field: pf index */ u8 rsvd; @@ -716,37 +708,13 @@ struct mctp_bdf_info { u8 function; }; -struct ipaddr_info { - u8 ip[16]; - u8 prefix; /* netmask */ - u8 rsvd[3]; -}; - -#define MCTP_HOST_MAX_IP_ADDR 8 -#define MCTP_IP_TYPE_V4 0U -#define MCTP_IP_TYPE_V6 1U - -struct mctp_ipaddrs_info { - struct mctp_hdr hdr; /* spc_field: pf index */ - u16 ip_cnt; - u8 ip_type_bitmap; - u8 rsvd; - - struct ipaddr_info ip[MCTP_HOST_MAX_IP_ADDR]; -}; - enum mctp_resp_code { /* COMMAND_COMPLETED = 0, */ - COMMAND_FAILED = 1, + /* COMMAND_FAILED = 1, */ /* COMMAND_UNAVALILABLE = 2, */ COMMAND_UNSUPPORTED = 3, }; -enum mctp_reason_code { - /* OEM_CMD_HEAD_INFO_INVALID = 0x8002, */ - OEM_GET_INFO_FAILED = 0x8003, -}; - static void __mctp_set_hdr(struct mctp_hdr *hdr, struct hinic_mctp_host_info *mctp_info) { @@ -760,29 +728,6 @@ static void __mctp_set_hdr(struct mctp_hdr *hdr, hdr->reason_code = cpu_to_be16(hdr->reason_code); } -static void __mctp_get_drv_info(struct hinic_pcidev *pci_adapter, - struct hinic_mctp_host_info *mctp_info) -{ - struct mctp_drv_info *drv_info = mctp_info->data; - char ver_split[MAX_VER_SPLIT_NUM][MAX_VER_FIELD_LEN] = { {0} }; - int split_num = 0, split; - u8 ver_i[MAX_VER_SPLIT_NUM] = {0}; - int drv_name_len; - - __version_split(HINIC_DRV_VERSION, &split_num, ver_split); - for (split = 0; split < split_num; split++) - ver_i[split] = (u8)local_atoi(ver_split[split]); - - drv_name_len = (int)strlen(HINIC_DRV_NAME); - memcpy(drv_info->drv_name, HINIC_DRV_NAME, drv_name_len); - memcpy(drv_info->drv_ver, ver_i, sizeof(drv_info->drv_ver)); - - memset(&drv_info->hdr, 0, sizeof(drv_info->hdr)); - __mctp_set_hdr(&drv_info->hdr, mctp_info); - - mctp_info->data_len = sizeof(*drv_info); -} - static void __mctp_get_bdf(struct hinic_pcidev *pci_adapter, struct hinic_mctp_host_info *mctp_info) { @@ -795,100 +740,12 @@ static void __mctp_get_bdf(struct hinic_pcidev *pci_adapter, memset(&bdf_info->hdr, 0, sizeof(bdf_info->hdr)); __mctp_set_hdr(&bdf_info->hdr, mctp_info); - bdf_info->hdr.spc_field = (u8)hinic_global_func_id(pci_adapter->hwdev); + bdf_info->hdr.spc_field = + (u8)hinic_global_func_id_hw(pci_adapter->hwdev); mctp_info->data_len = sizeof(*bdf_info); } -static void __copy_ipv6(u32 *dst, __be32 *src) -{ - *dst++ = *src++; - *dst++ = *src++; - *dst++ = *src++; - *dst = *src; -} - -static void __mctp_get_ipaddr(struct hinic_pcidev *pci_adapter, - struct hinic_mctp_host_info *mctp_info) -{ - struct mctp_ipaddrs_info *ip_info = mctp_info->data; - struct ipaddr_info *ip; - struct hinic_nic_dev *nic_dev; - struct net_device *netdev; - struct in_device *in_dev; - struct inet6_dev *in6_dev; - struct inet6_ifaddr *ifp; -#ifdef HAVE_INET6_IFADDR_LIST - struct inet6_ifaddr *tmp; -#endif - u16 ip_cnt = 0; - bool got_lock = true; - - memset(&ip_info->hdr, 0, sizeof(ip_info->hdr)); - - nic_dev = pci_adapter->uld_dev[SERVICE_T_NIC]; - if (!hinic_support_nic(pci_adapter->hwdev, NULL) || !nic_dev) { - ip_info->hdr.resp_code = COMMAND_FAILED; - ip_info->hdr.reason_code = OEM_GET_INFO_FAILED; - goto out; - } - - netdev = nic_dev->netdev; - - if (!rtnl_trylock()) - got_lock = false; - - in_dev = in_dev_get(netdev); - if (in_dev) { - for_ifa(in_dev) { - if (ip_cnt < MCTP_HOST_MAX_IP_ADDR) { - ip = &ip_info->ip[ip_cnt]; - *((u32 *)(ip->ip)) = ifa->ifa_address; - ip->prefix = ifa->ifa_prefixlen; - ip_info->ip_type_bitmap |= - (u8)(MCTP_IP_TYPE_V4 << ip_cnt); - } - - ip_cnt++; - } endfor_ifa(in_dev); - in_dev_put(in_dev); - } - - if (got_lock) - rtnl_unlock(); - - in6_dev = __in6_dev_get(netdev); - if (!in6_dev) - goto out; - - read_lock_bh(&in6_dev->lock); - -#ifdef HAVE_INET6_IFADDR_LIST - list_for_each_entry_safe(ifp, tmp, &in6_dev->addr_list, if_list) { -#else - for (ifp = in6_dev->addr_list; ifp; ifp = ifp->if_next) { -#endif - if (ip_cnt < MCTP_HOST_MAX_IP_ADDR) { - ip = &ip_info->ip[ip_cnt]; - __copy_ipv6((u32 *)(ip->ip), ifp->addr.in6_u.u6_addr32); - ip->prefix = (u8)ifp->prefix_len; - ip_info->ip_type_bitmap |= - (u8)(MCTP_IP_TYPE_V6 << ip_cnt); - } - - ip_cnt++; - } - - read_unlock_bh(&in6_dev->lock); - -out: - ip_info->ip_cnt = cpu_to_be16(ip_cnt); - __mctp_set_hdr(&ip_info->hdr, mctp_info); - ip_info->hdr.spc_field = (u8)hinic_global_func_id(pci_adapter->hwdev); - - mctp_info->data_len = sizeof(*ip_info); -} - #define MCTP_MAJOR_CMD_PUBLIC 0x0 #define MCTP_MAJOR_CMD_NIC 0x1 @@ -907,14 +764,6 @@ static void __mctp_get_host_info(struct hinic_pcidev *dev, __mctp_get_bdf(dev, mctp_info); break; - case (MCTP_MAJOR_CMD_PUBLIC << 8 | MCTP_PUBLIC_SUB_CMD_DRV): - __mctp_get_drv_info(dev, mctp_info); - break; - - case (MCTP_MAJOR_CMD_NIC << 8 | MCTP_NIC_SUB_CMD_IP): - __mctp_get_ipaddr(dev, mctp_info); - break; - default: hdr = mctp_info->data; hdr->reason_code = COMMAND_UNSUPPORTED; @@ -924,7 +773,8 @@ static void __mctp_get_host_info(struct hinic_pcidev *dev, } } -static bool __is_pcidev_match_chip_name(char *ifname, struct hinic_pcidev *dev, +static bool __is_pcidev_match_chip_name(const char *ifname, + struct hinic_pcidev *dev, struct card_node *chip_node, enum func_type type) { @@ -1004,7 +854,8 @@ static struct hinic_pcidev *hinic_get_pcidev_by_chip_name(char *ifname) return NULL; } -static bool __is_pcidev_match_dev_name(char *ifname, struct hinic_pcidev *dev, +static bool __is_pcidev_match_dev_name(const char *ifname, + struct hinic_pcidev *dev, enum hinic_service_type type) { struct hinic_nic_dev *nic_dev; @@ -1099,7 +950,7 @@ int hinic_get_chip_name_by_hwdev(void *hwdev, char *ifname) } EXPORT_SYMBOL(hinic_get_chip_name_by_hwdev); -static struct card_node *hinic_get_chip_node_by_hwdev(void *hwdev) +static struct card_node *hinic_get_chip_node_by_hwdev(const void *hwdev) { struct card_node *chip_node = NULL; struct card_node *node_tmp = NULL; @@ -1408,6 +1259,12 @@ void hinic_get_card_info(void *hwdev, void *bufin) if (hinic_func_for_mgmt(fun_hwdev)) strlcpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ); + if (hinic_func_for_pt(fun_hwdev)) + info->pf[i].pf_type |= (u32)BIT(SERVICE_T_PT); + + if (hinic_func_for_hwpt(fun_hwdev)) + info->pf[i].pf_type |= (u32)BIT(SERVICE_T_HWPT); + strlcpy(info->pf[i].bus_info, pci_name(dev->pcidev), sizeof(info->pf[i].bus_info)); info->pf_num++; @@ -1416,7 +1273,7 @@ void hinic_get_card_info(void *hwdev, void *bufin) lld_dev_put(); } -int hinic_get_card_func_info_by_card_name(char *chip_name, +int hinic_get_card_func_info_by_card_name(const char *chip_name, struct hinic_card_func_info *card_func) { @@ -1767,16 +1624,20 @@ struct pci_device_id *hinic_get_pci_device_id(struct pci_dev *pdev) return &adapter->id; } +EXPORT_SYMBOL(hinic_get_pci_device_id); static int __set_nic_func_state(struct hinic_pcidev *pci_adapter) { struct pci_dev *pdev = pci_adapter->pcidev; + u16 func_id; int err; bool enable_nic; - err = hinic_get_func_nic_enable(pci_adapter->hwdev, - hinic_global_func_id - (pci_adapter->hwdev), + err = hinic_global_func_id_get(pci_adapter->hwdev, &func_id); + if (err) + return err; + + err = hinic_get_func_nic_enable(pci_adapter->hwdev, func_id, &enable_nic); if (err) { sdk_err(&pdev->dev, "Failed to get nic state\n"); @@ -1800,6 +1661,88 @@ static int __set_nic_func_state(struct hinic_pcidev *pci_adapter) return 0; } +int hinic_ovs_set_vf_nic_state(struct hinic_lld_dev *lld_dev, u16 vf_func_id, + bool en) +{ + struct hinic_pcidev *dev, *des_dev; + struct hinic_nic_dev *uld_dev; + int err = -EFAULT; + + if (!lld_dev) + return -EINVAL; + + dev = pci_get_drvdata(lld_dev->pdev); + + if (!dev) + return -EFAULT; + /* find func_idx pci_adapter and disable or enable nic */ + lld_dev_hold(); + list_for_each_entry(des_dev, &dev->chip_node->func_list, node) { + if (test_bit(HINIC_FUNC_IN_REMOVE, &dev->flag)) + continue; + + if (des_dev->init_state < + HINIC_INIT_STATE_DBGTOOL_INITED && + !test_bit(HINIC_FUNC_PRB_ERR, + &des_dev->flag)) + continue; + + if (hinic_global_func_id(des_dev->hwdev) != vf_func_id) + continue; + + if (des_dev->init_state < + HINIC_INIT_STATE_DBGTOOL_INITED) { + break; + } + + sdk_info(&dev->pcidev->dev, "Receive event: %s vf%d nic\n", + en ? "enable" : "disable", vf_func_id); + + err = 0; + if (en) { + if (des_dev->uld_dev[SERVICE_T_NIC]) { + sdk_err(&des_dev->pcidev->dev, + "%s driver has attached to pcie device, cannot set VF max_queue_num\n", + s_uld_name[SERVICE_T_NIC]); + } else { + err = hinic_set_vf_dev_cap(des_dev->hwdev); + + if (err) { + sdk_err(&des_dev->pcidev->dev, + "%s driver Set VF max_queue_num failed, err=%d.\n", + s_uld_name[SERVICE_T_NIC], err); + + break; + } + } + + err = attach_uld(des_dev, SERVICE_T_NIC, + &g_uld_info[SERVICE_T_NIC]); + if (err) { + sdk_err(&des_dev->pcidev->dev, "Failed to initialize NIC\n"); + break; + } + + uld_dev = (struct hinic_nic_dev *) + (des_dev->uld_dev[SERVICE_T_NIC]); + uld_dev->in_vm = true; + uld_dev->is_vm_slave = + is_multi_vm_slave(uld_dev->hwdev); + if (des_dev->init_state < HINIC_INIT_STATE_NIC_INITED) + des_dev->init_state = + HINIC_INIT_STATE_NIC_INITED; + } else { + detach_uld(des_dev, SERVICE_T_NIC); + } + + break; + } + lld_dev_put(); + + return err; +} +EXPORT_SYMBOL(hinic_ovs_set_vf_nic_state); + static void slave_host_mgmt_work(struct work_struct *work) { struct hinic_pcidev *pci_adapter = @@ -1834,7 +1777,7 @@ static void __multi_host_mgmt(struct hinic_pcidev *dev, &des_dev->flag)) continue; - if (hinic_global_func_id(des_dev->hwdev) != + if (hinic_global_func_id_hw(des_dev->hwdev) != nic_state->func_idx) continue; @@ -1843,7 +1786,6 @@ static void __multi_host_mgmt(struct hinic_pcidev *dev, nic_state->status = test_bit(HINIC_FUNC_PRB_ERR, &des_dev->flag) ? 1 : 0; - break; } @@ -1923,7 +1865,7 @@ static int mapping_bar(struct pci_dev *pdev, struct hinic_pcidev *pci_adapter) dwqe_addr = pci_adapter->db_base_phy + HINIC_DB_DWQE_SIZE; - /* arm do not support call ioremap_wc() */ + /* arm do not support call ioremap_wc(), refer to */ pci_adapter->dwqe_mapping = __ioremap(dwqe_addr, HINIC_DB_DWQE_SIZE, __pgprot(PROT_DEVICE_nGnRnE)); if (!pci_adapter->dwqe_mapping) { @@ -2031,14 +1973,15 @@ static int alloc_chip_node(struct hinic_pcidev *pci_adapter) static void free_chip_node(struct hinic_pcidev *pci_adapter) { struct card_node *chip_node = pci_adapter->chip_node; - int id, err; + u32 id; + int err; if (list_empty(&chip_node->func_list)) { list_del(&chip_node->node); sdk_info(&pci_adapter->pcidev->dev, "Delete chip %s from global list succeed\n", chip_node->chip_name); - err = sscanf(chip_node->chip_name, HINIC_CHIP_NAME "%d", &id); + err = sscanf(chip_node->chip_name, HINIC_CHIP_NAME "%u", &id); if (err < 0) sdk_err(&pci_adapter->pcidev->dev, "Failed to get hinic id\n"); @@ -2081,19 +2024,16 @@ static bool hinic_get_vf_load_state(struct pci_dev *pdev) return disable_vf_load; } -static void hinic_set_vf_load_state(struct hinic_pcidev *pci_adapter) +static void hinic_set_vf_load_state(struct hinic_pcidev *pci_adapter, + bool vf_load_state) { struct card_node *chip_node; - bool vf_load_state; u16 func_id; if (hinic_func_type(pci_adapter->hwdev) == TYPE_VF) return; - vf_load_state = hinic_support_ovs(pci_adapter->hwdev, NULL) ? - true : disable_vf_load; - - func_id = hinic_global_func_id(pci_adapter->hwdev); + func_id = hinic_global_func_id_hw(pci_adapter->hwdev); chip_node = pci_adapter->chip_node; chip_node->disable_vf_load[func_id] = vf_load_state; @@ -2104,6 +2044,27 @@ static void hinic_set_vf_load_state(struct hinic_pcidev *pci_adapter) (vf_load_state ? "disable" : "enable")); } +int hinic_ovs_set_vf_load_state(struct pci_dev *pdev) +{ + struct hinic_pcidev *pci_adapter; + + if (!pdev) { + pr_err("pdev is null.\n"); + return -EINVAL; + } + + pci_adapter = pci_get_drvdata(pdev); + if (!pci_adapter) { + pr_err("pci_adapter is null.\n"); + return -EFAULT; + } + + hinic_set_vf_load_state(pci_adapter, disable_vf_load); + + return 0; +} +EXPORT_SYMBOL(hinic_ovs_set_vf_load_state); + static int hinic_config_deft_mrss(struct pci_dev *pdev) { return 0; @@ -2276,6 +2237,7 @@ static int hinic_func_init(struct pci_dev *pdev, struct hinic_pcidev *pci_adapter) { struct hinic_init_para init_para; + bool vf_load_state; int err; init_para.adapter_hdl = pci_adapter; @@ -2318,7 +2280,10 @@ static int hinic_func_init(struct pci_dev *pdev, hinic_notify_ppf_reg(pci_adapter); pci_adapter->init_state = HINIC_INIT_STATE_HWDEV_INITED; - hinic_set_vf_load_state(pci_adapter); + vf_load_state = hinic_support_ovs(pci_adapter->hwdev, NULL) ? + true : disable_vf_load; + + hinic_set_vf_load_state(pci_adapter, vf_load_state); pci_adapter->lld_dev.pdev = pdev; pci_adapter->lld_dev.hwdev = pci_adapter->hwdev; @@ -2416,9 +2381,9 @@ static void hinic_func_deinit(struct pci_dev *pdev) hinic_notify_ppf_unreg(pci_adapter); if (pci_adapter->init_state >= HINIC_INIT_STATE_HW_IF_INITED) { - /* Remove the current node from node-list first, - * then it's safe to free hwdev - */ + /* Remove the current node from node-list first, + * then it's safe to free hwdev + */ lld_lock_chip_node(); list_del(&pci_adapter->node); lld_unlock_chip_node(); @@ -2502,11 +2467,12 @@ static void hinic_remove(struct pci_dev *pdev) case HINIC_INIT_STATE_HW_IF_INITED: case HINIC_INIT_STATE_PCI_INITED: set_bit(HINIC_FUNC_IN_REMOVE, &pci_adapter->flag); - wait_tool_unused(); lld_lock_chip_node(); cancel_work_sync(&pci_adapter->slave_nic_work); lld_unlock_chip_node(); + wait_tool_unused(); + if (pci_adapter->init_state >= HINIC_INIT_STATE_HW_IF_INITED) hinic_func_deinit(pdev); @@ -2570,11 +2536,12 @@ static void slave_host_init_delay_work(struct work_struct *work) if (err) set_bit(HINIC_FUNC_PRB_ERR, &pci_adapter->flag); return; + } else { + queue_delayed_work(pci_adapter->slave_nic_init_workq, + &pci_adapter->slave_nic_init_dwork, + HINIC_SLAVE_NIC_DELAY_TIME); + return; } - - queue_delayed_work(pci_adapter->slave_nic_init_workq, - &pci_adapter->slave_nic_init_dwork, - HINIC_SLAVE_NIC_DELAY_TIME); } static int hinic_probe(struct pci_dev *pdev, const struct pci_device_id *id) @@ -2677,6 +2644,8 @@ static const struct pci_device_id hinic_pci_table[] = { {PCI_VDEVICE(HUAWEI, HINIC_DEV_ID_1822_KR_100GE), HINIC_BOARD_100GE}, {PCI_VDEVICE(HUAWEI, HINIC_DEV_ID_1822_KR_25GE), HINIC_BOARD_25GE}, {PCI_VDEVICE(HUAWEI, HINIC_DEV_ID_1822_MULTI_HOST), HINIC_BOARD_25GE}, + {PCI_VDEVICE(HUAWEI, HINIC_DEV_ID_1822_100GE), HINIC_BOARD_100GE}, + {PCI_VDEVICE(HUAWEI, HINIC_DEV_ID_1822_DUAL_25GE), HINIC_BOARD_25GE}, {0, 0} }; @@ -2775,6 +2744,7 @@ static void __exit hinic_lld_exit(void) pci_unregister_driver(&hinic_driver); hinic_unregister_uld(SERVICE_T_NIC); + } module_init(hinic_lld_init); module_exit(hinic_lld_exit); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_lld.h b/drivers/net/ethernet/huawei/hinic/hinic_lld.h index deaeb95d5345076cc34e7a09d4bbb6213fea2f36..844fb5f236d6d502085980bb00b6288503c6dab6 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_lld.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_lld.h @@ -109,6 +109,11 @@ void hinic_detach_roce(struct hinic_lld_dev *lld_dev); int hinic_disable_nic_rss(struct hinic_lld_dev *lld_dev); int hinic_enable_nic_rss(struct hinic_lld_dev *lld_dev); +int hinic_ovs_set_vf_nic_state(struct hinic_lld_dev *lld_dev, + u16 vf_func_id, bool en); + +int hinic_ovs_set_vf_load_state(struct pci_dev *pdev); + int hinic_get_self_test_result(char *ifname, u32 *result); enum hinic_init_state hinic_get_init_state_by_ifname(char *ifname); enum hinic_init_state hinic_get_init_state(struct pci_dev *pdev); @@ -117,5 +122,7 @@ extern struct hinic_uld_info g_uld_info[SERVICE_T_MAX]; struct pci_device_id *hinic_get_pci_device_id(struct pci_dev *pdev); bool hinic_is_in_host(void); + bool hinic_is_valid_bar_addr(u64 offset); + #endif diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c index 9fd3411b6c7d57f0ba773b9f66171e26cb7153e1..a2238b97ccef35a8c7ea760c8be670c39f89511f 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_main.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c @@ -105,8 +105,23 @@ static unsigned char lro_en_status = HINIC_LRO_STATUS_UNSET; module_param(lro_en_status, byte, 0444); MODULE_PARM_DESC(lro_en_status, "lro enable status. 0 - disable, 1 - enable, other - unset. (default unset)"); +static unsigned char qp_pending_limit_low = HINIC_RX_PENDING_LIMIT_LOW; +module_param(qp_pending_limit_low, byte, 0444); +MODULE_PARM_DESC(qp_pending_limit_low, "MSI-X adaptive low coalesce pending limit, range is 0 - 255"); -static unsigned int enable_bp;/*lint !e728*/ +static unsigned char qp_coalesc_timer_low = HINIC_RX_COAL_TIME_LOW; +module_param(qp_coalesc_timer_low, byte, 0444); +MODULE_PARM_DESC(qp_coalesc_timer_low, "MSI-X adaptive low coalesce time, range is 0 - 255"); + +static unsigned char qp_pending_limit_high = HINIC_RX_PENDING_LIMIT_HIGH; +module_param(qp_pending_limit_high, byte, 0444); +MODULE_PARM_DESC(qp_pending_limit_high, "MSI-X adaptive high coalesce pending limit, range is 0 - 255"); + +static unsigned char qp_coalesc_timer_high = HINIC_RX_COAL_TIME_HIGH; +module_param(qp_coalesc_timer_high, byte, 0444); +MODULE_PARM_DESC(qp_coalesc_timer_high, "MSI-X adaptive high coalesce time, range is 0 - 255"); + +static unsigned int enable_bp; static unsigned int bp_lower_thd = HINIC_RX_BP_LOWER_THD; static unsigned int bp_upper_thd = HINIC_RX_BP_UPPER_THD; @@ -445,6 +460,8 @@ int hinic_poll(struct napi_struct *napi, int budget) HINIC_MSIX_ENABLE); else if (!nic_dev->in_vm) enable_irq(irq_cfg->irq_id); + } else { + hinic_rx_poll(irq_cfg->rxq, HINIC_RX_BUFFER_WRITE); } return max(tx_pkts, rx_pkts); @@ -572,6 +589,12 @@ static void __calc_coal_para(struct hinic_nic_dev *nic_dev, struct hinic_intr_coal_info *q_coal, u64 rate, u8 *coalesc_timer_cfg, u8 *pending_limt) { + if (nic_dev->is_vm_slave && nic_dev->in_vm) { + *coalesc_timer_cfg = HINIC_MULTI_VM_LATENCY; + *pending_limt = HINIC_MULTI_VM_PENDING_LIMIT; + return; + } + if (rate < q_coal->pkt_rate_low) { *coalesc_timer_cfg = q_coal->rx_usecs_low; *pending_limt = q_coal->rx_pending_limt_low; @@ -609,6 +632,7 @@ static void hinic_auto_moderation_work(struct work_struct *work) nic_dev->last_moder_jiffies); u64 rx_packets, rx_bytes, rx_pkt_diff, rate, avg_pkt_size; + u64 tx_packets, tx_bytes, tx_pkt_diff, tx_rate; u8 coalesc_timer_cfg, pending_limt; u16 qid; @@ -624,6 +648,8 @@ static void hinic_auto_moderation_work(struct work_struct *work) for (qid = 0; qid < nic_dev->num_qps; qid++) { rx_packets = nic_dev->rxqs[qid].rxq_stats.packets; rx_bytes = nic_dev->rxqs[qid].rxq_stats.bytes; + tx_packets = nic_dev->txqs[qid].txq_stats.packets; + tx_bytes = nic_dev->txqs[qid].txq_stats.bytes; q_coal = &nic_dev->intr_coalesce[qid]; rx_pkt_diff = @@ -634,14 +660,24 @@ static void hinic_auto_moderation_work(struct work_struct *work) rx_pkt_diff : 0; rate = rx_pkt_diff * HZ / period; + tx_pkt_diff = + tx_packets - nic_dev->txqs[qid].last_moder_packets; + tx_rate = tx_pkt_diff * HZ / period; if ((rate > HINIC_RX_RATE_THRESH && - avg_pkt_size > HINIC_AVG_PKT_SMALL) || nic_dev->in_vm) { + avg_pkt_size > HINIC_AVG_PKT_SMALL) || + (nic_dev->in_vm && (rate > HINIC_RX_RATE_THRESH || + (nic_dev->is_vm_slave && + tx_rate > HINIC_TX_RATE_THRESH)))) { __calc_coal_para(nic_dev, q_coal, rate, &coalesc_timer_cfg, &pending_limt); } else { - coalesc_timer_cfg = HINIC_LOWEST_LATENCY; - pending_limt = q_coal->rx_pending_limt_low; + coalesc_timer_cfg = + (nic_dev->is_vm_slave && nic_dev->in_vm) ? + 0 : HINIC_LOWEST_LATENCY; + pending_limt = + (nic_dev->is_vm_slave && nic_dev->in_vm) ? + 0 : q_coal->rx_pending_limt_low; } set_interrupt_moder(nic_dev, qid, coalesc_timer_cfg, @@ -649,6 +685,8 @@ static void hinic_auto_moderation_work(struct work_struct *work) nic_dev->rxqs[qid].last_moder_packets = rx_packets; nic_dev->rxqs[qid].last_moder_bytes = rx_bytes; + nic_dev->txqs[qid].last_moder_packets = tx_packets; + nic_dev->txqs[qid].last_moder_bytes = tx_bytes; } nic_dev->last_moder_jiffies = jiffies; @@ -1039,8 +1077,8 @@ static u16 select_queue_by_toeplitz(struct net_device *dev, #if defined(HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK) #if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV) static u16 hinic_select_queue(struct net_device *netdev, struct sk_buff *skb, - struct net_device *sb_dev, - select_queue_fallback_t fallback) + struct net_device *sb_dev, + select_queue_fallback_t fallback) #else static u16 hinic_select_queue(struct net_device *netdev, struct sk_buff *skb, __always_unused void *accel, @@ -1084,7 +1122,7 @@ static u16 hinic_select_queue(struct net_device *netdev, struct sk_buff *skb) #ifdef HAVE_NDO_GET_STATS64 #ifdef HAVE_VOID_NDO_GET_STATS64 static void hinic_get_stats64(struct net_device *netdev, - struct rtnl_link_stats64 *stats) + struct rtnl_link_stats64 *stats) #else static struct rtnl_link_stats64 *hinic_get_stats64(struct net_device *netdev, @@ -1191,6 +1229,7 @@ static int hinic_set_mac_addr(struct net_device *netdev, void *addr) { struct hinic_nic_dev *nic_dev = netdev_priv(netdev); struct sockaddr *saddr = addr; + u16 func_id; int err; if (!FUNC_SUPPORT_CHANGE_MAC(nic_dev->hwdev)) { @@ -1209,8 +1248,12 @@ static int hinic_set_mac_addr(struct net_device *netdev, void *addr) return 0; } + err = hinic_global_func_id_get(nic_dev->hwdev, &func_id); + if (err) + return err; + err = hinic_update_mac(nic_dev->hwdev, netdev->dev_addr, saddr->sa_data, - 0, hinic_global_func_id(nic_dev->hwdev)); + 0, func_id); if (err) return err; @@ -1233,13 +1276,17 @@ hinic_vlan_rx_add_vid(struct net_device *netdev, { struct hinic_nic_dev *nic_dev = netdev_priv(netdev); unsigned long *vlan_bitmap = nic_dev->vlan_bitmap; - u16 func_id = hinic_global_func_id(nic_dev->hwdev); + u16 func_id; u32 col, line; int err; col = VID_COL(nic_dev, vid); line = VID_LINE(nic_dev, vid); + err = hinic_global_func_id_get(nic_dev->hwdev, &func_id); + if (err) + goto end; + err = hinic_add_vlan(nic_dev->hwdev, vid, func_id); if (err) { nicif_err(nic_dev, drv, netdev, "Failed to add vlan%d\n", vid); @@ -1261,12 +1308,16 @@ hinic_vlan_rx_kill_vid(struct net_device *netdev, { struct hinic_nic_dev *nic_dev = netdev_priv(netdev); unsigned long *vlan_bitmap = nic_dev->vlan_bitmap; - u16 func_id = hinic_global_func_id(nic_dev->hwdev); + u16 func_id; int err, col, line; col = VID_COL(nic_dev, vid); line = VID_LINE(nic_dev, vid); + err = hinic_global_func_id_get(nic_dev->hwdev, &func_id); + if (err) + goto end; + err = hinic_del_vlan(nic_dev->hwdev, vid, func_id); if (err) { nicif_err(nic_dev, drv, netdev, "Failed to delete vlan\n"); @@ -1409,7 +1460,7 @@ static int hinic_set_default_hw_feature(struct hinic_nic_dev *nic_dev) if (set_link_status_follow < HINIC_LINK_FOLLOW_STATUS_MAX && FUNC_SUPPORT_PORT_SETTING(nic_dev->hwdev)) { err = hinic_set_link_status_follow(nic_dev->hwdev, - set_link_status_follow); + set_link_status_follow); if (err == HINIC_MGMT_CMD_UNSUPPORTED) nic_warn(&nic_dev->pdev->dev, "Current version of firmware don't support to set link status follow port status\n"); @@ -1481,21 +1532,33 @@ static void hinic_netpoll(struct net_device *netdev) static int hinic_uc_sync(struct net_device *netdev, u8 *addr) { struct hinic_nic_dev *nic_dev = netdev_priv(netdev); + u16 func_id; + int err; - return hinic_set_mac(nic_dev->hwdev, addr, 0, - hinic_global_func_id(nic_dev->hwdev)); + err = hinic_global_func_id_get(nic_dev->hwdev, &func_id); + if (err) + return err; + + err = hinic_set_mac(nic_dev->hwdev, addr, 0, func_id); + return err; } static int hinic_uc_unsync(struct net_device *netdev, u8 *addr) { struct hinic_nic_dev *nic_dev = netdev_priv(netdev); + u16 func_id; + int err; /* The addr is in use */ if (ether_addr_equal(addr, netdev->dev_addr)) return 0; - return hinic_del_mac(nic_dev->hwdev, addr, 0, - hinic_global_func_id(nic_dev->hwdev)); + err = hinic_global_func_id_get(nic_dev->hwdev, &func_id); + if (err) + return err; + + err = hinic_del_mac(nic_dev->hwdev, addr, 0, func_id); + return err; } static void hinic_clean_mac_list_filter(struct hinic_nic_dev *nic_dev) @@ -2164,14 +2227,14 @@ static void netdev_feature_init(struct net_device *netdev) } #define MOD_PARA_VALIDATE_NUM_QPS(nic_dev, num_qps, out_qps) { \ - if ((num_qps) > (nic_dev)->max_qps) \ + if ((num_qps) > nic_dev->max_qps) \ nic_warn(&nic_dev->pdev->dev, \ "Module Parameter %s value %d is out of range, "\ "Maximum value for the device: %d, using %d\n",\ - #num_qps, num_qps, (nic_dev)->max_qps, \ - (nic_dev)->max_qps); \ - if (!(num_qps) || (num_qps) > (nic_dev)->max_qps) \ - out_qps = (nic_dev)->max_qps; \ + #num_qps, num_qps, nic_dev->max_qps, \ + nic_dev->max_qps); \ + if (!(num_qps) || (num_qps) > nic_dev->max_qps) \ + out_qps = nic_dev->max_qps; \ else \ out_qps = num_qps; \ } @@ -2197,8 +2260,12 @@ static void hinic_try_to_enable_rss(struct hinic_nic_dev *nic_dev) err = hinic_rss_template_alloc(nic_dev->hwdev, &nic_dev->rss_tmpl_idx); if (err) { - nic_err(&nic_dev->pdev->dev, - "Failed to alloc tmpl_idx for rss, can't enable rss for this function\n"); + if (err == -ENOSPC) + nic_warn(&nic_dev->pdev->dev, + "Failed to alloc tmpl_idx for rss, table is full\n"); + else + nic_err(&nic_dev->pdev->dev, + "Failed to alloc tmpl_idx for rss, can't enable rss for this function\n"); clear_bit(HINIC_RSS_ENABLE, &nic_dev->flags); nic_dev->max_qps = 1; nic_dev->rss_limit = nic_dev->max_qps; @@ -2244,6 +2311,7 @@ static void hinic_try_to_enable_rss(struct hinic_nic_dev *nic_dev) static int hinic_sw_init(struct hinic_nic_dev *adapter) { struct net_device *netdev = adapter->netdev; + u16 func_id; int err = 0; sema_init(&adapter->port_state_sem, 1); @@ -2285,8 +2353,11 @@ static int hinic_sw_init(struct hinic_nic_dev *adapter) eth_hw_addr_random(netdev); } - err = hinic_set_mac(adapter->hwdev, netdev->dev_addr, 0, - hinic_global_func_id(adapter->hwdev)); + err = hinic_global_func_id_get(adapter->hwdev, &func_id); + if (err) + goto func_id_err; + + err = hinic_set_mac(adapter->hwdev, netdev->dev_addr, 0, func_id); /* When this is VF driver, we must consider that PF has already set VF * MAC, and we can't consider this condition is error status during * driver probe procedure. @@ -2309,6 +2380,7 @@ static int hinic_sw_init(struct hinic_nic_dev *adapter) return 0; set_mac_err: +func_id_err: err_mac: get_mac_err: if (test_bit(HINIC_RSS_ENABLE, &adapter->flags)) @@ -2405,16 +2477,20 @@ static void init_intr_coal_param(struct hinic_nic_dev *nic_dev) info->resend_timer_cfg = HINIC_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG; info->pkt_rate_high = HINIC_RX_RATE_HIGH; - info->rx_usecs_high = HINIC_RX_COAL_TIME_HIGH; - info->rx_pending_limt_high = HINIC_RX_PENDING_LIMIT_HIGH; + info->rx_usecs_high = qp_coalesc_timer_high; + info->rx_pending_limt_high = qp_pending_limit_high; info->pkt_rate_low = HINIC_RX_RATE_LOW; - info->rx_usecs_low = HINIC_RX_COAL_TIME_LOW; - info->rx_pending_limt_low = HINIC_RX_PENDING_LIMIT_LOW; + info->rx_usecs_low = qp_coalesc_timer_low; + info->rx_pending_limt_low = qp_pending_limit_low; if (nic_dev->in_vm) { + if (qp_pending_limit_high == + HINIC_RX_PENDING_LIMIT_HIGH) + qp_pending_limit_high = + HINIC_RX_PENDING_LIMIT_HIGH_VM; info->pkt_rate_low = HINIC_RX_RATE_LOW_VM; info->rx_pending_limt_high = - HINIC_RX_PENDING_LIMIT_HIGH_VM; + qp_pending_limit_high; } } } @@ -2523,6 +2599,20 @@ static int hinic_validate_parameters(struct hinic_lld_dev *lld_dev) rx_buff = DEFAULT_RX_BUFF_LEN; } + if (qp_coalesc_timer_high <= qp_coalesc_timer_low) { + nic_warn(&pdev->dev, "Module Parameter qp_coalesc_timer_high: %d, qp_coalesc_timer_low: %d is invalid, resetting to default\n", + qp_coalesc_timer_high, qp_coalesc_timer_low); + qp_coalesc_timer_high = HINIC_RX_COAL_TIME_HIGH; + qp_coalesc_timer_low = HINIC_RX_COAL_TIME_LOW; + } + + if (qp_pending_limit_high <= qp_pending_limit_low) { + nic_warn(&pdev->dev, "Module Parameter qp_pending_limit_high: %d, qp_pending_limit_low: %d is invalid, resetting to default\n", + qp_pending_limit_high, qp_pending_limit_low); + qp_pending_limit_high = HINIC_RX_PENDING_LIMIT_HIGH; + qp_pending_limit_low = HINIC_RX_PENDING_LIMIT_LOW; + } + return 0; } @@ -2723,6 +2813,7 @@ static int nic_probe(struct hinic_lld_dev *lld_dev, void **uld_dev, nic_dev->msg_enable = DEFAULT_MSG_ENABLE; nic_dev->heart_status = true; nic_dev->in_vm = !hinic_is_in_host(); + nic_dev->is_vm_slave = is_multi_vm_slave(lld_dev->hwdev); nic_dev->lro_replenish_thld = lro_replenish_thld; nic_dev->rx_buff_len = (u16)(rx_buff * CONVERT_UNIT); page_num = (RX_BUFF_NUM_PER_PAGE * nic_dev->rx_buff_len) / PAGE_SIZE; @@ -2812,7 +2903,7 @@ static int nic_probe(struct hinic_lld_dev *lld_dev, void **uld_dev, alloc_qps_err: hinic_del_mac(nic_dev->hwdev, netdev->dev_addr, 0, - hinic_global_func_id(nic_dev->hwdev)); + hinic_global_func_id_hw(nic_dev->hwdev)); sw_init_err: (void)hinic_set_super_cqe_state(nic_dev->hwdev, false); @@ -2851,7 +2942,7 @@ static void nic_remove(struct hinic_lld_dev *lld_dev, void *adapter) hinic_clean_mac_list_filter(nic_dev); hinic_del_mac(nic_dev->hwdev, netdev->dev_addr, 0, - hinic_global_func_id(nic_dev->hwdev)); + hinic_global_func_id_hw(nic_dev->hwdev)); if (test_bit(HINIC_RSS_ENABLE, &nic_dev->flags)) hinic_rss_template_free(nic_dev->hwdev, nic_dev->rss_tmpl_idx); @@ -2927,7 +3018,12 @@ int hinic_enable_func_rss(struct hinic_nic_dev *nic_dev) err = hinic_rss_template_alloc(nic_dev->hwdev, &nic_dev->rss_tmpl_idx); if (err) { - nicif_err(nic_dev, drv, netdev, "Failed to alloc RSS template\n"); + if (err == -ENOSPC) + nicif_warn(nic_dev, drv, netdev, + "Failed to alloc RSS template,table is full\n"); + else + nicif_err(nic_dev, drv, netdev, + "Failed to alloc RSS template\n"); } else { set_bit(HINIC_RSS_ENABLE, &nic_dev->flags); nicif_info(nic_dev, drv, netdev, "Success to alloc RSS template\n"); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_mbox.c b/drivers/net/ethernet/huawei/hinic/hinic_mbox.c index bbefb5ef12cb66bdcbf7717fae0170eed435ad58..da8d590f1a622c16b02d1700ca8119b9b5550ac0 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_mbox.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_mbox.c @@ -207,7 +207,7 @@ struct hinic_set_random_id { }; static bool check_func_id(struct hinic_hwdev *hwdev, u16 src_func_idx, - void *buf_in, u16 in_size, u16 offset) + const void *buf_in, u16 in_size, u16 offset) { u16 func_idx; @@ -402,7 +402,7 @@ void hinic_unregister_vf_mbox_cb(struct hinic_hwdev *hwdev, clear_bit(HINIC_VF_MBOX_CB_REG, &func_to_func->vf_mbox_cb_state[mod]); while (test_bit(HINIC_VF_MBOX_CB_RUNNING, - &func_to_func->vf_mbox_cb_state[mod])) + &func_to_func->vf_mbox_cb_state[mod])) usleep_range(900, 1000); func_to_func->vf_mbox_cb[mod] = NULL; @@ -495,7 +495,7 @@ recv_pf_from_ppf_handler(struct hinic_mbox_func_to_func *func_to_func, recv_mbox->mbox, recv_mbox->mbox_len, buf_out, out_size); } else { - sdk_warn(func_to_func->hwdev->dev_hdl, "PF receive ppf mailbox callback is not registered\n"); + sdk_warn(func_to_func->hwdev->dev_hdl, "PF recvice ppf mailbox callback is not registered\n"); ret = -EINVAL; } @@ -659,11 +659,11 @@ static void recv_func_mbox_handler(struct hinic_mbox_func_to_func *func_to_func, buf_out, out_size, src_func_idx, HINIC_HWIF_RESPONSE, MBOX_ACK, &msg_info); - } else { - kfree(recv_mbox->buf_out); - kfree(recv_mbox->mbox); - kfree(recv_mbox); } + + kfree(recv_mbox->buf_out); + kfree(recv_mbox->mbox); + kfree(recv_mbox); } static bool check_mbox_seq_id_and_seg_len(struct hinic_recv_mbox *recv_mbox, @@ -717,7 +717,7 @@ static void recv_mbox_handler(struct hinic_mbox_func_to_func *func_to_func, { u64 mbox_header = *((u64 *)header); void *mbox_body = MBOX_BODY_FROM_HDR(header); - struct hinic_recv_mbox *asyc_rcv_mbox = NULL; + struct hinic_recv_mbox *rcv_mbox_temp = NULL; u16 src_func_idx; struct hinic_mbox_work *mbox_work; int pos; @@ -756,43 +756,34 @@ static void recv_mbox_handler(struct hinic_mbox_func_to_func *func_to_func, return; } - if (recv_mbox->ack_type == MBOX_NO_ACK) { - asyc_rcv_mbox = kzalloc(sizeof(*asyc_rcv_mbox), GFP_KERNEL); - if (!asyc_rcv_mbox) { - sdk_err(func_to_func->hwdev->dev_hdl, "Allocate asynchronous receive mbox memory failed.\n"); - return; - } - memcpy(asyc_rcv_mbox, recv_mbox, sizeof(*asyc_rcv_mbox)); + rcv_mbox_temp = kzalloc(sizeof(*rcv_mbox_temp), GFP_KERNEL); + if (!rcv_mbox_temp) { + sdk_err(func_to_func->hwdev->dev_hdl, "Allocate receive mbox memory failed.\n"); + return; + } + memcpy(rcv_mbox_temp, recv_mbox, sizeof(*rcv_mbox_temp)); - asyc_rcv_mbox->mbox = kzalloc(MBOX_MAX_BUF_SZ, GFP_KERNEL); - if (!asyc_rcv_mbox->mbox) { - sdk_err(func_to_func->hwdev->dev_hdl, "Allocate asynchronous receive mbox message memory failed.\n"); - goto asyc_rcv_mbox_msg_err; - } - memcpy(asyc_rcv_mbox->mbox, recv_mbox->mbox, MBOX_MAX_BUF_SZ); + rcv_mbox_temp->mbox = kzalloc(MBOX_MAX_BUF_SZ, GFP_KERNEL); + if (!rcv_mbox_temp->mbox) { + sdk_err(func_to_func->hwdev->dev_hdl, "Allocate receive mbox message memory failed.\n"); + goto rcv_mbox_msg_err; + } + memcpy(rcv_mbox_temp->mbox, recv_mbox->mbox, MBOX_MAX_BUF_SZ); - asyc_rcv_mbox->buf_out = kzalloc(MBOX_MAX_BUF_SZ, GFP_KERNEL); - if (!asyc_rcv_mbox->buf_out) { - sdk_err(func_to_func->hwdev->dev_hdl, "Allocate asynchronous receive mbox out buffer memory failed.\n"); - goto asyc_rcv_mbox_buf_err; - } + rcv_mbox_temp->buf_out = kzalloc(MBOX_MAX_BUF_SZ, GFP_KERNEL); + if (!rcv_mbox_temp->buf_out) { + sdk_err(func_to_func->hwdev->dev_hdl, "Allocate receive mbox out buffer memory failed.\n"); + goto rcv_mbox_buf_err; } mbox_work = kzalloc(sizeof(*mbox_work), GFP_KERNEL); if (!mbox_work) { sdk_err(func_to_func->hwdev->dev_hdl, "Allocate mbox work memory failed.\n"); - if (recv_mbox->ack_type == MBOX_NO_ACK) - goto mbox_work_err; - else - return; + goto mbox_work_err; } mbox_work->func_to_func = func_to_func; - - if (recv_mbox->ack_type == MBOX_NO_ACK) - mbox_work->recv_mbox = asyc_rcv_mbox; - else - mbox_work->recv_mbox = recv_mbox; + mbox_work->recv_mbox = rcv_mbox_temp; mbox_work->src_func_idx = src_func_idx; INIT_WORK(&mbox_work->work, recv_func_mbox_work_handler); @@ -801,13 +792,13 @@ static void recv_mbox_handler(struct hinic_mbox_func_to_func *func_to_func, return; mbox_work_err: - kfree(asyc_rcv_mbox->buf_out); + kfree(rcv_mbox_temp->buf_out); -asyc_rcv_mbox_buf_err: - kfree(asyc_rcv_mbox->mbox); +rcv_mbox_buf_err: + kfree(rcv_mbox_temp->mbox); -asyc_rcv_mbox_msg_err: - kfree(asyc_rcv_mbox); +rcv_mbox_msg_err: + kfree(rcv_mbox_temp); } int set_vf_mbox_random_id(struct hinic_hwdev *hwdev, u16 func_id) @@ -978,6 +969,13 @@ static void mbox_copy_send_data(struct hinic_hwdev *hwdev, u32 *data = seg; u32 data_len, chk_sz = sizeof(u32); u32 i, idx_max; + u8 mbox_max_buf[MBOX_SEG_LEN] = {0}; + + /* The mbox message should be aligned in 4 bytes. */ + if (seg_len % chk_sz) { + memcpy(mbox_max_buf, seg, seg_len); + data = (u32 *)mbox_max_buf; + } data_len = seg_len; idx_max = ALIGN(data_len, chk_sz) / chk_sz; @@ -1124,7 +1122,7 @@ static int send_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func, { struct hinic_hwdev *hwdev = func_to_func->hwdev; int err = 0; - int seq_id = 0; + u32 seq_id = 0; u16 seg_len = MBOX_SEG_LEN; u16 left = msg_len; u8 *msg_seg = (u8 *)msg; @@ -1143,7 +1141,7 @@ static int send_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func, /* The vf's offset to it's associated pf */ HINIC_MBOX_HEADER_SET(msg_info->msg_id, MSG_ID) | HINIC_MBOX_HEADER_SET(msg_info->status, STATUS) | - HINIC_MBOX_HEADER_SET(hinic_global_func_id(hwdev), + HINIC_MBOX_HEADER_SET(hinic_global_func_id_hw(hwdev), SRC_GLB_FUNC_IDX); while (!(HINIC_MBOX_HEADER_GET(header, LAST))) { @@ -1335,10 +1333,16 @@ int hinic_mbox_to_pf(struct hinic_hwdev *hwdev, return -EINVAL; } + err = hinic_func_own_get(hwdev); + if (err) + return err; + /* port_to_port_idx - imply which PCIE interface PF is connected */ - return hinic_mbox_to_func(func_to_func, mod, cmd, - hinic_pf_id_of_vf(hwdev), buf_in, in_size, - buf_out, out_size, timeout); + err = hinic_mbox_to_func(func_to_func, mod, cmd, + hinic_pf_id_of_vf_hw(hwdev), buf_in, in_size, + buf_out, out_size, timeout); + hinic_func_own_free(hwdev); + return err; } int hinic_mbox_to_func_no_ack(struct hinic_hwdev *hwdev, u16 func_idx, @@ -1367,8 +1371,16 @@ int hinic_mbox_to_func_no_ack(struct hinic_hwdev *hwdev, u16 func_idx, int hinic_mbox_to_pf_no_ack(struct hinic_hwdev *hwdev, enum hinic_mod_type mod, u8 cmd, void *buf_in, u16 in_size) { - return hinic_mbox_to_func_no_ack(hwdev, hinic_pf_id_of_vf(hwdev), mod, - cmd, buf_in, in_size); + int err; + + err = hinic_func_own_get(hwdev); + if (err) + return err; + + err = hinic_mbox_to_func_no_ack(hwdev, hinic_pf_id_of_vf_hw(hwdev), + mod, cmd, buf_in, in_size); + hinic_func_own_free(hwdev); + return err; } int __hinic_mbox_to_vf(void *hwdev, @@ -1409,9 +1421,8 @@ int __hinic_mbox_to_vf(void *hwdev, } int hinic_mbox_ppf_to_vf(void *hwdev, - enum hinic_mod_type mod, u16 func_id, u8 cmd, - void *buf_in, u16 in_size, void *buf_out, - u16 *out_size, u32 timeout) + enum hinic_mod_type mod, u16 func_id, u8 cmd, void *buf_in, + u16 in_size, void *buf_out, u16 *out_size, u32 timeout) { struct hinic_mbox_func_to_func *func_to_func; int err; @@ -1581,8 +1592,7 @@ int hinic_vf_mbox_random_id_init(struct hinic_hwdev *hwdev) for (vf_in_pf = 1; vf_in_pf <= hinic_func_max_vf(hwdev); vf_in_pf++) { err = set_vf_mbox_random_id(hwdev, - (hinic_glb_pf_vf_offset(hwdev) + - vf_in_pf)); + (hinic_glb_pf_vf_offset(hwdev) + vf_in_pf)); if (err) break; } @@ -1656,6 +1666,9 @@ int hinic_func_to_func_init(struct hinic_hwdev *hwdev) destroy_workqueue(func_to_func->workq); create_mbox_workq_err: + spin_lock_deinit(&func_to_func->mbox_lock); + sema_deinit(&func_to_func->msg_send_sem); + sema_deinit(&func_to_func->mbox_send_sem); kfree(func_to_func); return err; @@ -1671,9 +1684,7 @@ void hinic_func_to_func_free(struct hinic_hwdev *hwdev) destroy_workqueue(func_to_func->workq); free_mbox_wb_status(func_to_func); - free_mbox_info(func_to_func->mbox_resp); - free_mbox_info(func_to_func->mbox_send); spin_lock_deinit(&func_to_func->mbox_lock); sema_deinit(&func_to_func->mbox_send_sem); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_mbox.h b/drivers/net/ethernet/huawei/hinic/hinic_mbox.h index c55d32394f9e251d7fb7b8b66fd3367af256c35e..a54639d0df0d9e5dafc811c87a395da4a42d59af 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_mbox.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_mbox.h @@ -215,12 +215,12 @@ int hinic_mbox_to_pf_no_ack(struct hinic_hwdev *hwdev, enum hinic_mod_type mod, int hinic_mbox_ppf_to_pf(struct hinic_hwdev *hwdev, enum hinic_mod_type mod, u16 dst_pf_id, u8 cmd, - void *buf_in, u16 in_size, void *buf_out, - u16 *out_size, u32 timeout); + void *buf_in, u16 in_size, void *buf_out, + u16 *out_size, u32 timeout); int hinic_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func, - enum hinic_mod_type mod, u16 cmd, u16 dst_func, - void *buf_in, u16 in_size, void *buf_out, - u16 *out_size, u32 timeout); + enum hinic_mod_type mod, u16 cmd, u16 dst_func, + void *buf_in, u16 in_size, void *buf_out, + u16 *out_size, u32 timeout); int __hinic_mbox_to_vf(void *hwdev, enum hinic_mod_type mod, u16 vf_id, u8 cmd, void *buf_in, diff --git a/drivers/net/ethernet/huawei/hinic/hinic_mgmt.c b/drivers/net/ethernet/huawei/hinic/hinic_mgmt.c index 5543f1f22bfb7bae84ebc9ca0333e33bc6529a55..6a2c10923033a8746873c018ee956798002c6462 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_mgmt.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_mgmt.c @@ -34,6 +34,8 @@ #include "hinic_hwif.h" #include "hinic_api_cmd.h" #include "hinic_mgmt.h" +#include "hinic_nic_cfg.h" +#include "hinic_mgmt_interface.h" #include "hinic_eqs.h" #define BUF_OUT_DEFAULT_SIZE 1 @@ -219,7 +221,7 @@ static u16 mgmt_msg_len(u16 msg_data_len) * @msg_id: message id **/ static void prepare_header(struct hinic_msg_pf_to_mgmt *pf_to_mgmt, - u64 *header, int msg_len, enum hinic_mod_type mod, + u64 *header, u16 msg_len, enum hinic_mod_type mod, enum hinic_msg_ack_type ack_type, enum hinic_msg_direction_type direction, enum hinic_mgmt_cmd cmd, u32 msg_id) @@ -241,11 +243,10 @@ static void prepare_header(struct hinic_msg_pf_to_mgmt *pf_to_mgmt, } static void clp_prepare_header(struct hinic_hwdev *hwdev, - u64 *header, int msg_len, - enum hinic_mod_type mod, - enum hinic_msg_ack_type ack_type, - enum hinic_msg_direction_type direction, - enum hinic_mgmt_cmd cmd, u32 msg_id) + u64 *header, u16 msg_len, enum hinic_mod_type mod, + enum hinic_msg_ack_type ack_type, + enum hinic_msg_direction_type direction, + enum hinic_mgmt_cmd cmd, u32 msg_id) { struct hinic_hwif *hwif = hwdev->hwif; @@ -270,7 +271,7 @@ static void clp_prepare_header(struct hinic_hwdev *hwdev, * @msg: the data of the message * @msg_len: the length of the message **/ -static void prepare_mgmt_cmd(u8 *mgmt_cmd, u64 *header, void *msg, +static void prepare_mgmt_cmd(u8 *mgmt_cmd, u64 *header, const void *msg, int msg_len) { memset(mgmt_cmd, 0, MGMT_MSG_RSVD_FOR_DEV); @@ -392,16 +393,25 @@ static int send_msg_to_mgmt_sync(struct hinic_msg_pf_to_mgmt *pf_to_mgmt, int hinic_pf_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd, void *buf_in, u16 in_size, void *buf_out, - u16 *out_size, u32 timeout) + u16 *out_size, u32 timeout) { struct hinic_msg_pf_to_mgmt *pf_to_mgmt; void *dev = ((struct hinic_hwdev *)hwdev)->dev_hdl; struct hinic_recv_msg *recv_msg; + struct hinic_msg_head *msg_head; struct completion *recv_done; ulong timeo; int err; ulong ret; + /* set aeq fix num to 3, need to ensure response aeq id < 3*/ + if (mod == HINIC_MOD_COMM || mod == HINIC_MOD_L2NIC) { + msg_head = buf_in; + + if (msg_head->resp_aeq_num >= HINIC_MAX_AEQS) + msg_head->resp_aeq_num = 0; + } + pf_to_mgmt = ((struct hinic_hwdev *)hwdev)->pf_to_mgmt; /* Lock the sync_msg_buf */ @@ -462,7 +472,7 @@ int hinic_pf_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd, } static int __get_clp_reg(void *hwdev, enum clp_data_type data_type, - enum clp_reg_type reg_type, u32 *reg_addr) + enum clp_reg_type reg_type, u32 *reg_addr) { struct hinic_hwdev *dev = hwdev; u32 offset; @@ -506,8 +516,8 @@ static int __get_clp_reg(void *hwdev, enum clp_data_type data_type, } static int hinic_read_clp_reg(struct hinic_hwdev *hwdev, - enum clp_data_type data_type, - enum clp_reg_type reg_type, u32 *read_value) + enum clp_data_type data_type, + enum clp_reg_type reg_type, u32 *read_value) { int err; u32 reg_addr, reg_value; @@ -636,7 +646,7 @@ static void hinic_write_clp_reg(struct hinic_hwdev *hwdev, } static int hinic_read_clp_data(struct hinic_hwdev *hwdev, - void *buf_out, u16 *out_size) + void *buf_out, u16 *out_size) { int err; u32 reg = HINIC_CLP_DATA(RSP); @@ -762,7 +772,7 @@ static int hinic_check_clp_init_status(struct hinic_hwdev *hwdev) } static void hinic_clear_clp_data(struct hinic_hwdev *hwdev, - enum clp_data_type data_type) + enum clp_data_type data_type) { u32 reg = (data_type == HINIC_CLP_REQ_HOST) ? HINIC_CLP_DATA(REQ) : HINIC_CLP_DATA(RSP); @@ -775,8 +785,8 @@ static void hinic_clear_clp_data(struct hinic_hwdev *hwdev, } int hinic_pf_clp_to_mgmt(void *hwdev, enum hinic_mod_type mod, u8 cmd, - void *buf_in, u16 in_size, - void *buf_out, u16 *out_size) + const void *buf_in, u16 in_size, + void *buf_out, u16 *out_size) { struct hinic_clp_pf_to_mgmt *clp_pf_to_mgmt; struct hinic_hwdev *dev = hwdev; @@ -1004,7 +1014,7 @@ static void mgmt_recv_msg_handler(struct hinic_msg_pf_to_mgmt *pf_to_mgmt, if (!pf_to_mgmt->recv_mgmt_msg_cb[mod] || !test_bit(HINIC_MGMT_MSG_CB_REG, - &pf_to_mgmt->mgmt_msg_cb_state[tmp_mod])) { + &pf_to_mgmt->mgmt_msg_cb_state[tmp_mod])) { sdk_warn(dev, "Receive mgmt callback is null, mod = %d\n", mod); clear_bit(HINIC_MGMT_MSG_CB_RUNNING, @@ -1093,7 +1103,6 @@ static bool check_mgmt_seq_id_and_seg_len(struct hinic_recv_msg *recv_msg, } else { if (seq_id != recv_msg->seq_id + 1) return false; - recv_msg->seq_id = seq_id; } diff --git a/drivers/net/ethernet/huawei/hinic/hinic_mgmt.h b/drivers/net/ethernet/huawei/hinic/hinic_mgmt.h index 9411d50462bdfcd478a9d433c9a1ca6a88b52e68..38f747004518804f13748539469c782ada90cc00 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_mgmt.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_mgmt.h @@ -57,7 +57,6 @@ enum clp_data_type { HINIC_CLP_REQ_HOST = 0, HINIC_CLP_RSP_HOST = 1 }; - enum clp_reg_type { HINIC_CLP_BA_HOST = 0, HINIC_CLP_SIZE_HOST = 1, @@ -65,7 +64,6 @@ enum clp_reg_type { HINIC_CLP_START_REQ_HOST = 3, HINIC_CLP_READY_RSP_HOST = 4 }; - #define HINIC_CLP_REG_GAP (0x20) #define HINIC_CLP_INPUT_BUFFER_LEN_HOST (2048UL) #define HINIC_CLP_OUTPUT_BUFFER_LEN_HOST (2048UL) @@ -202,7 +200,7 @@ struct hinic_msg_pf_to_mgmt { struct comm_up_self_msg_info proc; - /* spinlock when sending msg */ + /* lock when sending msg */ spinlock_t sync_event_lock; enum comm_pf_to_mgmt_event_state event_flag; }; @@ -238,8 +236,8 @@ int hinic_pf_to_mgmt_async(void *hwdev, enum hinic_mod_type mod, u8 cmd, void *buf_in, u16 in_size); int hinic_pf_clp_to_mgmt(void *hwdev, enum hinic_mod_type mod, u8 cmd, - void *buf_in, u16 in_size, - void *buf_out, u16 *out_size); + const void *buf_in, u16 in_size, + void *buf_out, u16 *out_size); int hinic_clp_pf_to_mgmt_init(struct hinic_hwdev *hwdev); void hinic_clp_pf_to_mgmt_free(struct hinic_hwdev *hwdev); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_mgmt_interface.h b/drivers/net/ethernet/huawei/hinic/hinic_mgmt_interface.h index 14efbe1449f3d3b33cfaaadbfc1a38ee8c548004..13bc351a090237183820d9b9d5b59d9088c97da7 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_mgmt_interface.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_mgmt_interface.h @@ -24,6 +24,13 @@ /* up to driver event */ #define HINIC_PORT_CMD_MGMT_RESET 0x0 +struct hinic_msg_head { + u8 status; + u8 version; + u8 resp_aeq_num; + u8 rsvd0[5]; +}; + struct hinic_register_vf { u8 status; u8 version; @@ -909,12 +916,10 @@ struct hinic_link_ksettings_info { u8 fec; /* 0 - RSFEC; 1 - BASEFEC; 2 - NOFEC */ u8 rsvd2[18]; /* reserved for duplex, port, etc. */ }; - enum hinic_tx_promsic { HINIC_TX_PROMISC_ENABLE = 0, HINIC_TX_PROMISC_DISABLE = 1, }; - struct hinic_promsic_info { u8 status; u8 version; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_multi_host_mgmt.c b/drivers/net/ethernet/huawei/hinic/hinic_multi_host_mgmt.c index 05523596f3a85285db0b23633f092765c749ff5e..aad4b2c38a4b65daecfe5e21e1ecc00177c1122f 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_multi_host_mgmt.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_multi_host_mgmt.c @@ -63,18 +63,20 @@ void set_slave_host_enable(struct hinic_hwdev *hwdev, u8 host_id, bool enable) host_id, enable, reg_val); } -bool get_slave_host_enable(struct hinic_hwdev *hwdev, u8 host_id) +bool hinic_get_slave_host_enable(void *hwdev, u8 host_id) { u32 reg_val; + struct hinic_hwdev *dev = hwdev; - if (HINIC_FUNC_TYPE(hwdev) != TYPE_PPF) + if (HINIC_FUNC_TYPE(dev) != TYPE_PPF) return false; - reg_val = hinic_hwif_read_reg(hwdev->hwif, + reg_val = hinic_hwif_read_reg(dev->hwif, HINIC_MULT_HOST_SLAVE_STATUS_ADDR); return SLAVE_HOST_STATUS_GET(host_id, reg_val); } +EXPORT_SYMBOL(hinic_get_slave_host_enable); void set_master_host_mbox_enable(struct hinic_hwdev *hwdev, bool enable) { @@ -138,6 +140,16 @@ void set_func_host_mode(struct hinic_hwdev *hwdev, enum hinic_func_mode mode) } } +bool is_multi_vm_slave(void *hwdev) +{ + struct hinic_hwdev *hw_dev = hwdev; + + if (!hwdev) + return false; + + return (hw_dev->func_mode == FUNC_MOD_MULTI_VM_SLAVE) ? true : false; +} + int rectify_host_mode(struct hinic_hwdev *hwdev) { u16 cur_sdi_mode; @@ -304,7 +316,7 @@ int sw_func_pf_mbox_handler(void *handle, u16 vf_id, u8 cmd, void *buf_in, int err; switch (cmd) { - case HINIC_SW_GET_SLAVE_FUNC_NIC_STATE: + case HINIC_SW_CMD_GET_SLAVE_FUNC_NIC_STATE: nic_state = buf_in; out_state = buf_out; *out_size = sizeof(*nic_state); @@ -416,8 +428,7 @@ static int multi_host_event_handler(struct hinic_hwdev *hwdev, } static int sw_fwd_msg_to_vf(struct hinic_hwdev *hwdev, - void *buf_in, u16 in_size, - void *buf_out, u16 *out_size) + void *buf_in, u16 in_size, void *buf_out, u16 *out_size) { struct hinic_host_fwd_head *fwd_head; u16 fwd_head_len; @@ -428,9 +439,9 @@ static int sw_fwd_msg_to_vf(struct hinic_hwdev *hwdev, fwd_head_len = sizeof(struct hinic_host_fwd_head); msg = (void *)((u8 *)buf_in + fwd_head_len); err = hinic_mbox_ppf_to_vf(hwdev, fwd_head->mod, - fwd_head->dst_glb_func_idx, fwd_head->cmd, - msg, (in_size - fwd_head_len), - buf_out, out_size, 0); + fwd_head->dst_glb_func_idx, fwd_head->cmd, + msg, (in_size - fwd_head_len), + buf_out, out_size, 0); if (err) nic_err(hwdev->dev_hdl, "Fwd msg to func %u failed, err: %d\n", @@ -438,7 +449,6 @@ static int sw_fwd_msg_to_vf(struct hinic_hwdev *hwdev, return err; } - static int __slave_host_sw_func_handler(struct hinic_hwdev *hwdev, u16 pf_idx, u8 cmd, void *buf_in, u16 in_size, void *buf_out, u16 *out_size) @@ -473,9 +483,12 @@ static int __slave_host_sw_func_handler(struct hinic_hwdev *hwdev, u16 pf_idx, case HINIC_SW_CMD_SEND_MSG_TO_VF: err = sw_fwd_msg_to_vf(hwdev, buf_in, in_size, - buf_out, out_size); + buf_out, out_size); break; + case HINIC_SW_CMD_MIGRATE_READY: + hinic_migrate_report(hwdev); + break; default: err = -EINVAL; break; @@ -515,8 +528,7 @@ int __ppf_process_mbox_msg(struct hinic_hwdev *hwdev, u16 pf_idx, u16 vf_id, if (IS_SLAVE_HOST(hwdev)) { err = hinic_mbox_to_host_sync(hwdev, mod, cmd, - buf_in, in_size, buf_out, - out_size, 0); + buf_in, in_size, buf_out, out_size, 0); if (err) sdk_err(hwdev->dev_hdl, "send to mpf failed, err: %d\n", err); @@ -751,7 +763,7 @@ int hinic_set_func_nic_state(void *hwdev, struct hinic_func_nic_state *state) return -EFAULT; } - host_enable = get_slave_host_enable(hwdev, host_id); + host_enable = hinic_get_slave_host_enable(hwdev, host_id); sdk_info(ppf_hwdev->dev_hdl, "Set slave host %d(status: %d) func %d %s nic\n", host_id, host_enable, state->func_idx, state->state ? "enable" : "disable"); @@ -801,18 +813,23 @@ int hinic_get_func_nic_enable(void *hwdev, u16 glb_func_idx, bool *en) if (!hwdev || !en) return -EINVAL; - + /*if card mode is OVS, VFs donot need attach_uld, so return false.*/ if (!IS_SLAVE_HOST((struct hinic_hwdev *)hwdev)) { - *en = true; + if (hinic_func_type(hwdev) == TYPE_VF && + hinic_support_ovs(hwdev, NULL)) { + *en = false; + } else { + *en = true; + } return 0; } if (hinic_func_type(hwdev) == TYPE_VF) { nic_state.func_idx = glb_func_idx; err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_SW_FUNC, - HINIC_SW_GET_SLAVE_FUNC_NIC_STATE, - &nic_state, sizeof(nic_state), - &nic_state, &out_size, 0); + HINIC_SW_CMD_GET_SLAVE_FUNC_NIC_STATE, + &nic_state, sizeof(nic_state), + &nic_state, &out_size, 0); if (err || !out_size || nic_state.status) { sdk_err(((struct hinic_hwdev *)hwdev)->dev_hdl, "Failed to get func %d nic state, err: %d, out_size: 0x%x, status: 0x%x\n", glb_func_idx, err, out_size, nic_state.status); @@ -861,11 +878,16 @@ int hinic_multi_host_mgmt_init(struct hinic_hwdev *hwdev) /* master ppf idx fix to 0 */ hwdev->mhost_mgmt->mhost_ppf_idx = 0; - /* fix slave host ppf 6 and host 2 in bmwg mode - * TODO: get ppf_idx and host_idx according to pf_infos - */ - hwdev->mhost_mgmt->shost_ppf_idx = 6; - hwdev->mhost_mgmt->shost_host_idx = 2; + if (IS_BMGW_MASTER_HOST(hwdev) || IS_BMGW_SLAVE_HOST(hwdev)) { + /* fix slave host ppf 6 and host 2 in bmwg mode + * TODO: get ppf_idx and host_idx according to pf_infos + */ + hwdev->mhost_mgmt->shost_ppf_idx = 6; + hwdev->mhost_mgmt->shost_host_idx = 2; + } else { + hwdev->mhost_mgmt->shost_ppf_idx = 7; + hwdev->mhost_mgmt->shost_host_idx = 2; + } hinic_register_ppf_mbox_cb(hwdev, HINIC_MOD_COMM, comm_ppf_mbox_handler); @@ -885,10 +907,16 @@ int hinic_multi_host_mgmt_init(struct hinic_hwdev *hwdev) if (IS_SLAVE_HOST(hwdev)) { /* PXE don't support to receive mbox from master host */ set_slave_host_enable(hwdev, hinic_pcie_itf_id(hwdev), true); - if (IS_BMGW_SLAVE_HOST(hwdev)) { + if ((IS_VM_SLAVE_HOST(hwdev) && + hinic_get_master_host_mbox_enable(hwdev)) || + IS_BMGW_SLAVE_HOST(hwdev)) { err = hinic_register_slave_ppf(hwdev, true); - if (err) + if (err) { + set_slave_host_enable(hwdev, + hinic_pcie_itf_id(hwdev), + false); goto out_free_mhost_mgmt; + } } } else { /* slave host can send message to mgmt cpu after setup master @@ -912,8 +940,7 @@ int hinic_multi_host_mgmt_free(struct hinic_hwdev *hwdev) return 0; if (IS_SLAVE_HOST(hwdev)) { - if (IS_BMGW_SLAVE_HOST(hwdev)) - hinic_register_slave_ppf(hwdev, false); + hinic_register_slave_ppf(hwdev, false); set_slave_host_enable(hwdev, hinic_pcie_itf_id(hwdev), false); } else { diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nic.h b/drivers/net/ethernet/huawei/hinic/hinic_nic.h index be68f3cc5fef90655f1f293e103f022d3a1747b3..7e9256354493591d9dd1773c95f85c1070dc9ffc 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_nic.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_nic.h @@ -41,6 +41,8 @@ struct hinic_rq { u32 irq_id; u16 msix_entry_idx; + + dma_addr_t cqe_dma_addr; }; struct hinic_qp { diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c b/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c index 56d6da9948c7a3449291c964573a42c858e1c59c..d7796d9dc1b8107f9e00441fa70f09af8f07e54e 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c @@ -35,6 +35,7 @@ #include "hinic_nic.h" #include "hinic_mgmt_interface.h" #include "hinic_hwif.h" +#include "hinic_eqs.h" static unsigned char set_vf_link_state; module_param(set_vf_link_state, byte, 0444); @@ -150,8 +151,11 @@ int hinic_init_function_table(void *hwdev, u16 rx_buf_sz) if (!hwdev) return -EINVAL; + err = hinic_global_func_id_get(hwdev, &function_table.func_id); + if (err) + return err; + function_table.version = HINIC_CMD_VER_FUNC_ID; - function_table.func_id = hinic_global_func_id(hwdev); function_table.mtu = 0x3FFF; /* default, max mtu */ function_table.rx_wqe_buf_size = rx_buf_sz; @@ -178,7 +182,9 @@ int hinic_get_base_qpn(void *hwdev, u16 *global_qpn) if (!hwdev || !global_qpn) return -EINVAL; - cmd_qpn.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &cmd_qpn.func_id); + if (err) + return err; err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC, HINIC_PORT_CMD_GET_GLOBAL_QPN, @@ -196,6 +202,7 @@ int hinic_get_base_qpn(void *hwdev, u16 *global_qpn) return 0; } +#define HINIC_ADD_VLAN_IN_MAC 0x8000 #define HINIC_VLAN_ID_MASK 0x7FFF int hinic_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id) @@ -332,6 +339,55 @@ int hinic_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id, return 0; } +int hinic_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id) +{ + struct hinic_hwdev *dev = hwdev; + struct vf_data_storage *vf_info; + u16 func_id, vlan_id; + int err; + + if (!hwdev || !old_vlan || !new_vlan) + return -EINVAL; + + vf_info = dev->nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id); + if (!vf_info->pf_set_mac) + return 0; + + func_id = hinic_glb_pf_vf_offset(dev) + (u16)vf_id; + vlan_id = old_vlan; + if (vlan_id) + vlan_id |= HINIC_ADD_VLAN_IN_MAC; + err = hinic_del_mac(dev, vf_info->vf_mac_addr, vlan_id, + func_id); + if (err) { + nic_err(dev->dev_hdl, "Failed to delete VF %d MAC %pM vlan %d\n", + HW_VF_ID_TO_OS(vf_id), vf_info->vf_mac_addr, vlan_id); + return err; + } + + vlan_id = new_vlan; + if (vlan_id) + vlan_id |= HINIC_ADD_VLAN_IN_MAC; + err = hinic_set_mac(dev, vf_info->vf_mac_addr, vlan_id, + func_id); + if (err) { + nic_err(dev->dev_hdl, "Failed to add VF %d MAC %pM vlan %d\n", + HW_VF_ID_TO_OS(vf_id), vf_info->vf_mac_addr, vlan_id); + goto out; + } + + return 0; + +out: + vlan_id = old_vlan; + if (vlan_id) + vlan_id |= HINIC_ADD_VLAN_IN_MAC; + hinic_set_mac(dev, vf_info->vf_mac_addr, vlan_id, + func_id); + + return err; +} + int hinic_get_default_mac(void *hwdev, u8 *mac_addr) { struct hinic_hwdev *nic_hwdev = (struct hinic_hwdev *)hwdev; @@ -342,11 +398,13 @@ int hinic_get_default_mac(void *hwdev, u8 *mac_addr) if (!hwdev || !mac_addr) return -EINVAL; - mac_info.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &mac_info.func_id); + if (err) + return err; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_MAC, &mac_info, sizeof(mac_info), - &mac_info, &out_size); + &mac_info, &out_size); if (err || !out_size || mac_info.status) { nic_err(nic_hwdev->dev_hdl, "Failed to get mac, err: %d, status: 0x%x, out size: 0x%x\n", @@ -380,7 +438,10 @@ int hinic_set_port_mtu(void *hwdev, u32 new_mtu) return -EINVAL; } - mtu_info.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &mtu_info.func_id); + if (err) + return err; + mtu_info.mtu = new_mtu; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_CHANGE_MTU, @@ -457,7 +518,10 @@ int hinic_enable_netq(void *hwdev, u8 en) if (!hwdev) return -EINVAL; - netq_cfg.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &netq_cfg.func_id); + if (err) + return err; + netq_cfg.netq_en = en; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_NETQ, @@ -500,8 +564,11 @@ int hinic_add_hw_rqfilter(void *hwdev, struct hinic_rq_filter_info *filter_info) return -EINVAL; } + err = hinic_global_func_id_get(hwdev, &filter_msg.func_id); + if (err) + return err; + filter_msg.filter_type = filter_info->filter_type; - filter_msg.func_id = hinic_global_func_id(hwdev); filter_msg.qid = filter_info->qid; filter_msg.qflag = filter_info->qflag; @@ -547,8 +614,11 @@ int hinic_del_hw_rqfilter(void *hwdev, struct hinic_rq_filter_info *filter_info) return -EINVAL; } + err = hinic_global_func_id_get(hwdev, &filter_msg.func_id); + if (err) + return err; + filter_msg.filter_type = filter_info->filter_type; - filter_msg.func_id = hinic_global_func_id(hwdev); err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_DEL_RQ_FILTER, &filter_msg, sizeof(filter_msg), @@ -628,7 +698,9 @@ int hinic_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl) if (!hwdev) return -EINVAL; - vlan_filter.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &vlan_filter.func_id); + if (err) + return err; vlan_filter.vlan_filter_ctrl = vlan_filter_ctrl; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_VLAN_FILTER, @@ -659,11 +731,13 @@ int hinic_get_port_info(void *hwdev, struct nic_port_info *port_info) if (!hwdev || !port_info) return -EINVAL; - port_msg.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &port_msg.func_id); + if (err) + return err; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_PORT_INFO, &port_msg, sizeof(port_msg), - &port_msg, &out_size); + &port_msg, &out_size); if (err || !out_size || port_msg.status) { nic_err(nic_hwdev->dev_hdl, "Failed to get port info, err: %d, status: 0x%x, out size: 0x%x\n", @@ -691,7 +765,10 @@ int hinic_set_autoneg(void *hwdev, bool enable) if (!hwdev) return -EINVAL; - autoneg.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &autoneg.func_id); + if (err) + return err; + autoneg.enable = enable; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_AUTONEG, @@ -739,7 +816,9 @@ int hinic_get_link_mode(void *hwdev, enum hinic_link_mode *supported, if (!hwdev || !supported || !advertised) return -EINVAL; - link_mode.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &link_mode.func_id); + if (err) + return err; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_LINK_MODE, &link_mode, sizeof(link_mode), @@ -767,7 +846,10 @@ int hinic_set_port_link_status(void *hwdev, bool enable) if (!hwdev) return -EINVAL; - link_status.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &link_status.func_id); + if (err) + return err; + link_status.enable = enable; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_PORT_LINK_STATUS, @@ -793,7 +875,10 @@ int hinic_set_speed(void *hwdev, enum nic_speed_level speed) if (!hwdev) return -EINVAL; - speed_info.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &speed_info.func_id); + if (err) + return err; + speed_info.speed = speed; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_SPEED, @@ -819,7 +904,9 @@ int hinic_get_speed(void *hwdev, enum nic_speed_level *speed) if (!hwdev || !speed) return -EINVAL; - speed_info.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &speed_info.func_id); + if (err) + return err; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_SPEED, &speed_info, sizeof(speed_info), @@ -851,7 +938,9 @@ int hinic_get_link_state(void *hwdev, u8 *link_state) return 0; } - get_link.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &get_link.func_id); + if (err) + return err; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_LINK_STATE, &get_link, sizeof(get_link), @@ -878,7 +967,10 @@ static int hinic_set_hw_pause_info(void *hwdev, if (!hwdev) return -EINVAL; - pause_info.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &pause_info.func_id); + if (err) + return err; + pause_info.auto_neg = nic_pause.auto_neg; pause_info.rx_pause = nic_pause.rx_pause; pause_info.tx_pause = nic_pause.tx_pause; @@ -936,7 +1028,9 @@ int hinic_get_hw_pause_info(void *hwdev, struct nic_pause_config *nic_pause) if (!hwdev || !nic_pause) return -EINVAL; - pause_info.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &pause_info.func_id); + if (err) + return err; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_PAUSE_INFO, &pause_info, sizeof(pause_info), @@ -982,7 +1076,10 @@ int hinic_set_rx_mode(void *hwdev, u32 enable) if (!hwdev) return -EINVAL; - rx_mode_cfg.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &rx_mode_cfg.func_id); + if (err) + return err; + rx_mode_cfg.rx_mode = enable; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_RX_MODE, @@ -1008,7 +1105,10 @@ int hinic_set_rx_vlan_offload(void *hwdev, u8 en) if (!hwdev) return -EINVAL; - vlan_cfg.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &vlan_cfg.func_id); + if (err) + return err; + vlan_cfg.vlan_rx_offload = en; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_RX_VLAN_OFFLOAD, @@ -1033,7 +1133,10 @@ int hinic_set_rx_csum_offload(void *hwdev, u32 en) if (!hwdev) return -EINVAL; - rx_csum_cfg.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &rx_csum_cfg.func_id); + if (err) + return err; + rx_csum_cfg.rx_csum_offload = en; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_RX_CSUM, @@ -1058,7 +1161,10 @@ int hinic_set_tx_tso(void *hwdev, u8 tso_en) if (!hwdev) return -EINVAL; - tso_cfg.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &tso_cfg.func_id); + if (err) + return err; + tso_cfg.tso_en = tso_en; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_TSO, @@ -1144,7 +1250,10 @@ int hinic_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en, u8 max_wqe_num) if (!hwdev) return -EINVAL; - lro_cfg.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &lro_cfg.func_id); + if (err) + return err; + lro_cfg.lro_ipv4_en = ipv4_en; lro_cfg.lro_ipv6_en = ipv6_en; lro_cfg.lro_max_wqe_num = max_wqe_num; @@ -1168,9 +1277,12 @@ static int hinic_dcb_set_hw_pfc(void *hwdev, u8 pfc_en, u8 pfc_bitmap) u16 out_size = sizeof(pfc); int err; + err = hinic_global_func_id_get(hwdev, &pfc.func_id); + if (err) + return err; + pfc.pfc_bitmap = pfc_bitmap; pfc.pfc_en = pfc_en; - pfc.func_id = hinic_global_func_id(hwdev); err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_PFC, &pfc, sizeof(pfc), &pfc, &out_size); @@ -1306,7 +1418,12 @@ int hinic_dcb_set_rq_iq_mapping(void *hwdev, u32 num_rqs, u8 *map) dev = hwdev; nic_io = dev->nic_io; - rq_iq_mapping.func_id = hinic_global_func_id(hwdev); + hinic_qps_num_set(dev, nic_io->num_qps); + + err = hinic_global_func_id_get(hwdev, &rq_iq_mapping.func_id); + if (err) + return err; + rq_iq_mapping.num_rqs = num_rqs; rq_iq_mapping.rq_depth = (u16)ilog2(nic_io->rq_depth); @@ -1323,6 +1440,7 @@ int hinic_dcb_set_rq_iq_mapping(void *hwdev, u32 num_rqs, u8 *map) return 0; } +EXPORT_SYMBOL(hinic_dcb_set_rq_iq_mapping); int hinic_set_pfc_threshold(void *hwdev, u16 op_type, u16 threshold) { @@ -1337,7 +1455,10 @@ int hinic_set_pfc_threshold(void *hwdev, u16 op_type, u16 threshold) else return -EINVAL; - pfc_thd.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &pfc_thd.func_id); + if (err) + return err; + pfc_thd.op_type = op_type; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_PFC_THD, @@ -1468,7 +1589,9 @@ int hinic_get_rx_lro(void *hwdev, struct nic_lro_info *cfg) if (!hwdev || !cfg) return -EINVAL; - lro_cfg.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &lro_cfg.func_id); + if (err) + return err; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_LRO, &lro_cfg, sizeof(lro_cfg), @@ -1577,7 +1700,10 @@ int hinic_set_vport_enable(void *hwdev, bool enable) if (!hwdev) return -EINVAL; - en_state.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &en_state.func_id); + if (err) + return err; + en_state.state = enable ? 1 : 0; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_VPORT_ENABLE, @@ -1608,8 +1734,11 @@ int hinic_set_port_enable(void *hwdev, bool enable) if (HINIC_IS_VF(nic_hwdev)) return 0; + err = hinic_global_func_id_get(hwdev, &en_state.func_id); + if (err) + return err; + en_state.version = HINIC_CMD_VER_FUNC_ID; - en_state.func_id = hinic_global_func_id(hwdev); en_state.state = enable ? NIC_PORT_ENABLE : NIC_PORT_DISABLE; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_PORT_ENABLE, @@ -1691,7 +1820,10 @@ int hinic_get_rss_type(void *hwdev, u32 tmpl_idx, struct nic_rss_type *rss_type) if (!hwdev || !rss_type) return -EINVAL; - ctx_tbl.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &ctx_tbl.func_id); + if (err) + return err; + ctx_tbl.template_id = (u8)tmpl_idx; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_RSS_CTX_TBL, @@ -1726,7 +1858,10 @@ int hinic_rss_set_template_tbl(void *hwdev, u32 tmpl_idx, const u8 *temp) if (!hwdev || !temp) return -EINVAL; - temp_key.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &temp_key.func_id); + if (err) + return err; + temp_key.template_id = (u8)tmpl_idx; memcpy(temp_key.key, temp, HINIC_RSS_KEY_SIZE); @@ -1752,7 +1887,10 @@ int hinic_rss_get_template_tbl(void *hwdev, u32 tmpl_idx, u8 *temp) if (!hwdev || !temp) return -EINVAL; - temp_key.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &temp_key.func_id); + if (err) + return err; + temp_key.template_id = (u8)tmpl_idx; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_RSS_TEMPLATE_TBL, @@ -1779,7 +1917,10 @@ int hinic_rss_get_hash_engine(void *hwdev, u8 tmpl_idx, u8 *type) if (!hwdev || !type) return -EINVAL; - hash_type.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &hash_type.func_id); + if (err) + return err; + hash_type.template_id = tmpl_idx; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_RSS_HASH_ENGINE, @@ -1805,7 +1946,10 @@ int hinic_rss_set_hash_engine(void *hwdev, u8 tmpl_idx, u8 type) if (!hwdev) return -EINVAL; - hash_type.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &hash_type.func_id); + if (err) + return err; + hash_type.hash_engine = type; hash_type.template_id = tmpl_idx; @@ -1826,7 +1970,7 @@ int hinic_rss_set_indir_tbl(void *hwdev, u32 tmpl_idx, const u32 *indir_table) struct hinic_hwdev *nic_hwdev = (struct hinic_hwdev *)hwdev; struct nic_rss_indirect_tbl *indir_tbl; struct hinic_cmd_buf *cmd_buf; - int i; + u32 i; u32 *temp; u32 indir_size; u64 out_param; @@ -1896,7 +2040,10 @@ int hinic_rss_get_indir_tbl(void *hwdev, u32 tmpl_idx, u32 *indir_table) u16 out_size = sizeof(rss_cfg); int err = 0, i; - rss_cfg.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &rss_cfg.func_id); + if (err) + return err; + rss_cfg.template_id = (u8)tmpl_idx; err = l2nic_msg_to_mgmt_sync(hwdev, @@ -1927,7 +2074,10 @@ int hinic_rss_cfg(void *hwdev, u8 rss_en, u8 tmpl_idx, u8 tc_num, u8 *prio_tc) if (!hwdev || !prio_tc || (tc_num & (tc_num - 1))) return -EINVAL; - rss_cfg.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &rss_cfg.func_id); + if (err) + return err; + rss_cfg.rss_en = rss_en; rss_cfg.template_id = tmpl_idx; rss_cfg.rq_priority_number = tc_num ? (u8)ilog2(tc_num) : 0; @@ -1953,8 +2103,11 @@ int hinic_get_vport_stats(void *hwdev, struct hinic_vport_stats *stats) u16 out_size = sizeof(vport_stats); int err; + err = hinic_global_func_id_get(hwdev, &stats_info.func_id); + if (err) + return err; + stats_info.stats_version = HINIC_PORT_STATS_VERSION; - stats_info.func_id = hinic_global_func_id(hwdev); stats_info.stats_size = sizeof(vport_stats); err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_VPORT_STAT, @@ -2087,13 +2240,20 @@ int hinic_rss_template_alloc(void *hwdev, u8 *tmpl_idx) if (!hwdev || !tmpl_idx) return -EINVAL; - template_mgmt.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &template_mgmt.func_id); + if (err) + return err; + template_mgmt.cmd = NIC_RSS_CMD_TEMP_ALLOC; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR, &template_mgmt, sizeof(template_mgmt), &template_mgmt, &out_size); if (err || !out_size || template_mgmt.status) { + if (template_mgmt.status == HINIC_MGMT_STATUS_ERR_FULL) { + nic_warn(nic_hwdev->dev_hdl, "Failed to alloc rss template, table is full\n"); + return -ENOSPC; + } nic_err(nic_hwdev->dev_hdl, "Failed to alloc rss template, err: %d, status: 0x%x, out size: 0x%x\n", err, template_mgmt.status, out_size); return -EINVAL; @@ -2114,7 +2274,10 @@ int hinic_rss_template_free(void *hwdev, u8 tmpl_idx) if (!hwdev) return -EINVAL; - template_mgmt.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &template_mgmt.func_id); + if (err) + return err; + template_mgmt.template_id = tmpl_idx; template_mgmt.cmd = NIC_RSS_CMD_TEMP_FREE; @@ -2140,7 +2303,10 @@ int hinic_set_port_funcs_state(void *hwdev, bool enable) if (!hwdev) return -EINVAL; - state.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &state.func_id); + if (err) + return err; + state.drop_en = enable ? 0 : 1; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_PORT_FUNCS_STATE, @@ -2162,7 +2328,9 @@ int hinic_reset_port_link_cfg(void *hwdev) u16 out_size = sizeof(reset_cfg); int err; - reset_cfg.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &reset_cfg.func_id); + if (err) + return err; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_RESET_LINK_CFG, &reset_cfg, sizeof(reset_cfg), @@ -2207,6 +2375,11 @@ static int hinic_change_vf_mtu_msg_handler(struct hinic_hwdev *hwdev, u16 vf_id, return 0; } +static bool is_ether_addr_zero(const u8 *addr) +{ + return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]); +} + static int hinic_get_vf_mac_msg_handler(struct hinic_nic_io *nic_io, u16 vf, void *buf_in, u16 in_size, void *buf_out, u16 *out_size) @@ -2215,10 +2388,18 @@ static int hinic_get_vf_mac_msg_handler(struct hinic_nic_io *nic_io, u16 vf, struct hinic_port_mac_set *mac_info = buf_out; int err; - if (nic_io->hwdev->func_mode == FUNC_MOD_MULTI_BM_SLAVE) { + if (nic_io->hwdev->func_mode == FUNC_MOD_MULTI_BM_SLAVE || + nic_io->hwdev->func_mode == FUNC_MOD_MULTI_VM_SLAVE || + (hinic_support_ovs(nic_io->hwdev, NULL))) { err = hinic_pf_msg_to_mgmt_sync(nic_io->hwdev, HINIC_MOD_L2NIC, HINIC_PORT_CMD_GET_MAC, buf_in, in_size, buf_out, out_size, 0); + + if (!err) { + if (is_ether_addr_zero(&mac_info->mac[0])) + memcpy(mac_info->mac, + vf_info->vf_mac_addr, ETH_ALEN); + } return err; } @@ -2360,13 +2541,17 @@ static int hinic_set_vf_vlan(struct hinic_hwdev *hwdev, bool add, u16 vid, static int hinic_init_vf_config(struct hinic_hwdev *hwdev, u16 vf_id) { struct vf_data_storage *vf_info; - u16 func_id; + u16 func_id, vlan_id; int err = 0; vf_info = hwdev->nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id); if (vf_info->pf_set_mac) { func_id = hinic_glb_pf_vf_offset(hwdev) + vf_id; - err = hinic_set_mac(hwdev, vf_info->vf_mac_addr, 0, func_id); + vlan_id = vf_info->pf_vlan; + if (vlan_id) + vlan_id |= HINIC_ADD_VLAN_IN_MAC; + err = hinic_set_mac(hwdev, vf_info->vf_mac_addr, vlan_id, + func_id); if (err) { nic_err(hwdev->dev_hdl, "Failed to set VF %d MAC\n", HW_VF_ID_TO_OS(vf_id)); @@ -2774,7 +2959,8 @@ int hinic_kill_vf_vlan(void *hwdev, int vf_id) err = hinic_set_vf_vlan(hw_dev, false, nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan, - nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos, vf_id); + nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos, + vf_id); if (err) return err; @@ -3247,7 +3433,10 @@ int hinic_set_anti_attack(void *hwdev, bool enable) if (!hwdev) return -EINVAL; - rate.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &rate.func_id); + if (err) + return err; + rate.enable = enable; rate.cir = ANTI_ATTACK_DEFAULT_CIR; rate.xir = ANTI_ATTACK_DEFAULT_XIR; @@ -3277,7 +3466,12 @@ int hinic_flush_sq_res(void *hwdev) u16 out_size = sizeof(sq_res); int err; - sq_res.func_id = hinic_global_func_id(hwdev); + if (!hwdev) + return -EINVAL; + + err = hinic_global_func_id_get(hwdev, &sq_res.func_id); + if (err) + return err; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_CLEAR_SQ_RES, &sq_res, sizeof(sq_res), &sq_res, @@ -3290,6 +3484,7 @@ int hinic_flush_sq_res(void *hwdev) return 0; } +EXPORT_SYMBOL(hinic_flush_sq_res); static int __set_pf_bw(struct hinic_hwdev *hwdev, u8 speed_level); @@ -3336,7 +3531,10 @@ int hinic_set_super_cqe_state(void *hwdev, bool enable) if (!hwdev) return -EINVAL; - super_cqe.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &super_cqe.func_id); + if (err) + return err; + super_cqe.super_cqe_en = enable; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_SUPER_CQE, @@ -3438,7 +3636,10 @@ static int __set_pf_bw(struct hinic_hwdev *hwdev, u8 speed_level) pf_bw = 1; } - rate_cfg.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &rate_cfg.func_id); + if (err) + return err; + rate_cfg.tx_rate = pf_bw; err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC, @@ -3543,7 +3744,10 @@ int hinic_set_link_status_follow(void *hwdev, return -EINVAL; } - follow.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &follow.func_id); + if (err) + return err; + follow.follow_status = status; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_LINK_FOLLOW, @@ -3617,7 +3821,10 @@ int hinic_set_link_settings(void *hwdev, struct hinic_link_ksettings *settings) u16 out_size = sizeof(info); int err; - info.func_id = hinic_global_func_id(hwdev); + err = hinic_global_func_id_get(hwdev, &info.func_id); + if (err) + return err; + info.valid_bitmap = settings->valid_bitmap; info.autoneg = settings->autoneg; info.speed = settings->speed; @@ -3637,15 +3844,17 @@ int hinic_set_link_settings(void *hwdev, struct hinic_link_ksettings *settings) return info.status; } - int hinic_disable_tx_promisc(void *hwdev) { struct hinic_promsic_info info = {0}; u16 out_size = sizeof(info); int err; + err = hinic_global_func_id_get(hwdev, &info.func_id); + if (err) + return err; + info.cfg = HINIC_TX_PROMISC_DISABLE; - info.func_id = hinic_global_func_id(hwdev); err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC, HINIC_PORT_CMD_DISABLE_PROMISIC, &info, sizeof(info), &info, &out_size, 0); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.h b/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.h index 98a3e5320c958c03e0872986b00371de441dd1c5..0ea04ebd35a3c7d405f8579295e462cf0123f138 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.h @@ -53,6 +53,8 @@ #define HINIC_LRO_RX_TIMER_DEFAULT_PG_100GE 8 #define HINIC_LOWEST_LATENCY 1 +#define HINIC_MULTI_VM_LATENCY 32 +#define HINIC_MULTI_VM_PENDING_LIMIT 4 #define HINIC_RX_RATE_LOW 400000 #define HINIC_RX_COAL_TIME_LOW 20 #define HINIC_RX_PENDING_LIMIT_LOW 2 @@ -60,6 +62,7 @@ #define HINIC_RX_COAL_TIME_HIGH 225 #define HINIC_RX_PENDING_LIMIT_HIGH 50 #define HINIC_RX_RATE_THRESH 35000 +#define HINIC_TX_RATE_THRESH 35000 #define HINIC_RX_RATE_LOW_VM 400000 #define HINIC_RX_PENDING_LIMIT_HIGH_VM 50 @@ -413,6 +416,7 @@ int hinic_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id); int hinic_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id, u16 func_id); +int hinic_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id); /* Obtaining the permanent mac */ int hinic_get_default_mac(void *hwdev, u8 *mac_addr); /* Check whether the current solution is using this interface, @@ -615,8 +619,8 @@ int hinic_set_link_settings(void *hwdev, struct hinic_link_ksettings *settings); int hinic_enable_netq(void *hwdev, u8 en); int hinic_add_hw_rqfilter(void *hwdev, - struct hinic_rq_filter_info *filter_info); + struct hinic_rq_filter_info *filter_info); int hinic_del_hw_rqfilter(void *hwdev, - struct hinic_rq_filter_info *filter_info); + struct hinic_rq_filter_info *filter_info); #endif diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nic_dbg.c b/drivers/net/ethernet/huawei/hinic/hinic_nic_dbg.c index 90189f96374085790a2017066accf7cd58744caa..7091fd12c508777da778aeb389e4a4dd335c8995 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_nic_dbg.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_nic_dbg.c @@ -163,7 +163,7 @@ int hinic_dbg_get_sq_db_addr(void *hwdev, u16 q_id, u64 **map_addr, return 0; } -u16 hinic_dbg_get_global_qpn(void *hwdev) +u16 hinic_dbg_get_global_qpn(const void *hwdev) { if (!hwdev) return 0; @@ -226,7 +226,7 @@ int hinic_dbg_get_rq_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt, return err; } -int hinic_dbg_get_hw_stats(void *hwdev, u8 *hw_stats, u16 *out_size) +int hinic_dbg_get_hw_stats(const void *hwdev, u8 *hw_stats, u16 *out_size) { if (*out_size != sizeof(struct hinic_hw_stats)) { pr_err("Unexpect out buf size from user :%d, expect: %lu\n", @@ -248,7 +248,8 @@ u16 hinic_dbg_clear_hw_stats(void *hwdev) return sizeof(struct hinic_hw_stats); } -void hinic_get_chip_fault_stats(void *hwdev, u8 *chip_fault_stats, int offset) +void hinic_get_chip_fault_stats(const void *hwdev, + u8 *chip_fault_stats, int offset) { int copy_len = offset + MAX_DRV_BUF_SIZE - HINIC_CHIP_FAULT_SIZE; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nic_dev.h b/drivers/net/ethernet/huawei/hinic/hinic_nic_dev.h index 8524c459bedd6be44fb61ba837892c4935a032c7..d8439e67f766a800d4af706ea6950c9eff473547 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_nic_dev.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_nic_dev.h @@ -30,7 +30,7 @@ #define HINIC_DRV_NAME "hinic" #define HINIC_CHIP_NAME "hinic" -#define HINIC_DRV_VERSION "1.8.3.1" +#define HINIC_DRV_VERSION "2.3.2.1" struct vf_data_storage; #define HINIC_FUNC_IS_VF(hwdev) (hinic_func_type(hwdev) == TYPE_VF) @@ -45,6 +45,7 @@ enum hinic_flags { HINIC_SAME_RXTX, HINIC_INTR_ADAPT, HINIC_UPDATE_MAC_FILTER, + HINIC_ETS_ENABLE, }; #define RX_BUFF_NUM_PER_PAGE 2 @@ -135,9 +136,9 @@ struct hinic_intr_coal_info { #define HINIC_NIC_STATS_INC(nic_dev, field) \ { \ - u64_stats_update_begin(&(nic_dev)->stats.syncp); \ - (nic_dev)->stats.field++; \ - u64_stats_update_end(&(nic_dev)->stats.syncp); \ + u64_stats_update_begin(&nic_dev->stats.syncp); \ + nic_dev->stats.field++; \ + u64_stats_update_end(&nic_dev->stats.syncp); \ } struct hinic_nic_stats { @@ -232,6 +233,7 @@ struct hinic_nic_dev { u32 his_link_speed; /* interrupt coalesce must be different in virtual machine */ bool in_vm; + bool is_vm_slave; #ifndef HAVE_NETDEV_STATS_IN_NETDEV struct net_device_stats net_stats; @@ -275,12 +277,12 @@ int hinic_enable_func_rss(struct hinic_nic_dev *nic_dev); #define hinic_msg(level, nic_dev, msglvl, format, arg...) \ do { \ - if ((nic_dev)->netdev && (nic_dev)->netdev->reg_state \ + if (nic_dev->netdev && nic_dev->netdev->reg_state \ == NETREG_REGISTERED) \ - nicif_##level((nic_dev), msglvl, (nic_dev)->netdev, \ + nicif_##level(nic_dev, msglvl, nic_dev->netdev, \ format, ## arg); \ else \ - nic_##level(&(nic_dev)->pdev->dev, \ + nic_##level(&nic_dev->pdev->dev, \ format, ## arg); \ } while (0) diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nic_io.c b/drivers/net/ethernet/huawei/hinic/hinic_nic_io.c index 30398ee0cc4b2166c522dfc3278ad1feb5745b26..a2160f2ca20fcbba5a9b6adf3ef6ca86e3f44253 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_nic_io.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_nic_io.c @@ -107,9 +107,15 @@ struct hinic_sq_db { u32 db_info; }; +struct hinic_addr { + u32 addr_hi; + u32 addr_lo; +}; + struct hinic_clean_queue_ctxt { struct hinic_qp_ctxt_header cmdq_hdr; u32 ctxt_size; + struct hinic_addr cqe_dma_addr[HINIC_RQ_CQ_MAX]; }; static int init_sq(struct hinic_sq *sq, struct hinic_wq *wq, u16 q_id, @@ -131,6 +137,7 @@ static int init_rq(struct hinic_rq *rq, void *dev_hdl, struct hinic_wq *wq, { rq->wq = wq; rq->q_id = q_id; + rq->cqe_dma_addr = 0; rq->msix_entry_idx = rq_msix_idx; @@ -144,6 +151,15 @@ static int init_rq(struct hinic_rq *rq, void *dev_hdl, struct hinic_wq *wq, return 0; } +void hinic_rq_cqe_addr_set(void *hwdev, u16 qid, dma_addr_t cqe_dma_ddr) +{ + struct hinic_hwdev *dev = (struct hinic_hwdev *)hwdev; + struct hinic_nic_io *nic_io; + + nic_io = dev->nic_io; + nic_io->qps[qid].rq.cqe_dma_addr = cqe_dma_ddr; +} + static void clean_rq(struct hinic_rq *rq, void *dev_hdl) { dma_free_coherent(dev_hdl, PAGE_SIZE, rq->pi_virt_addr, @@ -624,8 +640,10 @@ static int clean_queue_offload_ctxt(struct hinic_nic_io *nic_io, struct hinic_hwdev *hwdev = nic_io->hwdev; struct hinic_clean_queue_ctxt *ctxt_block; struct hinic_cmd_buf *cmd_buf; + dma_addr_t cqe_dma_addr; + struct hinic_addr *addr; u64 out_param = 0; - int err; + int i, err; cmd_buf = hinic_alloc_cmd_buf(hwdev); if (!cmd_buf) { @@ -640,6 +658,15 @@ static int clean_queue_offload_ctxt(struct hinic_nic_io *nic_io, /* TSO/LRO ctxt size: 0x0:0B; 0x1:160B; 0x2:200B; 0x3:240B */ ctxt_block->ctxt_size = 0x3; + if ((hinic_func_type(hwdev) == TYPE_VF) && + ctxt_type == HINIC_QP_CTXT_TYPE_RQ) { + addr = ctxt_block->cqe_dma_addr; + for (i = 0; i < nic_io->max_qps; i++) { + cqe_dma_addr = nic_io->qps[i].rq.cqe_dma_addr; + addr[i].addr_hi = upper_32_bits(cqe_dma_addr); + addr[i].addr_lo = lower_32_bits(cqe_dma_addr); + } + } hinic_cpu_to_be32(ctxt_block, sizeof(*ctxt_block)); @@ -725,6 +752,7 @@ int hinic_init_qp_ctxts(void *dev) return err; } +EXPORT_SYMBOL(hinic_init_qp_ctxts); void hinic_free_qp_ctxts(void *hwdev) { @@ -791,6 +819,7 @@ int hinic_init_nic_hwdev(void *hwdev, u16 rx_buff_len) } return 0; } +EXPORT_SYMBOL(hinic_init_nic_hwdev); void hinic_free_nic_hwdev(void *hwdev) { diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nic_io.h b/drivers/net/ethernet/huawei/hinic/hinic_nic_io.h index 92b683f90f268d0a87409e6fa47b38435983fa00..e52f99f415b675c69c87eab07462e466f4a66e4d 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_nic_io.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_nic_io.h @@ -93,4 +93,7 @@ void hinic_be32_to_cpu(void *data, int len); void hinic_set_sge(struct hinic_sge *sge, dma_addr_t addr, u32 len); dma_addr_t hinic_sge_to_dma(struct hinic_sge *sge); + +void hinic_rq_cqe_addr_set(void *hwdev, u16 qid, dma_addr_t cqe_dma_ddr); + #endif diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nictool.c b/drivers/net/ethernet/huawei/hinic/hinic_nictool.c index f213f2cd660e8578a661d7de159c54dd31b91fd8..5e924ca8588a58965162578630118e6d87f8d61a 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_nictool.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_nictool.c @@ -39,6 +39,7 @@ #define MAJOR_DEV_NUM 921 #define HINIC_CMDQ_BUF_MAX_SIZE 2048U #define MSG_MAX_IN_SIZE (2048 * 1024) +#define MSG_MAX_OUT_SIZE (2048 * 1024) static dev_t g_dev_id = {0}; /*lint -save -e104 -e808*/ @@ -153,6 +154,10 @@ static int alloc_buff_out(void *hwdev, struct msg_module *nt_msg, cmd_buf = hinic_alloc_cmd_buf(hwdev); *buf_out = (void *)cmd_buf; } else { + if (out_size > MSG_MAX_OUT_SIZE) { + pr_err("out size(%u) more than 2M\n", out_size); + return -ENOMEM; + } *buf_out = kzalloc(out_size, GFP_KERNEL); } if (!(*buf_out)) { @@ -656,6 +661,248 @@ static int set_link_mode(struct hinic_nic_dev *nic_dev, void *buf_in, return 0; } +static int set_dcb_cfg(struct hinic_nic_dev *nic_dev, void *buf_in, + u32 in_size, void *buf_out, u32 *out_size) +{ + union _dcb_ctl dcb_ctl = {.data = 0}; + int err; + + if (!buf_in || !buf_out || !out_size) + return -EINVAL; + + dcb_ctl.data = *((u32 *)buf_in); + + err = hinic_setup_dcb_tool(nic_dev->netdev, + &dcb_ctl.dcb_data.dcb_en, + !!dcb_ctl.dcb_data.wr_flag); + if (err) { + nicif_err(nic_dev, drv, nic_dev->netdev, + "Failed to setup dcb state to %d\n", + !!dcb_ctl.dcb_data.dcb_en); + err = EINVAL; + } + dcb_ctl.dcb_data.err = (u8)err; + *((u32 *)buf_out) = (u32)dcb_ctl.data; + *out_size = sizeof(u32); + + return 0; +} + +int get_pfc_info(struct hinic_nic_dev *nic_dev, void *buf_in, + u32 in_size, void *buf_out, u32 *out_size) +{ + union _pfc pfc = {.data = 0}; + + if (!buf_in || !buf_out || !out_size) + return -EINVAL; + + pfc.data = *((u32 *)buf_in); + + hinic_dcbnl_set_pfc_en_tool(nic_dev->netdev, + &pfc.pfc_data.pfc_en, false); + hinic_dcbnl_get_pfc_cfg_tool(nic_dev->netdev, + &pfc.pfc_data.pfc_priority); + hinic_dcbnl_get_tc_num_tool(nic_dev->netdev, + &pfc.pfc_data.num_of_tc); + *((u32 *)buf_out) = (u32)pfc.data; + *out_size = sizeof(u32); + + return 0; +} + +int set_pfc_control(struct hinic_nic_dev *nic_dev, void *buf_in, + u32 in_size, void *buf_out, u32 *out_size) +{ + u8 pfc_en = 0; + u8 err = 0; + + if (!buf_in || !buf_out || !out_size) + return -EINVAL; + + pfc_en = *((u8 *)buf_in); + if (!(test_bit(HINIC_DCB_ENABLE, &nic_dev->flags))) { + nicif_err(nic_dev, drv, nic_dev->netdev, + "Need to enable dcb first.\n"); + err = 0xff; + goto exit; + } + + hinic_dcbnl_set_pfc_en_tool(nic_dev->netdev, &pfc_en, true); + err = hinic_dcbnl_set_pfc_tool(nic_dev->netdev); + if (err) { + nicif_err(nic_dev, drv, nic_dev->netdev, + "Failed to set pfc to %s\n", + pfc_en ? "enable" : "disable"); + } + +exit: + *((u8 *)buf_out) = (u8)err; + *out_size = sizeof(u8); + return 0; +} + +int set_ets(struct hinic_nic_dev *nic_dev, void *buf_in, + u32 in_size, void *buf_out, u32 *out_size) +{ + struct _ets ets = {0}; + u8 err = 0; + u8 i; + u8 support_tc = nic_dev->max_cos; + + if (!buf_in || !buf_out || !out_size) + return -EINVAL; + memcpy(&ets, buf_in, sizeof(struct _ets)); + + if (!(test_bit(HINIC_DCB_ENABLE, &nic_dev->flags))) { + nicif_err(nic_dev, drv, nic_dev->netdev, + "Need to enable dcb first.\n"); + err = 0xff; + goto exit; + } + if (ets.flag_com.ets_flag.flag_ets_enable) { + hinic_dcbnl_set_ets_en_tool(nic_dev->netdev, &ets.ets_en, true); + + if (!ets.ets_en) + goto exit; + } + + if (!(test_bit(HINIC_ETS_ENABLE, &nic_dev->flags))) { + nicif_err(nic_dev, drv, nic_dev->netdev, + "Need to enable ets first.\n"); + err = 0xff; + goto exit; + } + if (ets.flag_com.ets_flag.flag_ets_cos) + hinic_dcbnl_set_ets_tc_tool(nic_dev->netdev, ets.tc, true); + + if (ets.flag_com.ets_flag.flag_ets_percent) { + for (i = support_tc; i < HINIC_DCB_TC_MAX; i++) { + if (ets.ets_percent[i]) { + nicif_err(nic_dev, drv, nic_dev->netdev, + "ETS setting out of range\n"); + break; + } + } + + hinic_dcbnl_set_ets_pecent_tool(nic_dev->netdev, + ets.ets_percent, true); + } + + if (ets.flag_com.ets_flag.flag_ets_strict) + hinic_dcbnl_set_ets_strict_tool(nic_dev->netdev, + &ets.strict, true); + + err = hinic_dcbnl_set_ets_tool(nic_dev->netdev); + if (err) { + nicif_err(nic_dev, drv, nic_dev->netdev, + "Failed to set ets [%d].\n", err); + } +exit: + *((u8 *)buf_out) = err; + *out_size = sizeof(err); + return 0; +} + +int get_support_up(struct hinic_nic_dev *nic_dev, void *buf_in, + u32 in_size, void *buf_out, u32 *out_size) +{ + u8 *up_num = buf_out; + u8 support_up = 0; + u8 i; + u8 up_valid_bitmap = nic_dev->up_valid_bitmap; + + if (!buf_in || !buf_out || !out_size) + return -EINVAL; + + if (*out_size != sizeof(*up_num)) { + nicif_err(nic_dev, drv, nic_dev->netdev, + "Unexpect out buf size from user: %d, expect: %lu\n", + *out_size, sizeof(*up_num)); + return -EFAULT; + } + + for (i = 0; i < HINIC_DCB_UP_MAX; i++) { + if (up_valid_bitmap & BIT(i)) + support_up++; + } + + *up_num = support_up; + + return 0; +} + +int get_support_tc(struct hinic_nic_dev *nic_dev, void *buf_in, + u32 in_size, void *buf_out, u32 *out_size) +{ + u8 *tc_num = buf_out; + + if (!buf_in || !buf_out || !out_size) + return -EINVAL; + + if (*out_size != sizeof(*tc_num)) { + nicif_err(nic_dev, drv, nic_dev->netdev, + "Unexpect out buf size from user :%d, expect: %lu\n", + *out_size, sizeof(*tc_num)); + return -EFAULT; + } + + hinic_dcbnl_get_tc_num_tool(nic_dev->netdev, tc_num); + + return 0; +} + +int get_ets_info(struct hinic_nic_dev *nic_dev, void *buf_in, + u32 in_size, void *buf_out, u32 *out_size) +{ + struct _ets *ets = buf_out; + + if (!buf_in || !buf_out || !out_size) + return -EINVAL; + + hinic_dcbnl_set_ets_pecent_tool(nic_dev->netdev, + ets->ets_percent, false); + hinic_dcbnl_set_ets_tc_tool(nic_dev->netdev, ets->tc, false); + hinic_dcbnl_set_ets_en_tool(nic_dev->netdev, &ets->ets_en, false); + hinic_dcbnl_set_ets_strict_tool(nic_dev->netdev, &ets->strict, false); + ets->err = 0; + + *out_size = sizeof(*ets); + return 0; +} + +int set_pfc_priority(struct hinic_nic_dev *nic_dev, void *buf_in, + u32 in_size, void *buf_out, u32 *out_size) +{ + u8 pfc_prority = 0; + u8 err = 0; + + if (!buf_in || !buf_out || !out_size) + return -EINVAL; + + pfc_prority = *((u8 *)buf_in); + if (!((test_bit(HINIC_DCB_ENABLE, &nic_dev->flags)) && + nic_dev->tmp_dcb_cfg.pfc_state)) { + nicif_err(nic_dev, drv, nic_dev->netdev, + "Need to enable pfc first.\n"); + err = 0xff; + goto exit; + } + + hinic_dcbnl_set_pfc_cfg_tool(nic_dev->netdev, pfc_prority); + + err = hinic_dcbnl_set_pfc_tool(nic_dev->netdev); + if (err) { + nicif_err(nic_dev, drv, nic_dev->netdev, + "Failed to set pfc to %x priority\n", + pfc_prority); + } +exit: + *((u8 *)buf_out) = (u8)err; + *out_size = sizeof(u8); + + return 0; +} + static int set_pf_bw_limit(struct hinic_nic_dev *nic_dev, void *buf_in, u32 in_size, void *buf_out, u32 *out_size) { @@ -719,7 +966,6 @@ static int get_poll_weight(struct hinic_nic_dev *nic_dev, void *buf_in, u32 in_size, void *buf_out, u32 *out_size) { struct hinic_nic_poll_weight *weight_info = buf_out; - if (*out_size != sizeof(*weight_info)) { nicif_err(nic_dev, drv, nic_dev->netdev, "Unexpect out buf size from user :%d, expect: %lu\n", @@ -744,7 +990,6 @@ static int get_homologue(struct hinic_nic_dev *nic_dev, void *buf_in, u32 in_size, void *buf_out, u32 *out_size) { struct hinic_homologues *homo = buf_out; - if (*out_size != sizeof(*homo)) { nicif_err(nic_dev, drv, nic_dev->netdev, "Unexpect out buf size from user :%d, expect: %lu\n", @@ -788,8 +1033,8 @@ static int get_sset_count(struct hinic_nic_dev *nic_dev, void *buf_in, if (!buf_in || in_size != sizeof(u32) || !out_size || *out_size != sizeof(u32) || !buf_out) { - nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %d, out_size: %d\n", - in_size, *out_size); + nicif_err(nic_dev, drv, nic_dev->netdev, + "Invalid parameters.\n"); return -EINVAL; } @@ -873,7 +1118,7 @@ static int get_func_id(void *hwdev, void *buf_in, u32 in_size, return -EFAULT; } - func_id = hinic_global_func_id(hwdev); + func_id = hinic_global_func_id_hw(hwdev); *(u16 *)buf_out = func_id; *out_size = sizeof(u16); return 0; @@ -957,7 +1202,6 @@ static int get_device_id(void *hwdev, void *buf_in, u32 in_size, { u16 dev_id; int err; - if (*out_size != sizeof(u16)) { pr_err("Unexpect out buf size from user :%d, expect: %lu\n", *out_size, sizeof(u16)); @@ -992,7 +1236,7 @@ static int is_driver_in_vm(void *hwdev, void *buf_in, u32 in_size, } static int get_pf_id(void *hwdev, void *buf_in, u32 in_size, - void *buf_out, u32 *out_size) + void *buf_out, u32 *out_size) { struct hinic_pf_info *pf_info; u32 port_id = 0; @@ -1118,7 +1362,7 @@ static int knl_free_mem(char *dev_name, struct msg_module *nt_msg) return 0; } -extern int hinic_get_card_func_info_by_card_name(char *chip_name, +extern int hinic_get_card_func_info_by_card_name(const char *chip_name, struct hinic_card_func_info *card_func); @@ -1220,6 +1464,14 @@ struct nic_drv_module_handle nic_driv_module_cmd_handle[] = { {SET_HOMOLOGUE, set_homologue}, {GET_SSET_COUNT, get_sset_count}, {GET_SSET_ITEMS, get_sset_stats}, + {SET_PFC_CONTROL, set_pfc_control}, + {SET_ETS, set_ets}, + {GET_ETS_INFO, get_ets_info}, + {SET_PFC_PRIORITY, set_pfc_priority}, + {SET_DCB_CFG, set_dcb_cfg}, + {GET_PFC_INFO, get_pfc_info}, + {GET_SUPPORT_UP, get_support_up}, + {GET_SUPPORT_TC, get_support_tc}, }; struct hw_drv_module_handle hw_driv_module_cmd_handle[] = { @@ -1550,7 +1802,7 @@ static int send_to_sm(void *hwdev, struct msg_module *nt_msg, } static bool is_hwdev_cmd_support(unsigned int mod, - char *ifname, u32 up_api_type) + char *ifname, u32 up_api_type) { void *hwdev; @@ -1606,7 +1858,7 @@ static bool is_hwdev_cmd_support(unsigned int mod, } static bool nictool_k_is_cmd_support(unsigned int mod, - char *ifname, u32 up_api_type) + char *ifname, u32 up_api_type) { enum hinic_init_state init_state = hinic_get_init_state_by_ifname(ifname); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nictool.h b/drivers/net/ethernet/huawei/hinic/hinic_nictool.h index f903e7782f3ca8a15b215517863649b3403d8c2a..8e848a004d86f885c7aed1362a311d3b21e8184a 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_nictool.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_nictool.h @@ -74,6 +74,50 @@ struct up_cmd_st { }; }; +struct _dcb_data { + u8 wr_flag; + u8 dcb_en; + u8 err; + u8 rsvd; +}; + +union _dcb_ctl { + struct _dcb_data dcb_data; + u32 data; +}; + +struct _pfc_data { + u8 pfc_en; + u8 pfc_priority; + u8 num_of_tc; + u8 err; +}; + +union _pfc { + struct _pfc_data pfc_data; + u32 data; +}; + +union _flag_com { + struct _ets_flag { + u8 flag_ets_enable:1; + u8 flag_ets_percent:1; + u8 flag_ets_cos:1; + u8 flag_ets_strict:1; + u8 rev:4; + } ets_flag; + u8 data; +}; + +struct _ets { + u8 ets_en; + u8 err; + u8 strict; + u8 tc[8]; + u8 ets_percent[8]; + union _flag_com flag_com; +}; + #define API_CMD 0x1 #define API_CHAIN 0x2 #define API_CLP 0x3 @@ -209,8 +253,8 @@ struct hinic_card_func_info { extern void *g_card_node_array[MAX_CARD_NUM]; extern void *g_card_vir_addr[MAX_CARD_NUM]; extern u64 g_card_phy_addr[MAX_CARD_NUM]; -extern int card_id; extern struct mutex g_addr_lock; +extern int card_id; struct hinic_nic_loop_mode { u32 loop_mode; @@ -237,6 +281,7 @@ struct hinic_pf_info { int nictool_k_init(void); void nictool_k_uninit(void); + extern u32 hinic_get_io_stats_size(struct hinic_nic_dev *nic_dev); extern void hinic_get_io_stats(struct hinic_nic_dev *nic_dev, struct hinic_show_item *items); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_pci_id_tbl.h b/drivers/net/ethernet/huawei/hinic/hinic_pci_id_tbl.h index f45e54be9c3c926f5afbadd7cf1b04d5771eaf5d..d225e543f68a04facf251293e875b79bdf5b5bf5 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_pci_id_tbl.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_pci_id_tbl.h @@ -25,6 +25,7 @@ #define HINIC_DEV_ID_1822_PANGEA_TP_10GE 0x0204 #define HINIC_DEV_ID_1822_KR_40GE 0x020D #define HINIC_DEV_ID_1822_KR_100GE 0x0205 +#define HINIC_DEV_ID_1822_DUAL_25GE 0x0206 #define HINIC_DEV_ID_1822_KR_25GE 0x0210 #define HINIC_DEV_ID_1822_MULTI_HOST 0x0211 #define HINIC_DEV_ID_1822_100GE 0x0200 diff --git a/drivers/net/ethernet/huawei/hinic/hinic_port_cmd.h b/drivers/net/ethernet/huawei/hinic/hinic_port_cmd.h index 652d6429bbe8044d299cc5395c600706090b42bc..47428103fab7c6df3a92feeea7e7b00cdada2aab 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_port_cmd.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_port_cmd.h @@ -1,19 +1,4 @@ /* SPDX-License-Identifier: GPL-2.0*/ -/* Copyright (C), 2001-2011, Huawei Tech. Co., Ltd. - * - * File Name : hinic_port_cmd.h - * Version : Initial Draft - * Author : Qu Huichun - * Created : 2018/5/29 - * Last Modified : - * Description : Commands between NIC and uP - * Function List : - * History : - * 1.Date : 2018/5/29 - * Author : Qu Huichun - * Modification: Created file - */ - #ifndef __HINIC_PORT_CMD_H__ #define __HINIC_PORT_CMD_H__ @@ -225,7 +210,7 @@ enum hinic_mgmt_cmd { HINIC_MGMT_CMD_MQM_FIX_INFO_GET = 0x16, HINIC_MGMT_CMD_MQM_CFG_INFO_SET = 0x18, - HINIC_MGMT_MQM_SRCH_GPA_SET = 0x20, + HINIC_MGMT_CMD_MQM_SRCH_GPA_SET = 0x20, HINIC_MGMT_CMD_PPF_TMR_SET = 0x22, HINIC_MGMT_CMD_PPF_HT_GPA_SET = 0x23, HINIC_MGMT_CMD_RES_STATE_SET = 0x24, @@ -276,9 +261,11 @@ enum hinic_mgmt_cmd { HINIC_MGMT_CMD_GET_PHY_INIT_STATUS = 0x6A, HINIC_MGMT_CMD_HEARTBEAT_SUPPORTED = 0x6B, - HINIC_MGMT_HEARTBEAT_EVENT = 0x6C, + HINIC_MGMT_CMD_HEARTBEAT_EVENT = 0x6C, HINIC_MGMT_CMD_GET_HW_PF_INFOS = 0x6D, HINIC_MGMT_CMD_GET_SDI_MODE = 0x6E, + + HINIC_MGMT_CMD_ENABLE_MIGRATE = 0x6F, }; /* uCode relates commands */ @@ -299,9 +286,10 @@ enum hinic_ucode_cmd { enum hinic_sw_funcs_cmd { HINIC_SW_CMD_SLAVE_HOST_PPF_REGISTER = 0x0, HINIC_SW_CMD_SLAVE_HOST_PPF_UNREGISTER = 0x1, - HINIC_SW_GET_SLAVE_FUNC_NIC_STATE = 0x2, + HINIC_SW_CMD_GET_SLAVE_FUNC_NIC_STATE = 0x2, HINIC_SW_CMD_SET_SLAVE_FUNC_NIC_STATE = 0x3, HINIC_SW_CMD_SEND_MSG_TO_VF = 0x4, + HINIC_SW_CMD_MIGRATE_READY = 0x5, }; enum sq_l4offload_type { diff --git a/drivers/net/ethernet/huawei/hinic/hinic_qe_def.h b/drivers/net/ethernet/huawei/hinic/hinic_qe_def.h index 5a39ef678826778d45659b4fe08f933c85d7ecaa..a5b4e6f85639663e1292270459b4a3babf23385a 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_qe_def.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_qe_def.h @@ -155,17 +155,17 @@ extern "C"{ SQ_TASK_INFO4_##member##_SHIFT) /********************* SQ_DB *********************/ -#define SQ_DB_OFF 0x00000800 -#define SQ_DB_INFO_HI_PI_SHIFT 0 -#define SQ_DB_INFO_QID_SHIFT 8 +#define SQ_DB_OFF 0x00000800 +#define SQ_DB_INFO_HI_PI_SHIFT 0 +#define SQ_DB_INFO_QID_SHIFT 8 #define SQ_DB_INFO_CFLAG_SHIFT 23 -#define SQ_DB_INFO_COS_SHIFT 24 -#define SQ_DB_INFO_TYPE_SHIFT 27 -#define SQ_DB_INFO_HI_PI_MASK 0xFFU -#define SQ_DB_INFO_QID_MASK 0x3FFU -#define SQ_DB_INFO_CFLAG_MASK 0x1U -#define SQ_DB_INFO_COS_MASK 0x7U -#define SQ_DB_INFO_TYPE_MASK 0x1FU +#define SQ_DB_INFO_COS_SHIFT 24 +#define SQ_DB_INFO_TYPE_SHIFT 27 +#define SQ_DB_INFO_HI_PI_MASK 0xFFU +#define SQ_DB_INFO_QID_MASK 0x3FFU +#define SQ_DB_INFO_CFLAG_MASK 0x1U +#define SQ_DB_INFO_COS_MASK 0x7U +#define SQ_DB_INFO_TYPE_MASK 0x1FU #define SQ_DB_INFO_SET(val, member) (((u32)(val) & \ SQ_DB_INFO_##member##_MASK) << \ SQ_DB_INFO_##member##_SHIFT) @@ -174,21 +174,21 @@ extern "C"{ #define SQ_DB_PI_LOW(pi) ((pi) & SQ_DB_PI_LOW_MASK) #define SQ_DB_PI_HI_SHIFT 8 #define SQ_DB_PI_HIGH(pi) ((pi) >> SQ_DB_PI_HI_SHIFT) -#define SQ_DB_ADDR(sq, pi) ((u64 *)((sq)->db_addr + SQ_DB_OFF) + \ - SQ_DB_PI_LOW(pi)) -#define SQ_DB 1 -#define SQ_CFLAG_DP 0 +#define SQ_DB_ADDR(sq, pi) ((u64 *)((sq)->db_addr + SQ_DB_OFF) + \ + SQ_DB_PI_LOW(pi)) +#define SQ_DB 1 +#define SQ_CFLAG_DP 0 /* CFLAG_DATA_PATH */ /*********************** RQ_CTRL ******************/ #define RQ_CTRL_BUFDESC_SECT_LEN_SHIFT 0 #define RQ_CTRL_COMPLETE_FORMAT_SHIFT 15 #define RQ_CTRL_COMPLETE_LEN_SHIFT 27 -#define RQ_CTRL_LEN_SHIFT 29 +#define RQ_CTRL_LEN_SHIFT 29 #define RQ_CTRL_BUFDESC_SECT_LEN_MASK 0xFFU #define RQ_CTRL_COMPLETE_FORMAT_MASK 0x1U #define RQ_CTRL_COMPLETE_LEN_MASK 0x3U -#define RQ_CTRL_LEN_MASK 0x3U +#define RQ_CTRL_LEN_MASK 0x3U #define RQ_CTRL_SET(val, member) (((val) & \ RQ_CTRL_##member##_MASK) << \ @@ -232,8 +232,8 @@ extern "C"{ #define RQ_CQE_SGE_VLAN_SHIFT 0 #define RQ_CQE_SGE_LEN_SHIFT 16 -#define RQ_CQE_SGE_VLAN_MASK 0xFFFFU -#define RQ_CQE_SGE_LEN_MASK 0xFFFFU +#define RQ_CQE_SGE_VLAN_MASK 0xFFFFU +#define RQ_CQE_SGE_LEN_MASK 0xFFFFU #define RQ_CQE_SGE_GET(val, member) (((val) >> \ RQ_CQE_SGE_##member##_SHIFT) & \ @@ -313,10 +313,10 @@ extern "C"{ #define WQS_PAGE_SIZE (WQS_BLOCKS_PER_PAGE * WQ_BLOCK_SIZE) #define WQ_MAX_PAGES (WQ_BLOCK_SIZE >> WQ_PAGE_ADDR_SIZE_SHIFT) -#define CMDQ_BLOCKS_PER_PAGE 8 -#define CMDQ_BLOCK_SIZE 512UL -#define CMDQ_PAGE_SIZE ALIGN((CMDQ_BLOCKS_PER_PAGE * \ - CMDQ_BLOCK_SIZE), PAGE_SIZE) +#define CMDQ_BLOCKS_PER_PAGE 8 +#define CMDQ_BLOCK_SIZE 512UL +#define CMDQ_PAGE_SIZE ALIGN((CMDQ_BLOCKS_PER_PAGE * \ + CMDQ_BLOCK_SIZE), PAGE_SIZE) #define ADDR_4K_ALIGNED(addr) (0 == ((addr) & 0xfff)) #define ADDR_256K_ALIGNED(addr) (0 == ((addr) & 0x3ffff)) @@ -440,16 +440,16 @@ enum hinic_res_state { ((pkt_types) & RQ_CQE_PKT_TYPES_NON_L2_MASK) #define HINIC_PKT_TYPES_L2(pkt_types) \ - ((pkt_types) & RQ_CQE_PKT_TYPES_L2_MASK) + (pkt_types & RQ_CQE_PKT_TYPES_L2_MASK) #define HINIC_CSUM_ERR_BYPASSED(csum_err) \ - ((csum_err) == RQ_CQE_STATUS_CSUM_BYPASS_VAL) + (csum_err == RQ_CQE_STATUS_CSUM_BYPASS_VAL) #define HINIC_CSUM_ERR_IP(csum_err) \ - ((csum_err) & RQ_CQE_STATUS_CSUM_ERR_IP_MASK) + (csum_err & RQ_CQE_STATUS_CSUM_ERR_IP_MASK) #define HINIC_CSUM_ERR_L4(csum_err) \ - ((csum_err) & RQ_CQE_STATUS_CSUM_ERR_L4_MASK) + (csum_err & RQ_CQE_STATUS_CSUM_ERR_L4_MASK) #define TX_MSS_DEFAULT 0x3E00 #define TX_MSS_MIN 0x50 diff --git a/drivers/net/ethernet/huawei/hinic/hinic_rx.c b/drivers/net/ethernet/huawei/hinic/hinic_rx.c index 469759a324b5a9d237a4377fc64731b449bc16fe..bf9d58633f66824a76d3123f53fdb870c52e7967 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_rx.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_rx.c @@ -1,5 +1,5 @@ -/* - * Huawei HiNIC PCI Express Linux driver +// SPDX-License-Identifier: GPL-2.0 +/* Huawei HiNIC PCI Express Linux driver * Copyright(c) 2017 Huawei Technologies Co., Ltd * * This program is free software; you can redistribute it and/or modify it @@ -43,15 +43,14 @@ static void hinic_clear_rss_config_user(struct hinic_nic_dev *nic_dev); #define HINIC_RX_HDR_SIZE 256 -#define HINIC_RX_BUFFER_WRITE 16 #define HINIC_RX_IPV6_PKT 7 #define HINIC_RX_VXLAN_PKT 0xb #define RXQ_STATS_INC(rxq, field) \ { \ - u64_stats_update_begin(&(rxq)->rxq_stats.syncp); \ - (rxq)->rxq_stats.field++; \ - u64_stats_update_end(&(rxq)->rxq_stats.syncp); \ + u64_stats_update_begin(&rxq->rxq_stats.syncp); \ + rxq->rxq_stats.field++; \ + u64_stats_update_end(&rxq->rxq_stats.syncp); \ } static bool rx_alloc_mapped_page(struct hinic_rxq *rxq, @@ -770,6 +769,7 @@ static int rx_alloc_cqe(struct hinic_rxq *rxq) cqe_pa += sizeof(*rx_info->cqe); } + hinic_rq_cqe_addr_set(nic_dev->hwdev, rxq->q_id, rxq->cqe_start_paddr); return 0; } diff --git a/drivers/net/ethernet/huawei/hinic/hinic_rx.h b/drivers/net/ethernet/huawei/hinic/hinic_rx.h index f496516638ec8f2693475f43fd361c776bc5d5e3..89be4b6f9272b8d064b0c1146baf42e822c14034 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_rx.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_rx.h @@ -1,5 +1,5 @@ -/* - * Huawei HiNIC PCI Express Linux driver +/* SPDX-License-Identifier: GPL-2.0*/ +/* Huawei HiNIC PCI Express Linux driver * Copyright(c) 2017 Huawei Technologies Co., Ltd * * This program is free software; you can redistribute it and/or modify it @@ -33,6 +33,7 @@ #define HINIC_RX_BP_UPPER_THD 400 #define HINIC_SUPPORT_LRO_ADAP_QPS_MAX 16 +#define HINIC_RX_BUFFER_WRITE 16 enum { HINIC_RX_STATUS_BP_EN, diff --git a/drivers/net/ethernet/huawei/hinic/hinic_sm_lt.h b/drivers/net/ethernet/huawei/hinic/hinic_sm_lt.h index 091bcccd9c75e90b2fc9997a051ebce5c8932457..78767c4e4a0827f4831d6767d7f6b8b397dd3f24 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_sm_lt.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_sm_lt.h @@ -1,4 +1,4 @@ -/*SPDX-License-Identifier: GPL-2.0*/ +/* SPDX-License-Identifier: GPL-2.0*/ /* Huawei HiNIC PCI Express Linux driver * Copyright(c) 2017 Huawei Technologies Co., Ltd * diff --git a/drivers/net/ethernet/huawei/hinic/hinic_sml_counter.c b/drivers/net/ethernet/huawei/hinic/hinic_sml_counter.c index 7e1814520e43e765edeb1314bb5996dec898d817..9315aaeb8543137a1774cc40a00b60cbe5a68fec 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_sml_counter.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_sml_counter.c @@ -28,11 +28,11 @@ | (((x) & 0xff000000) >> 24)) #endif -static void sml_ctr_htonl_n(u32 *node, u32 ullen) +static void sml_ctr_htonl_n(u32 *node, u32 ulLen) { u32 i; - for (i = 0; i < ullen; i++) { + for (i = 0; i < ulLen; i++) { *node = HTONL(*node); node++; } diff --git a/drivers/net/ethernet/huawei/hinic/hinic_sriov.c b/drivers/net/ethernet/huawei/hinic/hinic_sriov.c index adc9b755c67bf68950209d274514ea3a0710e715..ddfa32029206c8a751aa1f176a7792f0bcb1b056 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_sriov.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_sriov.c @@ -310,6 +310,13 @@ int hinic_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) err = hinic_kill_vf_vlan(sriov_info->hwdev, OS_VF_ID_TO_HW(vf)); } + if (err) + return err; + + err = hinic_update_mac_vlan(sriov_info->hwdev, + cur_vlanprio & VLAN_VID_MASK, vlan, + OS_VF_ID_TO_HW(vf)); + out: return err; } @@ -334,7 +341,7 @@ int hinic_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting) return 0; err = hinic_set_vf_spoofchk(sriov_info->hwdev, - OS_VF_ID_TO_HW(vf), setting); + OS_VF_ID_TO_HW(vf), setting); if (!err) { nicif_info(adapter, drv, netdev, "Set VF %d spoofchk %s\n", @@ -490,4 +497,6 @@ int hinic_ndo_set_vf_bw(struct net_device *netdev, int vf, int max_tx_rate) #endif return 0; -} /*lint -restore*/ +} + +/*lint -restore*/ diff --git a/drivers/net/ethernet/huawei/hinic/hinic_tx.c b/drivers/net/ethernet/huawei/hinic/hinic_tx.c index 0088acc9836b427e7929a56597ea3b20214a0363..5b205dcb1e806a28daf400682935ca3f44b3c195 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_tx.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_tx.c @@ -1,5 +1,5 @@ -/* - * Huawei HiNIC PCI Express Linux driver +// SPDX-License-Identifier: GPL-2.0 +/* Huawei HiNIC PCI Express Linux driver * Copyright(c) 2017 Huawei Technologies Co., Ltd * * This program is free software; you can redistribute it and/or modify it @@ -47,9 +47,9 @@ #define TXQ_STATS_INC(txq, field) \ { \ - u64_stats_update_begin(&(txq)->txq_stats.syncp); \ - (txq)->txq_stats.field++; \ - u64_stats_update_end(&(txq)->txq_stats.syncp); \ + u64_stats_update_begin(&txq->txq_stats.syncp); \ + txq->txq_stats.field++; \ + u64_stats_update_end(&txq->txq_stats.syncp); \ } void hinic_txq_get_stats(struct hinic_txq *txq, @@ -162,7 +162,7 @@ static int tx_map_skb(struct hinic_nic_dev *nic_dev, struct sk_buff *skb, } dma_len[0].dma = dma_map_single(&pdev->dev, skb->data, - skb_headlen(skb), DMA_TO_DEVICE); + skb_headlen(skb), DMA_TO_DEVICE); if (dma_mapping_error(&pdev->dev, dma_len[0].dma)) { TXQ_STATS_INC(txq, map_frag_err); err = -EFAULT; @@ -181,8 +181,8 @@ static int tx_map_skb(struct hinic_nic_dev *nic_dev, struct sk_buff *skb, frag = &(skb_shinfo(skb)->frags[i]); i++; dma_len[i].dma = skb_frag_dma_map(&pdev->dev, frag, 0, - skb_frag_size(frag), - DMA_TO_DEVICE); + skb_frag_size(frag), + DMA_TO_DEVICE); if (dma_mapping_error(&pdev->dev, dma_len[i].dma)) { TXQ_STATS_INC(txq, map_frag_err); i--; @@ -298,14 +298,12 @@ static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic_ip *ip, int pld_off = 0; pld_off = ipv6_skip_exthdr(skb, - (int)(exthdr - - skb->data), - l4_proto, - &frag_off); + (int)(exthdr - skb->data), + l4_proto, &frag_off); l4->hdr = skb->data + pld_off; } else { l4->hdr = exthdr; - #endif +#endif } } else { *l3_type = UNKNOWN_L3TYPE; @@ -804,7 +802,7 @@ static netdev_tx_t hinic_send_one_skb(struct sk_buff *skb, num_sge = skb_nr_frags + 1; - /* if skb->len is more than 65536B but num_sge is 1, + /* :if skb->len is more than 65536B but num_sge is 1, * driver will drop it */ if (unlikely(skb->len > HINIC_GSO_MAX_SIZE && num_sge == 1)) { @@ -874,20 +872,38 @@ static netdev_tx_t hinic_send_one_skb(struct sk_buff *skb, return NETDEV_TX_OK; } -netdev_tx_t hinic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) +netdev_tx_t hinic_lb_xmit_frame(struct sk_buff *skb, + struct net_device *netdev) { struct hinic_nic_dev *nic_dev = netdev_priv(netdev); + u16 q_id = skb_get_queue_mapping(skb); struct hinic_txq *txq; + u8 flag = 0; + + if (unlikely(!nic_dev->heart_status)) { + dev_kfree_skb_any(skb); + HINIC_NIC_STATS_INC(nic_dev, tx_carrier_off_drop); + return NETDEV_TX_OK; + } + + txq = &nic_dev->txqs[q_id]; + + return hinic_send_one_skb(skb, netdev, txq, &flag, HINIC_TX_NON_AVD); +} + +netdev_tx_t hinic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) +{ + struct hinic_nic_dev *nic_dev = netdev_priv(netdev); u16 q_id = skb_get_queue_mapping(skb); + struct hinic_txq *txq; u8 flag = 0; #ifdef HAVE_IP6_FRAG_ID_ENABLE_UFO struct sk_buff *ufo_skb; int err; #endif - if (unlikely((!netif_carrier_ok(netdev) && - !test_bit(HINIC_LP_TEST, &nic_dev->flags)) || - !nic_dev->heart_status)) { + if (unlikely(!netif_carrier_ok(netdev) || + !nic_dev->heart_status)) { dev_kfree_skb_any(skb); HINIC_NIC_STATS_INC(nic_dev, tx_carrier_off_drop); return NETDEV_TX_OK; @@ -997,7 +1013,7 @@ int hinic_tx_poll(struct hinic_txq *txq, int budget) /* Whether all of the wqebb of this wqe is completed */ if (hw_ci == sw_ci || ((hw_ci - sw_ci) & - txq->q_mask) < tx_info->wqebb_cnt) { + txq->q_mask) < tx_info->wqebb_cnt) { break; } diff --git a/drivers/net/ethernet/huawei/hinic/hinic_tx.h b/drivers/net/ethernet/huawei/hinic/hinic_tx.h index 89fce0849e6e7f9c5bb86cc25aba1ba74c023db1..04aeb3365ccaa5b8cf838e91eb71c209acdb79b0 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_tx.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_tx.h @@ -1,5 +1,5 @@ -/* - * Huawei HiNIC PCI Express Linux driver +/* SPDX-License-Identifier: GPL-2.0*/ +/* Huawei HiNIC PCI Express Linux driver * Copyright(c) 2017 Huawei Technologies Co., Ltd * * This program is free software; you can redistribute it and/or modify it @@ -77,7 +77,8 @@ struct hinic_txq { u16 q_depth; u16 q_mask; struct hinic_txq_stats txq_stats; - + u64 last_moder_packets; + u64 last_moder_bytes; struct hinic_tx_info *tx_info; }; @@ -97,6 +98,9 @@ void hinic_txq_clean_stats(struct hinic_txq_stats *txq_stats); void hinic_txq_get_stats(struct hinic_txq *txq, struct hinic_txq_stats *stats); +netdev_tx_t hinic_lb_xmit_frame(struct sk_buff *skb, + struct net_device *netdev); + netdev_tx_t hinic_xmit_frame(struct sk_buff *skb, struct net_device *netdev); int hinic_setup_all_tx_resources(struct net_device *netdev); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_wq.c b/drivers/net/ethernet/huawei/hinic/hinic_wq.c index 43d34ea72363b2cfce8a776370271ba54270098f..06401a654629127a61177b5e3264456baa8d68e7 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_wq.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_wq.c @@ -663,7 +663,7 @@ void *hinic_read_wqe(struct hinic_wq *wq, int num_wqebbs, u16 *cons_idx) return WQ_PAGE_ADDR(wq, *cons_idx) + WQE_PAGE_OFF(wq, *cons_idx); } -static inline int wqe_shadow(struct hinic_wq *wq, void *wqe) +static inline int wqe_shadow(struct hinic_wq *wq, const void *wqe) { void *end_wqe_shadow_addr; u32 wqe_shadow_size = wq->num_q_pages * wq->max_wqe_size; diff --git a/drivers/net/ethernet/huawei/hinic/ossl_knl_linux.c b/drivers/net/ethernet/huawei/hinic/ossl_knl_linux.c index 4475206f0d95404d7c6070fb6650478624347f15..798faa6f401da3a3b6ece1173786dcbbc711cec2 100644 --- a/drivers/net/ethernet/huawei/hinic/ossl_knl_linux.c +++ b/drivers/net/ethernet/huawei/hinic/ossl_knl_linux.c @@ -19,12 +19,12 @@ #define OSSL_MINUTE_BASE (60) -sdk_file *file_creat(char *file_name) +sdk_file *file_creat(const char *file_name) { return filp_open(file_name, O_CREAT | O_RDWR | O_APPEND, 0); } -sdk_file *file_open(char *file_name) +sdk_file *file_open(const char *file_name) { return filp_open(file_name, O_RDONLY, 0); } diff --git a/drivers/net/ethernet/huawei/hinic/ossl_knl_linux.h b/drivers/net/ethernet/huawei/hinic/ossl_knl_linux.h index 28b0bfbd999484d61561bba37c8d2097a2f54836..8cdcb1db2c3a167e1c051e87c68ef53e73095b69 100644 --- a/drivers/net/ethernet/huawei/hinic/ossl_knl_linux.h +++ b/drivers/net/ethernet/huawei/hinic/ossl_knl_linux.h @@ -432,9 +432,9 @@ static inline void __kc_eth_zero_addr(u8 *addr) typedef struct file sdk_file; -sdk_file *file_creat(char *file_name); +sdk_file *file_creat(const char *file_name); -sdk_file *file_open(char *file_name); +sdk_file *file_open(const char *file_name); void file_close(sdk_file *file_handle);