Skip to content

Commit 51dc531

Browse files
kaleshap86rleon
authored andcommitted
RDMA/bnxt_re: Add support to handle DCB_CONFIG_CHANGE event
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>
1 parent c0ad30e commit 51dc531

4 files changed

Lines changed: 107 additions & 0 deletions

File tree

drivers/infiniband/hw/bnxt_re/bnxt_re.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ struct bnxt_re_dev {
231231
struct dentry *qp_debugfs;
232232
unsigned long event_bitmap;
233233
struct bnxt_qplib_cc_param cc_param;
234+
struct workqueue_struct *dcb_wq;
234235
};
235236

236237
#define to_bnxt_re_dev(ptr, member) \

drivers/infiniband/hw/bnxt_re/main.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,9 +295,96 @@ static void bnxt_re_vf_res_config(struct bnxt_re_dev *rdev)
295295
&rdev->qplib_ctx);
296296
}
297297

298+
struct bnxt_re_dcb_work {
299+
struct work_struct work;
300+
struct bnxt_re_dev *rdev;
301+
struct hwrm_async_event_cmpl cmpl;
302+
};
303+
304+
static bool bnxt_re_is_qp1_qp(struct bnxt_re_qp *qp)
305+
{
306+
return qp->ib_qp.qp_type == IB_QPT_GSI;
307+
}
308+
309+
static struct bnxt_re_qp *bnxt_re_get_qp1_qp(struct bnxt_re_dev *rdev)
310+
{
311+
struct bnxt_re_qp *qp;
312+
313+
mutex_lock(&rdev->qp_lock);
314+
list_for_each_entry(qp, &rdev->qp_list, list) {
315+
if (bnxt_re_is_qp1_qp(qp)) {
316+
mutex_unlock(&rdev->qp_lock);
317+
return qp;
318+
}
319+
}
320+
mutex_unlock(&rdev->qp_lock);
321+
return NULL;
322+
}
323+
324+
static int bnxt_re_update_qp1_tos_dscp(struct bnxt_re_dev *rdev)
325+
{
326+
struct bnxt_re_qp *qp;
327+
328+
if (!bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx))
329+
return 0;
330+
331+
qp = bnxt_re_get_qp1_qp(rdev);
332+
if (!qp)
333+
return 0;
334+
335+
qp->qplib_qp.modify_flags = CMDQ_MODIFY_QP_MODIFY_MASK_TOS_DSCP;
336+
qp->qplib_qp.tos_dscp = rdev->cc_param.qp1_tos_dscp;
337+
338+
return bnxt_qplib_modify_qp(&rdev->qplib_res, &qp->qplib_qp);
339+
}
340+
341+
static void bnxt_re_init_dcb_wq(struct bnxt_re_dev *rdev)
342+
{
343+
rdev->dcb_wq = create_singlethread_workqueue("bnxt_re_dcb_wq");
344+
}
345+
346+
static void bnxt_re_uninit_dcb_wq(struct bnxt_re_dev *rdev)
347+
{
348+
if (!rdev->dcb_wq)
349+
return;
350+
destroy_workqueue(rdev->dcb_wq);
351+
}
352+
353+
static void bnxt_re_dcb_wq_task(struct work_struct *work)
354+
{
355+
struct bnxt_re_dcb_work *dcb_work =
356+
container_of(work, struct bnxt_re_dcb_work, work);
357+
struct bnxt_re_dev *rdev = dcb_work->rdev;
358+
struct bnxt_qplib_cc_param *cc_param;
359+
int rc;
360+
361+
if (!rdev)
362+
goto free_dcb;
363+
364+
cc_param = &rdev->cc_param;
365+
rc = bnxt_qplib_query_cc_param(&rdev->qplib_res, cc_param);
366+
if (rc) {
367+
ibdev_dbg(&rdev->ibdev, "Failed to query ccparam rc:%d", rc);
368+
goto free_dcb;
369+
}
370+
if (cc_param->qp1_tos_dscp != cc_param->tos_dscp) {
371+
cc_param->qp1_tos_dscp = cc_param->tos_dscp;
372+
rc = bnxt_re_update_qp1_tos_dscp(rdev);
373+
if (rc) {
374+
ibdev_dbg(&rdev->ibdev, "%s: Failed to modify QP1 rc:%d",
375+
__func__, rc);
376+
goto free_dcb;
377+
}
378+
}
379+
380+
free_dcb:
381+
kfree(dcb_work);
382+
}
383+
298384
static void bnxt_re_async_notifier(void *handle, struct hwrm_async_event_cmpl *cmpl)
299385
{
300386
struct bnxt_re_dev *rdev = (struct bnxt_re_dev *)handle;
387+
struct bnxt_re_dcb_work *dcb_work;
301388
u32 data1, data2;
302389
u16 event_id;
303390

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

308395
ibdev_dbg(&rdev->ibdev, "Async event_id = %d data1 = %d data2 = %d",
309396
event_id, data1, data2);
397+
398+
switch (event_id) {
399+
case ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE:
400+
dcb_work = kzalloc(sizeof(*dcb_work), GFP_ATOMIC);
401+
if (!dcb_work)
402+
break;
403+
404+
dcb_work->rdev = rdev;
405+
memcpy(&dcb_work->cmpl, cmpl, sizeof(*cmpl));
406+
INIT_WORK(&dcb_work->work, bnxt_re_dcb_wq_task);
407+
queue_work(rdev->dcb_wq, &dcb_work->work);
408+
break;
409+
default:
410+
break;
411+
}
310412
}
311413

312414
static void bnxt_re_stop_irq(void *handle)
@@ -1900,6 +2002,7 @@ static void bnxt_re_dev_uninit(struct bnxt_re_dev *rdev, u8 op_type)
19002002
bnxt_re_debugfs_rem_pdev(rdev);
19012003

19022004
bnxt_re_net_unregister_async_event(rdev);
2005+
bnxt_re_uninit_dcb_wq(rdev);
19032006

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

21202223
bnxt_re_debugfs_add_pdev(rdev);
21212224

2225+
bnxt_re_init_dcb_wq(rdev);
21222226
bnxt_re_net_register_async_event(rdev);
21232227

21242228
return 0;

drivers/infiniband/hw/bnxt_re/qplib_fp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ struct bnxt_qplib_qp {
343343
u32 msn;
344344
u32 msn_tbl_sz;
345345
bool is_host_msn_tbl;
346+
u8 tos_dscp;
346347
};
347348

348349
#define BNXT_QPLIB_MAX_CQE_ENTRY_SIZE sizeof(struct cq_base)

drivers/infiniband/hw/bnxt_re/qplib_sp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ struct bnxt_qplib_cc_param_ext {
296296

297297
struct bnxt_qplib_cc_param {
298298
u8 alt_vlan_pcp;
299+
u8 qp1_tos_dscp;
299300
u16 alt_tos_dscp;
300301
u8 cc_mode;
301302
u8 enable;

0 commit comments

Comments
 (0)