Thomas Bogendoerfer 15c6c1
From: Michael Chan <michael.chan@broadcom.com>
Thomas Bogendoerfer 15c6c1
Date: Wed, 17 Jan 2018 03:21:12 -0500
Thomas Bogendoerfer 15c6c1
Subject: bnxt_en: Expand bnxt_check_rings() to check all resources.
Thomas Bogendoerfer 15c6c1
Patch-mainline: v4.16-rc1
Thomas Bogendoerfer 15c6c1
Git-commit: 8f23d638b36b4ff0fe5785cf01f9bdc41afb9c06
Thomas Bogendoerfer 15c6c1
References: bsc#1086282 FATE#324873
Thomas Bogendoerfer 15c6c1
Thomas Bogendoerfer 15c6c1
bnxt_check_rings() is called by ethtool, XDP setup, and ndo_setup_tc()
Thomas Bogendoerfer 15c6c1
to see if there are enough resources to support the new configuration.
Thomas Bogendoerfer 15c6c1
Expand the call to test all resources if the firmware supports the new
Thomas Bogendoerfer 15c6c1
API.  With the more flexible resource allocation scheme, this call must
Thomas Bogendoerfer 15c6c1
be made to check that all resources are available before committing to
Thomas Bogendoerfer 15c6c1
allocate the resources.
Thomas Bogendoerfer 15c6c1
Thomas Bogendoerfer 15c6c1
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Thomas Bogendoerfer 15c6c1
Signed-off-by: David S. Miller <davem@davemloft.net>
Thomas Bogendoerfer 15c6c1
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
Thomas Bogendoerfer 15c6c1
---
Thomas Bogendoerfer 15c6c1
 drivers/net/ethernet/broadcom/bnxt/bnxt.c |   93 +++++++++++++++++++++++++++---
Thomas Bogendoerfer 15c6c1
 1 file changed, 84 insertions(+), 9 deletions(-)
Thomas Bogendoerfer 15c6c1
Thomas Bogendoerfer 15c6c1
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
Thomas Bogendoerfer 15c6c1
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
Thomas Bogendoerfer 15c6c1
@@ -4712,28 +4712,99 @@ static bool bnxt_need_reserve_rings(stru
Thomas Bogendoerfer 15c6c1
 	return false;
Thomas Bogendoerfer 15c6c1
 }
Thomas Bogendoerfer 15c6c1
 
Thomas Bogendoerfer 15c6c1
-static int bnxt_hwrm_check_tx_rings(struct bnxt *bp, int tx_rings)
Thomas Bogendoerfer 15c6c1
+static int bnxt_hwrm_check_vf_rings(struct bnxt *bp, int tx_rings, int rx_rings,
Thomas Bogendoerfer 15c6c1
+				    int ring_grps, int cp_rings)
Thomas Bogendoerfer 15c6c1
 {
Thomas Bogendoerfer 15c6c1
-	struct hwrm_func_cfg_input req = {0};
Thomas Bogendoerfer 15c6c1
+	struct hwrm_func_vf_cfg_input req = {0};
Thomas Bogendoerfer 15c6c1
+	u32 flags, enables;
Thomas Bogendoerfer 15c6c1
 	int rc;
Thomas Bogendoerfer 15c6c1
 
Thomas Bogendoerfer 15c6c1
-	if (bp->hwrm_spec_code < 0x10801)
Thomas Bogendoerfer 15c6c1
+	if (!(bp->flags & BNXT_FLAG_NEW_RM))
Thomas Bogendoerfer 15c6c1
 		return 0;
Thomas Bogendoerfer 15c6c1
 
Thomas Bogendoerfer 15c6c1
-	if (BNXT_VF(bp))
Thomas Bogendoerfer 15c6c1
-		return 0;
Thomas Bogendoerfer 15c6c1
+	bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_VF_CFG, -1, -1);
Thomas Bogendoerfer 15c6c1
+	flags = FUNC_VF_CFG_REQ_FLAGS_TX_ASSETS_TEST |
Thomas Bogendoerfer 15c6c1
+		FUNC_VF_CFG_REQ_FLAGS_RX_ASSETS_TEST |
Thomas Bogendoerfer 15c6c1
+		FUNC_VF_CFG_REQ_FLAGS_CMPL_ASSETS_TEST |
Thomas Bogendoerfer 15c6c1
+		FUNC_VF_CFG_REQ_FLAGS_RING_GRP_ASSETS_TEST |
Thomas Bogendoerfer 15c6c1
+		FUNC_VF_CFG_REQ_FLAGS_STAT_CTX_ASSETS_TEST |
Thomas Bogendoerfer 15c6c1
+		FUNC_VF_CFG_REQ_FLAGS_VNIC_ASSETS_TEST;
Thomas Bogendoerfer 15c6c1
+	enables = FUNC_VF_CFG_REQ_ENABLES_NUM_TX_RINGS |
Thomas Bogendoerfer 15c6c1
+		  FUNC_VF_CFG_REQ_ENABLES_NUM_RX_RINGS |
Thomas Bogendoerfer 15c6c1
+		  FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS |
Thomas Bogendoerfer 15c6c1
+		  FUNC_VF_CFG_REQ_ENABLES_NUM_HW_RING_GRPS |
Thomas Bogendoerfer 15c6c1
+		  FUNC_VF_CFG_REQ_ENABLES_NUM_STAT_CTXS |
Thomas Bogendoerfer 15c6c1
+		  FUNC_VF_CFG_REQ_ENABLES_NUM_VNICS;
Thomas Bogendoerfer 15c6c1
+
Thomas Bogendoerfer 15c6c1
+	req.flags = cpu_to_le32(flags);
Thomas Bogendoerfer 15c6c1
+	req.enables = cpu_to_le32(enables);
Thomas Bogendoerfer 15c6c1
+	req.num_tx_rings = cpu_to_le16(tx_rings);
Thomas Bogendoerfer 15c6c1
+	req.num_rx_rings = cpu_to_le16(rx_rings);
Thomas Bogendoerfer 15c6c1
+	req.num_cmpl_rings = cpu_to_le16(cp_rings);
Thomas Bogendoerfer 15c6c1
+	req.num_hw_ring_grps = cpu_to_le16(ring_grps);
Thomas Bogendoerfer 15c6c1
+	req.num_stat_ctxs = cpu_to_le16(cp_rings);
Thomas Bogendoerfer 15c6c1
+	req.num_vnics = cpu_to_le16(1);
Thomas Bogendoerfer 15c6c1
+	if (bp->flags & BNXT_FLAG_RFS)
Thomas Bogendoerfer 15c6c1
+		req.num_vnics = cpu_to_le16(rx_rings + 1);
Thomas Bogendoerfer 15c6c1
+	rc = hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
Thomas Bogendoerfer 15c6c1
+	if (rc)
Thomas Bogendoerfer 15c6c1
+		return -ENOMEM;
Thomas Bogendoerfer 15c6c1
+	return 0;
Thomas Bogendoerfer 15c6c1
+}
Thomas Bogendoerfer 15c6c1
+
Thomas Bogendoerfer 15c6c1
+static int bnxt_hwrm_check_pf_rings(struct bnxt *bp, int tx_rings, int rx_rings,
Thomas Bogendoerfer 15c6c1
+				    int ring_grps, int cp_rings)
Thomas Bogendoerfer 15c6c1
+{
Thomas Bogendoerfer 15c6c1
+	struct hwrm_func_cfg_input req = {0};
Thomas Bogendoerfer 15c6c1
+	u32 flags, enables;
Thomas Bogendoerfer 15c6c1
+	int rc;
Thomas Bogendoerfer 15c6c1
 
Thomas Bogendoerfer 15c6c1
 	bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1);
Thomas Bogendoerfer 15c6c1
 	req.fid = cpu_to_le16(0xffff);
Thomas Bogendoerfer 15c6c1
-	req.flags = cpu_to_le32(FUNC_CFG_REQ_FLAGS_TX_ASSETS_TEST);
Thomas Bogendoerfer 15c6c1
-	req.enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_NUM_TX_RINGS);
Thomas Bogendoerfer 15c6c1
+	flags = FUNC_CFG_REQ_FLAGS_TX_ASSETS_TEST;
Thomas Bogendoerfer 15c6c1
+	enables = FUNC_CFG_REQ_ENABLES_NUM_TX_RINGS;
Thomas Bogendoerfer 15c6c1
 	req.num_tx_rings = cpu_to_le16(tx_rings);
Thomas Bogendoerfer 15c6c1
+	if (bp->flags & BNXT_FLAG_NEW_RM) {
Thomas Bogendoerfer 15c6c1
+		flags |= FUNC_CFG_REQ_FLAGS_RX_ASSETS_TEST |
Thomas Bogendoerfer 15c6c1
+			 FUNC_CFG_REQ_FLAGS_CMPL_ASSETS_TEST |
Thomas Bogendoerfer 15c6c1
+			 FUNC_CFG_REQ_FLAGS_RING_GRP_ASSETS_TEST |
Thomas Bogendoerfer 15c6c1
+			 FUNC_CFG_REQ_FLAGS_STAT_CTX_ASSETS_TEST |
Thomas Bogendoerfer 15c6c1
+			 FUNC_CFG_REQ_FLAGS_VNIC_ASSETS_TEST;
Thomas Bogendoerfer 15c6c1
+		enables |= FUNC_CFG_REQ_ENABLES_NUM_RX_RINGS |
Thomas Bogendoerfer 15c6c1
+			   FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS |
Thomas Bogendoerfer 15c6c1
+			   FUNC_CFG_REQ_ENABLES_NUM_HW_RING_GRPS |
Thomas Bogendoerfer 15c6c1
+			   FUNC_CFG_REQ_ENABLES_NUM_STAT_CTXS |
Thomas Bogendoerfer 15c6c1
+			   FUNC_CFG_REQ_ENABLES_NUM_VNICS;
Thomas Bogendoerfer 15c6c1
+		req.num_rx_rings = cpu_to_le16(rx_rings);
Thomas Bogendoerfer 15c6c1
+		req.num_cmpl_rings = cpu_to_le16(cp_rings);
Thomas Bogendoerfer 15c6c1
+		req.num_hw_ring_grps = cpu_to_le16(ring_grps);
Thomas Bogendoerfer 15c6c1
+		req.num_stat_ctxs = cpu_to_le16(cp_rings);
Thomas Bogendoerfer 15c6c1
+		req.num_vnics = cpu_to_le16(1);
Thomas Bogendoerfer 15c6c1
+		if (bp->flags & BNXT_FLAG_RFS)
Thomas Bogendoerfer 15c6c1
+			req.num_vnics = cpu_to_le16(rx_rings + 1);
Thomas Bogendoerfer 15c6c1
+	}
Thomas Bogendoerfer 15c6c1
+	req.flags = cpu_to_le32(flags);
Thomas Bogendoerfer 15c6c1
+	req.enables = cpu_to_le32(enables);
Thomas Bogendoerfer 15c6c1
 	rc = hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
Thomas Bogendoerfer 15c6c1
 	if (rc)
Thomas Bogendoerfer 15c6c1
 		return -ENOMEM;
Thomas Bogendoerfer 15c6c1
 	return 0;
Thomas Bogendoerfer 15c6c1
 }
Thomas Bogendoerfer 15c6c1
 
Thomas Bogendoerfer 15c6c1
+static int bnxt_hwrm_check_rings(struct bnxt *bp, int tx_rings, int rx_rings,
Thomas Bogendoerfer 15c6c1
+				 int ring_grps, int cp_rings)
Thomas Bogendoerfer 15c6c1
+{
Thomas Bogendoerfer 15c6c1
+	if (bp->hwrm_spec_code < 0x10801)
Thomas Bogendoerfer 15c6c1
+		return 0;
Thomas Bogendoerfer 15c6c1
+
Thomas Bogendoerfer 15c6c1
+	if (BNXT_PF(bp))
Thomas Bogendoerfer 15c6c1
+		return bnxt_hwrm_check_pf_rings(bp, tx_rings, rx_rings,
Thomas Bogendoerfer 15c6c1
+						ring_grps, cp_rings);
Thomas Bogendoerfer 15c6c1
+
Thomas Bogendoerfer 15c6c1
+	return bnxt_hwrm_check_vf_rings(bp, tx_rings, rx_rings, ring_grps,
Thomas Bogendoerfer 15c6c1
+					cp_rings);
Thomas Bogendoerfer 15c6c1
+}
Thomas Bogendoerfer 15c6c1
+
Thomas Bogendoerfer 15c6c1
 static void bnxt_hwrm_set_coal_params(struct bnxt_coal *hw_coal,
Thomas Bogendoerfer 15c6c1
 	struct hwrm_ring_cmpl_ring_cfg_aggint_params_input *req)
Thomas Bogendoerfer 15c6c1
 {
Thomas Bogendoerfer 15c6c1
@@ -7365,7 +7436,8 @@ int bnxt_check_rings(struct bnxt *bp, in
Thomas Bogendoerfer 15c6c1
 {
Thomas Bogendoerfer 15c6c1
 	int max_rx, max_tx, tx_sets = 1;
Thomas Bogendoerfer 15c6c1
 	int tx_rings_needed;
Thomas Bogendoerfer 15c6c1
-	int rc;
Thomas Bogendoerfer 15c6c1
+	int rx_rings = rx;
Thomas Bogendoerfer 15c6c1
+	int cp, rc;
Thomas Bogendoerfer 15c6c1
 
Thomas Bogendoerfer 15c6c1
 	if (tcs)
Thomas Bogendoerfer 15c6c1
 		tx_sets = tcs;
Thomas Bogendoerfer 15c6c1
@@ -7381,7 +7453,10 @@ int bnxt_check_rings(struct bnxt *bp, in
Thomas Bogendoerfer 15c6c1
 	if (max_tx < tx_rings_needed)
Thomas Bogendoerfer 15c6c1
 		return -ENOMEM;
Thomas Bogendoerfer 15c6c1
 
Thomas Bogendoerfer 15c6c1
-	return bnxt_hwrm_check_tx_rings(bp, tx_rings_needed);
Thomas Bogendoerfer 15c6c1
+	if (bp->flags & BNXT_FLAG_AGG_RINGS)
Thomas Bogendoerfer 15c6c1
+		rx_rings <<= 1;
Thomas Bogendoerfer 15c6c1
+	cp = sh ? max_t(int, tx_rings_needed, rx) : tx_rings_needed + rx;
Thomas Bogendoerfer 15c6c1
+	return bnxt_hwrm_check_rings(bp, tx_rings_needed, rx_rings, rx, cp);
Thomas Bogendoerfer 15c6c1
 }
Thomas Bogendoerfer 15c6c1
 
Thomas Bogendoerfer 15c6c1
 static void bnxt_unmap_bars(struct bnxt *bp, struct pci_dev *pdev)