[08/31] common/cnxk: disable BP on SDP link while closing SQ

Message ID 20230811085805.441256-8-ndabilpuram@marvell.com (mailing list archive)
State Accepted, archived
Delegated to: Jerin Jacob
Headers
Series [01/31] common/cnxk: add aura ref count mechanism |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Nithin Dabilpuram Aug. 11, 2023, 8:57 a.m. UTC
  From: Satha Rao <skoteshwar@marvell.com>

Host SDP port closes the SDP link on NIX causes crash when
BP enabled on SDP link. This patch disables BP on SDP link
when SQ flush fails due to link disabled at host.

Signed-off-by: Satha Rao <skoteshwar@marvell.com>
---
 drivers/common/cnxk/roc_nix_tm.c | 73 ++++++++++++++++++++++++++++++--
 1 file changed, 70 insertions(+), 3 deletions(-)
  

Patch

diff --git a/drivers/common/cnxk/roc_nix_tm.c b/drivers/common/cnxk/roc_nix_tm.c
index c104611355..ce1e44ac4f 100644
--- a/drivers/common/cnxk/roc_nix_tm.c
+++ b/drivers/common/cnxk/roc_nix_tm.c
@@ -610,8 +610,6 @@  roc_nix_tm_sq_flush_spin(struct roc_nix_sq *sq)
 
 	return 0;
 exit:
-	roc_nix_tm_dump(sq->roc_nix, NULL);
-	roc_nix_queues_ctx_dump(sq->roc_nix, NULL);
 	return -EFAULT;
 }
 
@@ -748,6 +746,70 @@  roc_nix_tm_sq_free_pending_sqe(struct nix *nix, int q)
 	return 0;
 }
 
+static inline int
+nix_tm_sdp_sq_drop_pkts(struct roc_nix *roc_nix, struct roc_nix_sq *sq)
+{
+	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+	struct mbox *mbox = mbox_get((&nix->dev)->mbox);
+	struct nix_txschq_config *req = NULL, *rsp;
+	enum roc_nix_tm_tree tree = nix->tm_tree;
+	int rc = 0, qid = sq->qid;
+	struct nix_tm_node *node;
+	uint64_t regval;
+
+	/* Find the node for this SQ */
+	node = nix_tm_node_search(nix, qid, tree);
+	while (node) {
+		if (node->hw_lvl != NIX_TXSCH_LVL_TL4) {
+			node = node->parent;
+			continue;
+		}
+		break;
+	}
+	if (!node) {
+		plt_err("Invalid node/state for sq %u", qid);
+		return -EFAULT;
+	}
+
+	/* Get present link config */
+	req = mbox_alloc_msg_nix_txschq_cfg(mbox);
+	req->read = 1;
+	req->lvl = NIX_TXSCH_LVL_TL4;
+	req->reg[0] = NIX_AF_TL4X_SDP_LINK_CFG(node->hw_id);
+	req->num_regs = 1;
+	rc = mbox_process_msg(mbox, (void **)&rsp);
+	if (rc || rsp->num_regs != 1)
+		goto err;
+	regval = rsp->regval[0];
+	/* Disable BP_ENA in SDP link config */
+	req = mbox_alloc_msg_nix_txschq_cfg(mbox);
+	req->lvl = NIX_TXSCH_LVL_TL4;
+	req->reg[0] = NIX_AF_TL4X_SDP_LINK_CFG(node->hw_id);
+	req->regval[0] = 0x0ull;
+	req->regval_mask[0] = ~(BIT_ULL(13));
+	req->num_regs = 1;
+	rc = mbox_process(mbox);
+	if (rc)
+		goto err;
+	mbox_put(mbox);
+	/* Flush SQ to drop all packets */
+	rc = roc_nix_tm_sq_flush_spin(sq);
+	if (rc)
+		plt_nix_dbg("SQ flush failed with link reset config rc %d", rc);
+	mbox = mbox_get((&nix->dev)->mbox);
+	/* Restore link config */
+	req = mbox_alloc_msg_nix_txschq_cfg(mbox);
+	req->reg[0] = NIX_AF_TL4X_SDP_LINK_CFG(node->hw_id);
+	req->lvl = NIX_TXSCH_LVL_TL4;
+	req->regval[0] = regval;
+	req->regval_mask[0] = ~(BIT_ULL(13) | BIT_ULL(12) | GENMASK_ULL(7, 0));
+	req->num_regs = 1;
+	rc = mbox_process(mbox);
+err:
+	mbox_put(mbox);
+	return rc;
+}
+
 /* Flush and disable tx queue and its parent SMQ */
 int
 nix_tm_sq_flush_pre(struct roc_nix_sq *sq)
@@ -834,8 +896,13 @@  nix_tm_sq_flush_pre(struct roc_nix_sq *sq)
 		/* Wait for sq entries to be flushed */
 		rc = roc_nix_tm_sq_flush_spin(sq);
 		if (rc) {
-			rc = roc_nix_tm_sq_free_pending_sqe(nix, sq->qid);
+			if (nix->sdp_link)
+				rc = nix_tm_sdp_sq_drop_pkts(roc_nix, sq);
+			else
+				rc = roc_nix_tm_sq_free_pending_sqe(nix, sq->qid);
 			if (rc) {
+				roc_nix_tm_dump(sq->roc_nix, NULL);
+				roc_nix_queues_ctx_dump(sq->roc_nix, NULL);
 				plt_err("Failed to drain sq %u, rc=%d\n", sq->qid, rc);
 				return rc;
 			}