dma_free_coherent(&rcfw->pdev->dev, sbuf.size, sbuf.sb, sbuf.dma_addr);
        return rc;
 }
+
+static void bnxt_qplib_read_cc_gen1(struct bnxt_qplib_cc_param_ext *cc_ext,
+                                   struct creq_query_roce_cc_gen1_resp_sb_tlv *sb)
+{
+       cc_ext->inact_th_hi = le16_to_cpu(sb->inactivity_th_hi);
+       cc_ext->min_delta_cnp = le16_to_cpu(sb->min_time_between_cnps);
+       cc_ext->init_cp = le16_to_cpu(sb->init_cp);
+       cc_ext->tr_update_mode = sb->tr_update_mode;
+       cc_ext->tr_update_cyls = sb->tr_update_cycles;
+       cc_ext->fr_rtt = sb->fr_num_rtts;
+       cc_ext->ai_rate_incr = sb->ai_rate_increase;
+       cc_ext->rr_rtt_th = le16_to_cpu(sb->reduction_relax_rtts_th);
+       cc_ext->ar_cr_th = le16_to_cpu(sb->additional_relax_cr_th);
+       cc_ext->cr_min_th = le16_to_cpu(sb->cr_min_th);
+       cc_ext->bw_avg_weight = sb->bw_avg_weight;
+       cc_ext->cr_factor = sb->actual_cr_factor;
+       cc_ext->cr_th_max_cp = le16_to_cpu(sb->max_cp_cr_th);
+       cc_ext->cp_bias_en = sb->cp_bias_en;
+       cc_ext->cp_bias = sb->cp_bias;
+       cc_ext->cnp_ecn = sb->cnp_ecn;
+       cc_ext->rtt_jitter_en = sb->rtt_jitter_en;
+       cc_ext->bytes_per_usec = le16_to_cpu(sb->link_bytes_per_usec);
+       cc_ext->cc_cr_reset_th = le16_to_cpu(sb->reset_cc_cr_th);
+       cc_ext->cr_width = sb->cr_width;
+       cc_ext->min_quota = sb->quota_period_min;
+       cc_ext->max_quota = sb->quota_period_max;
+       cc_ext->abs_max_quota = sb->quota_period_abs_max;
+       cc_ext->tr_lb = le16_to_cpu(sb->tr_lower_bound);
+       cc_ext->cr_prob_fac = sb->cr_prob_factor;
+       cc_ext->tr_prob_fac = sb->tr_prob_factor;
+       cc_ext->fair_cr_th = le16_to_cpu(sb->fairness_cr_th);
+       cc_ext->red_div = sb->red_div;
+       cc_ext->cnp_ratio_th = sb->cnp_ratio_th;
+       cc_ext->ai_ext_rtt = le16_to_cpu(sb->exp_ai_rtts);
+       cc_ext->exp_crcp_ratio = sb->exp_ai_cr_cp_ratio;
+       cc_ext->low_rate_en = sb->use_rate_table;
+       cc_ext->cpcr_update_th = le16_to_cpu(sb->cp_exp_update_th);
+       cc_ext->ai_rtt_th1 = le16_to_cpu(sb->high_exp_ai_rtts_th1);
+       cc_ext->ai_rtt_th2 = le16_to_cpu(sb->high_exp_ai_rtts_th2);
+       cc_ext->cf_rtt_th = le16_to_cpu(sb->actual_cr_cong_free_rtts_th);
+       cc_ext->sc_cr_th1 = le16_to_cpu(sb->severe_cong_cr_th1);
+       cc_ext->sc_cr_th2 = le16_to_cpu(sb->severe_cong_cr_th2);
+       cc_ext->l64B_per_rtt = le32_to_cpu(sb->link64B_per_rtt);
+       cc_ext->cc_ack_bytes = sb->cc_ack_bytes;
+       cc_ext->reduce_cf_rtt_th = le16_to_cpu(sb->reduce_init_cong_free_rtts_th);
+}
+
+int bnxt_qplib_query_cc_param(struct bnxt_qplib_res *res,
+                             struct bnxt_qplib_cc_param *cc_param)
+{
+       struct bnxt_qplib_tlv_query_rcc_sb *ext_sb;
+       struct bnxt_qplib_rcfw *rcfw = res->rcfw;
+       struct creq_query_roce_cc_resp resp = {};
+       struct creq_query_roce_cc_resp_sb *sb;
+       struct bnxt_qplib_cmdqmsg msg = {};
+       struct cmdq_query_roce_cc req = {};
+       struct bnxt_qplib_rcfw_sbuf sbuf;
+       size_t resp_size;
+       int rc;
+
+       /* Query the parameters from chip */
+       bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req, CMDQ_BASE_OPCODE_QUERY_ROCE_CC,
+                                sizeof(req));
+       if (bnxt_qplib_is_chip_gen_p5_p7(res->cctx))
+               resp_size = sizeof(*ext_sb);
+       else
+               resp_size = sizeof(*sb);
+
+       sbuf.size = ALIGN(resp_size, BNXT_QPLIB_CMDQE_UNITS);
+       sbuf.sb = dma_alloc_coherent(&rcfw->pdev->dev, sbuf.size,
+                                    &sbuf.dma_addr, GFP_KERNEL);
+       if (!sbuf.sb)
+               return -ENOMEM;
+
+       req.resp_size = sbuf.size / BNXT_QPLIB_CMDQE_UNITS;
+       bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, &sbuf, sizeof(req),
+                               sizeof(resp), 0);
+       rc = bnxt_qplib_rcfw_send_message(res->rcfw, &msg);
+       if (rc)
+               goto out;
+
+       ext_sb = sbuf.sb;
+       sb = bnxt_qplib_is_chip_gen_p5_p7(res->cctx) ? &ext_sb->base_sb :
+               (struct creq_query_roce_cc_resp_sb *)ext_sb;
+
+       cc_param->enable = sb->enable_cc & CREQ_QUERY_ROCE_CC_RESP_SB_ENABLE_CC;
+       cc_param->tos_ecn = (sb->tos_dscp_tos_ecn &
+                            CREQ_QUERY_ROCE_CC_RESP_SB_TOS_ECN_MASK) >>
+                           CREQ_QUERY_ROCE_CC_RESP_SB_TOS_ECN_SFT;
+       cc_param->tos_dscp = (sb->tos_dscp_tos_ecn &
+                             CREQ_QUERY_ROCE_CC_RESP_SB_TOS_DSCP_MASK) >>
+                            CREQ_QUERY_ROCE_CC_RESP_SB_TOS_DSCP_SFT;
+       cc_param->alt_tos_dscp = sb->alt_tos_dscp;
+       cc_param->alt_vlan_pcp = sb->alt_vlan_pcp;
+
+       cc_param->g = sb->g;
+       cc_param->nph_per_state = sb->num_phases_per_state;
+       cc_param->init_cr = le16_to_cpu(sb->init_cr);
+       cc_param->init_tr = le16_to_cpu(sb->init_tr);
+       cc_param->cc_mode = sb->cc_mode;
+       cc_param->inact_th = le16_to_cpu(sb->inactivity_th);
+       cc_param->rtt = le16_to_cpu(sb->rtt);
+       cc_param->tcp_cp = le16_to_cpu(sb->tcp_cp);
+       cc_param->time_pph = sb->time_per_phase;
+       cc_param->pkts_pph = sb->pkts_per_phase;
+       if (bnxt_qplib_is_chip_gen_p5_p7(res->cctx)) {
+               bnxt_qplib_read_cc_gen1(&cc_param->cc_ext, &ext_sb->gen1_sb);
+               cc_param->inact_th |= (cc_param->cc_ext.inact_th_hi & 0x3F) << 16;
+       }
+out:
+       dma_free_coherent(&rcfw->pdev->dev, sbuf.size, sbuf.sb, sbuf.dma_addr);
+       return rc;
+}