RDMA/hns: Add window selection field of congestion control

The window selection field is necessary for congestion control of HIP09,
it is got from firmware and then filled into QPC. Some algorithms need it
to decide whether to limit the number of windows.

Fixes: f91696f2f0 ("RDMA/hns: Support congestion control type selection according to the FW")
Link: https://lore.kernel.org/r/1624364163-44185-1-git-send-email-liweihang@huawei.com
Signed-off-by: Yixing Liu <liuyixing1@huawei.com>
Signed-off-by: Weihang Li <liweihang@huawei.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
Yixing Liu 2021-06-22 20:16:03 +08:00 committed by Jason Gunthorpe
parent 36f5625af3
commit 7ae61c5f16
2 changed files with 14 additions and 0 deletions

View File

@ -4556,6 +4556,11 @@ enum {
DIP_VALID, DIP_VALID,
}; };
enum {
WND_LIMIT,
WND_UNLIMIT,
};
static int check_cong_type(struct ib_qp *ibqp, static int check_cong_type(struct ib_qp *ibqp,
struct hns_roce_congestion_algorithm *cong_alg) struct hns_roce_congestion_algorithm *cong_alg)
{ {
@ -4567,21 +4572,25 @@ static int check_cong_type(struct ib_qp *ibqp,
cong_alg->alg_sel = CONG_DCQCN; cong_alg->alg_sel = CONG_DCQCN;
cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL; cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL;
cong_alg->dip_vld = DIP_INVALID; cong_alg->dip_vld = DIP_INVALID;
cong_alg->wnd_mode_sel = WND_LIMIT;
break; break;
case CONG_TYPE_LDCP: case CONG_TYPE_LDCP:
cong_alg->alg_sel = CONG_WINDOW; cong_alg->alg_sel = CONG_WINDOW;
cong_alg->alg_sub_sel = CONG_LDCP; cong_alg->alg_sub_sel = CONG_LDCP;
cong_alg->dip_vld = DIP_INVALID; cong_alg->dip_vld = DIP_INVALID;
cong_alg->wnd_mode_sel = WND_UNLIMIT;
break; break;
case CONG_TYPE_HC3: case CONG_TYPE_HC3:
cong_alg->alg_sel = CONG_WINDOW; cong_alg->alg_sel = CONG_WINDOW;
cong_alg->alg_sub_sel = CONG_HC3; cong_alg->alg_sub_sel = CONG_HC3;
cong_alg->dip_vld = DIP_INVALID; cong_alg->dip_vld = DIP_INVALID;
cong_alg->wnd_mode_sel = WND_LIMIT;
break; break;
case CONG_TYPE_DIP: case CONG_TYPE_DIP:
cong_alg->alg_sel = CONG_DCQCN; cong_alg->alg_sel = CONG_DCQCN;
cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL; cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL;
cong_alg->dip_vld = DIP_VALID; cong_alg->dip_vld = DIP_VALID;
cong_alg->wnd_mode_sel = WND_LIMIT;
break; break;
default: default:
ibdev_err(&hr_dev->ib_dev, ibdev_err(&hr_dev->ib_dev,
@ -4622,6 +4631,9 @@ static int fill_cong_field(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
hr_reg_clear(&qpc_mask->ext, QPCEX_CONG_ALG_SUB_SEL); hr_reg_clear(&qpc_mask->ext, QPCEX_CONG_ALG_SUB_SEL);
hr_reg_write(&context->ext, QPCEX_DIP_CTX_IDX_VLD, cong_field.dip_vld); hr_reg_write(&context->ext, QPCEX_DIP_CTX_IDX_VLD, cong_field.dip_vld);
hr_reg_clear(&qpc_mask->ext, QPCEX_DIP_CTX_IDX_VLD); hr_reg_clear(&qpc_mask->ext, QPCEX_DIP_CTX_IDX_VLD);
hr_reg_write(&context->ext, QPCEX_SQ_RQ_NOT_FORBID_EN,
cong_field.wnd_mode_sel);
hr_reg_clear(&qpc_mask->ext, QPCEX_SQ_RQ_NOT_FORBID_EN);
/* if dip is disabled, there is no need to set dip idx */ /* if dip is disabled, there is no need to set dip idx */
if (cong_field.dip_vld == 0) if (cong_field.dip_vld == 0)

View File

@ -700,6 +700,7 @@ struct hns_roce_v2_qp_context {
#define QPCEX_CONG_ALG_SUB_SEL QPCEX_FIELD_LOC(1, 1) #define QPCEX_CONG_ALG_SUB_SEL QPCEX_FIELD_LOC(1, 1)
#define QPCEX_DIP_CTX_IDX_VLD QPCEX_FIELD_LOC(2, 2) #define QPCEX_DIP_CTX_IDX_VLD QPCEX_FIELD_LOC(2, 2)
#define QPCEX_DIP_CTX_IDX QPCEX_FIELD_LOC(22, 3) #define QPCEX_DIP_CTX_IDX QPCEX_FIELD_LOC(22, 3)
#define QPCEX_SQ_RQ_NOT_FORBID_EN QPCEX_FIELD_LOC(23, 23)
#define QPCEX_STASH QPCEX_FIELD_LOC(82, 82) #define QPCEX_STASH QPCEX_FIELD_LOC(82, 82)
#define V2_QP_RWE_S 1 /* rdma write enable */ #define V2_QP_RWE_S 1 /* rdma write enable */
@ -1337,6 +1338,7 @@ struct hns_roce_congestion_algorithm {
u8 alg_sel; u8 alg_sel;
u8 alg_sub_sel; u8 alg_sub_sel;
u8 dip_vld; u8 dip_vld;
u8 wnd_mode_sel;
}; };
#define V2_QUERY_PF_CAPS_D_CEQ_DEPTH_S 0 #define V2_QUERY_PF_CAPS_D_CEQ_DEPTH_S 0