+
+int
+bnxt_hwrm_tunnel_redirect(struct bnxt *bp, uint8_t type)
+{
+ struct hwrm_cfa_redirect_tunnel_type_alloc_input req = {0};
+ struct hwrm_cfa_redirect_tunnel_type_alloc_output *resp =
+ bp->hwrm_cmd_resp_addr;
+ int rc = 0;
+
+ HWRM_PREP(req, CFA_REDIRECT_TUNNEL_TYPE_ALLOC, BNXT_USE_CHIMP_MB);
+ req.tunnel_type = type;
+ req.dest_fid = bp->fw_fid;
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+ HWRM_CHECK_RESULT();
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int
+bnxt_hwrm_tunnel_redirect_free(struct bnxt *bp, uint8_t type)
+{
+ struct hwrm_cfa_redirect_tunnel_type_free_input req = {0};
+ struct hwrm_cfa_redirect_tunnel_type_free_output *resp =
+ bp->hwrm_cmd_resp_addr;
+ int rc = 0;
+
+ HWRM_PREP(req, CFA_REDIRECT_TUNNEL_TYPE_FREE, BNXT_USE_CHIMP_MB);
+ req.tunnel_type = type;
+ req.dest_fid = bp->fw_fid;
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+ HWRM_CHECK_RESULT();
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_tunnel_redirect_query(struct bnxt *bp, uint32_t *type)
+{
+ struct hwrm_cfa_redirect_query_tunnel_type_input req = {0};
+ struct hwrm_cfa_redirect_query_tunnel_type_output *resp =
+ bp->hwrm_cmd_resp_addr;
+ int rc = 0;
+
+ HWRM_PREP(req, CFA_REDIRECT_QUERY_TUNNEL_TYPE, BNXT_USE_CHIMP_MB);
+ req.src_fid = bp->fw_fid;
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+ HWRM_CHECK_RESULT();
+
+ if (type)
+ *type = rte_le_to_cpu_32(resp->tunnel_mask);
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_tunnel_redirect_info(struct bnxt *bp, uint8_t tun_type,
+ uint16_t *dst_fid)
+{
+ struct hwrm_cfa_redirect_tunnel_type_info_input req = {0};
+ struct hwrm_cfa_redirect_tunnel_type_info_output *resp =
+ bp->hwrm_cmd_resp_addr;
+ int rc = 0;
+
+ HWRM_PREP(req, CFA_REDIRECT_TUNNEL_TYPE_INFO, BNXT_USE_CHIMP_MB);
+ req.src_fid = bp->fw_fid;
+ req.tunnel_type = tun_type;
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+ HWRM_CHECK_RESULT();
+
+ if (dst_fid)
+ *dst_fid = rte_le_to_cpu_16(resp->dest_fid);
+
+ PMD_DRV_LOG(DEBUG, "dst_fid: %x\n", resp->dest_fid);
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_set_mac(struct bnxt *bp)
+{
+ struct hwrm_func_vf_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_func_vf_cfg_input req = {0};
+ int rc = 0;
+
+ if (!BNXT_VF(bp))
+ return 0;
+
+ HWRM_PREP(req, FUNC_VF_CFG, BNXT_USE_CHIMP_MB);
+
+ req.enables =
+ rte_cpu_to_le_32(HWRM_FUNC_VF_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+ memcpy(req.dflt_mac_addr, bp->mac_addr, RTE_ETHER_ADDR_LEN);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+
+ HWRM_CHECK_RESULT();
+
+ memcpy(bp->dflt_mac_addr, bp->mac_addr, RTE_ETHER_ADDR_LEN);
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_if_change(struct bnxt *bp, bool up)
+{
+ struct hwrm_func_drv_if_change_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_func_drv_if_change_input req = {0};
+ uint32_t flags;
+ int rc;
+
+ if (!(bp->flags & BNXT_FLAG_FW_CAP_IF_CHANGE))
+ return 0;
+
+ /* Do not issue FUNC_DRV_IF_CHANGE during reset recovery.
+ * If we issue FUNC_DRV_IF_CHANGE with flags down before
+ * FUNC_DRV_UNRGTR, FW resets before FUNC_DRV_UNRGTR
+ */
+ if (!up && (bp->flags & BNXT_FLAG_FW_RESET))
+ return 0;
+
+ HWRM_PREP(req, FUNC_DRV_IF_CHANGE, BNXT_USE_CHIMP_MB);
+
+ if (up)
+ req.flags =
+ rte_cpu_to_le_32(HWRM_FUNC_DRV_IF_CHANGE_INPUT_FLAGS_UP);
+
+ 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 (!up)
+ return 0;
+
+ if (flags & HWRM_FUNC_DRV_IF_CHANGE_OUTPUT_FLAGS_HOT_FW_RESET_DONE) {
+ PMD_DRV_LOG(INFO, "FW reset happened while port was down\n");
+ bp->flags |= BNXT_FLAG_IF_CHANGE_HOT_FW_RESET_DONE;
+ }
+
+ return 0;
+}
+
+int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp)
+{
+ struct hwrm_error_recovery_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+ struct bnxt_error_recovery_info *info = bp->recovery_info;
+ struct hwrm_error_recovery_qcfg_input req = {0};
+ uint32_t flags = 0;
+ unsigned int i;
+ int rc;
+
+ /* Older FW does not have error recovery support */
+ if (!(bp->flags & BNXT_FLAG_FW_CAP_ERROR_RECOVERY))
+ return 0;
+
+ if (!info) {
+ info = rte_zmalloc("bnxt_hwrm_error_recovery_qcfg",
+ sizeof(*info), 0);
+ bp->recovery_info = info;
+ if (info == NULL)
+ return -ENOMEM;
+ } else {
+ memset(info, 0, sizeof(*info));
+ }
+
+ HWRM_PREP(req, ERROR_RECOVERY_QCFG, 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);
+ if (flags & HWRM_ERROR_RECOVERY_QCFG_OUTPUT_FLAGS_HOST)
+ info->flags |= BNXT_FLAG_ERROR_RECOVERY_HOST;
+ else if (flags & HWRM_ERROR_RECOVERY_QCFG_OUTPUT_FLAGS_CO_CPU)
+ info->flags |= BNXT_FLAG_ERROR_RECOVERY_CO_CPU;
+
+ if ((info->flags & BNXT_FLAG_ERROR_RECOVERY_CO_CPU) &&
+ !(bp->flags & BNXT_FLAG_KONG_MB_EN)) {
+ rc = -EINVAL;
+ goto err;
+ }
+
+ /* FW returned values are in units of 100msec */
+ info->driver_polling_freq =
+ rte_le_to_cpu_32(resp->driver_polling_freq) * 100;
+ info->master_func_wait_period =
+ rte_le_to_cpu_32(resp->master_func_wait_period) * 100;
+ info->normal_func_wait_period =
+ rte_le_to_cpu_32(resp->normal_func_wait_period) * 100;
+ info->master_func_wait_period_after_reset =
+ rte_le_to_cpu_32(resp->master_func_wait_period_after_reset) * 100;
+ info->max_bailout_time_after_reset =
+ rte_le_to_cpu_32(resp->max_bailout_time_after_reset) * 100;
+ info->status_regs[BNXT_FW_STATUS_REG] =
+ rte_le_to_cpu_32(resp->fw_health_status_reg);
+ info->status_regs[BNXT_FW_HEARTBEAT_CNT_REG] =
+ rte_le_to_cpu_32(resp->fw_heartbeat_reg);
+ info->status_regs[BNXT_FW_RECOVERY_CNT_REG] =
+ rte_le_to_cpu_32(resp->fw_reset_cnt_reg);
+ info->status_regs[BNXT_FW_RESET_INPROG_REG] =
+ rte_le_to_cpu_32(resp->reset_inprogress_reg);
+ info->reg_array_cnt =
+ rte_le_to_cpu_32(resp->reg_array_cnt);
+
+ if (info->reg_array_cnt >= BNXT_NUM_RESET_REG) {
+ rc = -EINVAL;
+ goto err;
+ }
+
+ for (i = 0; i < info->reg_array_cnt; i++) {
+ info->reset_reg[i] =
+ rte_le_to_cpu_32(resp->reset_reg[i]);
+ info->reset_reg_val[i] =
+ rte_le_to_cpu_32(resp->reset_reg_val[i]);
+ info->delay_after_reset[i] =
+ resp->delay_after_reset[i];
+ }
+err:
+ HWRM_UNLOCK();
+
+ /* Map the FW status registers */
+ if (!rc)
+ rc = bnxt_map_fw_health_status_regs(bp);
+
+ if (rc) {
+ rte_free(bp->recovery_info);
+ bp->recovery_info = NULL;
+ }
+ return rc;
+}
+
+int bnxt_hwrm_fw_reset(struct bnxt *bp)
+{
+ struct hwrm_fw_reset_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_fw_reset_input req = {0};
+ int rc;
+
+ if (!BNXT_PF(bp))
+ return -EOPNOTSUPP;
+
+ HWRM_PREP(req, FW_RESET, BNXT_USE_KONG(bp));
+
+ req.embedded_proc_type =
+ HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_CHIP;
+ req.selfrst_status =
+ HWRM_FW_RESET_INPUT_SELFRST_STATUS_SELFRSTASAP;
+ req.flags = HWRM_FW_RESET_INPUT_FLAGS_RESET_GRACEFUL;
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req),
+ BNXT_USE_KONG(bp));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_port_ts_query(struct bnxt *bp, uint8_t path, uint64_t *timestamp)
+{
+ struct hwrm_port_ts_query_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_port_ts_query_input req = {0};
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+ uint32_t flags = 0;
+ int rc;
+
+ if (!ptp)
+ return 0;
+
+ HWRM_PREP(req, PORT_TS_QUERY, BNXT_USE_CHIMP_MB);
+
+ switch (path) {
+ case BNXT_PTP_FLAGS_PATH_TX:
+ flags |= HWRM_PORT_TS_QUERY_INPUT_FLAGS_PATH_TX;
+ break;
+ case BNXT_PTP_FLAGS_PATH_RX:
+ flags |= HWRM_PORT_TS_QUERY_INPUT_FLAGS_PATH_RX;
+ break;
+ case BNXT_PTP_FLAGS_CURRENT_TIME:
+ flags |= HWRM_PORT_TS_QUERY_INPUT_FLAGS_CURRENT_TIME;
+ break;
+ }
+
+ req.flags = rte_cpu_to_le_32(flags);
+ req.port_id = rte_cpu_to_le_16(bp->pf.port_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+
+ HWRM_CHECK_RESULT();
+
+ if (timestamp) {
+ *timestamp = rte_le_to_cpu_32(resp->ptp_msg_ts[0]);
+ *timestamp |=
+ (uint64_t)(rte_le_to_cpu_32(resp->ptp_msg_ts[1])) << 32;
+ }
+ HWRM_UNLOCK();
+
+ 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->flags & BNXT_FLAG_ADV_FLOW_MGMT))
+ return 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, CFA_ADV_FLOW_MGNT_QCAPS, BNXT_USE_KONG(bp));
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_KONG(bp));
+
+ HWRM_CHECK_RESULT();
+ flags = rte_le_to_cpu_32(resp->flags);
+ HWRM_UNLOCK();
+
+ if (flags & HWRM_CFA_ADV_FLOW_MGNT_QCAPS_L2_HDR_SRC_FILTER_EN) {
+ bp->flow_flags |= BNXT_FLOW_FLAG_L2_HDR_SRC_FILTER_EN;
+ PMD_DRV_LOG(INFO, "Source L2 header filtering enabled\n");
+ }
+
+ return rc;
+}