bnxt_en: Check max_tx_scheduler_inputs value from firmware.
authorMichael Chan <michael.chan@broadcom.com>
Sat, 31 Mar 2018 17:54:13 +0000 (13:54 -0400)
committerDavid S. Miller <davem@davemloft.net>
Sun, 1 Apr 2018 03:24:19 +0000 (23:24 -0400)
When checking for the maximum pre-set TX channels for ethtool -l, we
need to check the current max_tx_scheduler_inputs parameter from firmware.
This parameter specifies the max input for the internal QoS nodes currently
available to this function.  The function's TX rings will be capped by this
parameter.  By adding this logic, we provide a more accurate pre-set max
TX channels to the user.

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_ethtool.c

index 2251327f8cdf5fe08bb1bf79e155c71a3f3b5099..62b7d69cc8e5b37fe8c2fb976f04c785f6c6cd02 100644 (file)
@@ -5093,7 +5093,7 @@ func_qcfg_exit:
        return rc;
 }
 
-static int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp)
+int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp, bool all)
 {
        struct hwrm_func_resource_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
        struct hwrm_func_resource_qcaps_input req = {0};
@@ -5110,6 +5110,10 @@ static int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp)
                goto hwrm_func_resc_qcaps_exit;
        }
 
+       hw_resc->max_tx_sch_inputs = le16_to_cpu(resp->max_tx_scheduler_inputs);
+       if (!all)
+               goto hwrm_func_resc_qcaps_exit;
+
        hw_resc->min_rsscos_ctxs = le16_to_cpu(resp->min_rsscos_ctx);
        hw_resc->max_rsscos_ctxs = le16_to_cpu(resp->max_rsscos_ctx);
        hw_resc->min_cp_rings = le16_to_cpu(resp->min_cmpl_rings);
@@ -5216,7 +5220,7 @@ static int bnxt_hwrm_func_qcaps(struct bnxt *bp)
        if (rc)
                return rc;
        if (bp->hwrm_spec_code >= 0x10803) {
-               rc = bnxt_hwrm_func_resc_qcaps(bp);
+               rc = bnxt_hwrm_func_resc_qcaps(bp, true);
                if (!rc)
                        bp->flags |= BNXT_FLAG_NEW_RM;
        }
index 78034b504baa84a729a5781aabd2ab453724eedd..22aa290c94a0f3804de83121c8d83264b8527a50 100644 (file)
@@ -786,6 +786,7 @@ struct bnxt_hw_resc {
        u16     min_tx_rings;
        u16     max_tx_rings;
        u16     resv_tx_rings;
+       u16     max_tx_sch_inputs;
        u16     min_rx_rings;
        u16     max_rx_rings;
        u16     resv_rx_rings;
@@ -1456,6 +1457,7 @@ int bnxt_hwrm_set_pause(struct bnxt *);
 int bnxt_hwrm_set_link_setting(struct bnxt *, bool, bool);
 int bnxt_hwrm_alloc_wol_fltr(struct bnxt *bp);
 int bnxt_hwrm_free_wol_fltr(struct bnxt *bp);
+int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp, bool all);
 int bnxt_hwrm_fw_set_time(struct bnxt *);
 int bnxt_open_nic(struct bnxt *, bool, bool);
 int bnxt_half_open_nic(struct bnxt *bp);
index e184e4bbe544ad1bc8219e123ef79d07182ccb65..8d8ccd67e0e27a58b7b1fde4f61dd0765d4b455f 100644 (file)
@@ -425,15 +425,26 @@ static void bnxt_get_channels(struct net_device *dev,
                              struct ethtool_channels *channel)
 {
        struct bnxt *bp = netdev_priv(dev);
+       struct bnxt_hw_resc *hw_resc = &bp->hw_resc;
        int max_rx_rings, max_tx_rings, tcs;
+       int max_tx_sch_inputs;
+
+       /* Get the most up-to-date max_tx_sch_inputs. */
+       if (bp->flags & BNXT_FLAG_NEW_RM)
+               bnxt_hwrm_func_resc_qcaps(bp, false);
+       max_tx_sch_inputs = hw_resc->max_tx_sch_inputs;
 
        bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, true);
+       if (max_tx_sch_inputs)
+               max_tx_rings = min_t(int, max_tx_rings, max_tx_sch_inputs);
        channel->max_combined = min_t(int, max_rx_rings, max_tx_rings);
 
        if (bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, false)) {
                max_rx_rings = 0;
                max_tx_rings = 0;
        }
+       if (max_tx_sch_inputs)
+               max_tx_rings = min_t(int, max_tx_rings, max_tx_sch_inputs);
 
        tcs = netdev_get_num_tc(dev);
        if (tcs > 1)