Skip to content

Commit

Permalink
RDMA/bnxt_re: Add support to handle DCB_CONFIG_CHANGE event
Browse files Browse the repository at this point in the history
QP1 context in HW needs to be updated when there is a
change in the default DSCP values used for RoCE traffic.
Handle the event from FW and modify the dscp value used
by QP1.

Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
Link: https://patch.msgid.link/20250107024553.2926983-5-kalesh-anakkur.purayil@broadcom.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
  • Loading branch information
Kalesh AP authored and Leon Romanovsky committed Jan 14, 2025
1 parent c0ad30e commit 51dc531
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/infiniband/hw/bnxt_re/bnxt_re.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ struct bnxt_re_dev {
struct dentry *qp_debugfs;
unsigned long event_bitmap;
struct bnxt_qplib_cc_param cc_param;
struct workqueue_struct *dcb_wq;
};

#define to_bnxt_re_dev(ptr, member) \
Expand Down
104 changes: 104 additions & 0 deletions drivers/infiniband/hw/bnxt_re/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,96 @@ static void bnxt_re_vf_res_config(struct bnxt_re_dev *rdev)
&rdev->qplib_ctx);
}

struct bnxt_re_dcb_work {
struct work_struct work;
struct bnxt_re_dev *rdev;
struct hwrm_async_event_cmpl cmpl;
};

static bool bnxt_re_is_qp1_qp(struct bnxt_re_qp *qp)
{
return qp->ib_qp.qp_type == IB_QPT_GSI;
}

static struct bnxt_re_qp *bnxt_re_get_qp1_qp(struct bnxt_re_dev *rdev)
{
struct bnxt_re_qp *qp;

mutex_lock(&rdev->qp_lock);
list_for_each_entry(qp, &rdev->qp_list, list) {
if (bnxt_re_is_qp1_qp(qp)) {
mutex_unlock(&rdev->qp_lock);
return qp;
}
}
mutex_unlock(&rdev->qp_lock);
return NULL;
}

static int bnxt_re_update_qp1_tos_dscp(struct bnxt_re_dev *rdev)
{
struct bnxt_re_qp *qp;

if (!bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx))
return 0;

qp = bnxt_re_get_qp1_qp(rdev);
if (!qp)
return 0;

qp->qplib_qp.modify_flags = CMDQ_MODIFY_QP_MODIFY_MASK_TOS_DSCP;
qp->qplib_qp.tos_dscp = rdev->cc_param.qp1_tos_dscp;

return bnxt_qplib_modify_qp(&rdev->qplib_res, &qp->qplib_qp);
}

static void bnxt_re_init_dcb_wq(struct bnxt_re_dev *rdev)
{
rdev->dcb_wq = create_singlethread_workqueue("bnxt_re_dcb_wq");
}

static void bnxt_re_uninit_dcb_wq(struct bnxt_re_dev *rdev)
{
if (!rdev->dcb_wq)
return;
destroy_workqueue(rdev->dcb_wq);
}

static void bnxt_re_dcb_wq_task(struct work_struct *work)
{
struct bnxt_re_dcb_work *dcb_work =
container_of(work, struct bnxt_re_dcb_work, work);
struct bnxt_re_dev *rdev = dcb_work->rdev;
struct bnxt_qplib_cc_param *cc_param;
int rc;

if (!rdev)
goto free_dcb;

cc_param = &rdev->cc_param;
rc = bnxt_qplib_query_cc_param(&rdev->qplib_res, cc_param);
if (rc) {
ibdev_dbg(&rdev->ibdev, "Failed to query ccparam rc:%d", rc);
goto free_dcb;
}
if (cc_param->qp1_tos_dscp != cc_param->tos_dscp) {
cc_param->qp1_tos_dscp = cc_param->tos_dscp;
rc = bnxt_re_update_qp1_tos_dscp(rdev);
if (rc) {
ibdev_dbg(&rdev->ibdev, "%s: Failed to modify QP1 rc:%d",
__func__, rc);
goto free_dcb;
}
}

free_dcb:
kfree(dcb_work);
}

static void bnxt_re_async_notifier(void *handle, struct hwrm_async_event_cmpl *cmpl)
{
struct bnxt_re_dev *rdev = (struct bnxt_re_dev *)handle;
struct bnxt_re_dcb_work *dcb_work;
u32 data1, data2;
u16 event_id;

Expand All @@ -307,6 +394,21 @@ static void bnxt_re_async_notifier(void *handle, struct hwrm_async_event_cmpl *c

ibdev_dbg(&rdev->ibdev, "Async event_id = %d data1 = %d data2 = %d",
event_id, data1, data2);

switch (event_id) {
case ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE:
dcb_work = kzalloc(sizeof(*dcb_work), GFP_ATOMIC);
if (!dcb_work)
break;

dcb_work->rdev = rdev;
memcpy(&dcb_work->cmpl, cmpl, sizeof(*cmpl));
INIT_WORK(&dcb_work->work, bnxt_re_dcb_wq_task);
queue_work(rdev->dcb_wq, &dcb_work->work);
break;
default:
break;
}
}

static void bnxt_re_stop_irq(void *handle)
Expand Down Expand Up @@ -1900,6 +2002,7 @@ static void bnxt_re_dev_uninit(struct bnxt_re_dev *rdev, u8 op_type)
bnxt_re_debugfs_rem_pdev(rdev);

bnxt_re_net_unregister_async_event(rdev);
bnxt_re_uninit_dcb_wq(rdev);

if (test_and_clear_bit(BNXT_RE_FLAG_QOS_WORK_REG, &rdev->flags))
cancel_delayed_work_sync(&rdev->worker);
Expand Down Expand Up @@ -2119,6 +2222,7 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 op_type)

bnxt_re_debugfs_add_pdev(rdev);

bnxt_re_init_dcb_wq(rdev);
bnxt_re_net_register_async_event(rdev);

return 0;
Expand Down
1 change: 1 addition & 0 deletions drivers/infiniband/hw/bnxt_re/qplib_fp.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ struct bnxt_qplib_qp {
u32 msn;
u32 msn_tbl_sz;
bool is_host_msn_tbl;
u8 tos_dscp;
};

#define BNXT_QPLIB_MAX_CQE_ENTRY_SIZE sizeof(struct cq_base)
Expand Down
1 change: 1 addition & 0 deletions drivers/infiniband/hw/bnxt_re/qplib_sp.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ struct bnxt_qplib_cc_param_ext {

struct bnxt_qplib_cc_param {
u8 alt_vlan_pcp;
u8 qp1_tos_dscp;
u16 alt_tos_dscp;
u8 cc_mode;
u8 enable;
Expand Down

0 comments on commit 51dc531

Please sign in to comment.