bp->stats_coal_ticks = BNXT_DEF_STATS_COAL_TICKS;
 }
 
+/* FW that pre-reserves 1 VNIC per function */
+static bool bnxt_fw_pre_resv_vnics(struct bnxt *bp)
+{
+       u16 fw_maj = BNXT_FW_MAJ(bp), fw_bld = BNXT_FW_BLD(bp);
+
+       if (!(bp->flags & BNXT_FLAG_CHIP_P5) &&
+           (fw_maj > 218 || (fw_maj == 218 && fw_bld >= 18)))
+               return true;
+       if ((bp->flags & BNXT_FLAG_CHIP_P5) &&
+           (fw_maj > 216 || (fw_maj == 216 && fw_bld >= 172)))
+               return true;
+       return false;
+}
+
 static int bnxt_fw_init_one_p1(struct bnxt *bp)
 {
        int rc;
        if (rc)
                return -ENODEV;
 
+       if (bnxt_fw_pre_resv_vnics(bp))
+               bp->fw_cap |= BNXT_FW_CAP_PRE_RESV_VNICS;
+
        bnxt_hwrm_func_qcfg(bp);
        bnxt_hwrm_vnic_qcaps(bp);
        bnxt_hwrm_port_led_qcaps(bp);
 
        #define BNXT_FW_CAP_PTP                         BIT_ULL(32)
        #define BNXT_FW_CAP_THRESHOLD_TEMP_SUPPORTED    BIT_ULL(33)
        #define BNXT_FW_CAP_DFLT_VLAN_TPID_PCP          BIT_ULL(34)
+       #define BNXT_FW_CAP_PRE_RESV_VNICS              BIT_ULL(35)
 
        u32                     fw_dbg_cap;
 
 #define BNXT_FW_VER_CODE(maj, min, bld, rsv)                   \
        ((u64)(maj) << 48 | (u64)(min) << 32 | (u64)(bld) << 16 | (rsv))
 #define BNXT_FW_MAJ(bp)                ((bp)->fw_ver_code >> 48)
+#define BNXT_FW_BLD(bp)                (((bp)->fw_ver_code >> 16) & 0xffff)
 
        u16                     vxlan_fw_dst_port_id;
        u16                     nge_fw_dst_port_id;
 
                vf_rx_rings = hw_resc->max_rx_rings - bp->rx_nr_rings;
        vf_tx_rings = hw_resc->max_tx_rings - bp->tx_nr_rings;
        vf_vnics = hw_resc->max_vnics - bp->nr_vnics;
-       vf_vnics = min_t(u16, vf_vnics, vf_rx_rings);
        vf_rss = hw_resc->max_rsscos_ctxs - bp->rsscos_nr_ctxs;
 
        req->min_rsscos_ctx = cpu_to_le16(BNXT_VF_MIN_RSS_CTX);
                vf_cp_rings /= num_vfs;
                vf_tx_rings /= num_vfs;
                vf_rx_rings /= num_vfs;
-               vf_vnics /= num_vfs;
+               if ((bp->fw_cap & BNXT_FW_CAP_PRE_RESV_VNICS) &&
+                   vf_vnics >= pf->max_vfs) {
+                       /* Take into account that FW has pre-reserved 1 VNIC for
+                        * each pf->max_vfs.
+                        */
+                       vf_vnics = (vf_vnics - pf->max_vfs + num_vfs) / num_vfs;
+               } else {
+                       vf_vnics /= num_vfs;
+               }
                vf_stat_ctx /= num_vfs;
                vf_ring_grps /= num_vfs;
                vf_rss /= num_vfs;
 
+               vf_vnics = min_t(u16, vf_vnics, vf_rx_rings);
                req->min_cmpl_rings = cpu_to_le16(vf_cp_rings);
                req->min_tx_rings = cpu_to_le16(vf_tx_rings);
                req->min_rx_rings = cpu_to_le16(vf_rx_rings);