From: Prabhakar Kushwaha <pkushwaha@xxxxxxxxxxx> This patch add support of get or set priority value for a given dscp index. Signed-off-by: Shai Malin <smalin@xxxxxxxxxxx> Signed-off-by: Ariel Elior <aelior@xxxxxxxxxxx> Signed-off-by: Prabhakar Kushwaha <pkushwaha@xxxxxxxxxxx> --- Changes for v2: - incorporated Leon Romanovsky's comments drivers/net/ethernet/qlogic/qed/qed_dcbx.c | 64 ++++++++++++++++++++++ drivers/net/ethernet/qlogic/qed/qed_dcbx.h | 9 +++ include/linux/qed/qed_if.h | 6 ++ 3 files changed, 79 insertions(+) diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c index e81dd34a3cac..f9254e0fd624 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c @@ -1280,6 +1280,70 @@ int qed_dcbx_get_config_params(struct qed_hwfn *p_hwfn, return 0; } +int qed_dcbx_get_dscp_priority(struct qed_hwfn *p_hwfn, u8 dscp_index, + u8 *p_dscp_pri) +{ + struct qed_dcbx_get *p_dcbx_info; + int rc; + + if (IS_VF(p_hwfn->cdev)) { + DP_ERR(p_hwfn->cdev, + "qed rdma get dscp priority not supported for VF.\n"); + return -EINVAL; + } + + if (dscp_index >= QED_DCBX_DSCP_SIZE) { + DP_ERR(p_hwfn, "Invalid dscp index %d\n", dscp_index); + return -EINVAL; + } + + p_dcbx_info = kzalloc(sizeof(*p_dcbx_info), GFP_KERNEL); + if (!p_dcbx_info) + return -ENOMEM; + + rc = qed_dcbx_query_params(p_hwfn, p_dcbx_info, + QED_DCBX_OPERATIONAL_MIB); + if (rc) { + kfree(p_dcbx_info); + return rc; + } + + *p_dscp_pri = p_dcbx_info->dscp.dscp_pri_map[dscp_index]; + kfree(p_dcbx_info); + + return 0; +} + +int qed_dcbx_set_dscp_priority(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, + u8 dscp_index, u8 pri_val) +{ + struct qed_dcbx_set dcbx_set; + int rc; + + if (IS_VF(p_hwfn->cdev)) { + DP_ERR(p_hwfn->cdev, + "qed rdma set dscp priority not supported for VF.\n"); + return -EINVAL; + } + + if (dscp_index >= QED_DCBX_DSCP_SIZE || + pri_val >= QED_MAX_PFC_PRIORITIES) { + DP_ERR(p_hwfn, "Invalid dscp params: index = %d pri = %d\n", + dscp_index, pri_val); + return -EINVAL; + } + + memset(&dcbx_set, 0, sizeof(dcbx_set)); + rc = qed_dcbx_get_config_params(p_hwfn, &dcbx_set); + if (rc) + return rc; + + dcbx_set.override_flags = QED_DCBX_OVERRIDE_DSCP_CFG; + dcbx_set.dscp.dscp_pri_map[dscp_index] = pri_val; + + return qed_dcbx_config_params(p_hwfn, p_ptt, &dcbx_set, 1); +} + static struct qed_dcbx_get *qed_dcbnl_get_dcbx(struct qed_hwfn *hwfn, enum qed_mib_read_type type) { diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.h b/drivers/net/ethernet/qlogic/qed/qed_dcbx.h index e1798925b444..6d8ce9bb30bd 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.h +++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.h @@ -46,6 +46,7 @@ struct qed_dcbx_set { bool enabled; struct qed_dcbx_admin_params config; u32 ver_num; + struct qed_dcbx_dscp_params dscp; }; struct qed_dcbx_results { @@ -100,6 +101,14 @@ void qed_dcbx_info_free(struct qed_hwfn *p_hwfn); void qed_dcbx_set_pf_update_params(struct qed_dcbx_results *p_src, struct pf_update_ramrod_data *p_dest); +/* Returns priority value for a given dscp index */ +int qed_dcbx_get_dscp_priority(struct qed_hwfn *p_hwfn, u8 dscp_index, + u8 *p_dscp_pri); + +/* Sets priority value for a given dscp index */ +int qed_dcbx_set_dscp_priority(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, + u8 dscp_index, u8 pri_val); + #define QED_DCBX_DEFAULT_TC 0 u8 qed_dcbx_get_priority_tc(struct qed_hwfn *p_hwfn, u8 pri); diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h index 850b98991670..f7ce9a923d7c 100644 --- a/include/linux/qed/qed_if.h +++ b/include/linux/qed/qed_if.h @@ -124,12 +124,18 @@ struct qed_dcbx_operational_params { u32 err; }; +struct qed_dcbx_dscp_params { + bool enabled; + u8 dscp_pri_map[QED_DCBX_DSCP_SIZE]; +}; + struct qed_dcbx_get { struct qed_dcbx_operational_params operational; struct qed_dcbx_lldp_remote lldp_remote; struct qed_dcbx_lldp_local lldp_local; struct qed_dcbx_remote_params remote; struct qed_dcbx_admin_params local; + struct qed_dcbx_dscp_params dscp; }; enum qed_nvm_images { -- 2.24.1