+uint16_t
+bnxt_get_svif(uint16_t port_id, bool func_svif,
+ enum bnxt_ulp_intf_type type)
+{
+ struct rte_eth_dev *eth_dev;
+ struct bnxt *bp;
+
+ eth_dev = &rte_eth_devices[port_id];
+ if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
+ struct bnxt_vf_representor *vfr = eth_dev->data->dev_private;
+ if (!vfr)
+ return 0;
+
+ if (type == BNXT_ULP_INTF_TYPE_VF_REP)
+ return vfr->svif;
+
+ eth_dev = vfr->parent_dev;
+ }
+
+ bp = eth_dev->data->dev_private;
+
+ return func_svif ? bp->func_svif : bp->port_svif;
+}
+
+uint16_t
+bnxt_get_vnic_id(uint16_t port, enum bnxt_ulp_intf_type type)
+{
+ struct rte_eth_dev *eth_dev;
+ struct bnxt_vnic_info *vnic;
+ struct bnxt *bp;
+
+ eth_dev = &rte_eth_devices[port];
+ if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
+ struct bnxt_vf_representor *vfr = eth_dev->data->dev_private;
+ if (!vfr)
+ return 0;
+
+ if (type == BNXT_ULP_INTF_TYPE_VF_REP)
+ return vfr->dflt_vnic_id;
+
+ eth_dev = vfr->parent_dev;
+ }
+
+ bp = eth_dev->data->dev_private;
+
+ vnic = BNXT_GET_DEFAULT_VNIC(bp);
+
+ return vnic->fw_vnic_id;
+}
+
+uint16_t
+bnxt_get_fw_func_id(uint16_t port, enum bnxt_ulp_intf_type type)
+{
+ struct rte_eth_dev *eth_dev;
+ struct bnxt *bp;
+
+ eth_dev = &rte_eth_devices[port];
+ if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
+ struct bnxt_vf_representor *vfr = eth_dev->data->dev_private;
+ if (!vfr)
+ return 0;
+
+ if (type == BNXT_ULP_INTF_TYPE_VF_REP)
+ return vfr->fw_fid;
+
+ eth_dev = vfr->parent_dev;
+ }
+
+ bp = eth_dev->data->dev_private;
+
+ return bp->fw_fid;
+}
+
+enum bnxt_ulp_intf_type
+bnxt_get_interface_type(uint16_t port)
+{
+ struct rte_eth_dev *eth_dev;
+ struct bnxt *bp;
+
+ eth_dev = &rte_eth_devices[port];
+ if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev))
+ return BNXT_ULP_INTF_TYPE_VF_REP;
+
+ bp = eth_dev->data->dev_private;
+ if (BNXT_PF(bp))
+ return BNXT_ULP_INTF_TYPE_PF;
+ else if (BNXT_VF_IS_TRUSTED(bp))
+ return BNXT_ULP_INTF_TYPE_TRUSTED_VF;
+ else if (BNXT_VF(bp))
+ return BNXT_ULP_INTF_TYPE_VF;
+
+ return BNXT_ULP_INTF_TYPE_INVALID;
+}
+
+uint16_t
+bnxt_get_phy_port_id(uint16_t port_id)
+{
+ struct bnxt_vf_representor *vfr;
+ struct rte_eth_dev *eth_dev;
+ struct bnxt *bp;
+
+ eth_dev = &rte_eth_devices[port_id];
+ if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
+ vfr = eth_dev->data->dev_private;
+ if (!vfr)
+ return 0;
+
+ eth_dev = vfr->parent_dev;
+ }
+
+ bp = eth_dev->data->dev_private;
+
+ return BNXT_PF(bp) ? bp->pf->port_id : bp->parent->port_id;
+}
+
+uint16_t
+bnxt_get_parif(uint16_t port_id, enum bnxt_ulp_intf_type type)
+{
+ struct rte_eth_dev *eth_dev;
+ struct bnxt *bp;
+
+ eth_dev = &rte_eth_devices[port_id];
+ if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
+ struct bnxt_vf_representor *vfr = eth_dev->data->dev_private;
+ if (!vfr)
+ return 0;
+
+ if (type == BNXT_ULP_INTF_TYPE_VF_REP)
+ return vfr->fw_fid - 1;
+
+ eth_dev = vfr->parent_dev;
+ }
+
+ bp = eth_dev->data->dev_private;
+
+ return BNXT_PF(bp) ? bp->fw_fid - 1 : bp->parent->fid - 1;
+}
+
+uint16_t
+bnxt_get_vport(uint16_t port_id)
+{
+ return (1 << bnxt_get_phy_port_id(port_id));
+}
+
+static void bnxt_alloc_error_recovery_info(struct bnxt *bp)
+{
+ struct bnxt_error_recovery_info *info = bp->recovery_info;
+
+ if (info) {
+ if (!(bp->fw_cap & BNXT_FW_CAP_HCOMM_FW_STATUS))
+ memset(info, 0, sizeof(*info));
+ return;
+ }
+
+ if (!(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY))
+ return;
+
+ info = rte_zmalloc("bnxt_hwrm_error_recovery_qcfg",
+ sizeof(*info), 0);
+ if (!info)
+ bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY;
+
+ bp->recovery_info = info;
+}
+
+static void bnxt_check_fw_status(struct bnxt *bp)
+{
+ uint32_t fw_status;
+
+ if (!(bp->recovery_info &&
+ (bp->fw_cap & BNXT_FW_CAP_HCOMM_FW_STATUS)))
+ return;
+
+ fw_status = bnxt_read_fw_status_reg(bp, BNXT_FW_STATUS_REG);
+ if (fw_status != BNXT_FW_STATUS_HEALTHY)
+ PMD_DRV_LOG(ERR, "Firmware not responding, status: %#x\n",
+ fw_status);
+}
+
+static int bnxt_map_hcomm_fw_status_reg(struct bnxt *bp)
+{
+ struct bnxt_error_recovery_info *info = bp->recovery_info;
+ uint32_t status_loc;
+ uint32_t sig_ver;
+
+ rte_write32(HCOMM_STATUS_STRUCT_LOC, (uint8_t *)bp->bar0 +
+ BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4);
+ sig_ver = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
+ BNXT_GRCP_WINDOW_2_BASE +
+ offsetof(struct hcomm_status,
+ sig_ver)));
+ /* If the signature is absent, then FW does not support this feature */
+ if ((sig_ver & HCOMM_STATUS_SIGNATURE_MASK) !=
+ HCOMM_STATUS_SIGNATURE_VAL)
+ return 0;
+
+ if (!info) {
+ info = rte_zmalloc("bnxt_hwrm_error_recovery_qcfg",
+ sizeof(*info), 0);
+ if (!info)
+ return -ENOMEM;
+ bp->recovery_info = info;
+ } else {
+ memset(info, 0, sizeof(*info));
+ }
+
+ status_loc = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
+ BNXT_GRCP_WINDOW_2_BASE +
+ offsetof(struct hcomm_status,
+ fw_status_loc)));
+
+ /* Only pre-map the FW health status GRC register */
+ if (BNXT_FW_STATUS_REG_TYPE(status_loc) != BNXT_FW_STATUS_REG_TYPE_GRC)
+ return 0;
+
+ info->status_regs[BNXT_FW_STATUS_REG] = status_loc;
+ info->mapped_status_regs[BNXT_FW_STATUS_REG] =
+ BNXT_GRCP_WINDOW_2_BASE + (status_loc & BNXT_GRCP_OFFSET_MASK);
+
+ rte_write32((status_loc & BNXT_GRCP_BASE_MASK), (uint8_t *)bp->bar0 +
+ BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4);
+
+ bp->fw_cap |= BNXT_FW_CAP_HCOMM_FW_STATUS;
+
+ return 0;
+}
+