]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA/bnxt_re: Add support for QP rate limiting
authorKalesh AP <kalesh-anakkur.purayil@broadcom.com>
Mon, 2 Feb 2026 13:34:09 +0000 (19:04 +0530)
committerLeon Romanovsky <leon@kernel.org>
Mon, 2 Feb 2026 13:37:59 +0000 (08:37 -0500)
Broadcom P7 chips supports applying rate limit to RC QPs.
It allows adjust shaper rate values during the INIT -> RTR,
RTR -> RTS, RTS -> RTS state changes or after QP transitions
to RTR or RTS.

Signed-off-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
Reviewed-by: Hongguang Gao <hongguang.gao@broadcom.com>
Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Link: https://patch.msgid.link/20260202133413.3182578-2-kalesh-anakkur.purayil@broadcom.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/hw/bnxt_re/ib_verbs.c
drivers/infiniband/hw/bnxt_re/qplib_fp.c
drivers/infiniband/hw/bnxt_re/qplib_fp.h
drivers/infiniband/hw/bnxt_re/qplib_res.h
drivers/infiniband/hw/bnxt_re/qplib_sp.c
drivers/infiniband/hw/bnxt_re/qplib_sp.h
drivers/infiniband/hw/bnxt_re/roce_hsi.h

index f19b55c13d580958834d39e5c402ac1944e24e03..39dd18af86eb5b1fb45d0511ba2c27e19d2dd11c 100644 (file)
@@ -2089,10 +2089,11 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
        unsigned int flags;
        u8 nw_type;
 
-       if (qp_attr_mask & ~IB_QP_ATTR_STANDARD_BITS)
+       if (qp_attr_mask & ~(IB_QP_ATTR_STANDARD_BITS | IB_QP_RATE_LIMIT))
                return -EOPNOTSUPP;
 
        qp->qplib_qp.modify_flags = 0;
+       qp->qplib_qp.ext_modify_flags = 0;
        if (qp_attr_mask & IB_QP_STATE) {
                curr_qp_state = __to_ib_qp_state(qp->qplib_qp.cur_qp_state);
                new_qp_state = qp_attr->qp_state;
@@ -2129,6 +2130,15 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
                        bnxt_re_unlock_cqs(qp, flags);
                }
        }
+
+       if (qp_attr_mask & IB_QP_RATE_LIMIT) {
+               if (qp->qplib_qp.type != IB_QPT_RC ||
+                   !_is_modify_qp_rate_limit_supported(dev_attr->dev_cap_flags2))
+                       return -EOPNOTSUPP;
+               qp->qplib_qp.ext_modify_flags |=
+                       CMDQ_MODIFY_QP_EXT_MODIFY_MASK_RATE_LIMIT_VALID;
+               qp->qplib_qp.rate_limit = qp_attr->rate_limit;
+       }
        if (qp_attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY) {
                qp->qplib_qp.modify_flags |=
                                CMDQ_MODIFY_QP_MODIFY_MASK_EN_SQD_ASYNC_NOTIFY;
index c88f049136fcb0de2fda90a916f618c049944446..3e44311bf939177e8c7bb1fc778a72ae2b028c7c 100644 (file)
@@ -1313,8 +1313,8 @@ int bnxt_qplib_modify_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
        struct bnxt_qplib_cmdqmsg msg = {};
        struct cmdq_modify_qp req = {};
        u16 vlan_pcp_vlan_dei_vlan_id;
+       u32 bmask, bmask_ext;
        u32 temp32[4];
-       u32 bmask;
        int rc;
 
        bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
@@ -1329,9 +1329,16 @@ int bnxt_qplib_modify_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
                    is_optimized_state_transition(qp))
                        bnxt_set_mandatory_attributes(res, qp, &req);
        }
+
        bmask = qp->modify_flags;
        req.modify_mask = cpu_to_le32(qp->modify_flags);
+       bmask_ext = qp->ext_modify_flags;
+       req.ext_modify_mask = cpu_to_le32(qp->ext_modify_flags);
        req.qp_cid = cpu_to_le32(qp->id);
+
+       if (bmask_ext & CMDQ_MODIFY_QP_EXT_MODIFY_MASK_RATE_LIMIT_VALID)
+               req.rate_limit = cpu_to_le32(qp->rate_limit);
+
        if (bmask & CMDQ_MODIFY_QP_MODIFY_MASK_STATE) {
                req.network_type_en_sqd_async_notify_new_state =
                                (qp->state & CMDQ_MODIFY_QP_NEW_STATE_MASK) |
@@ -1429,6 +1436,9 @@ int bnxt_qplib_modify_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
        rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
        if (rc)
                return rc;
+
+       if (bmask_ext & CMDQ_MODIFY_QP_EXT_MODIFY_MASK_RATE_LIMIT_VALID)
+               qp->shaper_allocation_status = resp.shaper_allocation_status;
        qp->cur_qp_state = qp->state;
        return 0;
 }
index 1b414a73b46d6812544b2829dc88fedfa2f8d186..30c3f99be07b4c91ce3f386c7a004df91c4d47b0 100644 (file)
@@ -280,6 +280,7 @@ struct bnxt_qplib_qp {
        u8                              state;
        u8                              cur_qp_state;
        u64                             modify_flags;
+       u32                             ext_modify_flags;
        u32                             max_inline_data;
        u32                             mtu;
        u8                              path_mtu;
@@ -346,6 +347,8 @@ struct bnxt_qplib_qp {
        bool                            is_host_msn_tbl;
        u8                              tos_dscp;
        u32                             ugid_index;
+       u32                             rate_limit;
+       u8                              shaper_allocation_status;
 };
 
 #define BNXT_RE_MAX_MSG_SIZE   0x80000000
index 2ea3b7f232a3faa4c9fbe4d475072dc711b09980..9a5dcf97b6f440a2444af3eff40b2429c7819d3a 100644 (file)
@@ -623,4 +623,10 @@ static inline bool _is_max_srq_ext_supported(u16 dev_cap_ext_flags_2)
        return !!(dev_cap_ext_flags_2 & CREQ_QUERY_FUNC_RESP_SB_MAX_SRQ_EXTENDED);
 }
 
+static inline bool _is_modify_qp_rate_limit_supported(u16 dev_cap_ext_flags2)
+{
+       return dev_cap_ext_flags2 &
+               CREQ_QUERY_FUNC_RESP_SB_MODIFY_QP_RATE_LIMIT_SUPPORTED;
+}
+
 #endif /* __BNXT_QPLIB_RES_H__ */
index 408a34df266721b67996e4dcf25c81f8220d1ead..ec9eb52a8ebf75c835272178af1b4d39961d7d06 100644 (file)
@@ -193,6 +193,11 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw)
                attr->max_dpi = le32_to_cpu(sb->max_dpi);
 
        attr->is_atomic = bnxt_qplib_is_atomic_cap(rcfw);
+
+       if (_is_modify_qp_rate_limit_supported(attr->dev_cap_flags2)) {
+               attr->rate_limit_min = le16_to_cpu(sb->rate_limit_min);
+               attr->rate_limit_max = le32_to_cpu(sb->rate_limit_max);
+       }
 bail:
        dma_free_coherent(&rcfw->pdev->dev, sbuf.size,
                          sbuf.sb, sbuf.dma_addr);
index 5a45c55c6464c9b0ec59acf56b9d3738f7916192..9fadd637cb5b105f1490bd44aa4e28ec520dff27 100644 (file)
@@ -76,6 +76,8 @@ struct bnxt_qplib_dev_attr {
        u16                             dev_cap_flags;
        u16                             dev_cap_flags2;
        u32                             max_dpi;
+       u16                             rate_limit_min;
+       u32                             rate_limit_max;
 };
 
 struct bnxt_qplib_pd {
index 99ecd72e72e20343635742bd36ce7ba57552202e..aac338f2afd8f4ea16d32722352291b8bf15e6e8 100644 (file)
@@ -690,10 +690,11 @@ struct cmdq_modify_qp {
        __le32  ext_modify_mask;
        #define CMDQ_MODIFY_QP_EXT_MODIFY_MASK_EXT_STATS_CTX     0x1UL
        #define CMDQ_MODIFY_QP_EXT_MODIFY_MASK_SCHQ_ID_VALID     0x2UL
+       #define CMDQ_MODIFY_QP_EXT_MODIFY_MASK_RATE_LIMIT_VALID  0x8UL
        __le32  ext_stats_ctx_id;
        __le16  schq_id;
        __le16  unused_0;
-       __le32  reserved32;
+       __le32  rate_limit;
 };
 
 /* creq_modify_qp_resp (size:128b/16B) */
@@ -716,7 +717,8 @@ struct creq_modify_qp_resp {
        #define CREQ_MODIFY_QP_RESP_PINGPONG_PUSH_INDEX_MASK  0xeUL
        #define CREQ_MODIFY_QP_RESP_PINGPONG_PUSH_INDEX_SFT   1
        #define CREQ_MODIFY_QP_RESP_PINGPONG_PUSH_STATE       0x10UL
-       u8      reserved8;
+       u8      shaper_allocation_status;
+       #define CREQ_MODIFY_QP_RESP_SHAPER_ALLOCATED          0x1UL
        __le32  lag_src_mac;
 };
 
@@ -2179,7 +2181,7 @@ struct creq_query_func_resp {
        u8      reserved48[6];
 };
 
-/* creq_query_func_resp_sb (size:1088b/136B) */
+/* creq_query_func_resp_sb (size:1280b/160B) */
 struct creq_query_func_resp_sb {
        u8      opcode;
        #define CREQ_QUERY_FUNC_RESP_SB_OPCODE_QUERY_FUNC 0x83UL
@@ -2256,12 +2258,15 @@ struct creq_query_func_resp_sb {
        #define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_LAST \
                        CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_IQM_MSN_TABLE
        #define CREQ_QUERY_FUNC_RESP_SB_MAX_SRQ_EXTENDED                         0x40UL
+       #define CREQ_QUERY_FUNC_RESP_SB_MODIFY_QP_RATE_LIMIT_SUPPORTED           0x400UL
        #define CREQ_QUERY_FUNC_RESP_SB_MIN_RNR_RTR_RTS_OPT_SUPPORTED            0x1000UL
        __le16  max_xp_qp_size;
        __le16  create_qp_batch_size;
        __le16  destroy_qp_batch_size;
        __le16  max_srq_ext;
-       __le64  reserved64;
+       __le16  reserved16;
+       __le16  rate_limit_min;
+       __le32  rate_limit_max;
 };
 
 /* cmdq_set_func_resources (size:448b/56B) */