提交 f9e0a2f5 编写于 作者: X Xue 提交者: Xie XiuQi

net: update hinic driver to 2.3.2.1

driver inclusion
category:bugfix
bugzilla:4472
CVE:NA

------------------------------------------------------------------------

Update Hi1822 nic driver from 1.8.2.8 to 2.3.2.0:
Problem repair and reliability enhancement. Due to the
complexity of this content, we do not describe it here. If necessary,
please contact (xue chaojing) Get the release note for
details.
Reviewed-by: NWu Like <wulike1@huawei.com>
Signed-off-by: NXue <xuechaojing@huawei.com>
Reviewed-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 a061f5d6
...@@ -251,8 +251,8 @@ static void prepare_cell_ctrl(u64 *cell_ctrl, u16 cell_len) ...@@ -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, static void prepare_api_cmd(struct hinic_api_cmd_chain *chain,
struct hinic_api_cmd_cell *cell, struct hinic_api_cmd_cell *cell,
enum hinic_node_id dest, enum hinic_node_id dest,
void *cmd, u16 cmd_size) const void *cmd, u16 cmd_size)
{ {
struct hinic_api_cmd_cell_ctxt *cell_ctxt; struct hinic_api_cmd_cell_ctxt *cell_ctxt;
u32 priv; u32 priv;
......
...@@ -34,6 +34,20 @@ ...@@ -34,6 +34,20 @@
#include "hinic_nic_cfg.h" #include "hinic_nic_cfg.h"
#include "hinic_mgmt_interface.h" #include "hinic_mgmt_interface.h"
#include "hinic_multi_host_mgmt.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 intr_mode;
uint timer_enable = 1; uint timer_enable = 1;
...@@ -149,6 +163,7 @@ static void parse_pub_res_cap(struct service_cap *cap, ...@@ -149,6 +163,7 @@ static void parse_pub_res_cap(struct service_cap *cap,
cap->cos_valid_bitmap = dev_cap->valid_cos_bitmap; cap->cos_valid_bitmap = dev_cap->valid_cos_bitmap;
cap->er_id = dev_cap->er_id; cap->er_id = dev_cap->er_id;
cap->port_id = dev_cap->port_id; cap->port_id = dev_cap->port_id;
cap->force_up = dev_cap->force_up;
parse_sf_en_cap(cap, dev_cap, type); parse_sf_en_cap(cap, dev_cap, type);
...@@ -253,6 +268,7 @@ static void parse_l2nic_res_cap(struct service_cap *cap, ...@@ -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->max_rqs = dev_cap->nic_max_rq;
nic_cap->vf_max_sqs = 0; nic_cap->vf_max_sqs = 0;
nic_cap->vf_max_rqs = 0; nic_cap->vf_max_rqs = 0;
nic_cap->max_queue_allowed = dev_cap->max_queue_allowed;
} }
if (dev_cap->nic_lro_en) if (dev_cap->nic_lro_en)
...@@ -263,11 +279,12 @@ static void parse_l2nic_res_cap(struct service_cap *cap, ...@@ -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->lro_sz = dev_cap->nic_lro_sz;
nic_cap->tso_sz = dev_cap->nic_tso_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_sqs,
nic_cap->max_rqs, nic_cap->max_rqs,
nic_cap->vf_max_sqs, nic_cap->vf_max_sqs,
nic_cap->vf_max_rqs); nic_cap->vf_max_rqs,
nic_cap->max_queue_allowed);
/* Check parameters from firmware */ /* Check parameters from firmware */
if (nic_cap->max_sqs > HINIC_CFG_MAX_QP || 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) ...@@ -557,7 +574,9 @@ static int get_cap_from_fw(struct hinic_hwdev *dev, enum func_type type)
int err; int err;
dev_cap.version = HINIC_CMD_VER_FUNC_ID; 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", sdk_info(dev->dev_hdl, "Get cap from fw, func_idx: %d\n",
dev_cap.func_id); dev_cap.func_id);
...@@ -630,6 +649,14 @@ static int get_dev_cap(struct hinic_hwdev *dev) ...@@ -630,6 +649,14 @@ static int get_dev_cap(struct hinic_hwdev *dev)
static void nic_param_fix(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) static void rdma_param_fix(struct hinic_hwdev *dev)
...@@ -696,7 +723,8 @@ 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 * we use original 8bits directly for simpilification
*/ */
rdma_cap->max_fmr_maps = 255; 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->log_mtt_seg = LOG_MTT_SEG;
rdma_cap->mtt_entry_sz = MTT_ENTRY_SZ; rdma_cap->mtt_entry_sz = MTT_ENTRY_SZ;
rdma_cap->log_rdmarc_seg = LOG_RDMARC_SEG; 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, ...@@ -1158,7 +1186,7 @@ int hinic_alloc_ceqs(void *hwdev, enum hinic_service_type type, int num,
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
if (eq->num_ceq_remain == 0) { if (eq->num_ceq_remain == 0) {
sdk_warn(dev->dev_hdl, "Alloc %d ceqs, less than required %d ceqs\n", 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); mutex_unlock(&eq->eq_mutex);
return 0; return 0;
} }
...@@ -1322,15 +1350,16 @@ static int cfg_mbx_pf_proc_vf_msg(void *hwdev, u16 vf_id, u8 cmd, void *buf_in, ...@@ -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_sq = dev_cap_tmp.nic_max_sq + 1;
dev_cap->nic_max_rq = dev_cap_tmp.nic_max_rq + 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", dev_cap->max_queue_allowed = dev_cap_tmp.max_queue_allowed;
func_id, dev_cap->nic_max_sq); 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; return 0;
} }
static int cfg_mbx_ppf_proc_msg(void *hwdev, u16 pf_id, u16 vf_id, u8 cmd, 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, void *buf_in, u16 in_size, void *buf_out,
u16 *out_size) u16 *out_size)
{ {
struct hinic_hwdev *dev = hwdev; 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, ...@@ -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, 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; struct hinic_hwdev *dev = hwdev;
...@@ -1734,6 +1763,32 @@ bool hinic_func_for_mgmt(void *hwdev) ...@@ -1734,6 +1763,32 @@ bool hinic_func_for_mgmt(void *hwdev)
return true; 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) int cfg_set_func_sf_en(void *hwdev, u32 enbits, u32 enmask)
{ {
struct hinic_hwdev *dev = hwdev; struct hinic_hwdev *dev = hwdev;
...@@ -1750,10 +1805,15 @@ int cfg_set_func_sf_en(void *hwdev, u32 enbits, u32 enmask) ...@@ -1750,10 +1805,15 @@ int cfg_set_func_sf_en(void *hwdev, u32 enbits, u32 enmask)
return -ENOMEM; return -ENOMEM;
} }
glb_func_idx = hinic_global_func_id(hwdev); err = hinic_global_func_id_get(dev, &glb_func_idx);
func_sf_enbits->function_id = glb_func_idx; if (err) {
kfree(func_sf_enbits);
return err;
}
func_sf_enbits->stateful_enbits = enbits; func_sf_enbits->stateful_enbits = enbits;
func_sf_enbits->stateful_enmask = enmask; func_sf_enbits->stateful_enmask = enmask;
func_sf_enbits->function_id = glb_func_idx;
err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC, err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC,
HINIC_MISC_SET_FUNC_SF_ENBITS, HINIC_MISC_SET_FUNC_SF_ENBITS,
...@@ -1788,7 +1848,11 @@ int cfg_get_func_sf_en(void *hwdev, u32 *enbits) ...@@ -1788,7 +1848,11 @@ int cfg_get_func_sf_en(void *hwdev, u32 *enbits)
return -ENOMEM; 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; func_sf_enbits->function_id = glb_func_idx;
...@@ -2056,7 +2120,9 @@ static int hinic_os_dep_init(struct hinic_hwdev *hwdev) ...@@ -2056,7 +2120,9 @@ static int hinic_os_dep_init(struct hinic_hwdev *hwdev)
static void hinic_os_dep_deinit(struct hinic_hwdev *hwdev) static void hinic_os_dep_deinit(struct hinic_hwdev *hwdev)
{ {
destroy_work(&hwdev->fault_work); destroy_work(&hwdev->fault_work);
destroy_workqueue(hwdev->workq); destroy_workqueue(hwdev->workq);
down(&hwdev->fault_list_sem); down(&hwdev->fault_list_sem);
up(&hwdev->fault_list_sem); up(&hwdev->fault_list_sem);
...@@ -2068,7 +2134,6 @@ static void hinic_os_dep_deinit(struct hinic_hwdev *hwdev) ...@@ -2068,7 +2134,6 @@ static void hinic_os_dep_deinit(struct hinic_hwdev *hwdev)
void hinic_ppf_hwdev_unreg(void *hwdev) void hinic_ppf_hwdev_unreg(void *hwdev)
{ {
struct hinic_hwdev *dev = hwdev; struct hinic_hwdev *dev = hwdev;
if (!hwdev) if (!hwdev)
return; return;
...@@ -2082,7 +2147,6 @@ void hinic_ppf_hwdev_unreg(void *hwdev) ...@@ -2082,7 +2147,6 @@ void hinic_ppf_hwdev_unreg(void *hwdev)
void hinic_ppf_hwdev_reg(void *hwdev, void *ppf_hwdev) void hinic_ppf_hwdev_reg(void *hwdev, void *ppf_hwdev)
{ {
struct hinic_hwdev *dev = hwdev; struct hinic_hwdev *dev = hwdev;
if (!hwdev) if (!hwdev)
return; return;
...@@ -2149,6 +2213,8 @@ int hinic_init_hwdev(struct hinic_init_para *para) ...@@ -2149,6 +2213,8 @@ int hinic_init_hwdev(struct hinic_init_para *para)
hwdev->chip_node = para->chip_node; hwdev->chip_node = para->chip_node;
hwdev->ppf_hwdev = para->ppf_hwdev; hwdev->ppf_hwdev = para->ppf_hwdev;
sema_init(&hwdev->ppf_sem, 1); 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); hwdev->chip_fault_stats = vzalloc(HINIC_CHIP_FAULT_SIZE);
if (!hwdev->chip_fault_stats) if (!hwdev->chip_fault_stats)
...@@ -2208,6 +2274,9 @@ int hinic_init_hwdev(struct hinic_init_para *para) ...@@ -2208,6 +2274,9 @@ int hinic_init_hwdev(struct hinic_init_para *para)
goto init_cap_err; 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); err = __vf_func_init(hwdev);
if (err) if (err)
goto vf_func_init_err; goto vf_func_init_err;
...@@ -2244,6 +2313,7 @@ int hinic_init_hwdev(struct hinic_init_para *para) ...@@ -2244,6 +2313,7 @@ int hinic_init_hwdev(struct hinic_init_para *para)
vfree(hwdev->chip_fault_stats); vfree(hwdev->chip_fault_stats);
alloc_chip_fault_stats_err: alloc_chip_fault_stats_err:
sema_deinit(&hwdev->func_sem);
sema_deinit(&hwdev->ppf_sem); sema_deinit(&hwdev->ppf_sem);
kfree(hwdev); kfree(hwdev);
*para->hwdev = NULL; *para->hwdev = NULL;
...@@ -2251,6 +2321,33 @@ int hinic_init_hwdev(struct hinic_init_para *para) ...@@ -2251,6 +2321,33 @@ int hinic_init_hwdev(struct hinic_init_para *para)
return -EFAULT; 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) void hinic_free_hwdev(void *hwdev)
{ {
struct hinic_hwdev *dev = hwdev; struct hinic_hwdev *dev = hwdev;
...@@ -2287,6 +2384,7 @@ void hinic_free_hwdev(void *hwdev) ...@@ -2287,6 +2384,7 @@ void hinic_free_hwdev(void *hwdev)
clear_bit(HINIC_HWDEV_NONE_INITED, &dev->func_state); clear_bit(HINIC_HWDEV_NONE_INITED, &dev->func_state);
hinic_free_hwif(dev); hinic_free_hwif(dev);
vfree(dev->chip_fault_stats); vfree(dev->chip_fault_stats);
sema_deinit(&dev->func_sem);
sema_deinit(&dev->ppf_sem); sema_deinit(&dev->ppf_sem);
kfree(dev); kfree(dev);
} }
...@@ -2337,6 +2435,7 @@ enum hinic_func_mode hinic_get_func_mode(void *hwdev) ...@@ -2337,6 +2435,7 @@ enum hinic_func_mode hinic_get_func_mode(void *hwdev)
return dev->func_mode; return dev->func_mode;
} }
EXPORT_SYMBOL(hinic_get_func_mode);
enum hinic_service_mode hinic_get_service_mode(void *hwdev) enum hinic_service_mode hinic_get_service_mode(void *hwdev)
{ {
......
...@@ -222,6 +222,7 @@ struct service_cap { ...@@ -222,6 +222,7 @@ struct service_cap {
u8 er_id; /* PF/VF's ER */ u8 er_id; /* PF/VF's ER */
u8 port_id; /* PF/VF's physical port */ u8 port_id; /* PF/VF's physical port */
u8 max_vf; /* max VF number that PF supported */ u8 max_vf; /* max VF number that PF supported */
u8 force_up;
bool sf_en; /* stateful business status */ bool sf_en; /* stateful business status */
u8 timer_en; /* 0:disable, 1:enable */ u8 timer_en; /* 0:disable, 1:enable */
u8 bloomfilter_en; /* 0:disable, 1:enable*/ u8 bloomfilter_en; /* 0:disable, 1:enable*/
...@@ -363,7 +364,7 @@ struct hinic_dev_cap { ...@@ -363,7 +364,7 @@ struct hinic_dev_cap {
u8 cfg_file_ver; u8 cfg_file_ver;
u8 net_port_mode; u8 net_port_mode;
u8 valid_cos_bitmap; /* every bit indicate cos is valid */ u8 valid_cos_bitmap; /* every bit indicate cos is valid */
u8 rsvd1; u8 force_up;
u32 pf_num; u32 pf_num;
u32 pf_id_start; u32 pf_id_start;
u32 vf_num; u32 vf_num;
...@@ -386,7 +387,7 @@ struct hinic_dev_cap { ...@@ -386,7 +387,7 @@ struct hinic_dev_cap {
u8 nic_lro_en; u8 nic_lro_en;
u8 nic_lro_sz; u8 nic_lro_sz;
u8 nic_tso_sz; u8 nic_tso_sz;
u8 rsvd3; u8 max_queue_allowed;
/* RoCE */ /* RoCE */
u32 roce_max_qp; u32 roce_max_qp;
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
#define CMDQ_DB_INFO_SRC_TYPE_MASK 0x1FU #define CMDQ_DB_INFO_SRC_TYPE_MASK 0x1FU
#define CMDQ_DB_INFO_SET(val, member) \ #define CMDQ_DB_INFO_SET(val, member) \
(((val) & CMDQ_DB_INFO_##member##_MASK) \ ((val & CMDQ_DB_INFO_##member##_MASK) \
<< CMDQ_DB_INFO_##member##_SHIFT) << CMDQ_DB_INFO_##member##_SHIFT)
#define CMDQ_CTRL_PI_SHIFT 0 #define CMDQ_CTRL_PI_SHIFT 0
...@@ -168,7 +168,7 @@ ...@@ -168,7 +168,7 @@
#define CMDQ_DB_PI_OFF(pi) (((u16)LOWER_8_BITS(pi)) << 3) #define CMDQ_DB_PI_OFF(pi) (((u16)LOWER_8_BITS(pi)) << 3)
#define CMDQ_DB_ADDR(db_base, pi) \ #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_SHIFT 12
#define CMDQ_PFN(addr) ((addr) >> CMDQ_PFN_SHIFT) #define CMDQ_PFN(addr) ((addr) >> CMDQ_PFN_SHIFT)
...@@ -194,6 +194,9 @@ ...@@ -194,6 +194,9 @@
#define CMDQ_SEND_CMPT_CODE 10 #define CMDQ_SEND_CMPT_CODE 10
#define CMDQ_COMPLETE_CMPT_CODE 11 #define CMDQ_COMPLETE_CMPT_CODE 11
#define HINIC_GET_CMDQ_FREE_WQEBBS(cmdq_wq) \
atomic_read(&(cmdq_wq)->delta)
enum cmdq_scmd_type { enum cmdq_scmd_type {
CMDQ_SET_ARM_CMD = 2, CMDQ_SET_ARM_CMD = 2,
}; };
...@@ -278,7 +281,7 @@ void hinic_free_cmd_buf(void *hwdev, struct hinic_cmd_buf *cmd_buf) ...@@ -278,7 +281,7 @@ void hinic_free_cmd_buf(void *hwdev, struct hinic_cmd_buf *cmd_buf)
struct hinic_cmdqs *cmdqs; struct hinic_cmdqs *cmdqs;
if (!hwdev || !cmd_buf) { if (!hwdev || !cmd_buf) {
pr_err("Failed to free cmd buf.\n"); pr_err("Failed to free cmd buf\n");
return; return;
} }
...@@ -337,7 +340,7 @@ static void cmdq_set_lcmd_bufdesc(struct hinic_cmdq_wqe_lcmd *wqe, ...@@ -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, 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; struct hinic_cmdq_wqe_scmd *wqe_scmd = &wqe->wqe_scmd;
...@@ -368,7 +371,7 @@ static void cmdq_set_db(struct hinic_cmdq *cmdq, ...@@ -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)); 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, memcpy((u8 *)dst + FIRST_DATA_TO_WRITE_LAST,
(u8 *)src + 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, ...@@ -541,8 +544,9 @@ static int hinic_cmdq_sync_timeout_check(struct hinic_cmdq *cmdq,
return 0; return 0;
} }
static void __clear_cmd_info(struct hinic_cmdq_cmd_info *cmd_info, int *errcode, static void __clear_cmd_info(struct hinic_cmdq_cmd_info *cmd_info,
struct completion *done, u64 *out_param) const int *errcode, struct completion *done,
u64 *out_param)
{ {
if (cmd_info->errcode == errcode) if (cmd_info->errcode == errcode)
cmd_info->errcode = NULL; cmd_info->errcode = NULL;
...@@ -576,10 +580,20 @@ static int cmdq_sync_cmd_direct_resp(struct hinic_cmdq *cmdq, ...@@ -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) */ /* Keep wrapped and doorbell index correct. bh - for tasklet(ceq) */
spin_lock_bh(&cmdq->cmdq_lock); 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); curr_wqe = hinic_get_wqe(cmdq->wq, num_wqebbs, &curr_prod_idx);
if (!curr_wqe) { if (!curr_wqe) {
spin_unlock_bh(&cmdq->cmdq_lock); 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; return -EBUSY;
} }
...@@ -696,10 +710,20 @@ static int cmdq_sync_cmd_detail_resp(struct hinic_cmdq *cmdq, ...@@ -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) */ /* Keep wrapped and doorbell index correct. bh - for tasklet(ceq) */
spin_lock_bh(&cmdq->cmdq_lock); 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*/ /* 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); curr_wqe = hinic_get_wqe(cmdq->wq, num_wqebbs, &curr_prod_idx);
if (!curr_wqe) { if (!curr_wqe) {
spin_unlock_bh(&cmdq->cmdq_lock); 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; return -EBUSY;
} }
...@@ -716,6 +740,7 @@ static int cmdq_sync_cmd_detail_resp(struct hinic_cmdq *cmdq, ...@@ -716,6 +740,7 @@ static int cmdq_sync_cmd_detail_resp(struct hinic_cmdq *cmdq,
cmd_info = &cmdq->cmd_infos[curr_prod_idx]; cmd_info = &cmdq->cmd_infos[curr_prod_idx];
init_completion(&done); init_completion(&done);
cmd_info->done = &done; cmd_info->done = &done;
cmd_info->errcode = &errcode; cmd_info->errcode = &errcode;
cmd_info->cmpt_code = &cmpt_code; 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) ...@@ -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); curr_wqe = hinic_get_wqe(cmdq->wq, num_wqebbs, &curr_prod_idx);
if (!curr_wqe) { if (!curr_wqe) {
spin_unlock_bh(&cmdq->cmdq_lock); spin_unlock_bh(&cmdq->cmdq_lock);
sdk_err(cmdq->hwdev->dev_hdl, "Can not get avalible wqebb setting arm\n");
return -EBUSY; return -EBUSY;
} }
...@@ -946,9 +972,13 @@ int hinic_cmdq_direct_resp(void *hwdev, enum hinic_ack_type ack_type, ...@@ -946,9 +972,13 @@ int hinic_cmdq_direct_resp(void *hwdev, enum hinic_ack_type ack_type,
return err; 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, err = cmdq_sync_cmd_direct_resp(&cmdqs->cmdq[HINIC_CMDQ_SYNC], ack_type,
mod, cmd, buf_in, out_param, timeout); mod, cmd, buf_in, out_param, timeout);
hinic_func_own_free(hwdev);
if (!(((struct hinic_hwdev *)hwdev)->chip_present_flag)) if (!(((struct hinic_hwdev *)hwdev)->chip_present_flag))
return -ETIMEDOUT; return -ETIMEDOUT;
else else
...@@ -1109,7 +1139,8 @@ static void cmdq_sync_cmd_handler(struct hinic_cmdq *cmdq, ...@@ -1109,7 +1139,8 @@ static void cmdq_sync_cmd_handler(struct hinic_cmdq *cmdq,
cmdq_update_cmd_status(cmdq, prod_idx, wqe); cmdq_update_cmd_status(cmdq, prod_idx, wqe);
if (cmdq->cmd_infos[prod_idx].cmpt_code) { 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; cmdq->cmd_infos[prod_idx].cmpt_code = NULL;
} }
...@@ -1267,7 +1298,7 @@ static void cmdq_init_queue_ctxt(struct hinic_cmdq *cmdq, ...@@ -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) | ctxt_info->wq_block_pfn = CMDQ_CTXT_BLOCK_INFO_SET(start_ci, CI) |
CMDQ_CTXT_BLOCK_INFO_SET(pfn, WQ_BLOCK_PFN); 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->ppf_idx = HINIC_HWIF_PPF_IDX(hwdev->hwif);
cmdq_ctxt->cmdq_id = cmdq->cmdq_type; cmdq_ctxt->cmdq_id = cmdq->cmdq_type;
} }
...@@ -1348,6 +1379,7 @@ int hinic_set_cmdq_ctxts(struct hinic_hwdev *hwdev) ...@@ -1348,6 +1379,7 @@ int hinic_set_cmdq_ctxts(struct hinic_hwdev *hwdev)
cmdq_type = HINIC_CMDQ_SYNC; cmdq_type = HINIC_CMDQ_SYNC;
for (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++) { for (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++) {
cmdq_ctxt = &cmdqs->cmdq[cmdq_type].cmdq_ctxt; cmdq_ctxt = &cmdqs->cmdq[cmdq_type].cmdq_ctxt;
cmdq_ctxt->func_idx = hinic_global_func_id_hw(hwdev);
in_size = sizeof(*cmdq_ctxt); in_size = sizeof(*cmdq_ctxt);
err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,
HINIC_MGMT_CMD_CMDQ_CTXT_SET, HINIC_MGMT_CMD_CMDQ_CTXT_SET,
......
/* SPDX-License-Identifier: GPL-2.0*/ /* 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 File Name : hinic_ctx_def.h
Version : Initial Draft Version : Initial Draft
...@@ -33,6 +33,8 @@ extern "C"{ ...@@ -33,6 +33,8 @@ extern "C"{
#define HINIC_Q_CTXT_MAX 42 #define HINIC_Q_CTXT_MAX 42
#define HINIC_RQ_CQ_MAX 128
#define MAX_WQE_SIZE(max_sge, wqebb_size) \ #define MAX_WQE_SIZE(max_sge, wqebb_size) \
(((max_sge) <= 2) ? (wqebb_size) : \ (((max_sge) <= 2) ? (wqebb_size) : \
((ALIGN(((max_sge) - 2), 4) / 4 + 1) * (wqebb_size))) ((ALIGN(((max_sge) - 2), 4) / 4 + 1) * (wqebb_size)))
...@@ -214,6 +216,7 @@ enum cfg_svc_type_en { ...@@ -214,6 +216,7 @@ enum cfg_svc_type_en {
CFG_SVC_OVS_BIT7 = (1 << 7), CFG_SVC_OVS_BIT7 = (1 << 7),
CFG_SVC_ACL_BIT8 = (1 << 8), CFG_SVC_ACL_BIT8 = (1 << 8),
CFG_SVC_IOE_BIT9 = (1 << 9), 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_FT_EN = (CFG_SVC_FCOE_BIT2 | CFG_SVC_TOE_BIT3 |
CFG_SVC_FC_BIT5 | CFG_SVC_IOE_BIT9), CFG_SVC_FC_BIT5 | CFG_SVC_IOE_BIT9),
...@@ -244,6 +247,8 @@ enum cfg_svc_type_en { ...@@ -244,6 +247,8 @@ enum cfg_svc_type_en {
((dev)->cfg_mgmt->svc_cap.chip_svc_type & CFG_SVC_FT_EN) ((dev)->cfg_mgmt->svc_cap.chip_svc_type & CFG_SVC_FT_EN)
#define IS_RDMA_TYPE(dev) \ #define IS_RDMA_TYPE(dev) \
((dev)->cfg_mgmt->svc_cap.chip_svc_type & CFG_SVC_RDMA_EN) ((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 #ifdef __cplusplus
#if __cplusplus #if __cplusplus
......
...@@ -39,7 +39,7 @@ u64 hinic_dbg_get_rq_cla_addr(void *hwdev, u16 q_id); ...@@ -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, int hinic_dbg_get_sq_db_addr(void *hwdev, u16 q_id, u64 **map_addr,
u64 *phy_addr, u32 *pg_idx); 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, int hinic_dbg_get_sq_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt,
u8 *wqe, u16 *wqe_size); u8 *wqe, u16 *wqe_size);
...@@ -79,11 +79,12 @@ int hinic_api_csr_wr32(void *hwdev, u8 dest, u32 addr, u32 val); ...@@ -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_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); 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); int hinic_dbg_get_pf_bw_limit(void *hwdev, u32 *pf_bw_limit);
......
...@@ -53,13 +53,9 @@ struct ffm_intr_info { ...@@ -53,13 +53,9 @@ struct ffm_intr_info {
void *g_card_node_array[MAX_CARD_NUM] = {0}; void *g_card_node_array[MAX_CARD_NUM] = {0};
void *g_card_vir_addr[MAX_CARD_NUM] = {0}; void *g_card_vir_addr[MAX_CARD_NUM] = {0};
u64 g_card_phy_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; struct mutex g_addr_lock;
int card_id; 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*/ /* dbgtool character device name, class name, dev path*/
#define CHR_DEV_DBGTOOL "dbgtool_chr_dev" #define CHR_DEV_DBGTOOL "dbgtool_chr_dev"
...@@ -111,7 +107,7 @@ static ssize_t dbgtool_knl_write(struct file *pfile, ...@@ -111,7 +107,7 @@ static ssize_t dbgtool_knl_write(struct file *pfile,
static bool is_valid_phy_addr(u64 offset) static bool is_valid_phy_addr(u64 offset)
{ {
int i = 0; int i;
for (i = 0; i < MAX_CARD_NUM; i++) { for (i = 0; i < MAX_CARD_NUM; i++) {
if (offset == g_card_phy_addr[i]) if (offset == g_card_phy_addr[i])
...@@ -129,20 +125,17 @@ int hinic_mem_mmap(struct file *filp, struct vm_area_struct *vma) ...@@ -129,20 +125,17 @@ int hinic_mem_mmap(struct file *filp, struct vm_area_struct *vma)
if (vmsize > (PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER))) { if (vmsize > (PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER))) {
pr_err("Map size = %lu is bigger than alloc\n", vmsize); pr_err("Map size = %lu is bigger than alloc\n", vmsize);
clear_bit(HINIC_CARD_ID_USE, &card_id_flag);
return -EAGAIN; return -EAGAIN;
} }
if (offset && !is_valid_phy_addr((u64)offset) && if (offset && !is_valid_phy_addr((u64)offset) &&
!hinic_is_valid_bar_addr((u64)offset)) { !hinic_is_valid_bar_addr((u64)offset)) {
pr_err("offset is invalid\n"); pr_err("offset is invalid");
clear_bit(HINIC_CARD_ID_USE, &card_id_flag);
return -EAGAIN; return -EAGAIN;
} }
/* old version of tool set vma->vm_pgoff to 0 */ /* old version of tool set vma->vm_pgoff to 0 */
phy_addr = offset ? offset : g_card_phy_addr[card_id]; phy_addr = offset ? offset : g_card_phy_addr[card_id];
clear_bit(HINIC_CARD_ID_USE, &card_id_flag);
if (!phy_addr) { if (!phy_addr) {
pr_err("Card_id = %d physical address is 0\n", card_id); pr_err("Card_id = %d physical address is 0\n", card_id);
return -EAGAIN; return -EAGAIN;
...@@ -200,9 +193,10 @@ long dbgtool_knl_api_cmd_read(struct dbgtool_param *para, ...@@ -200,9 +193,10 @@ long dbgtool_knl_api_cmd_read(struct dbgtool_param *para,
ack_size = para->param.api_rd.ack_size; ack_size = para->param.api_rd.ack_size;
if (para->param.api_rd.ack_size == 0) { if (para->param.api_rd.ack_size == 0) {
pr_err("Read cmd ack size is 0\n"); pr_err("Read cmd ack size is 0\n");
ret = -EINVAL; ret = -ENOMEM;
goto alloc_ack_mem_fail; goto alloc_ack_mem_fail;
} }
ack = kzalloc((unsigned long long)ack_size, GFP_KERNEL); ack = kzalloc((unsigned long long)ack_size, GFP_KERNEL);
if (!ack) { if (!ack) {
pr_err("Alloc read ack mem fail\n"); pr_err("Alloc read ack mem fail\n");
...@@ -557,7 +551,7 @@ long dbgtool_knl_unlocked_ioctl(struct file *pfile, ...@@ -557,7 +551,7 @@ long dbgtool_knl_unlocked_ioctl(struct file *pfile,
struct dbgtool_param param; struct dbgtool_param param;
struct dbgtool_k_glb_info *dbgtool_info; struct dbgtool_k_glb_info *dbgtool_info;
struct card_node *card_info = NULL; struct card_node *card_info = NULL;
int i, cnt = 0; int i;
(void)memset(&param, 0, sizeof(param)); (void)memset(&param, 0, sizeof(param));
...@@ -580,20 +574,7 @@ long dbgtool_knl_unlocked_ioctl(struct file *pfile, ...@@ -580,20 +574,7 @@ long dbgtool_knl_unlocked_ioctl(struct file *pfile,
return -EFAULT; return -EFAULT;
} }
while (cnt < 10) { card_id = i;
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;
}
dbgtool_info = (struct dbgtool_k_glb_info *)card_info->dbgtool_info; 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, ...@@ -651,6 +632,7 @@ void ffm_intr_msg_record(void *handle, void *buf_in, u16 in_size,
struct timex txc; struct timex txc;
struct rtc_time rctm; struct rtc_time rctm;
struct card_node *card_info = NULL; struct card_node *card_info = NULL;
bool flag = false;
int i, j; int i, j;
for (i = 0; i < MAX_CARD_NUM; i++) { 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, ...@@ -659,10 +641,14 @@ void ffm_intr_msg_record(void *handle, void *buf_in, u16 in_size,
continue; continue;
for (j = 0; j < MAX_FUNCTION_NUM; j++) { 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;
}
} }
break;
if (flag)
break;
} }
if (i == MAX_CARD_NUM || !card_info) { if (i == MAX_CARD_NUM || !card_info) {
...@@ -787,6 +773,7 @@ int dbgtool_knl_init(void *vhwdev, void *chip_node) ...@@ -787,6 +773,7 @@ int dbgtool_knl_init(void *vhwdev, void *chip_node)
pr_err("Failed to get hinic id\n"); pr_err("Failed to get hinic id\n");
goto sscanf_chdev_fail; goto sscanf_chdev_fail;
} }
g_card_node_array[id] = chip_info; g_card_node_array[id] = chip_info;
chip_info->func_num++; chip_info->func_num++;
......
...@@ -118,4 +118,5 @@ int hinic_mem_mmap(struct file *filp, struct vm_area_struct *vma); ...@@ -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 chipif_get_all_pf_dev_info(struct pf_dev_info *dev_info, int card_id,
void **g_func_handle_array); void **g_func_handle_array);
long dbgtool_knl_free_mem(int id); long dbgtool_knl_free_mem(int id);
#endif #endif
...@@ -120,6 +120,8 @@ void hinic_init_ieee_settings(struct hinic_nic_dev *nic_dev) ...@@ -120,6 +120,8 @@ void hinic_init_ieee_settings(struct hinic_nic_dev *nic_dev)
if (dcb_cfg->tc_cfg[i].pfc_en) if (dcb_cfg->tc_cfg[i].pfc_en)
pfc->pfc_en |= (u8)BIT(i); pfc->pfc_en |= (u8)BIT(i);
} }
return;
} }
static int hinic_set_up_cos_map(struct hinic_nic_dev *nic_dev, 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) ...@@ -330,6 +332,41 @@ int hinic_setup_tc(struct net_device *netdev, u8 tc)
return 0; 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) static u8 hinic_dcbnl_get_state(struct net_device *netdev)
{ {
struct hinic_nic_dev *nic_dev = netdev_priv(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) ...@@ -349,6 +386,13 @@ static u8 hinic_dcbnl_set_state(struct net_device *netdev, u8 state)
if (state == curr_state) if (state == curr_state)
return 0; 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); err = hinic_setup_tc(netdev, state ? nic_dev->dcb_cfg.pg_tcs : 0);
if (!err) if (!err)
netif_info(nic_dev, drv, netdev, "%s DCB\n", 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, ...@@ -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"); 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, static void hinic_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
u8 prio, u8 pg_id, u8 bw_pct, u8 prio, u8 pg_id, u8 bw_pct,
u8 up_map) u8 up_map)
...@@ -460,6 +556,69 @@ static void hinic_dcbnl_get_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, ...@@ -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]; *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, static void hinic_dcbnl_set_pfc_cfg(struct net_device *netdev, int prio,
u8 setting) u8 setting)
{ {
...@@ -471,6 +630,24 @@ static void hinic_dcbnl_set_pfc_cfg(struct net_device *netdev, int prio, ...@@ -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; 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, static void hinic_dcbnl_get_pfc_cfg(struct net_device *netdev, int prio,
u8 *setting) u8 *setting)
{ {
...@@ -598,7 +775,7 @@ static u8 hinic_sync_dcb_cfg(struct hinic_nic_dev *nic_dev) ...@@ -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, static void hinic_dcb_get_pfc_map(struct hinic_nic_dev *nic_dev,
struct hinic_dcb_config *dcb_cfg, u8 *pfc_map) struct hinic_dcb_config *dcb_cfg, u8 *pfc_map)
{ {
int i, up; u8 i, up;
u8 pfc_en = 0, outof_range_pfc = 0; u8 pfc_en = 0, outof_range_pfc = 0;
for (i = 0; i < dcb_cfg->pfc_tcs; i++) { 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, ...@@ -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) 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++) { for (i = 0; i < HINIC_DCB_UP_MAX; i++) {
if (!(up_valid_bitmap & BIT(i))) if (!(up_valid_bitmap & BIT(i)))
...@@ -869,6 +1046,52 @@ static int __set_hw_ets(struct hinic_nic_dev *nic_dev) ...@@ -869,6 +1046,52 @@ static int __set_hw_ets(struct hinic_nic_dev *nic_dev)
return 0; 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) static int hinic_dcbnl_set_df_ieee_cfg(struct net_device *netdev)
{ {
struct hinic_nic_dev *nic_dev = netdev_priv(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) ...@@ -910,7 +1133,44 @@ static int hinic_dcbnl_set_df_ieee_cfg(struct net_device *netdev)
hinic_start_port_traffic_flow(nic_dev); 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) u8 hinic_dcbnl_set_all(struct net_device *netdev)
...@@ -986,7 +1246,7 @@ 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, 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 hinic_nic_dev *nic_dev = netdev_priv(netdev);
struct ieee_ets *my_ets = &nic_dev->hinic_ieee_ets; 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, ...@@ -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, 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_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic_dcb_config *dcb_cfg = &nic_dev->dcb_cfg; 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, ...@@ -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, 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 hinic_nic_dev *nic_dev = netdev_priv(netdev);
struct ieee_pfc *my_pfc = &nic_dev->hinic_ieee_pfc; 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, ...@@ -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, 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_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic_dcb_config *dcb_cfg = &nic_dev->dcb_cfg; 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) ...@@ -1206,7 +1466,6 @@ static u8 hinic_dcbnl_setdcbx(struct net_device *netdev, u8 mode)
if (nic_dev->dcbx_cap == mode) if (nic_dev->dcbx_cap == mode)
return 0; return 0;
nic_dev->dcbx_cap = mode; nic_dev->dcbx_cap = mode;
if (mode & DCB_CAP_DCBX_VER_CEE) { if (mode & DCB_CAP_DCBX_VER_CEE) {
...@@ -1224,7 +1483,9 @@ static u8 hinic_dcbnl_setdcbx(struct net_device *netdev, u8 mode) ...@@ -1224,7 +1483,9 @@ static u8 hinic_dcbnl_setdcbx(struct net_device *netdev, u8 mode)
return 1; return 1;
} }
} }
hinic_dcbnl_set_df_ieee_cfg(netdev); hinic_dcbnl_set_df_ieee_cfg(netdev);
hinic_force_port_relink(nic_dev->hwdev);
} else { } else {
err = hinic_setup_tc(netdev, 0); err = hinic_setup_tc(netdev, 0);
if (err) { if (err) {
...@@ -1309,7 +1570,7 @@ void hinic_configure_dcb(struct net_device *netdev) ...@@ -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) 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++) { for (cos = 0; cos < nic_dev->max_cos; cos++) {
up = cos_up[cos]; up = cos_up[cos];
......
...@@ -48,5 +48,20 @@ int hinic_get_num_cos(struct hinic_nic_dev *nic_dev, u8 *num_cos); ...@@ -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, int hinic_get_cos_up_map(struct hinic_nic_dev *nic_dev,
u8 *num_cos, u8 *cos_up); 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 #endif
/* SPDX-License-Identifier: GPL-2.0*/ /* 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 File Name : hinic_dfx_def.h
Version : Initial Draft Version : Initial Draft
...@@ -95,6 +95,14 @@ enum driver_cmd_type { ...@@ -95,6 +95,14 @@ enum driver_cmd_type {
GET_NIC_STATS_STRING, GET_NIC_STATS_STRING,
GET_NIC_STATS_INFO, GET_NIC_STATS_INFO,
GET_PF_ID, 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_CFG = 0x40,
RSS_INDIR, RSS_INDIR,
...@@ -121,9 +129,9 @@ enum api_chain_cmd_type { ...@@ -121,9 +129,9 @@ enum api_chain_cmd_type {
}; };
enum sm_cmd_type { enum sm_cmd_type {
SM_CTR_RD32 = 1, SM_CTR_RD32 = 1,
SM_CTR_RD64_PAIR, SM_CTR_RD64_PAIR,
SM_CTR_RD64 SM_CTR_RD64
}; };
enum hinic_show_set { enum hinic_show_set {
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details. * for more details.
*
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt #define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
...@@ -35,15 +36,23 @@ ...@@ -35,15 +36,23 @@
#define HINIC_EQS_WQ_NAME "hinic_eqs" #define HINIC_EQS_WQ_NAME "hinic_eqs"
#define AEQ_CTRL_0_INTR_IDX_SHIFT 0 #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_DMA_ATTR_SHIFT 12
#define AEQ_CTRL_0_PCI_INTF_IDX_SHIFT 20 #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_MODE_SHIFT 31
#define AEQ_CTRL_0_INTR_IDX_MASK 0x3FFU #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_DMA_ATTR_MASK 0x3FU
#define AEQ_CTRL_0_PCI_INTF_IDX_MASK 0x3U #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_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) \ #define AEQ_CTRL_0_SET(val, member) \
(((val) & AEQ_CTRL_0_##member##_MASK) << \ (((val) & AEQ_CTRL_0_##member##_MASK) << \
AEQ_CTRL_0_##member##_SHIFT) AEQ_CTRL_0_##member##_SHIFT)
...@@ -53,13 +62,19 @@ ...@@ -53,13 +62,19 @@
<< AEQ_CTRL_0_##member##_SHIFT))) << AEQ_CTRL_0_##member##_SHIFT)))
#define AEQ_CTRL_1_LEN_SHIFT 0 #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_ELEM_SIZE_SHIFT 24
#define AEQ_CTRL_1_PAGE_SIZE_SHIFT 28 #define AEQ_CTRL_1_PAGE_SIZE_SHIFT 28
#define AEQ_CTRL_1_LEN_MASK 0x1FFFFFU #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_ELEM_SIZE_MASK 0x3U
#define AEQ_CTRL_1_PAGE_SIZE_MASK 0xFU #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) \ #define AEQ_CTRL_1_SET(val, member) \
(((val) & AEQ_CTRL_1_##member##_MASK) << \ (((val) & AEQ_CTRL_1_##member##_MASK) << \
AEQ_CTRL_1_##member##_SHIFT) AEQ_CTRL_1_##member##_SHIFT)
...@@ -213,6 +228,66 @@ MODULE_PARM_DESC(g_num_ceqe_in_tasklet, ...@@ -213,6 +228,66 @@ MODULE_PARM_DESC(g_num_ceqe_in_tasklet,
static irqreturn_t aeq_interrupt(int irq, void *data); static irqreturn_t aeq_interrupt(int irq, void *data);
static irqreturn_t ceq_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 void ceq_tasklet(ulong eq_tasklet);
static u8 eq_cons_idx_checksum_set(u32 val) static u8 eq_cons_idx_checksum_set(u32 val)
...@@ -463,7 +538,7 @@ static bool aeq_irq_handler(struct hinic_eq *eq) ...@@ -463,7 +538,7 @@ static bool aeq_irq_handler(struct hinic_eq *eq)
&aeqs->aeq_sw_cb_state[sw_event]); &aeqs->aeq_sw_cb_state[sw_event]);
if (aeqs->aeq_swe_cb[sw_event] && if (aeqs->aeq_swe_cb[sw_event] &&
test_bit(HINIC_AEQ_SW_CB_REG, 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, lev = aeqs->aeq_swe_cb[sw_event](aeqs->hwdev,
ucode_event, ucode_event,
aeqe_data); aeqe_data);
...@@ -479,7 +554,7 @@ static bool aeq_irq_handler(struct hinic_eq *eq) ...@@ -479,7 +554,7 @@ static bool aeq_irq_handler(struct hinic_eq *eq)
&aeqs->aeq_hw_cb_state[event]); &aeqs->aeq_hw_cb_state[event]);
if (aeqs->aeq_hwe_cb[event] && if (aeqs->aeq_hwe_cb[event] &&
test_bit(HINIC_AEQ_HW_CB_REG, 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, aeqs->aeq_hwe_cb[event](aeqs->hwdev,
aeqe_pos->aeqe_data, size); aeqe_pos->aeqe_data, size);
clear_bit(HINIC_AEQ_HW_CB_RUNNING, clear_bit(HINIC_AEQ_HW_CB_RUNNING,
...@@ -709,7 +784,10 @@ static int set_ceq_ctrl_reg(struct hinic_hwdev *hwdev, u16 q_id, ...@@ -709,7 +784,10 @@ static int set_ceq_ctrl_reg(struct hinic_hwdev *hwdev, u16 q_id,
u16 out_size = sizeof(ceq_ctrl); u16 out_size = sizeof(ceq_ctrl);
int err; 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.q_id = q_id;
ceq_ctrl.ctrl0 = ctrl0; ceq_ctrl.ctrl0 = ctrl0;
ceq_ctrl.ctrl1 = ctrl1; ceq_ctrl.ctrl1 = ctrl1;
...@@ -751,6 +829,11 @@ static int set_eq_ctrls(struct hinic_eq *eq) ...@@ -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, PCI_INTF_IDX) &
AEQ_CTRL_0_CLEAR(val, INTR_MODE); 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) | 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(AEQ_DMA_ATTR_DEFAULT, DMA_ATTR) |
AEQ_CTRL_0_SET(pci_intf_idx, PCI_INTF_IDX) | AEQ_CTRL_0_SET(pci_intf_idx, PCI_INTF_IDX) |
...@@ -955,7 +1038,6 @@ static void free_eq_pages(struct hinic_eq *eq) ...@@ -955,7 +1038,6 @@ static void free_eq_pages(struct hinic_eq *eq)
kfree(eq->virt_addr); kfree(eq->virt_addr);
kfree(eq->dma_addr); kfree(eq->dma_addr);
} }
static inline u32 get_page_size(struct hinic_eq *eq) static inline u32 get_page_size(struct hinic_eq *eq)
{ {
u32 total_size; u32 total_size;
...@@ -979,7 +1061,6 @@ static inline u32 get_page_size(struct hinic_eq *eq) ...@@ -979,7 +1061,6 @@ static inline u32 get_page_size(struct hinic_eq *eq)
return EQ_MIN_PAGE_SIZE << n; return EQ_MIN_PAGE_SIZE << n;
} }
/** /**
* init_eq - initialize eq * init_eq - initialize eq
* @eq: the event queue * @eq: the event queue
...@@ -1091,6 +1172,7 @@ static void remove_eq(struct hinic_eq *eq) ...@@ -1091,6 +1172,7 @@ static void remove_eq(struct hinic_eq *eq)
hinic_set_msix_state(eq->hwdev, entry->msix_entry_idx, hinic_set_msix_state(eq->hwdev, entry->msix_entry_idx,
HINIC_MSIX_DISABLE); HINIC_MSIX_DISABLE);
synchronize_irq(entry->irq_id); synchronize_irq(entry->irq_id);
free_irq(entry->irq_id, eq); free_irq(entry->irq_id, eq);
if (eq->type == HINIC_AEQ) { if (eq->type == HINIC_AEQ) {
......
...@@ -14,11 +14,13 @@ ...@@ -14,11 +14,13 @@
*/ */
#ifndef HINIC_EQS_H #ifndef HINIC_EQS_H
#include <linux/interrupt.h>
#define HINIC_EQS_H #define HINIC_EQS_H
#define HINIC_EQ_PAGE_SIZE 0x00001000 #define HINIC_EQ_PAGE_SIZE 0x00001000
#define HINIC_MAX_AEQS 4 #define HINIC_MAX_AEQS 3
#define HINIC_MAX_CEQS 32 #define HINIC_MAX_CEQS 32
#define HINIC_EQ_MAX_PAGES 8 #define HINIC_EQ_MAX_PAGES 8
...@@ -65,7 +67,6 @@ struct hinic_eq_work { ...@@ -65,7 +67,6 @@ struct hinic_eq_work {
struct hinic_ceq_tasklet_data { struct hinic_ceq_tasklet_data {
void *data; void *data;
}; };
struct hinic_eq { struct hinic_eq {
struct hinic_hwdev *hwdev; struct hinic_hwdev *hwdev;
u16 q_id; u16 q_id;
...@@ -113,7 +114,6 @@ struct hinic_aeqs { ...@@ -113,7 +114,6 @@ struct hinic_aeqs {
struct hinic_hwdev *hwdev; struct hinic_hwdev *hwdev;
hinic_aeq_hwe_cb aeq_hwe_cb[HINIC_MAX_AEQ_EVENTS]; hinic_aeq_hwe_cb aeq_hwe_cb[HINIC_MAX_AEQ_EVENTS];
hinic_aeq_swe_cb aeq_swe_cb[HINIC_MAX_AEQ_SW_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_hw_cb_state[HINIC_MAX_AEQ_EVENTS];
unsigned long aeq_sw_cb_state[HINIC_MAX_AEQ_SW_EVENTS]; unsigned long aeq_sw_cb_state[HINIC_MAX_AEQ_SW_EVENTS];
...@@ -140,6 +140,24 @@ struct hinic_ceqs { ...@@ -140,6 +140,24 @@ struct hinic_ceqs {
u16 num_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, int hinic_aeqs_init(struct hinic_hwdev *hwdev, u16 num_aeqs,
struct irq_info *msix_entries); struct irq_info *msix_entries);
......
...@@ -140,7 +140,7 @@ static struct hinic_stats hinic_tx_queue_stats_extern[] = { ...@@ -140,7 +140,7 @@ static struct hinic_stats hinic_tx_queue_stats_extern[] = {
HINIC_TXQ_STAT(alloc_cpy_frag_err), HINIC_TXQ_STAT(alloc_cpy_frag_err),
HINIC_TXQ_STAT(map_cpy_frag_err), HINIC_TXQ_STAT(map_cpy_frag_err),
HINIC_TXQ_STAT(map_frag_err), HINIC_TXQ_STAT(map_frag_err),
}; /*lint -restore*/ };/*lint -restore*/
#define HINIC_FUNC_STAT(_stat_item) { \ #define HINIC_FUNC_STAT(_stat_item) { \
.name = #_stat_item, \ .name = #_stat_item, \
...@@ -677,9 +677,9 @@ static int hinic_get_settings(struct net_device *netdev, ...@@ -677,9 +677,9 @@ static int hinic_get_settings(struct net_device *netdev,
} }
#ifdef ETHTOOL_GLINKSETTINGS #ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
static int hinic_get_link_ksettings(struct net_device *netdev, static int hinic_get_link_ksettings(struct net_device *netdev,
struct ethtool_link_ksettings struct ethtool_link_ksettings *link_settings)
*link_settings)
{ {
struct cmd_link_settings settings = {0}; struct cmd_link_settings settings = {0};
struct ethtool_link_settings *base = &link_settings->base; struct ethtool_link_settings *base = &link_settings->base;
...@@ -707,6 +707,7 @@ static int hinic_get_link_ksettings(struct net_device *netdev, ...@@ -707,6 +707,7 @@ static int hinic_get_link_ksettings(struct net_device *netdev,
return 0; return 0;
} }
#endif #endif
#endif
static int hinic_is_speed_legal(struct hinic_nic_dev *nic_dev, u32 speed) 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, ...@@ -852,15 +853,16 @@ static int hinic_set_settings(struct net_device *netdev,
} }
#ifdef ETHTOOL_GLINKSETTINGS #ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
static int hinic_set_link_ksettings(struct net_device *netdev, static int hinic_set_link_ksettings(struct net_device *netdev,
const struct ethtool_link_ksettings const struct ethtool_link_ksettings *link_settings)
*link_settings)
{ {
/* Only support to set autoneg and speed */ /* Only support to set autoneg and speed */
return set_link_settings(netdev, link_settings->base.autoneg, return set_link_settings(netdev, link_settings->base.autoneg,
link_settings->base.speed); link_settings->base.speed);
} }
#endif #endif
#endif
static void hinic_get_drvinfo(struct net_device *netdev, static void hinic_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *info) struct ethtool_drvinfo *info)
...@@ -1374,27 +1376,27 @@ static int is_coalesce_legal(struct net_device *netdev, ...@@ -1374,27 +1376,27 @@ static int is_coalesce_legal(struct net_device *netdev,
#define CHECK_COALESCE_ALIGN(coal, item, unit) \ #define CHECK_COALESCE_ALIGN(coal, item, unit) \
do { \ do { \
if ((coal)->item % (unit)) \ if (coal->item % (unit)) \
nicif_warn(nic_dev, drv, netdev, \ nicif_warn(nic_dev, drv, netdev, \
"%s in %d units, change to %d\n", \ "%s in %d units, change to %d\n", \
#item, (unit), ALIGN_DOWN((coal)->item, unit));\ #item, (unit), ALIGN_DOWN(coal->item, unit));\
} while (0) } while (0)
#define CHECK_COALESCE_CHANGED(coal, item, unit, ori_val, obj_str) \ #define CHECK_COALESCE_CHANGED(coal, item, unit, ori_val, obj_str) \
do { \ do { \
if (((coal)->item / (unit)) != (ori_val)) \ if ((coal->item / (unit)) != (ori_val)) \
nicif_info(nic_dev, drv, netdev, \ nicif_info(nic_dev, drv, netdev, \
"Change %s from %d to %d %s\n", \ "Change %s from %d to %d %s\n", \
#item, (ori_val) * (unit), \ #item, (ori_val) * (unit), \
ALIGN_DOWN((coal)->item, unit), (obj_str)); \ ALIGN_DOWN(coal->item, unit), (obj_str)); \
} while (0) } while (0)
#define CHECK_PKT_RATE_CHANGED(coal, item, ori_val, obj_str) \ #define CHECK_PKT_RATE_CHANGED(coal, item, ori_val, obj_str) \
do { \ do { \
if ((coal)->item != (ori_val)) \ if (coal->item != (ori_val)) \
nicif_info(nic_dev, drv, netdev, \ nicif_info(nic_dev, drv, netdev, \
"Change %s from %llu to %u %s\n", \ "Change %s from %llu to %u %s\n", \
#item, (ori_val), (coal)->item, (obj_str)); \ #item, (ori_val), coal->item, (obj_str)); \
} while (0) } while (0)
static int __hinic_set_coalesce(struct net_device *netdev, 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) ...@@ -1865,7 +1867,7 @@ static int hinic_run_lp_test(struct hinic_nic_dev *nic_dev, u32 test_time)
/* mark index for every pkt */ /* mark index for every pkt */
skb->data[LP_PKT_LEN - 1] = j; 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);
dev_kfree_skb_any(skb_tmp); dev_kfree_skb_any(skb_tmp);
nicif_err(nic_dev, drv, netdev, nicif_err(nic_dev, drv, netdev,
...@@ -2228,7 +2230,7 @@ static int __set_rss_rxfh(struct net_device *netdev, ...@@ -2228,7 +2230,7 @@ static int __set_rss_rxfh(struct net_device *netdev,
/* We request double spaces for the hash key, /* We request double spaces for the hash key,
* the second one holds the key of Big Edian * the second one holds the key of Big Edian
* format. * format.
*/ */
nic_dev->rss_hkey_user = nic_dev->rss_hkey_user =
kzalloc(HINIC_RSS_KEY_SIZE * 2, GFP_KERNEL); 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) ...@@ -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 = { static const struct ethtool_ops hinic_ethtool_ops = {
#ifdef ETHTOOL_GLINKSETTINGS #ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
.get_link_ksettings = hinic_get_link_ksettings, .get_link_ksettings = hinic_get_link_ksettings,
.set_link_ksettings = hinic_set_link_ksettings, .set_link_ksettings = hinic_set_link_ksettings,
#endif
#endif #endif
.get_settings = hinic_get_settings, .get_settings = hinic_get_settings,
.set_settings = hinic_set_settings, .set_settings = hinic_set_settings,
...@@ -2521,7 +2525,9 @@ static const struct ethtool_ops_ext hinic_ethtool_ops_ext = { ...@@ -2521,7 +2525,9 @@ static const struct ethtool_ops_ext hinic_ethtool_ops_ext = {
static const struct ethtool_ops hinicvf_ethtool_ops = { static const struct ethtool_ops hinicvf_ethtool_ops = {
#ifdef ETHTOOL_GLINKSETTINGS #ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
.get_link_ksettings = hinic_get_link_ksettings, .get_link_ksettings = hinic_get_link_ksettings,
#endif
#else #else
.get_settings = hinic_get_settings, .get_settings = hinic_get_settings,
#endif #endif
......
...@@ -84,8 +84,8 @@ int hinic_msg_to_mgmt_async(void *hwdev, enum hinic_mod_type mod, u8 cmd, ...@@ -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); void *buf_in, u16 in_size);
int hinic_mbox_to_vf(void *hwdev, enum hinic_mod_type mod, int hinic_mbox_to_vf(void *hwdev, enum hinic_mod_type mod,
u16 vf_id, u8 cmd, void *buf_in, u16 in_size, u16 vf_id, u8 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size, u32 timeout); void *buf_out, u16 *out_size, u32 timeout);
int hinic_api_cmd_write_nack(void *hwdev, u8 dest, int hinic_api_cmd_write_nack(void *hwdev, u8 dest,
void *cmd, u16 size); void *cmd, u16 size);
...@@ -375,11 +375,13 @@ enum hinic_func_cap { ...@@ -375,11 +375,13 @@ enum hinic_func_cap {
* allocation or dev_err print the parameter * allocation or dev_err print the parameter
*/ */
int hinic_init_hwdev(struct hinic_init_para *para); 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_free_hwdev(void *hwdev);
void hinic_shutdown_hwdev(void *hwdev); void hinic_shutdown_hwdev(void *hwdev);
void hinic_ppf_hwdev_unreg(void *hwdev); void hinic_ppf_hwdev_unreg(void *hwdev);
void hinic_ppf_hwdev_reg(void *hwdev, void *ppf_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); bool hinic_is_hwdev_mod_inited(void *hwdev, enum hinic_hwdev_init_state state);
enum hinic_func_mode hinic_get_func_mode(void *hwdev); enum hinic_func_mode hinic_get_func_mode(void *hwdev);
u64 hinic_get_func_feature_cap(void *hwdev); u64 hinic_get_func_feature_cap(void *hwdev);
...@@ -390,7 +392,6 @@ enum hinic_service_mode { ...@@ -390,7 +392,6 @@ enum hinic_service_mode {
HINIC_WORK_MODE_NIC, HINIC_WORK_MODE_NIC,
HINIC_WORK_MODE_INVALID = 0xFF, HINIC_WORK_MODE_INVALID = 0xFF,
}; };
enum hinic_service_mode hinic_get_service_mode(void *hwdev); enum hinic_service_mode hinic_get_service_mode(void *hwdev);
int hinic_slq_init(void *dev, int num_wqs); int hinic_slq_init(void *dev, int num_wqs);
...@@ -616,6 +617,7 @@ enum hinic_event_type { ...@@ -616,6 +617,7 @@ enum hinic_event_type {
HINIC_EVENT_PORT_MODULE_EVENT = 7, HINIC_EVENT_PORT_MODULE_EVENT = 7,
HINIC_EVENT_MCTP_GET_HOST_INFO, HINIC_EVENT_MCTP_GET_HOST_INFO,
HINIC_EVENT_MULTI_HOST_MGMT, HINIC_EVENT_MULTI_HOST_MGMT,
HINIC_EVENT_INIT_MIGRATE_PF,
}; };
struct hinic_event_info { struct hinic_event_info {
...@@ -726,14 +728,16 @@ struct hinic_hw_pf_infos { ...@@ -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_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_set_ip_check(void *hwdev, bool ip_check_ctl);
int hinic_mbox_to_host_sync(void *hwdev, enum hinic_mod_type mod, int hinic_mbox_to_host_sync(void *hwdev, enum hinic_mod_type mod,
u8 cmd, void *buf_in, u16 in_size, void *buf_out, u8 cmd, void *buf_in, u16 in_size, void *buf_out,
u16 *out_size, u32 timeout); u16 *out_size, u32 timeout);
int hinic_mbox_ppf_to_vf(void *hwdev, int hinic_mbox_ppf_to_vf(void *hwdev,
enum hinic_mod_type mod, u16 func_id, u8 cmd, enum hinic_mod_type mod, u16 func_id, u8 cmd, void *buf_in,
void *buf_in, u16 in_size, void *buf_out, u16 in_size, void *buf_out, u16 *out_size, u32 timeout);
u16 *out_size, u32 timeout);
int hinic_get_card_present_state(void *hwdev, bool *card_present_state); 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); int hinic_set_vxlan_udp_dport(void *hwdev, u32 udp_port);
bool is_multi_vm_slave(void *hwdev);
#endif #endif
/* /* SPDX-License-Identifier: GPL-2.0*/
* Huawei HiNIC PCI Express Linux driver /* Huawei HiNIC PCI Express Linux driver
* Copyright(c) 2017 Huawei Technologies Co., Ltd * Copyright(c) 2017 Huawei Technologies Co., Ltd
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
...@@ -27,6 +27,9 @@ enum hinic_service_type { ...@@ -27,6 +27,9 @@ enum hinic_service_type {
SERVICE_T_IWARP, SERVICE_T_IWARP,
SERVICE_T_FC, SERVICE_T_FC,
SERVICE_T_FCOE, SERVICE_T_FCOE,
SERVICE_T_MIGRATE,
SERVICE_T_PT,
SERVICE_T_HWPT,
SERVICE_T_MAX, SERVICE_T_MAX,
/* Only used for interruption resource management, /* Only used for interruption resource management,
...@@ -68,6 +71,8 @@ struct nic_service_cap { ...@@ -68,6 +71,8 @@ struct nic_service_cap {
bool lro_en; /* LRO feature enable bit*/ bool lro_en; /* LRO feature enable bit*/
u8 lro_sz; /* LRO context space: n*16B */ u8 lro_sz; /* LRO context space: n*16B */
u8 tso_sz; /* TSO context space: n*16B */ u8 tso_sz; /* TSO context space: n*16B */
u16 max_queue_allowed;
}; };
struct dev_roce_svc_own_cap { struct dev_roce_svc_own_cap {
...@@ -520,7 +525,6 @@ struct hinic_micro_log_info { ...@@ -520,7 +525,6 @@ struct hinic_micro_log_info {
int (*init)(void *hwdev); int (*init)(void *hwdev);
void (*deinit)(void *hwdev); void (*deinit)(void *hwdev);
}; };
int hinic_register_micro_log(struct hinic_micro_log_info *micro_log_info); 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); void hinic_unregister_micro_log(struct hinic_micro_log_info *micro_log_info);
...@@ -544,5 +548,12 @@ struct hinic_func_nic_state { ...@@ -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_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); 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_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 #endif
...@@ -24,6 +24,30 @@ ...@@ -24,6 +24,30 @@
#define HINIC_MSG_TO_MGMT_MAX_LEN 2016 #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 cfg_mgmt_info;
struct rdma_comp_resource; struct rdma_comp_resource;
...@@ -193,7 +217,8 @@ struct hinic_heartbeat_enhanced { ...@@ -193,7 +217,8 @@ struct hinic_heartbeat_enhanced {
HINIC_FUNC_SUPP_DFX_REG | \ HINIC_FUNC_SUPP_DFX_REG | \
HINIC_FUNC_SRIOV_EN_DFLT | \ HINIC_FUNC_SRIOV_EN_DFLT | \
HINIC_FUNC_SUPP_RX_MODE | \ 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_CHIP_MODE_SHIFT 0
#define MULTI_HOST_MASTER_MBX_STS_SHIFT 0x4 #define MULTI_HOST_MASTER_MBX_STS_SHIFT 0x4
...@@ -294,6 +319,8 @@ struct hinic_hwdev { ...@@ -294,6 +319,8 @@ struct hinic_hwdev {
struct semaphore ppf_sem; struct semaphore ppf_sem;
void *ppf_hwdev; void *ppf_hwdev;
struct semaphore func_sem;
int func_ref;
struct hinic_board_info board_info; struct hinic_board_info board_info;
#define MGMT_VERSION_MAX_LEN 32 #define MGMT_VERSION_MAX_LEN 32
u8 mgmt_ver[MGMT_VERSION_MAX_LEN]; 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, ...@@ -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); void *buf_out, u16 *out_size, u32 timeout);
int hinic_pf_send_clp_cmd(void *hwdev, enum hinic_mod_type mod, u8 cmd, int hinic_pf_send_clp_cmd(void *hwdev, enum hinic_mod_type mod, u8 cmd,
void *buf_in, u16 in_size, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size); void *buf_out, u16 *out_size);
int hinic_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit); 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); ...@@ -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 mgmt_heartbeat_event_handler(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size); void *buf_out, u16 *out_size);
#endif #endif
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details. * for more details.
*
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt #define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
...@@ -26,6 +27,7 @@ ...@@ -26,6 +27,7 @@
#include "hinic_csr.h" #include "hinic_csr.h"
#include "hinic_hwif.h" #include "hinic_hwif.h"
#include "hinic_eqs.h"
#define WAIT_HWIF_READY_TIMEOUT 10000 #define WAIT_HWIF_READY_TIMEOUT 10000
...@@ -671,6 +673,108 @@ u16 hinic_global_func_id(void *hwdev) ...@@ -671,6 +673,108 @@ u16 hinic_global_func_id(void *hwdev)
} }
EXPORT_SYMBOL(hinic_global_func_id); 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) u16 hinic_intr_num(void *hwdev)
{ {
struct hinic_hwif *hwif; struct hinic_hwif *hwif;
...@@ -697,6 +801,18 @@ u8 hinic_pf_id_of_vf(void *hwdev) ...@@ -697,6 +801,18 @@ u8 hinic_pf_id_of_vf(void *hwdev)
} }
EXPORT_SYMBOL(hinic_pf_id_of_vf); 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) u8 hinic_pcie_itf_id(void *hwdev)
{ {
struct hinic_hwif *hwif; struct hinic_hwif *hwif;
......
...@@ -134,7 +134,6 @@ struct hinic_pcidev { ...@@ -134,7 +134,6 @@ struct hinic_pcidev {
bool nic_cur_enable; bool nic_cur_enable;
bool nic_des_enable; bool nic_des_enable;
}; };
#define HINIC_EVENT_PROCESS_TIMEOUT 10000 #define HINIC_EVENT_PROCESS_TIMEOUT 10000
#define FIND_BIT(num, n) (((num) & (1UL << (n))) ? 1 : 0) #define FIND_BIT(num, n) (((num) & (1UL << (n))) ? 1 : 0)
...@@ -146,7 +145,7 @@ static u64 card_bit_map; ...@@ -146,7 +145,7 @@ static u64 card_bit_map;
LIST_HEAD(g_hinic_chip_list); LIST_HEAD(g_hinic_chip_list);
struct hinic_uld_info g_uld_info[SERVICE_T_MAX] = { {0} }; struct hinic_uld_info g_uld_info[SERVICE_T_MAX] = { {0} };
static const char *s_uld_name[SERVICE_T_MAX] = { 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 { enum hinic_lld_status {
HINIC_NODE_CHANGE = BIT(0), HINIC_NODE_CHANGE = BIT(0),
...@@ -276,7 +275,6 @@ static int attach_uld(struct hinic_pcidev *dev, enum hinic_service_type type, ...@@ -276,7 +275,6 @@ static int attach_uld(struct hinic_pcidev *dev, enum hinic_service_type type,
{ {
void *uld_dev = NULL; void *uld_dev = NULL;
int err; int err;
mutex_lock(&dev->pdev_mutex); mutex_lock(&dev->pdev_mutex);
if (dev->init_state < HINIC_INIT_STATE_HWDEV_INITED) { if (dev->init_state < HINIC_INIT_STATE_HWDEV_INITED) {
...@@ -702,12 +700,6 @@ struct mctp_hdr { ...@@ -702,12 +700,6 @@ struct mctp_hdr {
u8 spc_field; 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_bdf_info {
struct mctp_hdr hdr; /* spc_field: pf index */ struct mctp_hdr hdr; /* spc_field: pf index */
u8 rsvd; u8 rsvd;
...@@ -716,37 +708,13 @@ struct mctp_bdf_info { ...@@ -716,37 +708,13 @@ struct mctp_bdf_info {
u8 function; 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 { enum mctp_resp_code {
/* COMMAND_COMPLETED = 0, */ /* COMMAND_COMPLETED = 0, */
COMMAND_FAILED = 1, /* COMMAND_FAILED = 1, */
/* COMMAND_UNAVALILABLE = 2, */ /* COMMAND_UNAVALILABLE = 2, */
COMMAND_UNSUPPORTED = 3, 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, static void __mctp_set_hdr(struct mctp_hdr *hdr,
struct hinic_mctp_host_info *mctp_info) struct hinic_mctp_host_info *mctp_info)
{ {
...@@ -760,29 +728,6 @@ static void __mctp_set_hdr(struct mctp_hdr *hdr, ...@@ -760,29 +728,6 @@ static void __mctp_set_hdr(struct mctp_hdr *hdr,
hdr->reason_code = cpu_to_be16(hdr->reason_code); 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, static void __mctp_get_bdf(struct hinic_pcidev *pci_adapter,
struct hinic_mctp_host_info *mctp_info) struct hinic_mctp_host_info *mctp_info)
{ {
...@@ -795,100 +740,12 @@ static void __mctp_get_bdf(struct hinic_pcidev *pci_adapter, ...@@ -795,100 +740,12 @@ static void __mctp_get_bdf(struct hinic_pcidev *pci_adapter,
memset(&bdf_info->hdr, 0, sizeof(bdf_info->hdr)); memset(&bdf_info->hdr, 0, sizeof(bdf_info->hdr));
__mctp_set_hdr(&bdf_info->hdr, mctp_info); __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); 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_PUBLIC 0x0
#define MCTP_MAJOR_CMD_NIC 0x1 #define MCTP_MAJOR_CMD_NIC 0x1
...@@ -907,14 +764,6 @@ static void __mctp_get_host_info(struct hinic_pcidev *dev, ...@@ -907,14 +764,6 @@ static void __mctp_get_host_info(struct hinic_pcidev *dev,
__mctp_get_bdf(dev, mctp_info); __mctp_get_bdf(dev, mctp_info);
break; 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: default:
hdr = mctp_info->data; hdr = mctp_info->data;
hdr->reason_code = COMMAND_UNSUPPORTED; hdr->reason_code = COMMAND_UNSUPPORTED;
...@@ -924,7 +773,8 @@ static void __mctp_get_host_info(struct hinic_pcidev *dev, ...@@ -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, struct card_node *chip_node,
enum func_type type) enum func_type type)
{ {
...@@ -1004,7 +854,8 @@ static struct hinic_pcidev *hinic_get_pcidev_by_chip_name(char *ifname) ...@@ -1004,7 +854,8 @@ static struct hinic_pcidev *hinic_get_pcidev_by_chip_name(char *ifname)
return NULL; 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) enum hinic_service_type type)
{ {
struct hinic_nic_dev *nic_dev; struct hinic_nic_dev *nic_dev;
...@@ -1099,7 +950,7 @@ int hinic_get_chip_name_by_hwdev(void *hwdev, char *ifname) ...@@ -1099,7 +950,7 @@ int hinic_get_chip_name_by_hwdev(void *hwdev, char *ifname)
} }
EXPORT_SYMBOL(hinic_get_chip_name_by_hwdev); 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 *chip_node = NULL;
struct card_node *node_tmp = NULL; struct card_node *node_tmp = NULL;
...@@ -1408,6 +1259,12 @@ void hinic_get_card_info(void *hwdev, void *bufin) ...@@ -1408,6 +1259,12 @@ void hinic_get_card_info(void *hwdev, void *bufin)
if (hinic_func_for_mgmt(fun_hwdev)) if (hinic_func_for_mgmt(fun_hwdev))
strlcpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ); 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), strlcpy(info->pf[i].bus_info, pci_name(dev->pcidev),
sizeof(info->pf[i].bus_info)); sizeof(info->pf[i].bus_info));
info->pf_num++; info->pf_num++;
...@@ -1416,7 +1273,7 @@ void hinic_get_card_info(void *hwdev, void *bufin) ...@@ -1416,7 +1273,7 @@ void hinic_get_card_info(void *hwdev, void *bufin)
lld_dev_put(); 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 struct hinic_card_func_info
*card_func) *card_func)
{ {
...@@ -1767,16 +1624,20 @@ struct pci_device_id *hinic_get_pci_device_id(struct pci_dev *pdev) ...@@ -1767,16 +1624,20 @@ struct pci_device_id *hinic_get_pci_device_id(struct pci_dev *pdev)
return &adapter->id; return &adapter->id;
} }
EXPORT_SYMBOL(hinic_get_pci_device_id);
static int __set_nic_func_state(struct hinic_pcidev *pci_adapter) static int __set_nic_func_state(struct hinic_pcidev *pci_adapter)
{ {
struct pci_dev *pdev = pci_adapter->pcidev; struct pci_dev *pdev = pci_adapter->pcidev;
u16 func_id;
int err; int err;
bool enable_nic; bool enable_nic;
err = hinic_get_func_nic_enable(pci_adapter->hwdev, err = hinic_global_func_id_get(pci_adapter->hwdev, &func_id);
hinic_global_func_id if (err)
(pci_adapter->hwdev), return err;
err = hinic_get_func_nic_enable(pci_adapter->hwdev, func_id,
&enable_nic); &enable_nic);
if (err) { if (err) {
sdk_err(&pdev->dev, "Failed to get nic state\n"); 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) ...@@ -1800,6 +1661,88 @@ static int __set_nic_func_state(struct hinic_pcidev *pci_adapter)
return 0; 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) static void slave_host_mgmt_work(struct work_struct *work)
{ {
struct hinic_pcidev *pci_adapter = struct hinic_pcidev *pci_adapter =
...@@ -1834,7 +1777,7 @@ static void __multi_host_mgmt(struct hinic_pcidev *dev, ...@@ -1834,7 +1777,7 @@ static void __multi_host_mgmt(struct hinic_pcidev *dev,
&des_dev->flag)) &des_dev->flag))
continue; continue;
if (hinic_global_func_id(des_dev->hwdev) != if (hinic_global_func_id_hw(des_dev->hwdev) !=
nic_state->func_idx) nic_state->func_idx)
continue; continue;
...@@ -1843,7 +1786,6 @@ static void __multi_host_mgmt(struct hinic_pcidev *dev, ...@@ -1843,7 +1786,6 @@ static void __multi_host_mgmt(struct hinic_pcidev *dev,
nic_state->status = nic_state->status =
test_bit(HINIC_FUNC_PRB_ERR, test_bit(HINIC_FUNC_PRB_ERR,
&des_dev->flag) ? 1 : 0; &des_dev->flag) ? 1 : 0;
break; break;
} }
...@@ -1923,7 +1865,7 @@ static int mapping_bar(struct pci_dev *pdev, struct hinic_pcidev *pci_adapter) ...@@ -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; 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, pci_adapter->dwqe_mapping = __ioremap(dwqe_addr, HINIC_DB_DWQE_SIZE,
__pgprot(PROT_DEVICE_nGnRnE)); __pgprot(PROT_DEVICE_nGnRnE));
if (!pci_adapter->dwqe_mapping) { if (!pci_adapter->dwqe_mapping) {
...@@ -2031,14 +1973,15 @@ static int alloc_chip_node(struct hinic_pcidev *pci_adapter) ...@@ -2031,14 +1973,15 @@ static int alloc_chip_node(struct hinic_pcidev *pci_adapter)
static void free_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; struct card_node *chip_node = pci_adapter->chip_node;
int id, err; u32 id;
int err;
if (list_empty(&chip_node->func_list)) { if (list_empty(&chip_node->func_list)) {
list_del(&chip_node->node); list_del(&chip_node->node);
sdk_info(&pci_adapter->pcidev->dev, sdk_info(&pci_adapter->pcidev->dev,
"Delete chip %s from global list succeed\n", "Delete chip %s from global list succeed\n",
chip_node->chip_name); 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) if (err < 0)
sdk_err(&pci_adapter->pcidev->dev, "Failed to get hinic id\n"); 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) ...@@ -2081,19 +2024,16 @@ static bool hinic_get_vf_load_state(struct pci_dev *pdev)
return disable_vf_load; 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; struct card_node *chip_node;
bool vf_load_state;
u16 func_id; u16 func_id;
if (hinic_func_type(pci_adapter->hwdev) == TYPE_VF) if (hinic_func_type(pci_adapter->hwdev) == TYPE_VF)
return; return;
vf_load_state = hinic_support_ovs(pci_adapter->hwdev, NULL) ? func_id = hinic_global_func_id_hw(pci_adapter->hwdev);
true : disable_vf_load;
func_id = hinic_global_func_id(pci_adapter->hwdev);
chip_node = pci_adapter->chip_node; chip_node = pci_adapter->chip_node;
chip_node->disable_vf_load[func_id] = vf_load_state; 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) ...@@ -2104,6 +2044,27 @@ static void hinic_set_vf_load_state(struct hinic_pcidev *pci_adapter)
(vf_load_state ? "disable" : "enable")); (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) static int hinic_config_deft_mrss(struct pci_dev *pdev)
{ {
return 0; return 0;
...@@ -2276,6 +2237,7 @@ static int hinic_func_init(struct pci_dev *pdev, ...@@ -2276,6 +2237,7 @@ static int hinic_func_init(struct pci_dev *pdev,
struct hinic_pcidev *pci_adapter) struct hinic_pcidev *pci_adapter)
{ {
struct hinic_init_para init_para; struct hinic_init_para init_para;
bool vf_load_state;
int err; int err;
init_para.adapter_hdl = pci_adapter; init_para.adapter_hdl = pci_adapter;
...@@ -2318,7 +2280,10 @@ static int hinic_func_init(struct pci_dev *pdev, ...@@ -2318,7 +2280,10 @@ static int hinic_func_init(struct pci_dev *pdev,
hinic_notify_ppf_reg(pci_adapter); hinic_notify_ppf_reg(pci_adapter);
pci_adapter->init_state = HINIC_INIT_STATE_HWDEV_INITED; 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.pdev = pdev;
pci_adapter->lld_dev.hwdev = pci_adapter->hwdev; pci_adapter->lld_dev.hwdev = pci_adapter->hwdev;
...@@ -2416,9 +2381,9 @@ static void hinic_func_deinit(struct pci_dev *pdev) ...@@ -2416,9 +2381,9 @@ static void hinic_func_deinit(struct pci_dev *pdev)
hinic_notify_ppf_unreg(pci_adapter); hinic_notify_ppf_unreg(pci_adapter);
if (pci_adapter->init_state >= HINIC_INIT_STATE_HW_IF_INITED) { if (pci_adapter->init_state >= HINIC_INIT_STATE_HW_IF_INITED) {
/* Remove the current node from node-list first, /* Remove the current node from node-list first,
* then it's safe to free hwdev * then it's safe to free hwdev
*/ */
lld_lock_chip_node(); lld_lock_chip_node();
list_del(&pci_adapter->node); list_del(&pci_adapter->node);
lld_unlock_chip_node(); lld_unlock_chip_node();
...@@ -2502,11 +2467,12 @@ static void hinic_remove(struct pci_dev *pdev) ...@@ -2502,11 +2467,12 @@ static void hinic_remove(struct pci_dev *pdev)
case HINIC_INIT_STATE_HW_IF_INITED: case HINIC_INIT_STATE_HW_IF_INITED:
case HINIC_INIT_STATE_PCI_INITED: case HINIC_INIT_STATE_PCI_INITED:
set_bit(HINIC_FUNC_IN_REMOVE, &pci_adapter->flag); set_bit(HINIC_FUNC_IN_REMOVE, &pci_adapter->flag);
wait_tool_unused();
lld_lock_chip_node(); lld_lock_chip_node();
cancel_work_sync(&pci_adapter->slave_nic_work); cancel_work_sync(&pci_adapter->slave_nic_work);
lld_unlock_chip_node(); lld_unlock_chip_node();
wait_tool_unused();
if (pci_adapter->init_state >= HINIC_INIT_STATE_HW_IF_INITED) if (pci_adapter->init_state >= HINIC_INIT_STATE_HW_IF_INITED)
hinic_func_deinit(pdev); hinic_func_deinit(pdev);
...@@ -2570,11 +2536,12 @@ static void slave_host_init_delay_work(struct work_struct *work) ...@@ -2570,11 +2536,12 @@ static void slave_host_init_delay_work(struct work_struct *work)
if (err) if (err)
set_bit(HINIC_FUNC_PRB_ERR, &pci_adapter->flag); set_bit(HINIC_FUNC_PRB_ERR, &pci_adapter->flag);
return; 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) 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[] = { ...@@ -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_100GE), HINIC_BOARD_100GE},
{PCI_VDEVICE(HUAWEI, HINIC_DEV_ID_1822_KR_25GE), HINIC_BOARD_25GE}, {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_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} {0, 0}
}; };
...@@ -2775,6 +2744,7 @@ static void __exit hinic_lld_exit(void) ...@@ -2775,6 +2744,7 @@ static void __exit hinic_lld_exit(void)
pci_unregister_driver(&hinic_driver); pci_unregister_driver(&hinic_driver);
hinic_unregister_uld(SERVICE_T_NIC); hinic_unregister_uld(SERVICE_T_NIC);
} }
module_init(hinic_lld_init); module_init(hinic_lld_init);
module_exit(hinic_lld_exit); module_exit(hinic_lld_exit);
......
...@@ -109,6 +109,11 @@ void hinic_detach_roce(struct hinic_lld_dev *lld_dev); ...@@ -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_disable_nic_rss(struct hinic_lld_dev *lld_dev);
int hinic_enable_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); 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_by_ifname(char *ifname);
enum hinic_init_state hinic_get_init_state(struct pci_dev *pdev); 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]; ...@@ -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); struct pci_device_id *hinic_get_pci_device_id(struct pci_dev *pdev);
bool hinic_is_in_host(void); bool hinic_is_in_host(void);
bool hinic_is_valid_bar_addr(u64 offset); bool hinic_is_valid_bar_addr(u64 offset);
#endif #endif
...@@ -105,8 +105,23 @@ static unsigned char lro_en_status = HINIC_LRO_STATUS_UNSET; ...@@ -105,8 +105,23 @@ static unsigned char lro_en_status = HINIC_LRO_STATUS_UNSET;
module_param(lro_en_status, byte, 0444); module_param(lro_en_status, byte, 0444);
MODULE_PARM_DESC(lro_en_status, "lro enable status. 0 - disable, 1 - enable, other - unset. (default unset)"); 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_lower_thd = HINIC_RX_BP_LOWER_THD;
static unsigned int bp_upper_thd = HINIC_RX_BP_UPPER_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) ...@@ -445,6 +460,8 @@ int hinic_poll(struct napi_struct *napi, int budget)
HINIC_MSIX_ENABLE); HINIC_MSIX_ENABLE);
else if (!nic_dev->in_vm) else if (!nic_dev->in_vm)
enable_irq(irq_cfg->irq_id); enable_irq(irq_cfg->irq_id);
} else {
hinic_rx_poll(irq_cfg->rxq, HINIC_RX_BUFFER_WRITE);
} }
return max(tx_pkts, rx_pkts); return max(tx_pkts, rx_pkts);
...@@ -572,6 +589,12 @@ static void __calc_coal_para(struct hinic_nic_dev *nic_dev, ...@@ -572,6 +589,12 @@ static void __calc_coal_para(struct hinic_nic_dev *nic_dev,
struct hinic_intr_coal_info *q_coal, u64 rate, struct hinic_intr_coal_info *q_coal, u64 rate,
u8 *coalesc_timer_cfg, u8 *pending_limt) 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) { if (rate < q_coal->pkt_rate_low) {
*coalesc_timer_cfg = q_coal->rx_usecs_low; *coalesc_timer_cfg = q_coal->rx_usecs_low;
*pending_limt = q_coal->rx_pending_limt_low; *pending_limt = q_coal->rx_pending_limt_low;
...@@ -609,6 +632,7 @@ static void hinic_auto_moderation_work(struct work_struct *work) ...@@ -609,6 +632,7 @@ static void hinic_auto_moderation_work(struct work_struct *work)
nic_dev->last_moder_jiffies); nic_dev->last_moder_jiffies);
u64 rx_packets, rx_bytes, rx_pkt_diff, rate, avg_pkt_size; 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; u8 coalesc_timer_cfg, pending_limt;
u16 qid; u16 qid;
...@@ -624,6 +648,8 @@ static void hinic_auto_moderation_work(struct work_struct *work) ...@@ -624,6 +648,8 @@ static void hinic_auto_moderation_work(struct work_struct *work)
for (qid = 0; qid < nic_dev->num_qps; qid++) { for (qid = 0; qid < nic_dev->num_qps; qid++) {
rx_packets = nic_dev->rxqs[qid].rxq_stats.packets; rx_packets = nic_dev->rxqs[qid].rxq_stats.packets;
rx_bytes = nic_dev->rxqs[qid].rxq_stats.bytes; 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]; q_coal = &nic_dev->intr_coalesce[qid];
rx_pkt_diff = rx_pkt_diff =
...@@ -634,14 +660,24 @@ static void hinic_auto_moderation_work(struct work_struct *work) ...@@ -634,14 +660,24 @@ static void hinic_auto_moderation_work(struct work_struct *work)
rx_pkt_diff : 0; rx_pkt_diff : 0;
rate = rx_pkt_diff * HZ / period; 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 && 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, __calc_coal_para(nic_dev, q_coal, rate,
&coalesc_timer_cfg, &pending_limt); &coalesc_timer_cfg, &pending_limt);
} else { } else {
coalesc_timer_cfg = HINIC_LOWEST_LATENCY; coalesc_timer_cfg =
pending_limt = q_coal->rx_pending_limt_low; (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, set_interrupt_moder(nic_dev, qid, coalesc_timer_cfg,
...@@ -649,6 +685,8 @@ static void hinic_auto_moderation_work(struct work_struct *work) ...@@ -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_packets = rx_packets;
nic_dev->rxqs[qid].last_moder_bytes = rx_bytes; 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; nic_dev->last_moder_jiffies = jiffies;
...@@ -1039,8 +1077,8 @@ static u16 select_queue_by_toeplitz(struct net_device *dev, ...@@ -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_ACCEL_FALLBACK)
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV) #if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV)
static u16 hinic_select_queue(struct net_device *netdev, struct sk_buff *skb, static u16 hinic_select_queue(struct net_device *netdev, struct sk_buff *skb,
struct net_device *sb_dev, struct net_device *sb_dev,
select_queue_fallback_t fallback) select_queue_fallback_t fallback)
#else #else
static u16 hinic_select_queue(struct net_device *netdev, struct sk_buff *skb, static u16 hinic_select_queue(struct net_device *netdev, struct sk_buff *skb,
__always_unused void *accel, __always_unused void *accel,
...@@ -1084,7 +1122,7 @@ static u16 hinic_select_queue(struct net_device *netdev, struct sk_buff *skb) ...@@ -1084,7 +1122,7 @@ static u16 hinic_select_queue(struct net_device *netdev, struct sk_buff *skb)
#ifdef HAVE_NDO_GET_STATS64 #ifdef HAVE_NDO_GET_STATS64
#ifdef HAVE_VOID_NDO_GET_STATS64 #ifdef HAVE_VOID_NDO_GET_STATS64
static void hinic_get_stats64(struct net_device *netdev, static void hinic_get_stats64(struct net_device *netdev,
struct rtnl_link_stats64 *stats) struct rtnl_link_stats64 *stats)
#else #else
static struct rtnl_link_stats64 static struct rtnl_link_stats64
*hinic_get_stats64(struct net_device *netdev, *hinic_get_stats64(struct net_device *netdev,
...@@ -1191,6 +1229,7 @@ static int hinic_set_mac_addr(struct net_device *netdev, void *addr) ...@@ -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 hinic_nic_dev *nic_dev = netdev_priv(netdev);
struct sockaddr *saddr = addr; struct sockaddr *saddr = addr;
u16 func_id;
int err; int err;
if (!FUNC_SUPPORT_CHANGE_MAC(nic_dev->hwdev)) { if (!FUNC_SUPPORT_CHANGE_MAC(nic_dev->hwdev)) {
...@@ -1209,8 +1248,12 @@ static int hinic_set_mac_addr(struct net_device *netdev, void *addr) ...@@ -1209,8 +1248,12 @@ static int hinic_set_mac_addr(struct net_device *netdev, void *addr)
return 0; 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, 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) if (err)
return err; return err;
...@@ -1233,13 +1276,17 @@ hinic_vlan_rx_add_vid(struct net_device *netdev, ...@@ -1233,13 +1276,17 @@ hinic_vlan_rx_add_vid(struct net_device *netdev,
{ {
struct hinic_nic_dev *nic_dev = netdev_priv(netdev); struct hinic_nic_dev *nic_dev = netdev_priv(netdev);
unsigned long *vlan_bitmap = nic_dev->vlan_bitmap; unsigned long *vlan_bitmap = nic_dev->vlan_bitmap;
u16 func_id = hinic_global_func_id(nic_dev->hwdev); u16 func_id;
u32 col, line; u32 col, line;
int err; int err;
col = VID_COL(nic_dev, vid); col = VID_COL(nic_dev, vid);
line = VID_LINE(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); err = hinic_add_vlan(nic_dev->hwdev, vid, func_id);
if (err) { if (err) {
nicif_err(nic_dev, drv, netdev, "Failed to add vlan%d\n", vid); 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, ...@@ -1261,12 +1308,16 @@ hinic_vlan_rx_kill_vid(struct net_device *netdev,
{ {
struct hinic_nic_dev *nic_dev = netdev_priv(netdev); struct hinic_nic_dev *nic_dev = netdev_priv(netdev);
unsigned long *vlan_bitmap = nic_dev->vlan_bitmap; 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; int err, col, line;
col = VID_COL(nic_dev, vid); col = VID_COL(nic_dev, vid);
line = VID_LINE(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); err = hinic_del_vlan(nic_dev->hwdev, vid, func_id);
if (err) { if (err) {
nicif_err(nic_dev, drv, netdev, "Failed to delete vlan\n"); 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) ...@@ -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 && if (set_link_status_follow < HINIC_LINK_FOLLOW_STATUS_MAX &&
FUNC_SUPPORT_PORT_SETTING(nic_dev->hwdev)) { FUNC_SUPPORT_PORT_SETTING(nic_dev->hwdev)) {
err = hinic_set_link_status_follow(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) if (err == HINIC_MGMT_CMD_UNSUPPORTED)
nic_warn(&nic_dev->pdev->dev, nic_warn(&nic_dev->pdev->dev,
"Current version of firmware don't support to set link status follow port status\n"); "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) ...@@ -1481,21 +1532,33 @@ static void hinic_netpoll(struct net_device *netdev)
static int hinic_uc_sync(struct net_device *netdev, u8 *addr) static int hinic_uc_sync(struct net_device *netdev, u8 *addr)
{ {
struct hinic_nic_dev *nic_dev = netdev_priv(netdev); struct hinic_nic_dev *nic_dev = netdev_priv(netdev);
u16 func_id;
int err;
return hinic_set_mac(nic_dev->hwdev, addr, 0, err = hinic_global_func_id_get(nic_dev->hwdev, &func_id);
hinic_global_func_id(nic_dev->hwdev)); 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) static int hinic_uc_unsync(struct net_device *netdev, u8 *addr)
{ {
struct hinic_nic_dev *nic_dev = netdev_priv(netdev); struct hinic_nic_dev *nic_dev = netdev_priv(netdev);
u16 func_id;
int err;
/* The addr is in use */ /* The addr is in use */
if (ether_addr_equal(addr, netdev->dev_addr)) if (ether_addr_equal(addr, netdev->dev_addr))
return 0; return 0;
return hinic_del_mac(nic_dev->hwdev, addr, 0, err = hinic_global_func_id_get(nic_dev->hwdev, &func_id);
hinic_global_func_id(nic_dev->hwdev)); 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) 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) ...@@ -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) { \ #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, \ nic_warn(&nic_dev->pdev->dev, \
"Module Parameter %s value %d is out of range, "\ "Module Parameter %s value %d is out of range, "\
"Maximum value for the device: %d, using %d\n",\ "Maximum value for the device: %d, using %d\n",\
#num_qps, num_qps, (nic_dev)->max_qps, \ #num_qps, num_qps, nic_dev->max_qps, \
(nic_dev)->max_qps); \ nic_dev->max_qps); \
if (!(num_qps) || (num_qps) > (nic_dev)->max_qps) \ if (!(num_qps) || (num_qps) > nic_dev->max_qps) \
out_qps = (nic_dev)->max_qps; \ out_qps = nic_dev->max_qps; \
else \ else \
out_qps = num_qps; \ out_qps = num_qps; \
} }
...@@ -2197,8 +2260,12 @@ static void hinic_try_to_enable_rss(struct hinic_nic_dev *nic_dev) ...@@ -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); err = hinic_rss_template_alloc(nic_dev->hwdev, &nic_dev->rss_tmpl_idx);
if (err) { if (err) {
nic_err(&nic_dev->pdev->dev, if (err == -ENOSPC)
"Failed to alloc tmpl_idx for rss, can't enable rss for this function\n"); 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); clear_bit(HINIC_RSS_ENABLE, &nic_dev->flags);
nic_dev->max_qps = 1; nic_dev->max_qps = 1;
nic_dev->rss_limit = nic_dev->max_qps; 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) ...@@ -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) static int hinic_sw_init(struct hinic_nic_dev *adapter)
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
u16 func_id;
int err = 0; int err = 0;
sema_init(&adapter->port_state_sem, 1); sema_init(&adapter->port_state_sem, 1);
...@@ -2285,8 +2353,11 @@ static int hinic_sw_init(struct hinic_nic_dev *adapter) ...@@ -2285,8 +2353,11 @@ static int hinic_sw_init(struct hinic_nic_dev *adapter)
eth_hw_addr_random(netdev); eth_hw_addr_random(netdev);
} }
err = hinic_set_mac(adapter->hwdev, netdev->dev_addr, 0, err = hinic_global_func_id_get(adapter->hwdev, &func_id);
hinic_global_func_id(adapter->hwdev)); 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 /* 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 * MAC, and we can't consider this condition is error status during
* driver probe procedure. * driver probe procedure.
...@@ -2309,6 +2380,7 @@ static int hinic_sw_init(struct hinic_nic_dev *adapter) ...@@ -2309,6 +2380,7 @@ static int hinic_sw_init(struct hinic_nic_dev *adapter)
return 0; return 0;
set_mac_err: set_mac_err:
func_id_err:
err_mac: err_mac:
get_mac_err: get_mac_err:
if (test_bit(HINIC_RSS_ENABLE, &adapter->flags)) if (test_bit(HINIC_RSS_ENABLE, &adapter->flags))
...@@ -2405,16 +2477,20 @@ static void init_intr_coal_param(struct hinic_nic_dev *nic_dev) ...@@ -2405,16 +2477,20 @@ static void init_intr_coal_param(struct hinic_nic_dev *nic_dev)
info->resend_timer_cfg = info->resend_timer_cfg =
HINIC_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG; HINIC_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG;
info->pkt_rate_high = HINIC_RX_RATE_HIGH; info->pkt_rate_high = HINIC_RX_RATE_HIGH;
info->rx_usecs_high = HINIC_RX_COAL_TIME_HIGH; info->rx_usecs_high = qp_coalesc_timer_high;
info->rx_pending_limt_high = HINIC_RX_PENDING_LIMIT_HIGH; info->rx_pending_limt_high = qp_pending_limit_high;
info->pkt_rate_low = HINIC_RX_RATE_LOW; info->pkt_rate_low = HINIC_RX_RATE_LOW;
info->rx_usecs_low = HINIC_RX_COAL_TIME_LOW; info->rx_usecs_low = qp_coalesc_timer_low;
info->rx_pending_limt_low = HINIC_RX_PENDING_LIMIT_LOW; info->rx_pending_limt_low = qp_pending_limit_low;
if (nic_dev->in_vm) { 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->pkt_rate_low = HINIC_RX_RATE_LOW_VM;
info->rx_pending_limt_high = 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) ...@@ -2523,6 +2599,20 @@ static int hinic_validate_parameters(struct hinic_lld_dev *lld_dev)
rx_buff = DEFAULT_RX_BUFF_LEN; 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; return 0;
} }
...@@ -2723,6 +2813,7 @@ static int nic_probe(struct hinic_lld_dev *lld_dev, void **uld_dev, ...@@ -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->msg_enable = DEFAULT_MSG_ENABLE;
nic_dev->heart_status = true; nic_dev->heart_status = true;
nic_dev->in_vm = !hinic_is_in_host(); 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->lro_replenish_thld = lro_replenish_thld;
nic_dev->rx_buff_len = (u16)(rx_buff * CONVERT_UNIT); nic_dev->rx_buff_len = (u16)(rx_buff * CONVERT_UNIT);
page_num = (RX_BUFF_NUM_PER_PAGE * nic_dev->rx_buff_len) / PAGE_SIZE; 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, ...@@ -2812,7 +2903,7 @@ static int nic_probe(struct hinic_lld_dev *lld_dev, void **uld_dev,
alloc_qps_err: alloc_qps_err:
hinic_del_mac(nic_dev->hwdev, netdev->dev_addr, 0, 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: sw_init_err:
(void)hinic_set_super_cqe_state(nic_dev->hwdev, false); (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) ...@@ -2851,7 +2942,7 @@ static void nic_remove(struct hinic_lld_dev *lld_dev, void *adapter)
hinic_clean_mac_list_filter(nic_dev); hinic_clean_mac_list_filter(nic_dev);
hinic_del_mac(nic_dev->hwdev, netdev->dev_addr, 0, 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)) if (test_bit(HINIC_RSS_ENABLE, &nic_dev->flags))
hinic_rss_template_free(nic_dev->hwdev, nic_dev->rss_tmpl_idx); 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) ...@@ -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); err = hinic_rss_template_alloc(nic_dev->hwdev, &nic_dev->rss_tmpl_idx);
if (err) { 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 { } else {
set_bit(HINIC_RSS_ENABLE, &nic_dev->flags); set_bit(HINIC_RSS_ENABLE, &nic_dev->flags);
nicif_info(nic_dev, drv, netdev, "Success to alloc RSS template\n"); nicif_info(nic_dev, drv, netdev, "Success to alloc RSS template\n");
......
...@@ -207,7 +207,7 @@ struct hinic_set_random_id { ...@@ -207,7 +207,7 @@ struct hinic_set_random_id {
}; };
static bool check_func_id(struct hinic_hwdev *hwdev, u16 src_func_idx, 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; u16 func_idx;
...@@ -402,7 +402,7 @@ void hinic_unregister_vf_mbox_cb(struct hinic_hwdev *hwdev, ...@@ -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]); clear_bit(HINIC_VF_MBOX_CB_REG, &func_to_func->vf_mbox_cb_state[mod]);
while (test_bit(HINIC_VF_MBOX_CB_RUNNING, 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); usleep_range(900, 1000);
func_to_func->vf_mbox_cb[mod] = NULL; 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, ...@@ -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, recv_mbox->mbox, recv_mbox->mbox_len,
buf_out, out_size); buf_out, out_size);
} else { } 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; ret = -EINVAL;
} }
...@@ -659,11 +659,11 @@ static void recv_func_mbox_handler(struct hinic_mbox_func_to_func *func_to_func, ...@@ -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, buf_out, out_size, src_func_idx,
HINIC_HWIF_RESPONSE, MBOX_ACK, HINIC_HWIF_RESPONSE, MBOX_ACK,
&msg_info); &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, 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, ...@@ -717,7 +717,7 @@ static void recv_mbox_handler(struct hinic_mbox_func_to_func *func_to_func,
{ {
u64 mbox_header = *((u64 *)header); u64 mbox_header = *((u64 *)header);
void *mbox_body = MBOX_BODY_FROM_HDR(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; u16 src_func_idx;
struct hinic_mbox_work *mbox_work; struct hinic_mbox_work *mbox_work;
int pos; int pos;
...@@ -756,43 +756,34 @@ static void recv_mbox_handler(struct hinic_mbox_func_to_func *func_to_func, ...@@ -756,43 +756,34 @@ static void recv_mbox_handler(struct hinic_mbox_func_to_func *func_to_func,
return; return;
} }
if (recv_mbox->ack_type == MBOX_NO_ACK) { rcv_mbox_temp = kzalloc(sizeof(*rcv_mbox_temp), GFP_KERNEL);
asyc_rcv_mbox = kzalloc(sizeof(*asyc_rcv_mbox), GFP_KERNEL); if (!rcv_mbox_temp) {
if (!asyc_rcv_mbox) { sdk_err(func_to_func->hwdev->dev_hdl, "Allocate receive mbox memory failed.\n");
sdk_err(func_to_func->hwdev->dev_hdl, "Allocate asynchronous receive mbox memory failed.\n"); return;
return; }
} memcpy(rcv_mbox_temp, recv_mbox, sizeof(*rcv_mbox_temp));
memcpy(asyc_rcv_mbox, recv_mbox, sizeof(*asyc_rcv_mbox));
asyc_rcv_mbox->mbox = kzalloc(MBOX_MAX_BUF_SZ, GFP_KERNEL); rcv_mbox_temp->mbox = kzalloc(MBOX_MAX_BUF_SZ, GFP_KERNEL);
if (!asyc_rcv_mbox->mbox) { if (!rcv_mbox_temp->mbox) {
sdk_err(func_to_func->hwdev->dev_hdl, "Allocate asynchronous receive mbox message memory failed.\n"); sdk_err(func_to_func->hwdev->dev_hdl, "Allocate receive mbox message memory failed.\n");
goto asyc_rcv_mbox_msg_err; goto rcv_mbox_msg_err;
} }
memcpy(asyc_rcv_mbox->mbox, recv_mbox->mbox, MBOX_MAX_BUF_SZ); memcpy(rcv_mbox_temp->mbox, recv_mbox->mbox, MBOX_MAX_BUF_SZ);
asyc_rcv_mbox->buf_out = kzalloc(MBOX_MAX_BUF_SZ, GFP_KERNEL); rcv_mbox_temp->buf_out = kzalloc(MBOX_MAX_BUF_SZ, GFP_KERNEL);
if (!asyc_rcv_mbox->buf_out) { if (!rcv_mbox_temp->buf_out) {
sdk_err(func_to_func->hwdev->dev_hdl, "Allocate asynchronous receive mbox out buffer memory failed.\n"); sdk_err(func_to_func->hwdev->dev_hdl, "Allocate receive mbox out buffer memory failed.\n");
goto asyc_rcv_mbox_buf_err; goto rcv_mbox_buf_err;
}
} }
mbox_work = kzalloc(sizeof(*mbox_work), GFP_KERNEL); mbox_work = kzalloc(sizeof(*mbox_work), GFP_KERNEL);
if (!mbox_work) { if (!mbox_work) {
sdk_err(func_to_func->hwdev->dev_hdl, "Allocate mbox work memory failed.\n"); 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;
goto mbox_work_err;
else
return;
} }
mbox_work->func_to_func = func_to_func; mbox_work->func_to_func = func_to_func;
mbox_work->recv_mbox = rcv_mbox_temp;
if (recv_mbox->ack_type == MBOX_NO_ACK)
mbox_work->recv_mbox = asyc_rcv_mbox;
else
mbox_work->recv_mbox = recv_mbox;
mbox_work->src_func_idx = src_func_idx; mbox_work->src_func_idx = src_func_idx;
INIT_WORK(&mbox_work->work, recv_func_mbox_work_handler); 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, ...@@ -801,13 +792,13 @@ static void recv_mbox_handler(struct hinic_mbox_func_to_func *func_to_func,
return; return;
mbox_work_err: mbox_work_err:
kfree(asyc_rcv_mbox->buf_out); kfree(rcv_mbox_temp->buf_out);
asyc_rcv_mbox_buf_err: rcv_mbox_buf_err:
kfree(asyc_rcv_mbox->mbox); kfree(rcv_mbox_temp->mbox);
asyc_rcv_mbox_msg_err: rcv_mbox_msg_err:
kfree(asyc_rcv_mbox); kfree(rcv_mbox_temp);
} }
int set_vf_mbox_random_id(struct hinic_hwdev *hwdev, u16 func_id) 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, ...@@ -978,6 +969,13 @@ static void mbox_copy_send_data(struct hinic_hwdev *hwdev,
u32 *data = seg; u32 *data = seg;
u32 data_len, chk_sz = sizeof(u32); u32 data_len, chk_sz = sizeof(u32);
u32 i, idx_max; 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; data_len = seg_len;
idx_max = ALIGN(data_len, chk_sz) / chk_sz; 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, ...@@ -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; struct hinic_hwdev *hwdev = func_to_func->hwdev;
int err = 0; int err = 0;
int seq_id = 0; u32 seq_id = 0;
u16 seg_len = MBOX_SEG_LEN; u16 seg_len = MBOX_SEG_LEN;
u16 left = msg_len; u16 left = msg_len;
u8 *msg_seg = (u8 *)msg; u8 *msg_seg = (u8 *)msg;
...@@ -1143,7 +1141,7 @@ static int send_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func, ...@@ -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 */ /* 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->msg_id, MSG_ID) |
HINIC_MBOX_HEADER_SET(msg_info->status, STATUS) | 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); SRC_GLB_FUNC_IDX);
while (!(HINIC_MBOX_HEADER_GET(header, LAST))) { while (!(HINIC_MBOX_HEADER_GET(header, LAST))) {
...@@ -1335,10 +1333,16 @@ int hinic_mbox_to_pf(struct hinic_hwdev *hwdev, ...@@ -1335,10 +1333,16 @@ int hinic_mbox_to_pf(struct hinic_hwdev *hwdev,
return -EINVAL; return -EINVAL;
} }
err = hinic_func_own_get(hwdev);
if (err)
return err;
/* port_to_port_idx - imply which PCIE interface PF is connected */ /* port_to_port_idx - imply which PCIE interface PF is connected */
return hinic_mbox_to_func(func_to_func, mod, cmd, err = hinic_mbox_to_func(func_to_func, mod, cmd,
hinic_pf_id_of_vf(hwdev), buf_in, in_size, hinic_pf_id_of_vf_hw(hwdev), buf_in, in_size,
buf_out, out_size, timeout); 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, 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, ...@@ -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, int hinic_mbox_to_pf_no_ack(struct hinic_hwdev *hwdev, enum hinic_mod_type mod,
u8 cmd, void *buf_in, u16 in_size) u8 cmd, void *buf_in, u16 in_size)
{ {
return hinic_mbox_to_func_no_ack(hwdev, hinic_pf_id_of_vf(hwdev), mod, int err;
cmd, buf_in, in_size);
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, int __hinic_mbox_to_vf(void *hwdev,
...@@ -1409,9 +1421,8 @@ 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, int hinic_mbox_ppf_to_vf(void *hwdev,
enum hinic_mod_type mod, u16 func_id, u8 cmd, enum hinic_mod_type mod, u16 func_id, u8 cmd, void *buf_in,
void *buf_in, u16 in_size, void *buf_out, u16 in_size, void *buf_out, u16 *out_size, u32 timeout)
u16 *out_size, u32 timeout)
{ {
struct hinic_mbox_func_to_func *func_to_func; struct hinic_mbox_func_to_func *func_to_func;
int err; int err;
...@@ -1581,8 +1592,7 @@ int hinic_vf_mbox_random_id_init(struct hinic_hwdev *hwdev) ...@@ -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++) { for (vf_in_pf = 1; vf_in_pf <= hinic_func_max_vf(hwdev); vf_in_pf++) {
err = set_vf_mbox_random_id(hwdev, err = set_vf_mbox_random_id(hwdev,
(hinic_glb_pf_vf_offset(hwdev) + (hinic_glb_pf_vf_offset(hwdev) + vf_in_pf));
vf_in_pf));
if (err) if (err)
break; break;
} }
...@@ -1656,6 +1666,9 @@ int hinic_func_to_func_init(struct hinic_hwdev *hwdev) ...@@ -1656,6 +1666,9 @@ int hinic_func_to_func_init(struct hinic_hwdev *hwdev)
destroy_workqueue(func_to_func->workq); destroy_workqueue(func_to_func->workq);
create_mbox_workq_err: 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); kfree(func_to_func);
return err; return err;
...@@ -1671,9 +1684,7 @@ void hinic_func_to_func_free(struct hinic_hwdev *hwdev) ...@@ -1671,9 +1684,7 @@ void hinic_func_to_func_free(struct hinic_hwdev *hwdev)
destroy_workqueue(func_to_func->workq); destroy_workqueue(func_to_func->workq);
free_mbox_wb_status(func_to_func); free_mbox_wb_status(func_to_func);
free_mbox_info(func_to_func->mbox_resp); free_mbox_info(func_to_func->mbox_resp);
free_mbox_info(func_to_func->mbox_send); free_mbox_info(func_to_func->mbox_send);
spin_lock_deinit(&func_to_func->mbox_lock); spin_lock_deinit(&func_to_func->mbox_lock);
sema_deinit(&func_to_func->mbox_send_sem); sema_deinit(&func_to_func->mbox_send_sem);
......
...@@ -215,12 +215,12 @@ int hinic_mbox_to_pf_no_ack(struct hinic_hwdev *hwdev, enum hinic_mod_type mod, ...@@ -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, int hinic_mbox_ppf_to_pf(struct hinic_hwdev *hwdev, enum hinic_mod_type mod,
u16 dst_pf_id, u8 cmd, u16 dst_pf_id, u8 cmd,
void *buf_in, u16 in_size, void *buf_out, void *buf_in, u16 in_size, void *buf_out,
u16 *out_size, u32 timeout); u16 *out_size, u32 timeout);
int hinic_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func, int hinic_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func,
enum hinic_mod_type mod, u16 cmd, u16 dst_func, enum hinic_mod_type mod, u16 cmd, u16 dst_func,
void *buf_in, u16 in_size, void *buf_out, void *buf_in, u16 in_size, void *buf_out,
u16 *out_size, u32 timeout); u16 *out_size, u32 timeout);
int __hinic_mbox_to_vf(void *hwdev, int __hinic_mbox_to_vf(void *hwdev,
enum hinic_mod_type mod, u16 vf_id, u8 cmd, void *buf_in, enum hinic_mod_type mod, u16 vf_id, u8 cmd, void *buf_in,
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include "hinic_hwif.h" #include "hinic_hwif.h"
#include "hinic_api_cmd.h" #include "hinic_api_cmd.h"
#include "hinic_mgmt.h" #include "hinic_mgmt.h"
#include "hinic_nic_cfg.h"
#include "hinic_mgmt_interface.h"
#include "hinic_eqs.h" #include "hinic_eqs.h"
#define BUF_OUT_DEFAULT_SIZE 1 #define BUF_OUT_DEFAULT_SIZE 1
...@@ -219,7 +221,7 @@ static u16 mgmt_msg_len(u16 msg_data_len) ...@@ -219,7 +221,7 @@ static u16 mgmt_msg_len(u16 msg_data_len)
* @msg_id: message id * @msg_id: message id
**/ **/
static void prepare_header(struct hinic_msg_pf_to_mgmt *pf_to_mgmt, 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_ack_type ack_type,
enum hinic_msg_direction_type direction, enum hinic_msg_direction_type direction,
enum hinic_mgmt_cmd cmd, u32 msg_id) 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, ...@@ -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, static void clp_prepare_header(struct hinic_hwdev *hwdev,
u64 *header, int msg_len, u64 *header, u16 msg_len, enum hinic_mod_type mod,
enum hinic_mod_type mod, enum hinic_msg_ack_type ack_type,
enum hinic_msg_ack_type ack_type, enum hinic_msg_direction_type direction,
enum hinic_msg_direction_type direction, enum hinic_mgmt_cmd cmd, u32 msg_id)
enum hinic_mgmt_cmd cmd, u32 msg_id)
{ {
struct hinic_hwif *hwif = hwdev->hwif; struct hinic_hwif *hwif = hwdev->hwif;
...@@ -270,7 +271,7 @@ static void clp_prepare_header(struct hinic_hwdev *hwdev, ...@@ -270,7 +271,7 @@ static void clp_prepare_header(struct hinic_hwdev *hwdev,
* @msg: the data of the message * @msg: the data of the message
* @msg_len: the length 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) int msg_len)
{ {
memset(mgmt_cmd, 0, MGMT_MSG_RSVD_FOR_DEV); 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, ...@@ -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, int hinic_pf_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd,
void *buf_in, u16 in_size, void *buf_out, 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; struct hinic_msg_pf_to_mgmt *pf_to_mgmt;
void *dev = ((struct hinic_hwdev *)hwdev)->dev_hdl; void *dev = ((struct hinic_hwdev *)hwdev)->dev_hdl;
struct hinic_recv_msg *recv_msg; struct hinic_recv_msg *recv_msg;
struct hinic_msg_head *msg_head;
struct completion *recv_done; struct completion *recv_done;
ulong timeo; ulong timeo;
int err; int err;
ulong ret; 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; pf_to_mgmt = ((struct hinic_hwdev *)hwdev)->pf_to_mgmt;
/* Lock the sync_msg_buf */ /* Lock the sync_msg_buf */
...@@ -462,7 +472,7 @@ int hinic_pf_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd, ...@@ -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, 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; struct hinic_hwdev *dev = hwdev;
u32 offset; u32 offset;
...@@ -506,8 +516,8 @@ static int __get_clp_reg(void *hwdev, enum clp_data_type data_type, ...@@ -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, static int hinic_read_clp_reg(struct hinic_hwdev *hwdev,
enum clp_data_type data_type, enum clp_data_type data_type,
enum clp_reg_type reg_type, u32 *read_value) enum clp_reg_type reg_type, u32 *read_value)
{ {
int err; int err;
u32 reg_addr, reg_value; u32 reg_addr, reg_value;
...@@ -636,7 +646,7 @@ static void hinic_write_clp_reg(struct hinic_hwdev *hwdev, ...@@ -636,7 +646,7 @@ static void hinic_write_clp_reg(struct hinic_hwdev *hwdev,
} }
static int hinic_read_clp_data(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; int err;
u32 reg = HINIC_CLP_DATA(RSP); u32 reg = HINIC_CLP_DATA(RSP);
...@@ -762,7 +772,7 @@ static int hinic_check_clp_init_status(struct hinic_hwdev *hwdev) ...@@ -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, 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) ? u32 reg = (data_type == HINIC_CLP_REQ_HOST) ?
HINIC_CLP_DATA(REQ) : HINIC_CLP_DATA(RSP); HINIC_CLP_DATA(REQ) : HINIC_CLP_DATA(RSP);
...@@ -775,8 +785,8 @@ static void hinic_clear_clp_data(struct hinic_hwdev *hwdev, ...@@ -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, int hinic_pf_clp_to_mgmt(void *hwdev, enum hinic_mod_type mod, u8 cmd,
void *buf_in, u16 in_size, const void *buf_in, u16 in_size,
void *buf_out, u16 *out_size) void *buf_out, u16 *out_size)
{ {
struct hinic_clp_pf_to_mgmt *clp_pf_to_mgmt; struct hinic_clp_pf_to_mgmt *clp_pf_to_mgmt;
struct hinic_hwdev *dev = hwdev; struct hinic_hwdev *dev = hwdev;
...@@ -1004,7 +1014,7 @@ static void mgmt_recv_msg_handler(struct hinic_msg_pf_to_mgmt *pf_to_mgmt, ...@@ -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] || if (!pf_to_mgmt->recv_mgmt_msg_cb[mod] ||
!test_bit(HINIC_MGMT_MSG_CB_REG, !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", sdk_warn(dev, "Receive mgmt callback is null, mod = %d\n",
mod); mod);
clear_bit(HINIC_MGMT_MSG_CB_RUNNING, 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, ...@@ -1093,7 +1103,6 @@ static bool check_mgmt_seq_id_and_seg_len(struct hinic_recv_msg *recv_msg,
} else { } else {
if (seq_id != recv_msg->seq_id + 1) if (seq_id != recv_msg->seq_id + 1)
return false; return false;
recv_msg->seq_id = seq_id; recv_msg->seq_id = seq_id;
} }
......
...@@ -57,7 +57,6 @@ enum clp_data_type { ...@@ -57,7 +57,6 @@ enum clp_data_type {
HINIC_CLP_REQ_HOST = 0, HINIC_CLP_REQ_HOST = 0,
HINIC_CLP_RSP_HOST = 1 HINIC_CLP_RSP_HOST = 1
}; };
enum clp_reg_type { enum clp_reg_type {
HINIC_CLP_BA_HOST = 0, HINIC_CLP_BA_HOST = 0,
HINIC_CLP_SIZE_HOST = 1, HINIC_CLP_SIZE_HOST = 1,
...@@ -65,7 +64,6 @@ enum clp_reg_type { ...@@ -65,7 +64,6 @@ enum clp_reg_type {
HINIC_CLP_START_REQ_HOST = 3, HINIC_CLP_START_REQ_HOST = 3,
HINIC_CLP_READY_RSP_HOST = 4 HINIC_CLP_READY_RSP_HOST = 4
}; };
#define HINIC_CLP_REG_GAP (0x20) #define HINIC_CLP_REG_GAP (0x20)
#define HINIC_CLP_INPUT_BUFFER_LEN_HOST (2048UL) #define HINIC_CLP_INPUT_BUFFER_LEN_HOST (2048UL)
#define HINIC_CLP_OUTPUT_BUFFER_LEN_HOST (2048UL) #define HINIC_CLP_OUTPUT_BUFFER_LEN_HOST (2048UL)
...@@ -202,7 +200,7 @@ struct hinic_msg_pf_to_mgmt { ...@@ -202,7 +200,7 @@ struct hinic_msg_pf_to_mgmt {
struct comm_up_self_msg_info proc; struct comm_up_self_msg_info proc;
/* spinlock when sending msg */ /* lock when sending msg */
spinlock_t sync_event_lock; spinlock_t sync_event_lock;
enum comm_pf_to_mgmt_event_state event_flag; 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, ...@@ -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); u8 cmd, void *buf_in, u16 in_size);
int hinic_pf_clp_to_mgmt(void *hwdev, enum hinic_mod_type mod, u8 cmd, int hinic_pf_clp_to_mgmt(void *hwdev, enum hinic_mod_type mod, u8 cmd,
void *buf_in, u16 in_size, const void *buf_in, u16 in_size,
void *buf_out, u16 *out_size); void *buf_out, u16 *out_size);
int hinic_clp_pf_to_mgmt_init(struct hinic_hwdev *hwdev); int hinic_clp_pf_to_mgmt_init(struct hinic_hwdev *hwdev);
void hinic_clp_pf_to_mgmt_free(struct hinic_hwdev *hwdev); void hinic_clp_pf_to_mgmt_free(struct hinic_hwdev *hwdev);
......
...@@ -24,6 +24,13 @@ ...@@ -24,6 +24,13 @@
/* up to driver event */ /* up to driver event */
#define HINIC_PORT_CMD_MGMT_RESET 0x0 #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 { struct hinic_register_vf {
u8 status; u8 status;
u8 version; u8 version;
...@@ -909,12 +916,10 @@ struct hinic_link_ksettings_info { ...@@ -909,12 +916,10 @@ struct hinic_link_ksettings_info {
u8 fec; /* 0 - RSFEC; 1 - BASEFEC; 2 - NOFEC */ u8 fec; /* 0 - RSFEC; 1 - BASEFEC; 2 - NOFEC */
u8 rsvd2[18]; /* reserved for duplex, port, etc. */ u8 rsvd2[18]; /* reserved for duplex, port, etc. */
}; };
enum hinic_tx_promsic { enum hinic_tx_promsic {
HINIC_TX_PROMISC_ENABLE = 0, HINIC_TX_PROMISC_ENABLE = 0,
HINIC_TX_PROMISC_DISABLE = 1, HINIC_TX_PROMISC_DISABLE = 1,
}; };
struct hinic_promsic_info { struct hinic_promsic_info {
u8 status; u8 status;
u8 version; u8 version;
......
...@@ -63,18 +63,20 @@ void set_slave_host_enable(struct hinic_hwdev *hwdev, u8 host_id, bool enable) ...@@ -63,18 +63,20 @@ void set_slave_host_enable(struct hinic_hwdev *hwdev, u8 host_id, bool enable)
host_id, enable, reg_val); 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; u32 reg_val;
struct hinic_hwdev *dev = hwdev;
if (HINIC_FUNC_TYPE(hwdev) != TYPE_PPF) if (HINIC_FUNC_TYPE(dev) != TYPE_PPF)
return false; return false;
reg_val = hinic_hwif_read_reg(hwdev->hwif, reg_val = hinic_hwif_read_reg(dev->hwif,
HINIC_MULT_HOST_SLAVE_STATUS_ADDR); HINIC_MULT_HOST_SLAVE_STATUS_ADDR);
return SLAVE_HOST_STATUS_GET(host_id, reg_val); 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) 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) ...@@ -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) int rectify_host_mode(struct hinic_hwdev *hwdev)
{ {
u16 cur_sdi_mode; u16 cur_sdi_mode;
...@@ -304,7 +316,7 @@ int sw_func_pf_mbox_handler(void *handle, u16 vf_id, u8 cmd, void *buf_in, ...@@ -304,7 +316,7 @@ int sw_func_pf_mbox_handler(void *handle, u16 vf_id, u8 cmd, void *buf_in,
int err; int err;
switch (cmd) { switch (cmd) {
case HINIC_SW_GET_SLAVE_FUNC_NIC_STATE: case HINIC_SW_CMD_GET_SLAVE_FUNC_NIC_STATE:
nic_state = buf_in; nic_state = buf_in;
out_state = buf_out; out_state = buf_out;
*out_size = sizeof(*nic_state); *out_size = sizeof(*nic_state);
...@@ -416,8 +428,7 @@ static int multi_host_event_handler(struct hinic_hwdev *hwdev, ...@@ -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, static int sw_fwd_msg_to_vf(struct hinic_hwdev *hwdev,
void *buf_in, u16 in_size, void *buf_in, u16 in_size, void *buf_out, u16 *out_size)
void *buf_out, u16 *out_size)
{ {
struct hinic_host_fwd_head *fwd_head; struct hinic_host_fwd_head *fwd_head;
u16 fwd_head_len; u16 fwd_head_len;
...@@ -428,9 +439,9 @@ static int sw_fwd_msg_to_vf(struct hinic_hwdev *hwdev, ...@@ -428,9 +439,9 @@ static int sw_fwd_msg_to_vf(struct hinic_hwdev *hwdev,
fwd_head_len = sizeof(struct hinic_host_fwd_head); fwd_head_len = sizeof(struct hinic_host_fwd_head);
msg = (void *)((u8 *)buf_in + fwd_head_len); msg = (void *)((u8 *)buf_in + fwd_head_len);
err = hinic_mbox_ppf_to_vf(hwdev, fwd_head->mod, err = hinic_mbox_ppf_to_vf(hwdev, fwd_head->mod,
fwd_head->dst_glb_func_idx, fwd_head->cmd, fwd_head->dst_glb_func_idx, fwd_head->cmd,
msg, (in_size - fwd_head_len), msg, (in_size - fwd_head_len),
buf_out, out_size, 0); buf_out, out_size, 0);
if (err) if (err)
nic_err(hwdev->dev_hdl, nic_err(hwdev->dev_hdl,
"Fwd msg to func %u failed, err: %d\n", "Fwd msg to func %u failed, err: %d\n",
...@@ -438,7 +449,6 @@ static int sw_fwd_msg_to_vf(struct hinic_hwdev *hwdev, ...@@ -438,7 +449,6 @@ static int sw_fwd_msg_to_vf(struct hinic_hwdev *hwdev,
return err; return err;
} }
static int __slave_host_sw_func_handler(struct hinic_hwdev *hwdev, u16 pf_idx, static int __slave_host_sw_func_handler(struct hinic_hwdev *hwdev, u16 pf_idx,
u8 cmd, void *buf_in, u16 in_size, u8 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_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, ...@@ -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: case HINIC_SW_CMD_SEND_MSG_TO_VF:
err = sw_fwd_msg_to_vf(hwdev, buf_in, in_size, err = sw_fwd_msg_to_vf(hwdev, buf_in, in_size,
buf_out, out_size); buf_out, out_size);
break; break;
case HINIC_SW_CMD_MIGRATE_READY:
hinic_migrate_report(hwdev);
break;
default: default:
err = -EINVAL; err = -EINVAL;
break; break;
...@@ -515,8 +528,7 @@ int __ppf_process_mbox_msg(struct hinic_hwdev *hwdev, u16 pf_idx, u16 vf_id, ...@@ -515,8 +528,7 @@ int __ppf_process_mbox_msg(struct hinic_hwdev *hwdev, u16 pf_idx, u16 vf_id,
if (IS_SLAVE_HOST(hwdev)) { if (IS_SLAVE_HOST(hwdev)) {
err = hinic_mbox_to_host_sync(hwdev, mod, cmd, err = hinic_mbox_to_host_sync(hwdev, mod, cmd,
buf_in, in_size, buf_out, buf_in, in_size, buf_out, out_size, 0);
out_size, 0);
if (err) if (err)
sdk_err(hwdev->dev_hdl, "send to mpf failed, err: %d\n", sdk_err(hwdev->dev_hdl, "send to mpf failed, err: %d\n",
err); err);
...@@ -751,7 +763,7 @@ int hinic_set_func_nic_state(void *hwdev, struct hinic_func_nic_state *state) ...@@ -751,7 +763,7 @@ int hinic_set_func_nic_state(void *hwdev, struct hinic_func_nic_state *state)
return -EFAULT; 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", sdk_info(ppf_hwdev->dev_hdl, "Set slave host %d(status: %d) func %d %s nic\n",
host_id, host_enable, host_id, host_enable,
state->func_idx, state->state ? "enable" : "disable"); 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) ...@@ -801,18 +813,23 @@ int hinic_get_func_nic_enable(void *hwdev, u16 glb_func_idx, bool *en)
if (!hwdev || !en) if (!hwdev || !en)
return -EINVAL; return -EINVAL;
/*if card mode is OVS, VFs donot need attach_uld, so return false.*/
if (!IS_SLAVE_HOST((struct hinic_hwdev *)hwdev)) { 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; return 0;
} }
if (hinic_func_type(hwdev) == TYPE_VF) { if (hinic_func_type(hwdev) == TYPE_VF) {
nic_state.func_idx = glb_func_idx; nic_state.func_idx = glb_func_idx;
err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_SW_FUNC, err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_SW_FUNC,
HINIC_SW_GET_SLAVE_FUNC_NIC_STATE, HINIC_SW_CMD_GET_SLAVE_FUNC_NIC_STATE,
&nic_state, sizeof(nic_state), &nic_state, sizeof(nic_state),
&nic_state, &out_size, 0); &nic_state, &out_size, 0);
if (err || !out_size || nic_state.status) { 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", 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); glb_func_idx, err, out_size, nic_state.status);
...@@ -861,11 +878,16 @@ int hinic_multi_host_mgmt_init(struct hinic_hwdev *hwdev) ...@@ -861,11 +878,16 @@ int hinic_multi_host_mgmt_init(struct hinic_hwdev *hwdev)
/* master ppf idx fix to 0 */ /* master ppf idx fix to 0 */
hwdev->mhost_mgmt->mhost_ppf_idx = 0; hwdev->mhost_mgmt->mhost_ppf_idx = 0;
/* fix slave host ppf 6 and host 2 in bmwg mode if (IS_BMGW_MASTER_HOST(hwdev) || IS_BMGW_SLAVE_HOST(hwdev)) {
* TODO: get ppf_idx and host_idx according to pf_infos /* 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; 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, hinic_register_ppf_mbox_cb(hwdev, HINIC_MOD_COMM,
comm_ppf_mbox_handler); comm_ppf_mbox_handler);
...@@ -885,10 +907,16 @@ int hinic_multi_host_mgmt_init(struct hinic_hwdev *hwdev) ...@@ -885,10 +907,16 @@ int hinic_multi_host_mgmt_init(struct hinic_hwdev *hwdev)
if (IS_SLAVE_HOST(hwdev)) { if (IS_SLAVE_HOST(hwdev)) {
/* PXE don't support to receive mbox from master host */ /* PXE don't support to receive mbox from master host */
set_slave_host_enable(hwdev, hinic_pcie_itf_id(hwdev), true); 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); 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; goto out_free_mhost_mgmt;
}
} }
} else { } else {
/* slave host can send message to mgmt cpu after setup master /* 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) ...@@ -912,8 +940,7 @@ int hinic_multi_host_mgmt_free(struct hinic_hwdev *hwdev)
return 0; return 0;
if (IS_SLAVE_HOST(hwdev)) { 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); set_slave_host_enable(hwdev, hinic_pcie_itf_id(hwdev), false);
} else { } else {
......
...@@ -41,6 +41,8 @@ struct hinic_rq { ...@@ -41,6 +41,8 @@ struct hinic_rq {
u32 irq_id; u32 irq_id;
u16 msix_entry_idx; u16 msix_entry_idx;
dma_addr_t cqe_dma_addr;
}; };
struct hinic_qp { struct hinic_qp {
......
...@@ -53,6 +53,8 @@ ...@@ -53,6 +53,8 @@
#define HINIC_LRO_RX_TIMER_DEFAULT_PG_100GE 8 #define HINIC_LRO_RX_TIMER_DEFAULT_PG_100GE 8
#define HINIC_LOWEST_LATENCY 1 #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_RATE_LOW 400000
#define HINIC_RX_COAL_TIME_LOW 20 #define HINIC_RX_COAL_TIME_LOW 20
#define HINIC_RX_PENDING_LIMIT_LOW 2 #define HINIC_RX_PENDING_LIMIT_LOW 2
...@@ -60,6 +62,7 @@ ...@@ -60,6 +62,7 @@
#define HINIC_RX_COAL_TIME_HIGH 225 #define HINIC_RX_COAL_TIME_HIGH 225
#define HINIC_RX_PENDING_LIMIT_HIGH 50 #define HINIC_RX_PENDING_LIMIT_HIGH 50
#define HINIC_RX_RATE_THRESH 35000 #define HINIC_RX_RATE_THRESH 35000
#define HINIC_TX_RATE_THRESH 35000
#define HINIC_RX_RATE_LOW_VM 400000 #define HINIC_RX_RATE_LOW_VM 400000
#define HINIC_RX_PENDING_LIMIT_HIGH_VM 50 #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); ...@@ -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, int hinic_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac,
u16 vlan_id, u16 func_id); 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 */ /* Obtaining the permanent mac */
int hinic_get_default_mac(void *hwdev, u8 *mac_addr); int hinic_get_default_mac(void *hwdev, u8 *mac_addr);
/* Check whether the current solution is using this interface, /* 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); ...@@ -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_enable_netq(void *hwdev, u8 en);
int hinic_add_hw_rqfilter(void *hwdev, 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, int hinic_del_hw_rqfilter(void *hwdev,
struct hinic_rq_filter_info *filter_info); struct hinic_rq_filter_info *filter_info);
#endif #endif
...@@ -163,7 +163,7 @@ int hinic_dbg_get_sq_db_addr(void *hwdev, u16 q_id, u64 **map_addr, ...@@ -163,7 +163,7 @@ int hinic_dbg_get_sq_db_addr(void *hwdev, u16 q_id, u64 **map_addr,
return 0; return 0;
} }
u16 hinic_dbg_get_global_qpn(void *hwdev) u16 hinic_dbg_get_global_qpn(const void *hwdev)
{ {
if (!hwdev) if (!hwdev)
return 0; return 0;
...@@ -226,7 +226,7 @@ int hinic_dbg_get_rq_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt, ...@@ -226,7 +226,7 @@ int hinic_dbg_get_rq_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt,
return err; 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)) { if (*out_size != sizeof(struct hinic_hw_stats)) {
pr_err("Unexpect out buf size from user :%d, expect: %lu\n", pr_err("Unexpect out buf size from user :%d, expect: %lu\n",
...@@ -248,7 +248,8 @@ u16 hinic_dbg_clear_hw_stats(void *hwdev) ...@@ -248,7 +248,8 @@ u16 hinic_dbg_clear_hw_stats(void *hwdev)
return sizeof(struct hinic_hw_stats); 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; int copy_len = offset + MAX_DRV_BUF_SIZE - HINIC_CHIP_FAULT_SIZE;
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#define HINIC_DRV_NAME "hinic" #define HINIC_DRV_NAME "hinic"
#define HINIC_CHIP_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; struct vf_data_storage;
#define HINIC_FUNC_IS_VF(hwdev) (hinic_func_type(hwdev) == TYPE_VF) #define HINIC_FUNC_IS_VF(hwdev) (hinic_func_type(hwdev) == TYPE_VF)
...@@ -45,6 +45,7 @@ enum hinic_flags { ...@@ -45,6 +45,7 @@ enum hinic_flags {
HINIC_SAME_RXTX, HINIC_SAME_RXTX,
HINIC_INTR_ADAPT, HINIC_INTR_ADAPT,
HINIC_UPDATE_MAC_FILTER, HINIC_UPDATE_MAC_FILTER,
HINIC_ETS_ENABLE,
}; };
#define RX_BUFF_NUM_PER_PAGE 2 #define RX_BUFF_NUM_PER_PAGE 2
...@@ -135,9 +136,9 @@ struct hinic_intr_coal_info { ...@@ -135,9 +136,9 @@ struct hinic_intr_coal_info {
#define HINIC_NIC_STATS_INC(nic_dev, field) \ #define HINIC_NIC_STATS_INC(nic_dev, field) \
{ \ { \
u64_stats_update_begin(&(nic_dev)->stats.syncp); \ u64_stats_update_begin(&nic_dev->stats.syncp); \
(nic_dev)->stats.field++; \ nic_dev->stats.field++; \
u64_stats_update_end(&(nic_dev)->stats.syncp); \ u64_stats_update_end(&nic_dev->stats.syncp); \
} }
struct hinic_nic_stats { struct hinic_nic_stats {
...@@ -232,6 +233,7 @@ struct hinic_nic_dev { ...@@ -232,6 +233,7 @@ struct hinic_nic_dev {
u32 his_link_speed; u32 his_link_speed;
/* interrupt coalesce must be different in virtual machine */ /* interrupt coalesce must be different in virtual machine */
bool in_vm; bool in_vm;
bool is_vm_slave;
#ifndef HAVE_NETDEV_STATS_IN_NETDEV #ifndef HAVE_NETDEV_STATS_IN_NETDEV
struct net_device_stats net_stats; struct net_device_stats net_stats;
...@@ -275,12 +277,12 @@ int hinic_enable_func_rss(struct hinic_nic_dev *nic_dev); ...@@ -275,12 +277,12 @@ int hinic_enable_func_rss(struct hinic_nic_dev *nic_dev);
#define hinic_msg(level, nic_dev, msglvl, format, arg...) \ #define hinic_msg(level, nic_dev, msglvl, format, arg...) \
do { \ do { \
if ((nic_dev)->netdev && (nic_dev)->netdev->reg_state \ if (nic_dev->netdev && nic_dev->netdev->reg_state \
== NETREG_REGISTERED) \ == NETREG_REGISTERED) \
nicif_##level((nic_dev), msglvl, (nic_dev)->netdev, \ nicif_##level(nic_dev, msglvl, nic_dev->netdev, \
format, ## arg); \ format, ## arg); \
else \ else \
nic_##level(&(nic_dev)->pdev->dev, \ nic_##level(&nic_dev->pdev->dev, \
format, ## arg); \ format, ## arg); \
} while (0) } while (0)
......
...@@ -107,9 +107,15 @@ struct hinic_sq_db { ...@@ -107,9 +107,15 @@ struct hinic_sq_db {
u32 db_info; u32 db_info;
}; };
struct hinic_addr {
u32 addr_hi;
u32 addr_lo;
};
struct hinic_clean_queue_ctxt { struct hinic_clean_queue_ctxt {
struct hinic_qp_ctxt_header cmdq_hdr; struct hinic_qp_ctxt_header cmdq_hdr;
u32 ctxt_size; 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, 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, ...@@ -131,6 +137,7 @@ static int init_rq(struct hinic_rq *rq, void *dev_hdl, struct hinic_wq *wq,
{ {
rq->wq = wq; rq->wq = wq;
rq->q_id = q_id; rq->q_id = q_id;
rq->cqe_dma_addr = 0;
rq->msix_entry_idx = rq_msix_idx; 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, ...@@ -144,6 +151,15 @@ static int init_rq(struct hinic_rq *rq, void *dev_hdl, struct hinic_wq *wq,
return 0; 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) static void clean_rq(struct hinic_rq *rq, void *dev_hdl)
{ {
dma_free_coherent(dev_hdl, PAGE_SIZE, rq->pi_virt_addr, 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, ...@@ -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_hwdev *hwdev = nic_io->hwdev;
struct hinic_clean_queue_ctxt *ctxt_block; struct hinic_clean_queue_ctxt *ctxt_block;
struct hinic_cmd_buf *cmd_buf; struct hinic_cmd_buf *cmd_buf;
dma_addr_t cqe_dma_addr;
struct hinic_addr *addr;
u64 out_param = 0; u64 out_param = 0;
int err; int i, err;
cmd_buf = hinic_alloc_cmd_buf(hwdev); cmd_buf = hinic_alloc_cmd_buf(hwdev);
if (!cmd_buf) { if (!cmd_buf) {
...@@ -640,6 +658,15 @@ static int clean_queue_offload_ctxt(struct hinic_nic_io *nic_io, ...@@ -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 */ /* TSO/LRO ctxt size: 0x0:0B; 0x1:160B; 0x2:200B; 0x3:240B */
ctxt_block->ctxt_size = 0x3; 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)); hinic_cpu_to_be32(ctxt_block, sizeof(*ctxt_block));
...@@ -725,6 +752,7 @@ int hinic_init_qp_ctxts(void *dev) ...@@ -725,6 +752,7 @@ int hinic_init_qp_ctxts(void *dev)
return err; return err;
} }
EXPORT_SYMBOL(hinic_init_qp_ctxts);
void hinic_free_qp_ctxts(void *hwdev) void hinic_free_qp_ctxts(void *hwdev)
{ {
...@@ -791,6 +819,7 @@ int hinic_init_nic_hwdev(void *hwdev, u16 rx_buff_len) ...@@ -791,6 +819,7 @@ int hinic_init_nic_hwdev(void *hwdev, u16 rx_buff_len)
} }
return 0; return 0;
} }
EXPORT_SYMBOL(hinic_init_nic_hwdev);
void hinic_free_nic_hwdev(void *hwdev) void hinic_free_nic_hwdev(void *hwdev)
{ {
......
...@@ -93,4 +93,7 @@ void hinic_be32_to_cpu(void *data, int len); ...@@ -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); 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); 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 #endif
...@@ -74,6 +74,50 @@ struct up_cmd_st { ...@@ -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_CMD 0x1
#define API_CHAIN 0x2 #define API_CHAIN 0x2
#define API_CLP 0x3 #define API_CLP 0x3
...@@ -209,8 +253,8 @@ struct hinic_card_func_info { ...@@ -209,8 +253,8 @@ struct hinic_card_func_info {
extern void *g_card_node_array[MAX_CARD_NUM]; extern void *g_card_node_array[MAX_CARD_NUM];
extern void *g_card_vir_addr[MAX_CARD_NUM]; extern void *g_card_vir_addr[MAX_CARD_NUM];
extern u64 g_card_phy_addr[MAX_CARD_NUM]; extern u64 g_card_phy_addr[MAX_CARD_NUM];
extern int card_id;
extern struct mutex g_addr_lock; extern struct mutex g_addr_lock;
extern int card_id;
struct hinic_nic_loop_mode { struct hinic_nic_loop_mode {
u32 loop_mode; u32 loop_mode;
...@@ -237,6 +281,7 @@ struct hinic_pf_info { ...@@ -237,6 +281,7 @@ struct hinic_pf_info {
int nictool_k_init(void); int nictool_k_init(void);
void nictool_k_uninit(void); void nictool_k_uninit(void);
extern u32 hinic_get_io_stats_size(struct hinic_nic_dev *nic_dev); 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, extern void hinic_get_io_stats(struct hinic_nic_dev *nic_dev,
struct hinic_show_item *items); struct hinic_show_item *items);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define HINIC_DEV_ID_1822_PANGEA_TP_10GE 0x0204 #define HINIC_DEV_ID_1822_PANGEA_TP_10GE 0x0204
#define HINIC_DEV_ID_1822_KR_40GE 0x020D #define HINIC_DEV_ID_1822_KR_40GE 0x020D
#define HINIC_DEV_ID_1822_KR_100GE 0x0205 #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_KR_25GE 0x0210
#define HINIC_DEV_ID_1822_MULTI_HOST 0x0211 #define HINIC_DEV_ID_1822_MULTI_HOST 0x0211
#define HINIC_DEV_ID_1822_100GE 0x0200 #define HINIC_DEV_ID_1822_100GE 0x0200
......
/* SPDX-License-Identifier: GPL-2.0*/ /* 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__ #ifndef __HINIC_PORT_CMD_H__
#define __HINIC_PORT_CMD_H__ #define __HINIC_PORT_CMD_H__
...@@ -225,7 +210,7 @@ enum hinic_mgmt_cmd { ...@@ -225,7 +210,7 @@ enum hinic_mgmt_cmd {
HINIC_MGMT_CMD_MQM_FIX_INFO_GET = 0x16, HINIC_MGMT_CMD_MQM_FIX_INFO_GET = 0x16,
HINIC_MGMT_CMD_MQM_CFG_INFO_SET = 0x18, 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_TMR_SET = 0x22,
HINIC_MGMT_CMD_PPF_HT_GPA_SET = 0x23, HINIC_MGMT_CMD_PPF_HT_GPA_SET = 0x23,
HINIC_MGMT_CMD_RES_STATE_SET = 0x24, HINIC_MGMT_CMD_RES_STATE_SET = 0x24,
...@@ -276,9 +261,11 @@ enum hinic_mgmt_cmd { ...@@ -276,9 +261,11 @@ enum hinic_mgmt_cmd {
HINIC_MGMT_CMD_GET_PHY_INIT_STATUS = 0x6A, HINIC_MGMT_CMD_GET_PHY_INIT_STATUS = 0x6A,
HINIC_MGMT_CMD_HEARTBEAT_SUPPORTED = 0x6B, 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_HW_PF_INFOS = 0x6D,
HINIC_MGMT_CMD_GET_SDI_MODE = 0x6E, HINIC_MGMT_CMD_GET_SDI_MODE = 0x6E,
HINIC_MGMT_CMD_ENABLE_MIGRATE = 0x6F,
}; };
/* uCode relates commands */ /* uCode relates commands */
...@@ -299,9 +286,10 @@ enum hinic_ucode_cmd { ...@@ -299,9 +286,10 @@ enum hinic_ucode_cmd {
enum hinic_sw_funcs_cmd { enum hinic_sw_funcs_cmd {
HINIC_SW_CMD_SLAVE_HOST_PPF_REGISTER = 0x0, HINIC_SW_CMD_SLAVE_HOST_PPF_REGISTER = 0x0,
HINIC_SW_CMD_SLAVE_HOST_PPF_UNREGISTER = 0x1, 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_SET_SLAVE_FUNC_NIC_STATE = 0x3,
HINIC_SW_CMD_SEND_MSG_TO_VF = 0x4, HINIC_SW_CMD_SEND_MSG_TO_VF = 0x4,
HINIC_SW_CMD_MIGRATE_READY = 0x5,
}; };
enum sq_l4offload_type { enum sq_l4offload_type {
......
...@@ -155,17 +155,17 @@ extern "C"{ ...@@ -155,17 +155,17 @@ extern "C"{
SQ_TASK_INFO4_##member##_SHIFT) SQ_TASK_INFO4_##member##_SHIFT)
/********************* SQ_DB *********************/ /********************* SQ_DB *********************/
#define SQ_DB_OFF 0x00000800 #define SQ_DB_OFF 0x00000800
#define SQ_DB_INFO_HI_PI_SHIFT 0 #define SQ_DB_INFO_HI_PI_SHIFT 0
#define SQ_DB_INFO_QID_SHIFT 8 #define SQ_DB_INFO_QID_SHIFT 8
#define SQ_DB_INFO_CFLAG_SHIFT 23 #define SQ_DB_INFO_CFLAG_SHIFT 23
#define SQ_DB_INFO_COS_SHIFT 24 #define SQ_DB_INFO_COS_SHIFT 24
#define SQ_DB_INFO_TYPE_SHIFT 27 #define SQ_DB_INFO_TYPE_SHIFT 27
#define SQ_DB_INFO_HI_PI_MASK 0xFFU #define SQ_DB_INFO_HI_PI_MASK 0xFFU
#define SQ_DB_INFO_QID_MASK 0x3FFU #define SQ_DB_INFO_QID_MASK 0x3FFU
#define SQ_DB_INFO_CFLAG_MASK 0x1U #define SQ_DB_INFO_CFLAG_MASK 0x1U
#define SQ_DB_INFO_COS_MASK 0x7U #define SQ_DB_INFO_COS_MASK 0x7U
#define SQ_DB_INFO_TYPE_MASK 0x1FU #define SQ_DB_INFO_TYPE_MASK 0x1FU
#define SQ_DB_INFO_SET(val, member) (((u32)(val) & \ #define SQ_DB_INFO_SET(val, member) (((u32)(val) & \
SQ_DB_INFO_##member##_MASK) << \ SQ_DB_INFO_##member##_MASK) << \
SQ_DB_INFO_##member##_SHIFT) SQ_DB_INFO_##member##_SHIFT)
...@@ -174,21 +174,21 @@ extern "C"{ ...@@ -174,21 +174,21 @@ extern "C"{
#define SQ_DB_PI_LOW(pi) ((pi) & SQ_DB_PI_LOW_MASK) #define SQ_DB_PI_LOW(pi) ((pi) & SQ_DB_PI_LOW_MASK)
#define SQ_DB_PI_HI_SHIFT 8 #define SQ_DB_PI_HI_SHIFT 8
#define SQ_DB_PI_HIGH(pi) ((pi) >> SQ_DB_PI_HI_SHIFT) #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) + \ #define SQ_DB_ADDR(sq, pi) ((u64 *)((sq)->db_addr + SQ_DB_OFF) + \
SQ_DB_PI_LOW(pi)) SQ_DB_PI_LOW(pi))
#define SQ_DB 1 #define SQ_DB 1
#define SQ_CFLAG_DP 0 #define SQ_CFLAG_DP 0 /* CFLAG_DATA_PATH */
/*********************** RQ_CTRL ******************/ /*********************** RQ_CTRL ******************/
#define RQ_CTRL_BUFDESC_SECT_LEN_SHIFT 0 #define RQ_CTRL_BUFDESC_SECT_LEN_SHIFT 0
#define RQ_CTRL_COMPLETE_FORMAT_SHIFT 15 #define RQ_CTRL_COMPLETE_FORMAT_SHIFT 15
#define RQ_CTRL_COMPLETE_LEN_SHIFT 27 #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_BUFDESC_SECT_LEN_MASK 0xFFU
#define RQ_CTRL_COMPLETE_FORMAT_MASK 0x1U #define RQ_CTRL_COMPLETE_FORMAT_MASK 0x1U
#define RQ_CTRL_COMPLETE_LEN_MASK 0x3U #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) & \ #define RQ_CTRL_SET(val, member) (((val) & \
RQ_CTRL_##member##_MASK) << \ RQ_CTRL_##member##_MASK) << \
...@@ -232,8 +232,8 @@ extern "C"{ ...@@ -232,8 +232,8 @@ extern "C"{
#define RQ_CQE_SGE_VLAN_SHIFT 0 #define RQ_CQE_SGE_VLAN_SHIFT 0
#define RQ_CQE_SGE_LEN_SHIFT 16 #define RQ_CQE_SGE_LEN_SHIFT 16
#define RQ_CQE_SGE_VLAN_MASK 0xFFFFU #define RQ_CQE_SGE_VLAN_MASK 0xFFFFU
#define RQ_CQE_SGE_LEN_MASK 0xFFFFU #define RQ_CQE_SGE_LEN_MASK 0xFFFFU
#define RQ_CQE_SGE_GET(val, member) (((val) >> \ #define RQ_CQE_SGE_GET(val, member) (((val) >> \
RQ_CQE_SGE_##member##_SHIFT) & \ RQ_CQE_SGE_##member##_SHIFT) & \
...@@ -313,10 +313,10 @@ extern "C"{ ...@@ -313,10 +313,10 @@ extern "C"{
#define WQS_PAGE_SIZE (WQS_BLOCKS_PER_PAGE * WQ_BLOCK_SIZE) #define WQS_PAGE_SIZE (WQS_BLOCKS_PER_PAGE * WQ_BLOCK_SIZE)
#define WQ_MAX_PAGES (WQ_BLOCK_SIZE >> WQ_PAGE_ADDR_SIZE_SHIFT) #define WQ_MAX_PAGES (WQ_BLOCK_SIZE >> WQ_PAGE_ADDR_SIZE_SHIFT)
#define CMDQ_BLOCKS_PER_PAGE 8 #define CMDQ_BLOCKS_PER_PAGE 8
#define CMDQ_BLOCK_SIZE 512UL #define CMDQ_BLOCK_SIZE 512UL
#define CMDQ_PAGE_SIZE ALIGN((CMDQ_BLOCKS_PER_PAGE * \ #define CMDQ_PAGE_SIZE ALIGN((CMDQ_BLOCKS_PER_PAGE * \
CMDQ_BLOCK_SIZE), PAGE_SIZE) CMDQ_BLOCK_SIZE), PAGE_SIZE)
#define ADDR_4K_ALIGNED(addr) (0 == ((addr) & 0xfff)) #define ADDR_4K_ALIGNED(addr) (0 == ((addr) & 0xfff))
#define ADDR_256K_ALIGNED(addr) (0 == ((addr) & 0x3ffff)) #define ADDR_256K_ALIGNED(addr) (0 == ((addr) & 0x3ffff))
...@@ -440,16 +440,16 @@ enum hinic_res_state { ...@@ -440,16 +440,16 @@ enum hinic_res_state {
((pkt_types) & RQ_CQE_PKT_TYPES_NON_L2_MASK) ((pkt_types) & RQ_CQE_PKT_TYPES_NON_L2_MASK)
#define HINIC_PKT_TYPES_L2(pkt_types) \ #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) \ #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) \ #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) \ #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_DEFAULT 0x3E00
#define TX_MSS_MIN 0x50 #define TX_MSS_MIN 0x50
......
/* // SPDX-License-Identifier: GPL-2.0
* Huawei HiNIC PCI Express Linux driver /* Huawei HiNIC PCI Express Linux driver
* Copyright(c) 2017 Huawei Technologies Co., Ltd * Copyright(c) 2017 Huawei Technologies Co., Ltd
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
...@@ -43,15 +43,14 @@ ...@@ -43,15 +43,14 @@
static void hinic_clear_rss_config_user(struct hinic_nic_dev *nic_dev); static void hinic_clear_rss_config_user(struct hinic_nic_dev *nic_dev);
#define HINIC_RX_HDR_SIZE 256 #define HINIC_RX_HDR_SIZE 256
#define HINIC_RX_BUFFER_WRITE 16
#define HINIC_RX_IPV6_PKT 7 #define HINIC_RX_IPV6_PKT 7
#define HINIC_RX_VXLAN_PKT 0xb #define HINIC_RX_VXLAN_PKT 0xb
#define RXQ_STATS_INC(rxq, field) \ #define RXQ_STATS_INC(rxq, field) \
{ \ { \
u64_stats_update_begin(&(rxq)->rxq_stats.syncp); \ u64_stats_update_begin(&rxq->rxq_stats.syncp); \
(rxq)->rxq_stats.field++; \ rxq->rxq_stats.field++; \
u64_stats_update_end(&(rxq)->rxq_stats.syncp); \ u64_stats_update_end(&rxq->rxq_stats.syncp); \
} }
static bool rx_alloc_mapped_page(struct hinic_rxq *rxq, static bool rx_alloc_mapped_page(struct hinic_rxq *rxq,
...@@ -770,6 +769,7 @@ static int rx_alloc_cqe(struct hinic_rxq *rxq) ...@@ -770,6 +769,7 @@ static int rx_alloc_cqe(struct hinic_rxq *rxq)
cqe_pa += sizeof(*rx_info->cqe); cqe_pa += sizeof(*rx_info->cqe);
} }
hinic_rq_cqe_addr_set(nic_dev->hwdev, rxq->q_id, rxq->cqe_start_paddr);
return 0; return 0;
} }
......
/* /* SPDX-License-Identifier: GPL-2.0*/
* Huawei HiNIC PCI Express Linux driver /* Huawei HiNIC PCI Express Linux driver
* Copyright(c) 2017 Huawei Technologies Co., Ltd * Copyright(c) 2017 Huawei Technologies Co., Ltd
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#define HINIC_RX_BP_UPPER_THD 400 #define HINIC_RX_BP_UPPER_THD 400
#define HINIC_SUPPORT_LRO_ADAP_QPS_MAX 16 #define HINIC_SUPPORT_LRO_ADAP_QPS_MAX 16
#define HINIC_RX_BUFFER_WRITE 16
enum { enum {
HINIC_RX_STATUS_BP_EN, HINIC_RX_STATUS_BP_EN,
......
/*SPDX-License-Identifier: GPL-2.0*/ /* SPDX-License-Identifier: GPL-2.0*/
/* Huawei HiNIC PCI Express Linux driver /* Huawei HiNIC PCI Express Linux driver
* Copyright(c) 2017 Huawei Technologies Co., Ltd * Copyright(c) 2017 Huawei Technologies Co., Ltd
* *
......
...@@ -28,11 +28,11 @@ ...@@ -28,11 +28,11 @@
| (((x) & 0xff000000) >> 24)) | (((x) & 0xff000000) >> 24))
#endif #endif
static void sml_ctr_htonl_n(u32 *node, u32 ullen) static void sml_ctr_htonl_n(u32 *node, u32 ulLen)
{ {
u32 i; u32 i;
for (i = 0; i < ullen; i++) { for (i = 0; i < ulLen; i++) {
*node = HTONL(*node); *node = HTONL(*node);
node++; node++;
} }
......
...@@ -310,6 +310,13 @@ int hinic_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) ...@@ -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)); 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: out:
return err; return err;
} }
...@@ -334,7 +341,7 @@ int hinic_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting) ...@@ -334,7 +341,7 @@ int hinic_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting)
return 0; return 0;
err = hinic_set_vf_spoofchk(sriov_info->hwdev, err = hinic_set_vf_spoofchk(sriov_info->hwdev,
OS_VF_ID_TO_HW(vf), setting); OS_VF_ID_TO_HW(vf), setting);
if (!err) { if (!err) {
nicif_info(adapter, drv, netdev, "Set VF %d spoofchk %s\n", 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) ...@@ -490,4 +497,6 @@ int hinic_ndo_set_vf_bw(struct net_device *netdev, int vf, int max_tx_rate)
#endif #endif
return 0; return 0;
} /*lint -restore*/ }
/*lint -restore*/
...@@ -663,7 +663,7 @@ void *hinic_read_wqe(struct hinic_wq *wq, int num_wqebbs, u16 *cons_idx) ...@@ -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); 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; void *end_wqe_shadow_addr;
u32 wqe_shadow_size = wq->num_q_pages * wq->max_wqe_size; u32 wqe_shadow_size = wq->num_q_pages * wq->max_wqe_size;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册