From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 477B0424E7; Mon, 4 Sep 2023 06:59:24 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5CCAB40A89; Mon, 4 Sep 2023 06:57:55 +0200 (CEST) Received: from VLXDG1SPAM1.ramaxel.com (email.unionmem.com [221.4.138.186]) by mails.dpdk.org (Postfix) with ESMTP id 99C6640A75 for ; Mon, 4 Sep 2023 06:57:48 +0200 (CEST) Received: from V12DG1MBS03.ramaxel.local ([172.26.18.33]) by VLXDG1SPAM1.ramaxel.com with ESMTP id 3844vF1Z054273; Mon, 4 Sep 2023 12:57:15 +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; Mon, 4 Sep 2023 12:57:15 +0800 From: To: CC: , Renyong Wan , Steven Song Subject: [PATCH v5 18/32] net/sssnic: add Rx interrupt support Date: Mon, 4 Sep 2023 12:56:44 +0800 Message-ID: <20230904045658.238185-19-wanry@3snic.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230904045658.238185-1-wanry@3snic.com> References: <20230904045658.238185-1-wanry@3snic.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain 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 3844vF1Z054273 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 --- doc/guides/nics/features/sssnic.ini | 1 + drivers/net/sssnic/base/sssnic_hw.c | 14 +++ drivers/net/sssnic/base/sssnic_hw.h | 2 + drivers/net/sssnic/sssnic_ethdev.c | 2 + drivers/net/sssnic/sssnic_ethdev_rx.c | 135 ++++++++++++++++++++++++++ drivers/net/sssnic/sssnic_ethdev_rx.h | 6 ++ 6 files changed, 160 insertions(+) diff --git a/doc/guides/nics/features/sssnic.ini b/doc/guides/nics/features/sssnic.ini index b75c68cb33..e3b8166629 100644 --- a/doc/guides/nics/features/sssnic.ini +++ b/doc/guides/nics/features/sssnic.ini @@ -7,6 +7,7 @@ Link status = Y Link status event = Y Queue start/stop = Y +Rx interrupt = Y Unicast MAC filter = Y Multicast MAC filter = Y Linux = Y diff --git a/drivers/net/sssnic/base/sssnic_hw.c b/drivers/net/sssnic/base/sssnic_hw.c index 82eb4ea295..651a0aa7ef 100644 --- a/drivers/net/sssnic/base/sssnic_hw.c +++ b/drivers/net/sssnic/base/sssnic_hw.c @@ -145,6 +145,20 @@ sssnic_msix_resend_disable(struct sssnic_hw *hw, uint16_t msix_id) sssnic_cfg_reg_write(hw, SSSNIC_MSIX_CTRL_REG, reg.u32); } +void +sssnic_msix_auto_mask_set(struct sssnic_hw *hw, uint16_t msix_id, int state) +{ + struct sssnic_msix_ctrl_reg reg; + + reg.u32 = 0; + if (state == SSSNIC_MSIX_ENABLE) + reg.auto_msk_set = 1; + else + reg.auto_msk_clr = 1; + reg.msxi_idx = msix_id; + sssnic_cfg_reg_write(hw, SSSNIC_MSIX_CTRL_REG, reg.u32); +} + static void sssnic_pf_status_set(struct sssnic_hw *hw, enum sssnic_pf_status status) { diff --git a/drivers/net/sssnic/base/sssnic_hw.h b/drivers/net/sssnic/base/sssnic_hw.h index e25f5595e6..4820212543 100644 --- a/drivers/net/sssnic/base/sssnic_hw.h +++ b/drivers/net/sssnic/base/sssnic_hw.h @@ -100,6 +100,8 @@ int sssnic_hw_init(struct sssnic_hw *hw); void sssnic_hw_shutdown(struct sssnic_hw *hw); void sssnic_msix_state_set(struct sssnic_hw *hw, uint16_t msix_id, int state); void sssnic_msix_resend_disable(struct sssnic_hw *hw, uint16_t msix_id); +void sssnic_msix_auto_mask_set(struct sssnic_hw *hw, uint16_t msix_id, + int state); int sssnic_link_event_callback_register(struct sssnic_hw *hw, sssnic_link_event_cb_t *cb, void *priv); void sssnic_link_event_callback_unregister(struct sssnic_hw *hw); diff --git a/drivers/net/sssnic/sssnic_ethdev.c b/drivers/net/sssnic/sssnic_ethdev.c index 8a18f25889..35bb26a0b1 100644 --- a/drivers/net/sssnic/sssnic_ethdev.c +++ b/drivers/net/sssnic/sssnic_ethdev.c @@ -362,6 +362,8 @@ static const struct eth_dev_ops sssnic_ethdev_ops = { .rx_queue_stop = sssnic_ethdev_rx_queue_stop, .tx_queue_start = sssnic_ethdev_tx_queue_start, .tx_queue_stop = sssnic_ethdev_tx_queue_stop, + .rx_queue_intr_enable = sssnic_ethdev_rx_queue_intr_enable, + .rx_queue_intr_disable = sssnic_ethdev_rx_queue_intr_disable, }; static int diff --git a/drivers/net/sssnic/sssnic_ethdev_rx.c b/drivers/net/sssnic/sssnic_ethdev_rx.c index d8429e734d..9c1b2f20d1 100644 --- a/drivers/net/sssnic/sssnic_ethdev_rx.c +++ b/drivers/net/sssnic/sssnic_ethdev_rx.c @@ -136,6 +136,12 @@ static const uint16_t sssnic_ethdev_rx_buf_size_tbl[] = { 32, 64, 96, 128, 192, /* Doorbell offset 8192 */ #define SSSNIC_ETHDEV_RXQ_DB_OFFSET 0x2000 +#define SSSNIC_ETHDEV_RX_MSIX_ID_START 1 +#define SSSNIC_ETHDEV_RX_MSIX_ID_INVAL 0 +#define SSSNIC_ETHDEV_RX_MSIX_PENDING_LIMIT 2 +#define SSSNIC_ETHDEV_RX_MSIX_COALESCING_TIMER 2 +#define SSSNIC_ETHDEV_RX_MSIX_RESNEDING_TIMER 7 + struct sssnic_ethdev_rxq_doorbell { union { uint64_t u64; @@ -750,3 +756,132 @@ sssnic_ethdev_rx_queue_all_stop(struct rte_eth_dev *ethdev) return 0; } + +static int +sssinc_ethdev_rxq_intr_attr_init(struct sssnic_ethdev_rxq *rxq) +{ + int ret; + struct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(rxq->ethdev); + struct sssnic_msix_attr attr; + + attr.lli_set = 0; + attr.coalescing_set = 1; + attr.pending_limit = SSSNIC_ETHDEV_RX_MSIX_PENDING_LIMIT; + attr.coalescing_timer = SSSNIC_ETHDEV_RX_MSIX_COALESCING_TIMER; + attr.resend_timer = SSSNIC_ETHDEV_RX_MSIX_RESNEDING_TIMER; + + ret = sssnic_msix_attr_set(hw, rxq->intr.msix_id, &attr); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Failed to set msxi attributes"); + return ret; + } + + return 0; +} + +int +sssnic_ethdev_rx_queue_intr_enable(struct rte_eth_dev *ethdev, uint16_t qid) +{ + struct sssnic_ethdev_rxq *rxq = ethdev->data->rx_queues[qid]; + struct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev); + + if (rxq->intr.enable) + return 0; + + sssnic_msix_auto_mask_set(hw, rxq->intr.msix_id, SSSNIC_MSIX_ENABLE); + sssnic_msix_state_set(hw, rxq->intr.msix_id, SSSNIC_MSIX_ENABLE); + rxq->intr.enable = 1; + + return 0; +} + +int +sssnic_ethdev_rx_queue_intr_disable(struct rte_eth_dev *ethdev, uint16_t qid) +{ + struct sssnic_ethdev_rxq *rxq = ethdev->data->rx_queues[qid]; + struct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev); + + if (!rxq->intr.enable) + return 0; + + sssnic_msix_auto_mask_set(hw, rxq->intr.msix_id, SSSNIC_MSIX_DISABLE); + sssnic_msix_state_set(hw, rxq->intr.msix_id, SSSNIC_MSIX_DISABLE); + sssnic_msix_resend_disable(hw, rxq->intr.msix_id); + rxq->intr.enable = 0; + + return 0; +} + +int +sssnic_ethdev_rx_intr_init(struct rte_eth_dev *ethdev) +{ + struct rte_intr_handle *intr_handle; + struct sssnic_ethdev_rxq *rxq; + uint32_t nb_rxq, i; + int vec; + int ret; + + if (!ethdev->data->dev_conf.intr_conf.rxq) + return 0; + + intr_handle = ethdev->intr_handle; + + if (!rte_intr_cap_multiple(intr_handle)) { + PMD_DRV_LOG(ERR, + "Rx interrupts require MSI-X interrupts (vfio-pci driver)\n"); + return -ENOTSUP; + } + + rte_intr_efd_disable(intr_handle); + + nb_rxq = ethdev->data->nb_rx_queues; + + ret = rte_intr_efd_enable(intr_handle, nb_rxq); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Failed to enable intr efd"); + return ret; + } + + ret = rte_intr_vec_list_alloc(intr_handle, NULL, nb_rxq); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Failed to allocate rx intr vec list"); + rte_intr_efd_disable(intr_handle); + return ret; + } + + for (i = 0; i < nb_rxq; i++) { + vec = (int)(i + SSSNIC_ETHDEV_RX_MSIX_ID_START); + rte_intr_vec_list_index_set(intr_handle, i, vec); + rxq = ethdev->data->rx_queues[i]; + rxq->intr.msix_id = vec; + + ret = sssinc_ethdev_rxq_intr_attr_init(rxq); + if (ret != 0) { + PMD_DRV_LOG(ERR, + "Failed to initialize rxq %u (port %u) msix attribute.", + rxq->qid, rxq->port); + goto intr_attr_init_fail; + } + } + + return 0; + +intr_attr_init_fail: + rte_intr_vec_list_free(intr_handle); + rte_intr_efd_disable(intr_handle); + + return ret; +} + +void +sssnic_ethdev_rx_intr_shutdown(struct rte_eth_dev *ethdev) +{ + struct rte_intr_handle *intr_handle = ethdev->intr_handle; + uint16_t i; + + for (i = 0; i < ethdev->data->nb_rx_queues; i++) + sssnic_ethdev_rx_queue_intr_disable(ethdev, i); + + rte_intr_efd_disable(intr_handle); + rte_intr_vec_list_free(intr_handle); +} diff --git a/drivers/net/sssnic/sssnic_ethdev_rx.h b/drivers/net/sssnic/sssnic_ethdev_rx.h index c6ddc366d5..77a116f4a5 100644 --- a/drivers/net/sssnic/sssnic_ethdev_rx.h +++ b/drivers/net/sssnic/sssnic_ethdev_rx.h @@ -24,5 +24,11 @@ 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); +int sssnic_ethdev_rx_queue_intr_enable(struct rte_eth_dev *ethdev, + uint16_t qid); +int sssnic_ethdev_rx_queue_intr_disable(struct rte_eth_dev *ethdev, + uint16_t qid); +int sssnic_ethdev_rx_intr_init(struct rte_eth_dev *ethdev); +void sssnic_ethdev_rx_intr_shutdown(struct rte_eth_dev *ethdev); #endif -- 2.27.0