From patchwork Tue Aug 29 07:58:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Renyong Wan X-Patchwork-Id: 130819 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9507041F53; Tue, 29 Aug 2023 10:09:26 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 34DE5402B7; Tue, 29 Aug 2023 10:09:17 +0200 (CEST) Received: from VLXDG1SPAM1.ramaxel.com (email.unionmem.com [221.4.138.186]) by mails.dpdk.org (Postfix) with ESMTP id 1B7C640293 for ; Tue, 29 Aug 2023 10:09:12 +0200 (CEST) Received: from V12DG1MBS03.ramaxel.local ([172.26.18.33]) by VLXDG1SPAM1.ramaxel.com with ESMTP id 37T7wbm9080463; Tue, 29 Aug 2023 15:59:17 +0800 (GMT-8) (envelope-from wanry@3snic.com) Received: from localhost.localdomain (10.64.136.151) by V12DG1MBS03.ramaxel.local (172.26.18.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2375.17; Tue, 29 Aug 2023 15:58:43 +0800 From: To: CC: , Renyong Wan , Steven Song Subject: [PATCH 16/32] net/sssnic: support Rx queue start and stop Date: Tue, 29 Aug 2023 15:58:13 +0800 Message-ID: <20230829075829.208413-17-wanry@3snic.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230829075829.208413-1-wanry@3snic.com> References: <20230829075829.208413-1-wanry@3snic.com> MIME-Version: 1.0 X-Originating-IP: [10.64.136.151] X-ClientProxiedBy: V12DG1MBS03.ramaxel.local (172.26.18.33) To V12DG1MBS03.ramaxel.local (172.26.18.33) X-DNSRBL: X-SPAM-SOURCE-CHECK: pass X-MAIL: VLXDG1SPAM1.ramaxel.com 37T7wbm9080463 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Renyong Wan Signed-off-by: Steven Song Signed-off-by: Renyong Wan --- drivers/net/sssnic/base/sssnic_api.c | 63 +++++ drivers/net/sssnic/base/sssnic_api.h | 2 + drivers/net/sssnic/base/sssnic_cmd.h | 49 ++++ drivers/net/sssnic/sssnic_ethdev.c | 2 + drivers/net/sssnic/sssnic_ethdev.h | 2 + drivers/net/sssnic/sssnic_ethdev_rx.c | 332 ++++++++++++++++++++++++++ drivers/net/sssnic/sssnic_ethdev_rx.h | 4 + 7 files changed, 454 insertions(+) diff --git a/drivers/net/sssnic/base/sssnic_api.c b/drivers/net/sssnic/base/sssnic_api.c index 3bb31009c5..3050d573bf 100644 --- a/drivers/net/sssnic/base/sssnic_api.c +++ b/drivers/net/sssnic/base/sssnic_api.c @@ -11,6 +11,7 @@ #include "sssnic_hw.h" #include "sssnic_cmd.h" #include "sssnic_mbox.h" +#include "sssnic_ctrlq.h" #include "sssnic_api.h" int @@ -434,3 +435,65 @@ sssnic_netif_enable_set(struct sssnic_hw *hw, uint8_t state) return 0; } + +int +sssnic_port_enable_set(struct sssnic_hw *hw, bool state) +{ + int ret; + struct sssnic_port_enable_set_cmd cmd; + struct sssnic_msg msg; + uint32_t cmd_len; + + if (hw == NULL) + return -EINVAL; + + memset(&cmd, 0, sizeof(cmd)); + cmd.function = SSSNIC_FUNC_IDX(hw); + cmd.state = state ? 1 : 0; + cmd_len = sizeof(cmd); + sssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, + SSSNIC_SET_PORT_ENABLE_CMD, SSSNIC_MPU_FUNC_IDX, + SSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ); + ret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Failed to send mbox message, ret=%d", ret); + return ret; + } + + if (cmd_len == 0 || cmd.common.status != 0) { + PMD_DRV_LOG(ERR, + "Bad response to SSSNIC_SET_PORT_ENABLE_CMD, len=%u, status=%u", + cmd_len, cmd.common.status); + return -EIO; + } + + return 0; +} + +int +sssnic_rxq_flush(struct sssnic_hw *hw, uint16_t qid) +{ + struct sssnic_ctrlq_cmd cmd; + struct sssnic_rxq_flush_cmd data; + int ret; + + data.u32 = 0; + data.qid = qid; + data.u32 = rte_cpu_to_be_32(data.u32); + + memset(&cmd, 0, sizeof(cmd)); + cmd.data = &data; + cmd.module = SSSNIC_LAN_MODULE; + cmd.data_len = sizeof(data); + cmd.cmd = SSSNIC_FLUSH_RXQ_CMD; + + ret = sssnic_ctrlq_cmd_exec(hw, &cmd, 0); + if (ret != 0 || cmd.result != 0) { + PMD_DRV_LOG(ERR, + "Failed to execulte ctrlq command %s, ret=%d, result=%" PRIu64, + "SSSNIC_FLUSH_RXQ_CMD", ret, cmd.result); + return -EIO; + } + + return 0; +} diff --git a/drivers/net/sssnic/base/sssnic_api.h b/drivers/net/sssnic/base/sssnic_api.h index 168aa152b9..29962aabf8 100644 --- a/drivers/net/sssnic/base/sssnic_api.h +++ b/drivers/net/sssnic/base/sssnic_api.h @@ -45,5 +45,7 @@ int sssnic_netif_link_status_get(struct sssnic_hw *hw, uint8_t *status); int sssnic_netif_link_info_get(struct sssnic_hw *hw, struct sssnic_netif_link_info *info); int sssnic_netif_enable_set(struct sssnic_hw *hw, uint8_t state); +int sssnic_port_enable_set(struct sssnic_hw *hw, bool state); +int sssnic_rxq_flush(struct sssnic_hw *hw, uint16_t qid); #endif /* _SSSNIC_API_H_ */ diff --git a/drivers/net/sssnic/base/sssnic_cmd.h b/drivers/net/sssnic/base/sssnic_cmd.h index 6957b742fc..6364058d36 100644 --- a/drivers/net/sssnic/base/sssnic_cmd.h +++ b/drivers/net/sssnic/base/sssnic_cmd.h @@ -35,6 +35,37 @@ enum sssnic_netif_cmd_id { SSSNIC_GET_NETIF_LINK_INFO_CMD = 153, }; +enum sssnic_port_cmd_id { + SSSNIC_REGISTER_VF_PORT_CMD = 0, + SSSNIC_SET_PORT_RXTX_SIZE_CMD = 5, + SSSNIC_SET_PORT_ENABLE_CMD = 6, + SSSNIC_SET_PORT_RX_MODE_CMD = 7, + SSSNIC_SET_PORT_TX_CI_ATTR_CMD = 8, + SSSNIC_GET_PORT_STATS_CMD = 9, + SSSNIC_CLEAR_PORT_STATS_CMD = 10, + + SSSNIC_CLEAN_PORT_RES_CMD = 11, + + SSSNIC_PORT_LRO_CFG_CMD = 13, + SSSNIC_PORT_LRO_TIMER_CMD = 14, + SSSNIC_PORT_FEATURE_CMD = 15, + + SSSNIC_SET_PORT_VLAN_FILTER_CMD = 25, + SSSNIC_ENABLE_PORT_VLAN_FILTER_CMD = 26, + SSSNIC_ENABLE_PORT_VLAN_STRIP_CMD = 27, + + SSSNIC_PORT_FLOW_CTRL_CMD = 101, +}; + +enum sssnic_ctrlq_cmd_id { + SSSNIC_SET_RXTXQ_CTX_CMD = 0, + SSSNIC_RESET_OFFLOAD_CTX_CMD = 1, + SSSNIC_SET_RSS_INDIR_TABLE_CMD = 4, + SSSNIC_SET_RSS_KEY_CTRLQ_CMD = 5, + SSSNIC_GET_RSS_INDIR_TABLE_CMD = 6, + SSSNIC_FLUSH_RXQ_CMD = 10, +}; + struct sssnic_cmd_common { uint8_t status; uint8_t version; @@ -187,4 +218,22 @@ struct sssnic_netif_enable_set_cmd { uint8_t resvd1[3]; }; +struct sssnic_port_enable_set_cmd { + struct sssnic_cmd_common common; + uint16_t function; + uint16_t resvd0; + uint8_t state; + uint8_t resvd1[3]; +}; + +struct sssnic_rxq_flush_cmd { + union { + struct { + uint16_t resvd0; + uint16_t qid; + }; + uint32_t u32; + }; +}; + #endif /* _SSSNIC_CMD_H_ */ diff --git a/drivers/net/sssnic/sssnic_ethdev.c b/drivers/net/sssnic/sssnic_ethdev.c index 44d62d99f2..8822e5a17b 100644 --- a/drivers/net/sssnic/sssnic_ethdev.c +++ b/drivers/net/sssnic/sssnic_ethdev.c @@ -359,6 +359,8 @@ static const struct eth_dev_ops sssnic_ethdev_ops = { .rx_queue_release = sssnic_ethdev_rx_queue_release, .tx_queue_setup = sssnic_ethdev_tx_queue_setup, .tx_queue_release = sssnic_ethdev_tx_queue_release, + .rx_queue_start = sssnic_ethdev_rx_queue_start, + .rx_queue_stop = sssnic_ethdev_rx_queue_stop, }; static int diff --git a/drivers/net/sssnic/sssnic_ethdev.h b/drivers/net/sssnic/sssnic_ethdev.h index ab832d179f..38e6dc0d62 100644 --- a/drivers/net/sssnic/sssnic_ethdev.h +++ b/drivers/net/sssnic/sssnic_ethdev.h @@ -65,6 +65,8 @@ struct sssnic_netdev { struct rte_ether_addr default_addr; uint16_t max_num_txq; uint16_t max_num_rxq; + uint16_t num_started_rxqs; + uint16_t num_started_txqs; }; #define SSSNIC_ETHDEV_PRIVATE(eth_dev) \ diff --git a/drivers/net/sssnic/sssnic_ethdev_rx.c b/drivers/net/sssnic/sssnic_ethdev_rx.c index cf4d32deb0..3866539f00 100644 --- a/drivers/net/sssnic/sssnic_ethdev_rx.c +++ b/drivers/net/sssnic/sssnic_ethdev_rx.c @@ -163,24 +163,64 @@ struct sssnic_ethdev_rxq_doorbell { }; }; +static inline void +sssnic_ethdev_rxq_doorbell_ring(struct sssnic_ethdev_rxq *rxq, uint16_t pi) +{ + uint64_t *db_addr; + struct sssnic_ethdev_rxq_doorbell db; + uint16_t hw_pi; + static const struct sssnic_ethdev_rxq_doorbell default_db = { + .cf = 1, + .service = 1, + }; + + hw_pi = pi << 1; + + db.u64 = default_db.u64; + db.qid = rxq->qid; + db.pi_hi = (hw_pi >> 8) & 0xff; + + db_addr = (uint64_t *)(rxq->doorbell + (hw_pi & 0xff)); + + rte_write64(db.u64, db_addr); +} + static inline uint16_t sssnic_ethdev_rxq_num_used_entries(struct sssnic_ethdev_rxq *rxq) { return sssnic_workq_num_used_entries(rxq->workq); } +static inline uint16_t +sssnic_ethdev_rxq_num_idle_entries(struct sssnic_ethdev_rxq *rxq) +{ + return rxq->workq->idle_entries; +} + static inline uint16_t sssnic_ethdev_rxq_ci_get(struct sssnic_ethdev_rxq *rxq) { return sssnic_workq_ci_get(rxq->workq); } +static inline uint16_t +sssnic_ethdev_rxq_pi_get(struct sssnic_ethdev_rxq *rxq) +{ + return sssnic_workq_pi_get(rxq->workq); +} + static inline void sssnic_ethdev_rxq_consume(struct sssnic_ethdev_rxq *rxq, uint16_t num_entries) { sssnic_workq_consume_fast(rxq->workq, num_entries); } +static inline void +sssnic_ethdev_rxq_produce(struct sssnic_ethdev_rxq *rxq, uint16_t num_entries) +{ + sssnic_workq_produce_fast(rxq->workq, num_entries); +} + static void sssnic_ethdev_rx_buf_size_optimize(uint32_t orig_size, uint16_t *new_size) { @@ -419,3 +459,295 @@ sssnic_ethdev_rx_queue_all_release(struct rte_eth_dev *ethdev) for (qid = 0; qid < ethdev->data->nb_rx_queues; qid++) sssnic_ethdev_rx_queue_release(ethdev, qid); } + +static void +sssnic_ethdev_rxq_pktmbufs_fill(struct sssnic_ethdev_rxq *rxq) +{ + struct rte_mbuf **pktmbuf; + rte_iova_t buf_iova; + struct sssnic_ethdev_rxq_entry *rqe; + uint16_t idle_entries; + uint16_t bulk_entries; + uint16_t pi; + uint16_t i; + int ret; + + idle_entries = sssnic_ethdev_rxq_num_idle_entries(rxq) - 1; + pi = sssnic_ethdev_rxq_pi_get(rxq); + + while (idle_entries > 0) { + /* calculate number of continuous entries */ + bulk_entries = rxq->depth - pi; + if (idle_entries < bulk_entries) + bulk_entries = idle_entries; + + pktmbuf = (struct rte_mbuf **)(&rxq->rxe[pi]); + + ret = rte_pktmbuf_alloc_bulk(rxq->mp, pktmbuf, bulk_entries); + if (ret != 0) { + rxq->stats.nombuf += idle_entries; + return; + } + + for (i = 0; i < bulk_entries; i++) { + rqe = SSSNIC_ETHDEV_RXQ_ENTRY(rxq, pi); + buf_iova = rte_mbuf_data_iova(pktmbuf[i]); + rqe->buf_hi_addr = SSSNIC_UPPER_32_BITS(buf_iova); + rqe->buf_lo_addr = SSSNIC_LOWER_32_BITS(buf_iova); + sssnic_ethdev_rxq_produce(rxq, 1); + pi = sssnic_ethdev_rxq_pi_get(rxq); + } + + idle_entries -= bulk_entries; + sssnic_ethdev_rxq_doorbell_ring(rxq, pi); + } +} + +static uint16_t +sssnic_ethdev_rxq_pktmbufs_cleanup(struct sssnic_ethdev_rxq *rxq) +{ + struct sssnic_ethdev_rx_entry *rxe; + volatile struct sssnic_ethdev_rx_desc *rxd; + uint16_t ci, count = 0; + uint32_t pktlen = 0; + uint32_t buflen = rxq->rx_buf_size; + uint16_t num_entries; + + num_entries = sssnic_ethdev_rxq_num_used_entries(rxq); + + ci = sssnic_ethdev_rxq_ci_get(rxq); + rxe = &rxq->rxe[ci]; + rxd = &rxq->desc[ci]; + + while (num_entries > 0) { + if (pktlen > 0) + pktlen = pktlen > buflen ? (pktlen - buflen) : 0; + else if (rxd->flush != 0) + pktlen = 0; + else if (rxd->done != 0) + pktlen = rxd->len > buflen ? (rxd->len - buflen) : 0; + else + break; + + rte_pktmbuf_free(rxe->pktmbuf); + rxe->pktmbuf = NULL; + + count++; + num_entries--; + + sssnic_ethdev_rxq_consume(rxq, 1); + ci = sssnic_ethdev_rxq_ci_get(rxq); + rxe = &rxq->rxe[ci]; + rxd = &rxq->desc[ci]; + } + + PMD_DRV_LOG(DEBUG, + "%u rx packets cleanned up (Port:%u rxq:%u), ci=%u, pi=%u", + count, rxq->port, rxq->qid, ci, sssnic_ethdev_rxq_pi_get(rxq)); + + return count; +} + +#define SSSNIC_ETHDEV_RXQ_FUSH_TIMEOUT 3000 /* 3000 ms */ +static int +sssnic_ethdev_rxq_flush(struct sssnic_ethdev_rxq *rxq) +{ + struct sssnic_hw *hw; + uint64_t timeout; + uint16_t used_entries; + int ret; + + hw = SSSNIC_ETHDEV_TO_HW(rxq->ethdev); + + ret = sssnic_rxq_flush(hw, rxq->qid); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Failed to flush rxq:%u, port:%u", rxq->qid, + rxq->port); + return ret; + } + + timeout = rte_get_timer_cycles() + + rte_get_timer_hz() * SSSNIC_ETHDEV_RXQ_FUSH_TIMEOUT / 1000; + + do { + sssnic_ethdev_rxq_pktmbufs_cleanup(rxq); + used_entries = sssnic_ethdev_rxq_num_used_entries(rxq); + if (used_entries == 0) + return 0; + rte_delay_us_sleep(1000); + } while (((long)(rte_get_timer_cycles() - timeout)) < 0); + + PMD_DRV_LOG(ERR, "Flush port:%u rxq:%u timeout, used_rxq_entries:%u", + rxq->port, rxq->qid, sssnic_ethdev_rxq_num_used_entries(rxq)); + + return -ETIMEDOUT; +} + +static int +sssnic_ethdev_rxq_enable(struct rte_eth_dev *ethdev, uint16_t queue_id) +{ + struct sssnic_ethdev_rxq *rxq = ethdev->data->rx_queues[queue_id]; + + sssnic_ethdev_rxq_pktmbufs_fill(rxq); + + return 0; +} + +static int +sssnic_ethdev_rxq_disable(struct rte_eth_dev *ethdev, uint16_t queue_id) +{ + struct sssnic_ethdev_rxq *rxq = ethdev->data->rx_queues[queue_id]; + int ret; + + ret = sssnic_ethdev_rxq_flush(rxq); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Failed to flush rxq:%u, port:%u", queue_id, + ethdev->data->port_id); + return ret; + } + + return 0; +} +int +sssnic_ethdev_rx_queue_start(struct rte_eth_dev *ethdev, uint16_t queue_id) +{ + struct sssnic_netdev *netdev = SSSNIC_ETHDEV_PRIVATE(ethdev); + struct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev); + int ret; + + ret = sssnic_ethdev_rxq_enable(ethdev, queue_id); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Failed to start rxq:%u, port:%u", queue_id, + ethdev->data->port_id); + return ret; + } + + if (netdev->num_started_rxqs == 0) { + ret = sssnic_port_enable_set(hw, true); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Failed to enable sssnic port:%u", + ethdev->data->port_id); + sssnic_ethdev_rxq_disable(ethdev, queue_id); + return ret; + } + } + + netdev->num_started_rxqs++; + ethdev->data->rx_queue_state[queue_id] = RTE_ETH_QUEUE_STATE_STARTED; + + PMD_DRV_LOG(DEBUG, "port %u rxq %u started", ethdev->data->port_id, + queue_id); + + return 0; +} + +int +sssnic_ethdev_rx_queue_stop(struct rte_eth_dev *ethdev, uint16_t queue_id) +{ + struct sssnic_netdev *netdev = SSSNIC_ETHDEV_PRIVATE(ethdev); + struct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev); + int ret; + + if (netdev->num_started_rxqs == 1) { + ret = sssnic_port_enable_set(hw, false); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Failed to disable sssnic port:%u", + ethdev->data->port_id); + return ret; + } + } + + ret = sssnic_ethdev_rxq_disable(ethdev, queue_id); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Failed to disable rxq:%u, port:%u", queue_id, + ethdev->data->port_id); + sssnic_port_enable_set(hw, true); + return ret; + } + + netdev->num_started_rxqs--; + ethdev->data->rx_queue_state[queue_id] = RTE_ETH_QUEUE_STATE_STOPPED; + + PMD_DRV_LOG(DEBUG, "port %u rxq %u stopped", ethdev->data->port_id, + queue_id); + + return 0; +} + +int +sssnic_ethdev_rx_queue_all_start(struct rte_eth_dev *ethdev) +{ + struct sssnic_netdev *netdev = SSSNIC_ETHDEV_PRIVATE(ethdev); + struct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev); + uint16_t numq = ethdev->data->nb_rx_queues; + uint16_t qid; + + int ret; + + for (qid = 0; qid < numq; qid++) { + ret = sssnic_ethdev_rxq_enable(ethdev, qid); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Failed to enable rxq:%u, port:%u", + qid, ethdev->data->port_id); + goto fail_out; + } + + ethdev->data->rx_queue_state[qid] = RTE_ETH_QUEUE_STATE_STARTED; + netdev->num_started_rxqs++; + + PMD_DRV_LOG(DEBUG, "port %u rxq %u started", + ethdev->data->port_id, qid); + } + + ret = sssnic_port_enable_set(hw, true); + if (ret) { + PMD_DRV_LOG(ERR, "Failed to enable port:%u", + ethdev->data->port_id); + goto fail_out; + } + + return 0; + +fail_out: + while (qid--) { + sssnic_ethdev_rxq_disable(ethdev, qid); + ethdev->data->rx_queue_state[qid] = RTE_ETH_QUEUE_STATE_STOPPED; + netdev->num_started_rxqs--; + } + + return ret; +} + +int +sssnic_ethdev_rx_queue_all_stop(struct rte_eth_dev *ethdev) +{ + struct sssnic_netdev *netdev = SSSNIC_ETHDEV_PRIVATE(ethdev); + struct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev); + uint16_t numq = ethdev->data->nb_rx_queues; + uint16_t qid; + int ret; + + ret = sssnic_port_enable_set(hw, false); + if (ret) { + PMD_DRV_LOG(ERR, "Failed to disable port:%u", + ethdev->data->port_id); + return ret; + } + + for (qid = 0; qid < numq; qid++) { + ret = sssnic_ethdev_rxq_disable(ethdev, qid); + if (ret != 0) { + PMD_DRV_LOG(WARNING, "Failed to enable rxq:%u, port:%u", + qid, ethdev->data->port_id); + continue; + } + + ethdev->data->rx_queue_state[qid] = RTE_ETH_QUEUE_STATE_STOPPED; + netdev->num_started_rxqs--; + + PMD_DRV_LOG(DEBUG, "port %u rxq %u stopped", + ethdev->data->port_id, qid); + } + + return 0; +} diff --git a/drivers/net/sssnic/sssnic_ethdev_rx.h b/drivers/net/sssnic/sssnic_ethdev_rx.h index dc41811a2f..c6ddc366d5 100644 --- a/drivers/net/sssnic/sssnic_ethdev_rx.h +++ b/drivers/net/sssnic/sssnic_ethdev_rx.h @@ -20,5 +20,9 @@ int sssnic_ethdev_rx_queue_setup(struct rte_eth_dev *ethdev, void sssnic_ethdev_rx_queue_release(struct rte_eth_dev *ethdev, uint16_t queue_id); void sssnic_ethdev_rx_queue_all_release(struct rte_eth_dev *ethdev); +int sssnic_ethdev_rx_queue_start(struct rte_eth_dev *ethdev, uint16_t queue_id); +int sssnic_ethdev_rx_queue_stop(struct rte_eth_dev *ethdev, uint16_t queue_id); +int sssnic_ethdev_rx_queue_all_start(struct rte_eth_dev *ethdev); +int sssnic_ethdev_rx_queue_all_stop(struct rte_eth_dev *ethdev); #endif