From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 0EBA046140;
	Tue, 28 Jan 2025 15:48:25 +0100 (CET)
Received: from mails.dpdk.org (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id B6F8640EF0;
	Tue, 28 Jan 2025 15:47:20 +0100 (CET)
Received: from lf-2-14.ptr.blmpb.com (lf-2-14.ptr.blmpb.com [101.36.218.14])
 by mails.dpdk.org (Postfix) with ESMTP id F018D40ED4
 for <dev@dpdk.org>; Tue, 28 Jan 2025 15:47:16 +0100 (CET)
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
 s=feishu2403070942; d=yunsilicon.com; t=1738075632; h=from:subject:
 mime-version:from:date:message-id:subject:to:cc:reply-to:content-type:
 mime-version:in-reply-to:message-id;
 bh=98ZVqt/GEUX4otQWxjmGnKXYWNqSPm6FRZJFCKzyY40=;
 b=K57+oLGgfRzscmcNXN8S204IvRoLZThWYBtlcKF4byj9/Ac4vyS6Uw/gTkRBkvnemRiHzP
 iIDwt5l+fDVGjS2LwkqCuDTDEyTVvs0PVIiJlQMryehpbQazH2p6Xm6Lq39ekpO/bmOIak
 rrhZy0pgK1/NqzdBWrfDqM9mG7evDTaJmPALrG6vnI4y7B80Ea+rT0f81OKbVCMFPc9hQA
 2WTZuKCd1xvM4DQg3HuUNd2+qScqu4zRGxH62qYD3vYSPN8YF4bF71y+anbtDOI/vvZny4
 VLvSm69cGtsJEWJmkoNQKIWTH7tunTLUSPt9XcG/qYNIFUAhRMZYuMATB5ojwg==
Subject: [PATCH v7 10/15] net/xsc: add ethdev stop and close
X-Original-From: Renyong Wan <wanry@yunsilicon.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
In-Reply-To: <20250128144649.1956159-1-wanry@yunsilicon.com>
X-Lms-Return-Path: <lba+26798edee+f3f6f3+dpdk.org+wanry@yunsilicon.com>
Content-Transfer-Encoding: 7bit
Date: Tue, 28 Jan 2025 22:47:09 +0800
Message-Id: <20250128144708.1956159-11-wanry@yunsilicon.com>
References: <20250128144649.1956159-1-wanry@yunsilicon.com>
To: <dev@dpdk.org>
From: "Renyong Wan" <wanry@yunsilicon.com>
X-Mailer: git-send-email 2.25.1
Cc: <ferruh.yigit@amd.com>, <thomas@monjalon.net>, 
 <stephen@networkplumber.org>, <qianr@yunsilicon.com>, 
 <nana@yunsilicon.com>, <zhangxx@yunsilicon.com>, <xudw@yunsilicon.com>, 
 <jacky@yunsilicon.com>, <weihg@yunsilicon.com>
Received: from ubuntu-liun.yunsilicon.com ([58.34.192.114]) by smtp.feishu.cn
 with ESMTPS; Tue, 28 Jan 2025 22:47:09 +0800
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org

Implement xsc ethdev close and stop functions.

Signed-off-by: Renyong Wan <wanry@yunsilicon.com>
---
 drivers/net/xsc/xsc_dev.c    |  12 ++++
 drivers/net/xsc/xsc_dev.h    |   2 +
 drivers/net/xsc/xsc_ethdev.c | 108 +++++++++++++++++++++++++++++++++++
 drivers/net/xsc/xsc_rx.c     |  47 +++++++++++++++
 drivers/net/xsc/xsc_rx.h     |   2 +
 drivers/net/xsc/xsc_tx.c     |  33 +++++++++++
 drivers/net/xsc/xsc_tx.h     |   2 +
 7 files changed, 206 insertions(+)

diff --git a/drivers/net/xsc/xsc_dev.c b/drivers/net/xsc/xsc_dev.c
index 054a08bf84..350a1fbc70 100644
--- a/drivers/net/xsc/xsc_dev.c
+++ b/drivers/net/xsc/xsc_dev.c
@@ -68,6 +68,18 @@ xsc_dev_get_mac(struct xsc_dev *xdev, uint8_t *mac)
 	return xdev->dev_ops->get_mac(xdev, mac);
 }
 
+int
+xsc_dev_destroy_qp(struct xsc_dev *xdev, void *qp)
+{
+	return xdev->dev_ops->destroy_qp(qp);
+}
+
+int
+xsc_dev_destroy_cq(struct xsc_dev *xdev, void *cq)
+{
+	return xdev->dev_ops->destroy_cq(cq);
+}
+
 int
 xsc_dev_modify_qp_status(struct xsc_dev *xdev, uint32_t qpn, int num, int opcode)
 {
diff --git a/drivers/net/xsc/xsc_dev.h b/drivers/net/xsc/xsc_dev.h
index fafe53f752..c0a4d57af7 100644
--- a/drivers/net/xsc/xsc_dev.h
+++ b/drivers/net/xsc/xsc_dev.h
@@ -158,6 +158,8 @@ struct xsc_dev_ops {
 int xsc_dev_mailbox_exec(struct xsc_dev *xdev, void *data_in,
 			 int in_len, void *data_out, int out_len);
 void xsc_dev_ops_register(struct xsc_dev_ops *new_ops);
+int xsc_dev_destroy_qp(struct xsc_dev *xdev, void *qp);
+int xsc_dev_destroy_cq(struct xsc_dev *xdev, void *cq);
 int xsc_dev_modify_qp_status(struct xsc_dev *xdev, uint32_t qpn, int num, int opcode);
 int xsc_dev_modify_qp_qostree(struct xsc_dev *xdev, uint16_t qpn);
 int xsc_dev_rx_cq_create(struct xsc_dev *xdev, struct xsc_rx_cq_params *cq_params,
diff --git a/drivers/net/xsc/xsc_ethdev.c b/drivers/net/xsc/xsc_ethdev.c
index 24ee1e2cdc..0f5a6c3ba2 100644
--- a/drivers/net/xsc/xsc_ethdev.c
+++ b/drivers/net/xsc/xsc_ethdev.c
@@ -87,6 +87,44 @@ xsc_ethdev_configure(struct rte_eth_dev *dev)
 	return -rte_errno;
 }
 
+static void
+xsc_ethdev_txq_release(struct rte_eth_dev *dev, uint16_t idx)
+{
+	struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
+	struct xsc_txq_data *txq_data = xsc_txq_get(priv, idx);
+
+	if (txq_data == NULL)
+		return;
+
+	xsc_dev_set_qpsetid(priv->xdev, txq_data->qpn, 0);
+	xsc_txq_obj_release(priv->xdev, txq_data);
+	rte_free(txq_data->fcqs);
+	txq_data->fcqs = NULL;
+	xsc_txq_elts_free(txq_data);
+	rte_free(txq_data);
+	(*priv->txqs)[idx] = NULL;
+
+	dev->data->tx_queues[idx] = NULL;
+	dev->data->tx_queue_state[idx] = RTE_ETH_QUEUE_STATE_STOPPED;
+}
+
+static void
+xsc_ethdev_rxq_release(struct rte_eth_dev *dev, uint16_t idx)
+{
+	struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
+	struct xsc_rxq_data *rxq_data = xsc_rxq_get(priv, idx);
+
+	if (rxq_data == NULL)
+		return;
+	xsc_rxq_rss_obj_release(priv->xdev, rxq_data);
+	xsc_rxq_elts_free(rxq_data);
+	rte_free(rxq_data);
+	(*priv->rxqs)[idx] = NULL;
+
+	dev->data->rx_queues[idx] = NULL;
+	dev->data->rx_queue_state[idx] = RTE_ETH_QUEUE_STATE_STOPPED;
+}
+
 static int
 xsc_ethdev_enable(struct rte_eth_dev *dev)
 {
@@ -149,6 +187,30 @@ xsc_ethdev_enable(struct rte_eth_dev *dev)
 	return 0;
 }
 
+static void
+xsc_rxq_stop(struct rte_eth_dev *dev)
+{
+	struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
+	uint16_t i;
+
+	for (i = 0; i != priv->num_rq; ++i)
+		xsc_ethdev_rxq_release(dev, i);
+	priv->rxqs = NULL;
+	priv->flags &= ~XSC_FLAG_RX_QUEUE_INIT;
+}
+
+static void
+xsc_txq_stop(struct rte_eth_dev *dev)
+{
+	struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
+	uint16_t i;
+
+	for (i = 0; i != priv->num_sq; ++i)
+		xsc_ethdev_txq_release(dev, i);
+	priv->txqs = NULL;
+	priv->flags &= ~XSC_FLAG_TX_QUEUE_INIT;
+}
+
 static int
 xsc_txq_start(struct xsc_ethdev_priv *priv)
 {
@@ -253,9 +315,51 @@ xsc_ethdev_start(struct rte_eth_dev *dev)
 
 error:
 	dev->data->dev_started = 0;
+	xsc_txq_stop(dev);
+	xsc_rxq_stop(dev);
 	return -rte_errno;
 }
 
+static int
+xsc_ethdev_stop(struct rte_eth_dev *dev)
+{
+	struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
+	uint16_t i;
+
+	PMD_DRV_LOG(DEBUG, "Port %u stopping", dev->data->port_id);
+	dev->data->dev_started = 0;
+	dev->rx_pkt_burst = rte_eth_pkt_burst_dummy;
+	dev->tx_pkt_burst = rte_eth_pkt_burst_dummy;
+	rte_wmb();
+
+	rte_delay_us_sleep(1000 * priv->num_rq);
+	for (i = 0; i < priv->num_rq; ++i)
+		dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+	for (i = 0; i < priv->num_sq; ++i)
+		dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+
+	return 0;
+}
+
+static int
+xsc_ethdev_close(struct rte_eth_dev *dev)
+{
+	struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
+
+	PMD_DRV_LOG(DEBUG, "Port %u closing", dev->data->port_id);
+	dev->rx_pkt_burst = rte_eth_pkt_burst_dummy;
+	dev->tx_pkt_burst = rte_eth_pkt_burst_dummy;
+	rte_wmb();
+
+	xsc_txq_stop(dev);
+	xsc_rxq_stop(dev);
+
+	rte_free(priv->rss_conf.rss_key);
+	xsc_dev_close(priv->xdev, priv->representor_id);
+	dev->data->mac_addrs = NULL;
+	return 0;
+}
+
 static int
 xsc_ethdev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 			  uint32_t socket, const struct rte_eth_rxconf *conf,
@@ -364,8 +468,12 @@ xsc_ethdev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac, uin
 const struct eth_dev_ops xsc_eth_dev_ops = {
 	.dev_configure = xsc_ethdev_configure,
 	.dev_start = xsc_ethdev_start,
+	.dev_stop = xsc_ethdev_stop,
+	.dev_close = xsc_ethdev_close,
 	.rx_queue_setup = xsc_ethdev_rx_queue_setup,
 	.tx_queue_setup = xsc_ethdev_tx_queue_setup,
+	.rx_queue_release = xsc_ethdev_rxq_release,
+	.tx_queue_release = xsc_ethdev_txq_release,
 	.rss_hash_update = xsc_ethdev_rss_hash_update,
 	.rss_hash_conf_get = xsc_ethdev_rss_hash_conf_get,
 };
diff --git a/drivers/net/xsc/xsc_rx.c b/drivers/net/xsc/xsc_rx.c
index f3667313be..2081f3b619 100644
--- a/drivers/net/xsc/xsc_rx.c
+++ b/drivers/net/xsc/xsc_rx.c
@@ -289,3 +289,50 @@ xsc_rxq_elts_alloc(struct xsc_rxq_data *rxq_data)
 
 	return -rte_errno;
 }
+
+void
+xsc_rxq_elts_free(struct xsc_rxq_data *rxq_data)
+{
+	uint16_t i;
+
+	if (rxq_data->elts == NULL)
+		return;
+	for (i = 0; i != rxq_data->wqe_s; ++i) {
+		if ((*rxq_data->elts)[i] != NULL)
+			rte_pktmbuf_free_seg((*rxq_data->elts)[i]);
+		(*rxq_data->elts)[i] = NULL;
+	}
+
+	PMD_DRV_LOG(DEBUG, "Port %u rxq %u free elts", rxq_data->port_id, rxq_data->idx);
+}
+
+void
+xsc_rxq_rss_obj_release(struct xsc_dev *xdev, struct xsc_rxq_data *rxq_data)
+{
+	struct xsc_cmd_destroy_qp_mbox_in in = { .hdr = { 0 } };
+	struct xsc_cmd_destroy_qp_mbox_out out = { .hdr = { 0 } };
+	int ret, in_len, out_len;
+	uint32_t qpn = rxq_data->qpn;
+
+	xsc_dev_modify_qp_status(xdev, qpn, 1, XSC_CMD_OP_QP_2RST);
+
+	in_len = sizeof(struct xsc_cmd_destroy_qp_mbox_in);
+	out_len = sizeof(struct xsc_cmd_destroy_qp_mbox_out);
+	in.hdr.opcode = rte_cpu_to_be_16(XSC_CMD_OP_DESTROY_QP);
+	in.qpn = rte_cpu_to_be_32(rxq_data->qpn);
+
+	ret = xsc_dev_mailbox_exec(xdev, &in, in_len, &out, out_len);
+	if (ret != 0 || out.hdr.status != 0) {
+		PMD_DRV_LOG(ERR,
+			    "Release rss rq failed, port id=%d, qid=%d, err=%d, out.status=%u",
+			    rxq_data->port_id, rxq_data->idx, ret, out.hdr.status);
+		rte_errno = ENOEXEC;
+		return;
+	}
+
+	rte_memzone_free(rxq_data->rq_pas);
+
+	if (rxq_data->cq != NULL)
+		xsc_dev_destroy_cq(xdev, rxq_data->cq);
+	rxq_data->cq = NULL;
+}
diff --git a/drivers/net/xsc/xsc_rx.h b/drivers/net/xsc/xsc_rx.h
index 5a2c4839ce..e24b1a8829 100644
--- a/drivers/net/xsc/xsc_rx.h
+++ b/drivers/net/xsc/xsc_rx.h
@@ -58,5 +58,7 @@ struct __rte_cache_aligned xsc_rxq_data {
 
 int xsc_rxq_elts_alloc(struct xsc_rxq_data *rxq_data);
 int xsc_rxq_rss_obj_new(struct xsc_ethdev_priv *priv, uint16_t port_id);
+void xsc_rxq_rss_obj_release(struct xsc_dev *xdev, struct xsc_rxq_data *rxq_data);
+void xsc_rxq_elts_free(struct xsc_rxq_data *rxq_data);
 
 #endif /* _XSC_RX_H_ */
diff --git a/drivers/net/xsc/xsc_tx.c b/drivers/net/xsc/xsc_tx.c
index ba80488010..56daf6b4c6 100644
--- a/drivers/net/xsc/xsc_tx.c
+++ b/drivers/net/xsc/xsc_tx.c
@@ -91,3 +91,36 @@ xsc_txq_obj_new(struct xsc_dev *xdev, struct xsc_txq_data *txq_data,
 error:
 	return -rte_errno;
 }
+
+void
+xsc_txq_obj_release(struct xsc_dev *xdev, struct xsc_txq_data *txq_data)
+{
+	PMD_DRV_LOG(DEBUG, "Destroy tx queue %u, portid %u",
+		    txq_data->idx, txq_data->port_id);
+	if (txq_data->qp != NULL)
+		xsc_dev_destroy_qp(xdev, txq_data->qp);
+	if (txq_data->cq != NULL)
+		xsc_dev_destroy_cq(xdev, txq_data->cq);
+}
+
+void
+xsc_txq_elts_free(struct xsc_txq_data *txq_data)
+{
+	const uint16_t elts_n = 1 << txq_data->elts_n;
+	const uint16_t elts_m = elts_n - 1;
+	uint16_t elts_head = txq_data->elts_head;
+	uint16_t elts_tail = txq_data->elts_tail;
+	struct rte_mbuf *(*elts)[elts_n] = &txq_data->elts;
+
+	txq_data->elts_head = 0;
+	txq_data->elts_tail = 0;
+	txq_data->elts_comp = 0;
+
+	while (elts_tail != elts_head) {
+		struct rte_mbuf *elt = (*elts)[elts_tail & elts_m];
+
+		rte_pktmbuf_free_seg(elt);
+		++elts_tail;
+	}
+	PMD_DRV_LOG(DEBUG, "Port %u txq %u free elts", txq_data->port_id, txq_data->idx);
+}
diff --git a/drivers/net/xsc/xsc_tx.h b/drivers/net/xsc/xsc_tx.h
index 674b65a555..208f1c8490 100644
--- a/drivers/net/xsc/xsc_tx.h
+++ b/drivers/net/xsc/xsc_tx.h
@@ -55,5 +55,7 @@ struct __rte_cache_aligned xsc_txq_data {
 int xsc_txq_obj_new(struct xsc_dev *xdev, struct xsc_txq_data *txq_data,
 		    uint64_t offloads, uint16_t idx);
 void xsc_txq_elts_alloc(struct xsc_txq_data *txq_data);
+void xsc_txq_obj_release(struct xsc_dev *xdev, struct xsc_txq_data *txq_data);
+void xsc_txq_elts_free(struct xsc_txq_data *txq_data);
 
 #endif /* _XSC_TX_H_ */
-- 
2.25.1