+
+int bnxt_hwrm_cfa_counter_qcaps(struct bnxt *bp, uint16_t *max_fc)
+{
+ int rc = 0;
+
+ struct hwrm_cfa_counter_qcaps_input req = {0};
+ struct hwrm_cfa_counter_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
+
+ if (!(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp))) {
+ PMD_DRV_LOG(DEBUG,
+ "Not a PF or trusted VF. Command not supported\n");
+ return 0;
+ }
+
+ HWRM_PREP(&req, HWRM_CFA_COUNTER_QCAPS, BNXT_USE_KONG(bp));
+ req.target_id = rte_cpu_to_le_16(bp->fw_fid);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_KONG(bp));
+
+ HWRM_CHECK_RESULT();
+ if (max_fc)
+ *max_fc = rte_le_to_cpu_16(resp->max_rx_fc);
+ HWRM_UNLOCK();
+
+ return 0;
+}
+
+int bnxt_hwrm_ctx_rgtr(struct bnxt *bp, rte_iova_t dma_addr, uint16_t *ctx_id)
+{
+ int rc = 0;
+ struct hwrm_cfa_ctx_mem_rgtr_input req = {.req_type = 0 };
+ struct hwrm_cfa_ctx_mem_rgtr_output *resp = bp->hwrm_cmd_resp_addr;
+
+ if (!(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp))) {
+ PMD_DRV_LOG(DEBUG,
+ "Not a PF or trusted VF. Command not supported\n");
+ return 0;
+ }
+
+ HWRM_PREP(&req, HWRM_CFA_CTX_MEM_RGTR, BNXT_USE_KONG(bp));
+
+ req.page_level = HWRM_CFA_CTX_MEM_RGTR_INPUT_PAGE_LEVEL_LVL_0;
+ req.page_size = HWRM_CFA_CTX_MEM_RGTR_INPUT_PAGE_SIZE_2M;
+ req.page_dir = rte_cpu_to_le_64(dma_addr);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_KONG(bp));
+
+ HWRM_CHECK_RESULT();
+ if (ctx_id) {
+ *ctx_id = rte_le_to_cpu_16(resp->ctx_id);
+ PMD_DRV_LOG(DEBUG, "ctx_id = %d\n", *ctx_id);
+ }
+ HWRM_UNLOCK();
+
+ return 0;
+}
+
+int bnxt_hwrm_ctx_unrgtr(struct bnxt *bp, uint16_t ctx_id)
+{
+ int rc = 0;
+ struct hwrm_cfa_ctx_mem_unrgtr_input req = {.req_type = 0 };
+ struct hwrm_cfa_ctx_mem_unrgtr_output *resp = bp->hwrm_cmd_resp_addr;
+
+ if (!(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp))) {
+ PMD_DRV_LOG(DEBUG,
+ "Not a PF or trusted VF. Command not supported\n");
+ return 0;
+ }
+
+ HWRM_PREP(&req, HWRM_CFA_CTX_MEM_UNRGTR, BNXT_USE_KONG(bp));
+
+ req.ctx_id = rte_cpu_to_le_16(ctx_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_KONG(bp));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_cfa_counter_cfg(struct bnxt *bp, enum bnxt_flow_dir dir,
+ uint16_t cntr, uint16_t ctx_id,
+ uint32_t num_entries, bool enable)
+{
+ struct hwrm_cfa_counter_cfg_input req = {0};
+ struct hwrm_cfa_counter_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ uint16_t flags = 0;
+ int rc;
+
+ if (!(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp))) {
+ PMD_DRV_LOG(DEBUG,
+ "Not a PF or trusted VF. Command not supported\n");
+ return 0;
+ }
+
+ HWRM_PREP(&req, HWRM_CFA_COUNTER_CFG, BNXT_USE_KONG(bp));
+
+ req.target_id = rte_cpu_to_le_16(bp->fw_fid);
+ req.counter_type = rte_cpu_to_le_16(cntr);
+ flags = enable ? HWRM_CFA_COUNTER_CFG_INPUT_FLAGS_CFG_MODE_ENABLE :
+ HWRM_CFA_COUNTER_CFG_INPUT_FLAGS_CFG_MODE_DISABLE;
+ flags |= HWRM_CFA_COUNTER_CFG_INPUT_FLAGS_DATA_TRANSFER_MODE_PULL;
+ if (dir == BNXT_DIR_RX)
+ flags |= HWRM_CFA_COUNTER_CFG_INPUT_FLAGS_PATH_RX;
+ else if (dir == BNXT_DIR_TX)
+ flags |= HWRM_CFA_COUNTER_CFG_INPUT_FLAGS_PATH_TX;
+ req.flags = rte_cpu_to_le_16(flags);
+ req.ctx_id = rte_cpu_to_le_16(ctx_id);
+ req.num_entries = rte_cpu_to_le_32(num_entries);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_KONG(bp));
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return 0;
+}
+
+int bnxt_hwrm_cfa_counter_qstats(struct bnxt *bp,
+ enum bnxt_flow_dir dir,
+ uint16_t cntr,
+ uint16_t num_entries)
+{
+ struct hwrm_cfa_counter_qstats_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_cfa_counter_qstats_input req = {0};
+ uint16_t flow_ctx_id = 0;
+ uint16_t flags = 0;
+ int rc = 0;
+
+ if (!(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp))) {
+ PMD_DRV_LOG(DEBUG,
+ "Not a PF or trusted VF. Command not supported\n");
+ return 0;
+ }
+
+ if (dir == BNXT_DIR_RX) {
+ flow_ctx_id = bp->flow_stat->rx_fc_in_tbl.ctx_id;
+ flags = HWRM_CFA_COUNTER_QSTATS_INPUT_FLAGS_PATH_RX;
+ } else if (dir == BNXT_DIR_TX) {
+ flow_ctx_id = bp->flow_stat->tx_fc_in_tbl.ctx_id;
+ flags = HWRM_CFA_COUNTER_QSTATS_INPUT_FLAGS_PATH_TX;
+ }
+
+ HWRM_PREP(&req, HWRM_CFA_COUNTER_QSTATS, BNXT_USE_KONG(bp));
+ req.target_id = rte_cpu_to_le_16(bp->fw_fid);
+ req.counter_type = rte_cpu_to_le_16(cntr);
+ req.input_flow_ctx_id = rte_cpu_to_le_16(flow_ctx_id);
+ req.num_entries = rte_cpu_to_le_16(num_entries);
+ req.flags = rte_cpu_to_le_16(flags);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_KONG(bp));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return 0;
+}
+
+int bnxt_hwrm_first_vf_id_query(struct bnxt *bp, uint16_t fid,
+ uint16_t *first_vf_id)
+{
+ int rc = 0;
+ struct hwrm_func_qcaps_input req = {.req_type = 0 };
+ struct hwrm_func_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(&req, HWRM_FUNC_QCAPS, BNXT_USE_CHIMP_MB);
+
+ req.fid = rte_cpu_to_le_16(fid);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+
+ HWRM_CHECK_RESULT();
+
+ if (first_vf_id)
+ *first_vf_id = rte_le_to_cpu_16(resp->first_vf_id);
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_cfa_pair_alloc(struct bnxt *bp, struct bnxt_representor *rep_bp)
+{
+ struct hwrm_cfa_pair_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_cfa_pair_alloc_input req = {0};
+ int rc;
+
+ if (!(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp))) {
+ PMD_DRV_LOG(DEBUG,
+ "Not a PF or trusted VF. Command not supported\n");
+ return 0;
+ }
+
+ HWRM_PREP(&req, HWRM_CFA_PAIR_ALLOC, BNXT_USE_CHIMP_MB);
+ req.pair_mode = HWRM_CFA_PAIR_FREE_INPUT_PAIR_MODE_REP2FN_TRUFLOW;
+ snprintf(req.pair_name, sizeof(req.pair_name), "%svfr%d",
+ bp->eth_dev->data->name, rep_bp->vf_id);
+
+ req.pf_b_id = rep_bp->parent_pf_idx;
+ req.vf_b_id = BNXT_REP_PF(rep_bp) ? rte_cpu_to_le_16(((uint16_t)-1)) :
+ rte_cpu_to_le_16(rep_bp->vf_id);
+ req.vf_a_id = rte_cpu_to_le_16(bp->fw_fid);
+ req.host_b_id = 1; /* TBD - Confirm if this is OK */
+
+ req.enables |= rep_bp->flags & BNXT_REP_Q_R2F_VALID ?
+ HWRM_CFA_PAIR_ALLOC_INPUT_ENABLES_Q_AB_VALID : 0;
+ req.enables |= rep_bp->flags & BNXT_REP_Q_F2R_VALID ?
+ HWRM_CFA_PAIR_ALLOC_INPUT_ENABLES_Q_BA_VALID : 0;
+ req.enables |= rep_bp->flags & BNXT_REP_FC_R2F_VALID ?
+ HWRM_CFA_PAIR_ALLOC_INPUT_ENABLES_FC_AB_VALID : 0;
+ req.enables |= rep_bp->flags & BNXT_REP_FC_F2R_VALID ?
+ HWRM_CFA_PAIR_ALLOC_INPUT_ENABLES_FC_BA_VALID : 0;
+
+ req.q_ab = rep_bp->rep_q_r2f;
+ req.q_ba = rep_bp->rep_q_f2r;
+ req.fc_ab = rep_bp->rep_fc_r2f;
+ req.fc_ba = rep_bp->rep_fc_f2r;
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+ HWRM_CHECK_RESULT();
+
+ HWRM_UNLOCK();
+ PMD_DRV_LOG(DEBUG, "%s %d allocated\n",
+ BNXT_REP_PF(rep_bp) ? "PFR" : "VFR", rep_bp->vf_id);
+ return rc;
+}
+
+int bnxt_hwrm_cfa_pair_free(struct bnxt *bp, struct bnxt_representor *rep_bp)
+{
+ struct hwrm_cfa_pair_free_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_cfa_pair_free_input req = {0};
+ int rc;
+
+ if (!(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp))) {
+ PMD_DRV_LOG(DEBUG,
+ "Not a PF or trusted VF. Command not supported\n");
+ return 0;
+ }
+
+ HWRM_PREP(&req, HWRM_CFA_PAIR_FREE, BNXT_USE_CHIMP_MB);
+ snprintf(req.pair_name, sizeof(req.pair_name), "%svfr%d",
+ bp->eth_dev->data->name, rep_bp->vf_id);
+ req.pf_b_id = rep_bp->parent_pf_idx;
+ req.pair_mode = HWRM_CFA_PAIR_FREE_INPUT_PAIR_MODE_REP2FN_TRUFLOW;
+ req.vf_id = BNXT_REP_PF(rep_bp) ? rte_cpu_to_le_16(((uint16_t)-1)) :
+ rte_cpu_to_le_16(rep_bp->vf_id);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+ PMD_DRV_LOG(DEBUG, "%s %d freed\n", BNXT_REP_PF(rep_bp) ? "PFR" : "VFR",
+ rep_bp->vf_id);
+ return rc;
+}
+
+int bnxt_hwrm_cfa_adv_flow_mgmt_qcaps(struct bnxt *bp)
+{
+ struct hwrm_cfa_adv_flow_mgnt_qcaps_output *resp =
+ bp->hwrm_cmd_resp_addr;
+ struct hwrm_cfa_adv_flow_mgnt_qcaps_input req = {0};
+ uint32_t flags = 0;
+ int rc = 0;
+
+ if (!(bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_MGMT))
+ return 0;
+
+ if (!(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp))) {
+ PMD_DRV_LOG(DEBUG,
+ "Not a PF or trusted VF. Command not supported\n");
+ return 0;
+ }
+
+ HWRM_PREP(&req, HWRM_CFA_ADV_FLOW_MGNT_QCAPS, BNXT_USE_CHIMP_MB);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+
+ HWRM_CHECK_RESULT();
+ flags = rte_le_to_cpu_32(resp->flags);
+ HWRM_UNLOCK();
+
+ if (flags & HWRM_CFA_ADV_FLOW_MGNT_QCAPS_RFS_RING_TBL_IDX_V2_SUPPORTED)
+ bp->flags |= BNXT_FLAG_FLOW_CFA_RFS_RING_TBL_IDX_V2;
+ else
+ bp->flags |= BNXT_FLAG_RFS_NEEDS_VNIC;
+
+ return rc;
+}
+
+int bnxt_hwrm_fw_echo_reply(struct bnxt *bp, uint32_t echo_req_data1,
+ uint32_t echo_req_data2)
+{
+ struct hwrm_func_echo_response_input req = {0};
+ struct hwrm_func_echo_response_output *resp = bp->hwrm_cmd_resp_addr;
+ int rc;
+
+ HWRM_PREP(&req, HWRM_FUNC_ECHO_RESPONSE, BNXT_USE_CHIMP_MB);
+ req.event_data1 = rte_cpu_to_le_32(echo_req_data1);
+ req.event_data2 = rte_cpu_to_le_32(echo_req_data2);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_poll_ver_get(struct bnxt *bp)
+{
+ struct hwrm_ver_get_input req = {.req_type = 0 };
+ struct hwrm_ver_get_output *resp = bp->hwrm_cmd_resp_addr;
+ int rc = 0;
+
+ bp->max_req_len = HWRM_MAX_REQ_LEN;
+ bp->max_resp_len = BNXT_PAGE_SIZE;
+ bp->hwrm_cmd_timeout = SHORT_HWRM_CMD_TIMEOUT;
+
+ HWRM_PREP(&req, HWRM_VER_GET, BNXT_USE_CHIMP_MB);
+ req.hwrm_intf_maj = HWRM_VERSION_MAJOR;
+ req.hwrm_intf_min = HWRM_VERSION_MINOR;
+ req.hwrm_intf_upd = HWRM_VERSION_UPDATE;
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+
+ HWRM_CHECK_RESULT_SILENT();
+
+ if (resp->flags & HWRM_VER_GET_OUTPUT_FLAGS_DEV_NOT_RDY)
+ rc = -EAGAIN;
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_read_sfp_module_eeprom_info(struct bnxt *bp, uint16_t i2c_addr,
+ uint16_t page_number, uint16_t start_addr,
+ uint16_t data_length, uint8_t *buf)
+{
+ struct hwrm_port_phy_i2c_read_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_port_phy_i2c_read_input req = {0};
+ uint32_t enables = HWRM_PORT_PHY_I2C_READ_INPUT_ENABLES_PAGE_OFFSET;
+ int rc, byte_offset = 0;
+
+ do {
+ uint16_t xfer_size;
+
+ HWRM_PREP(&req, HWRM_PORT_PHY_I2C_READ, BNXT_USE_CHIMP_MB);
+ req.i2c_slave_addr = i2c_addr;
+ req.page_number = rte_cpu_to_le_16(page_number);
+ req.port_id = rte_cpu_to_le_16(bp->pf->port_id);
+
+ xfer_size = RTE_MIN(data_length, BNXT_MAX_PHY_I2C_RESP_SIZE);
+ req.page_offset = rte_cpu_to_le_16(start_addr + byte_offset);
+ req.data_length = xfer_size;
+ req.enables = rte_cpu_to_le_32(start_addr + byte_offset ? enables : 0);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+ HWRM_CHECK_RESULT();
+
+ memcpy(buf + byte_offset, resp->data, xfer_size);
+
+ data_length -= xfer_size;
+ byte_offset += xfer_size;
+
+ HWRM_UNLOCK();
+ } while (data_length > 0);
+
+ return rc;
+}
+
+void bnxt_free_hwrm_tx_ring(struct bnxt *bp, int queue_index)
+{
+ struct bnxt_tx_queue *txq = bp->tx_queues[queue_index];
+ struct bnxt_tx_ring_info *txr = txq->tx_ring;
+ struct bnxt_ring *ring = txr->tx_ring_struct;
+ struct bnxt_cp_ring_info *cpr = txq->cp_ring;
+
+ if (ring->fw_ring_id != INVALID_HW_RING_ID) {
+ bnxt_hwrm_ring_free(bp, ring,
+ HWRM_RING_FREE_INPUT_RING_TYPE_TX,
+ cpr->cp_ring_struct->fw_ring_id);
+ ring->fw_ring_id = INVALID_HW_RING_ID;
+ }
+
+ if (cpr->hw_stats_ctx_id != HWRM_NA_SIGNATURE) {
+ bnxt_hwrm_stat_ctx_free(bp, cpr);
+ cpr->hw_stats_ctx_id = HWRM_NA_SIGNATURE;
+ }
+
+ if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) {
+ bnxt_free_cp_ring(bp, cpr);
+ cpr->cp_ring_struct->fw_ring_id = INVALID_HW_RING_ID;
+ }
+}