Blob Blame History Raw
From: Michael Chan <michael.chan@broadcom.com>
Date: Sat, 31 Mar 2018 13:54:13 -0400
Subject: bnxt_en: Check max_tx_scheduler_inputs value from firmware.
Patch-mainline: v4.17-rc1
Git-commit: db4723b3cd2d836ae44382d16e6a4418ae8929dc
References: bsc#1086282 FATE#324873

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>
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c         |    8 ++++++--
 drivers/net/ethernet/broadcom/bnxt/bnxt.h         |    2 ++
 drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c |   11 +++++++++++
 3 files changed, 19 insertions(+), 2 deletions(-)

--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -5038,7 +5038,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};
@@ -5055,6 +5055,10 @@ static int bnxt_hwrm_func_resc_qcaps(str
 		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);
@@ -5161,7 +5165,7 @@ static int bnxt_hwrm_func_qcaps(struct b
 	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;
 	}
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -765,6 +765,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;
@@ -1446,6 +1447,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);
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -413,15 +413,26 @@ static void bnxt_get_channels(struct net
 			      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)