bnxt_en: Update VNIC resource calculation for VFs
authorVikas Gupta <vikas.gupta@broadcom.com>
Wed, 27 Sep 2023 03:57:34 +0000 (20:57 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 4 Oct 2023 10:23:01 +0000 (11:23 +0100)
Newer versions of firmware will pre-reserve 1 VNIC for every possible
PF and VF function.  Update the driver logic to take this into account
when assigning VNICs to the VFs.  These pre-reserved VNICs for the
inactive VFs should be subtracted from the global pool before
assigning them to the active VFs.

Not doing so may cause discrepancies that ultimately may cause some VFs to
have insufficient VNICs to support features such as aRFS.

Signed-off-by: Vikas Gupta <vikas.gupta@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c

index d0a255bd71daf1636f74caf21fb95a25f09718d9..82833326a852849325a9f1c9193f146d52e6c67f 100644 (file)
@@ -12215,6 +12215,20 @@ static void bnxt_init_dflt_coal(struct bnxt *bp)
        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;
@@ -12271,6 +12285,9 @@ static int bnxt_fw_init_one_p2(struct bnxt *bp)
        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);
index ae03c5ba83adac2fd81b6ba0c7518e2f1950a423..5d8252272cc9ec17b3a2195d214dfeb5f284ede2 100644 (file)
@@ -2014,6 +2014,7 @@ struct bnxt {
        #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;
 
@@ -2054,6 +2055,7 @@ struct bnxt {
 #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;
index 98c167ff0ffbf0c2a70a7a0ddfe92b3460feb98a..38fe44838639e18853ba480b9d61f50ec34359ee 100644 (file)
@@ -552,7 +552,6 @@ static int bnxt_hwrm_func_vf_resc_cfg(struct bnxt *bp, int num_vfs, bool reset)
                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);
@@ -574,11 +573,20 @@ static int bnxt_hwrm_func_vf_resc_cfg(struct bnxt *bp, int num_vfs, bool reset)
                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);