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 CF08DA0524; Wed, 2 Jun 2021 11:42:32 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E1556411AA; Wed, 2 Jun 2021 11:40:13 +0200 (CEST) Received: from smtpbgbr2.qq.com (smtpbgbr2.qq.com [54.207.22.56]) by mails.dpdk.org (Postfix) with ESMTP id 0BD8A4119B for ; Wed, 2 Jun 2021 11:40:10 +0200 (CEST) X-QQ-mid: bizesmtp32t1622626806tuyx1x7s Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Wed, 02 Jun 2021 17:40:06 +0800 (CST) X-QQ-SSF: 01400000000000D0E000B00A0000000 X-QQ-FEAT: aiXUkxla6RCaCzrYa9Ud8uLfQV0epSu0L+PBLQKjiy2kwggG6mwOKWf84zM5R 4TwgJ27WLNAlz4eM9sP46P3Q9BPLb9z3G3V9rDxuILTenQAGNIl4EAPLOex6b7sTtDqAOxs +x2bEn0rFO2KWCQuA5oS+Rk7AefkyfjSwUs4XJ29FPfQRdxLZSnVsYiqypNsT1Sube8sHKs GOh+9+HpZm4ftUtBq/WSR64tAKL3jJ19dxVIEqPx9HrNpsDBgWHAnECifxEvOl6B14lv59y tDtKiX47w0f8iOgkpT7NpMgo+RETqrON90Q+BgWCRutb6TrwCI1+vtk6JelIeOq2tY1fvBj bwY/5hS+dsBvVwwI9/2GWk9SIaApA== X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Wed, 2 Jun 2021 17:41:07 +0800 Message-Id: <20210602094108.1575640-24-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210602094108.1575640-1-jiawenwu@trustnetic.com> References: <20210602094108.1575640-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign7 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH v5 23/24] net/ngbe: start and stop RxTx 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 Sender: "dev" Support to start and stop receive and transmit unit for specified queues. Signed-off-by: Jiawen Wu --- doc/guides/nics/features/ngbe.ini | 1 + drivers/net/ngbe/base/ngbe_dummy.h | 15 ++ drivers/net/ngbe/base/ngbe_hw.c | 105 ++++++++++ drivers/net/ngbe/base/ngbe_hw.h | 4 + drivers/net/ngbe/base/ngbe_type.h | 5 + drivers/net/ngbe/ngbe_ethdev.c | 10 + drivers/net/ngbe/ngbe_ethdev.h | 15 ++ drivers/net/ngbe/ngbe_rxtx.c | 307 +++++++++++++++++++++++++++++ drivers/net/ngbe/ngbe_rxtx.h | 3 + 9 files changed, 465 insertions(+) diff --git a/doc/guides/nics/features/ngbe.ini b/doc/guides/nics/features/ngbe.ini index 443c6691a3..43b6b2c2c7 100644 --- a/doc/guides/nics/features/ngbe.ini +++ b/doc/guides/nics/features/ngbe.ini @@ -7,6 +7,7 @@ Speed capabilities = Y Link status = Y Link status event = Y +Queue start/stop = Y Jumbo frame = Y Scattered Rx = Y TSO = Y diff --git a/drivers/net/ngbe/base/ngbe_dummy.h b/drivers/net/ngbe/base/ngbe_dummy.h index dfc7b13192..384631b4f1 100644 --- a/drivers/net/ngbe/base/ngbe_dummy.h +++ b/drivers/net/ngbe/base/ngbe_dummy.h @@ -59,6 +59,18 @@ static inline s32 ngbe_mac_get_mac_addr_dummy(struct ngbe_hw *TUP0, u8 *TUP1) { return NGBE_ERR_OPS_DUMMY; } +static inline s32 ngbe_mac_enable_rx_dma_dummy(struct ngbe_hw *TUP0, u32 TUP1) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_mac_disable_sec_rx_path_dummy(struct ngbe_hw *TUP0) +{ + return NGBE_ERR_OPS_DUMMY; +} +static inline s32 ngbe_mac_enable_sec_rx_path_dummy(struct ngbe_hw *TUP0) +{ + return NGBE_ERR_OPS_DUMMY; +} static inline s32 ngbe_mac_acquire_swfw_sync_dummy(struct ngbe_hw *TUP0, u32 TUP1) { @@ -167,6 +179,9 @@ static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw) hw->mac.start_hw = ngbe_mac_start_hw_dummy; hw->mac.stop_hw = ngbe_mac_stop_hw_dummy; hw->mac.get_mac_addr = ngbe_mac_get_mac_addr_dummy; + hw->mac.enable_rx_dma = ngbe_mac_enable_rx_dma_dummy; + hw->mac.disable_sec_rx_path = ngbe_mac_disable_sec_rx_path_dummy; + hw->mac.enable_sec_rx_path = ngbe_mac_enable_sec_rx_path_dummy; hw->mac.acquire_swfw_sync = ngbe_mac_acquire_swfw_sync_dummy; hw->mac.release_swfw_sync = ngbe_mac_release_swfw_sync_dummy; hw->mac.setup_link = ngbe_mac_setup_link_dummy; diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c index b0bc714741..030068f3f7 100644 --- a/drivers/net/ngbe/base/ngbe_hw.c +++ b/drivers/net/ngbe/base/ngbe_hw.c @@ -536,6 +536,63 @@ void ngbe_release_swfw_sync(struct ngbe_hw *hw, u32 mask) ngbe_release_eeprom_semaphore(hw); } +/** + * ngbe_disable_sec_rx_path - Stops the receive data path + * @hw: pointer to hardware structure + * + * Stops the receive data path and waits for the HW to internally empty + * the Rx security block + **/ +s32 ngbe_disable_sec_rx_path(struct ngbe_hw *hw) +{ +#define NGBE_MAX_SECRX_POLL 4000 + + int i; + u32 secrxreg; + + DEBUGFUNC("ngbe_disable_sec_rx_path"); + + + secrxreg = rd32(hw, NGBE_SECRXCTL); + secrxreg |= NGBE_SECRXCTL_XDSA; + wr32(hw, NGBE_SECRXCTL, secrxreg); + for (i = 0; i < NGBE_MAX_SECRX_POLL; i++) { + secrxreg = rd32(hw, NGBE_SECRXSTAT); + if (!(secrxreg & NGBE_SECRXSTAT_RDY)) + /* Use interrupt-safe sleep just in case */ + usec_delay(10); + else + break; + } + + /* For informational purposes only */ + if (i >= NGBE_MAX_SECRX_POLL) + DEBUGOUT("Rx unit being enabled before security " + "path fully disabled. Continuing with init.\n"); + + return 0; +} + +/** + * ngbe_enable_sec_rx_path - Enables the receive data path + * @hw: pointer to hardware structure + * + * Enables the receive data path. + **/ +s32 ngbe_enable_sec_rx_path(struct ngbe_hw *hw) +{ + u32 secrxreg; + + DEBUGFUNC("ngbe_enable_sec_rx_path"); + + secrxreg = rd32(hw, NGBE_SECRXCTL); + secrxreg &= ~NGBE_SECRXCTL_XDSA; + wr32(hw, NGBE_SECRXCTL, secrxreg); + ngbe_flush(hw); + + return 0; +} + /** * ngbe_clear_vmdq - Disassociate a VMDq pool index from a rx address * @hw: pointer to hardware struct @@ -757,6 +814,21 @@ void ngbe_disable_rx(struct ngbe_hw *hw) wr32m(hw, NGBE_MACRXCFG, NGBE_MACRXCFG_ENA, 0); } +void ngbe_enable_rx(struct ngbe_hw *hw) +{ + u32 pfdtxgswc; + + wr32m(hw, NGBE_MACRXCFG, NGBE_MACRXCFG_ENA, NGBE_MACRXCFG_ENA); + wr32m(hw, NGBE_PBRXCTL, NGBE_PBRXCTL_ENA, NGBE_PBRXCTL_ENA); + + if (hw->mac.set_lben) { + pfdtxgswc = rd32(hw, NGBE_PSRCTL); + pfdtxgswc |= NGBE_PSRCTL_LBENA; + wr32(hw, NGBE_PSRCTL, pfdtxgswc); + hw->mac.set_lben = false; + } +} + /** * ngbe_set_mac_type - Sets MAC type * @hw: pointer to the HW structure @@ -803,6 +875,36 @@ s32 ngbe_set_mac_type(struct ngbe_hw *hw) return err; } +/** + * ngbe_enable_rx_dma - Enable the Rx DMA unit + * @hw: pointer to hardware structure + * @regval: register value to write to RXCTRL + * + * Enables the Rx DMA unit + **/ +s32 ngbe_enable_rx_dma(struct ngbe_hw *hw, u32 regval) +{ + DEBUGFUNC("ngbe_enable_rx_dma"); + + /* + * Workaround silicon errata when enabling the Rx datapath. + * If traffic is incoming before we enable the Rx unit, it could hang + * the Rx DMA unit. Therefore, make sure the security engine is + * completely disabled prior to enabling the Rx unit. + */ + + hw->mac.disable_sec_rx_path(hw); + + if (regval & NGBE_PBRXCTL_ENA) + ngbe_enable_rx(hw); + else + ngbe_disable_rx(hw); + + hw->mac.enable_sec_rx_path(hw); + + return 0; +} + void ngbe_map_device_id(struct ngbe_hw *hw) { u16 oem = hw->sub_system_id & NGBE_OEM_MASK; @@ -887,11 +989,14 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw) mac->init_hw = ngbe_init_hw; mac->reset_hw = ngbe_reset_hw_em; mac->start_hw = ngbe_start_hw; + mac->enable_rx_dma = ngbe_enable_rx_dma; mac->get_mac_addr = ngbe_get_mac_addr; mac->stop_hw = ngbe_stop_hw; mac->acquire_swfw_sync = ngbe_acquire_swfw_sync; mac->release_swfw_sync = ngbe_release_swfw_sync; + mac->disable_sec_rx_path = ngbe_disable_sec_rx_path; + mac->enable_sec_rx_path = ngbe_enable_sec_rx_path; /* RAR */ mac->set_rar = ngbe_set_rar; mac->clear_rar = ngbe_clear_rar; diff --git a/drivers/net/ngbe/base/ngbe_hw.h b/drivers/net/ngbe/base/ngbe_hw.h index 4fee5735ac..01f41fe9b3 100644 --- a/drivers/net/ngbe/base/ngbe_hw.h +++ b/drivers/net/ngbe/base/ngbe_hw.h @@ -34,6 +34,8 @@ s32 ngbe_set_rar(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq, u32 enable_addr); s32 ngbe_clear_rar(struct ngbe_hw *hw, u32 index); s32 ngbe_init_rx_addrs(struct ngbe_hw *hw); +s32 ngbe_disable_sec_rx_path(struct ngbe_hw *hw); +s32 ngbe_enable_sec_rx_path(struct ngbe_hw *hw); s32 ngbe_validate_mac_addr(u8 *mac_addr); s32 ngbe_acquire_swfw_sync(struct ngbe_hw *hw, u32 mask); @@ -46,10 +48,12 @@ s32 ngbe_init_uta_tables(struct ngbe_hw *hw); s32 ngbe_init_thermal_sensor_thresh(struct ngbe_hw *hw); s32 ngbe_mac_check_overtemp(struct ngbe_hw *hw); void ngbe_disable_rx(struct ngbe_hw *hw); +void ngbe_enable_rx(struct ngbe_hw *hw); s32 ngbe_init_shared_code(struct ngbe_hw *hw); s32 ngbe_set_mac_type(struct ngbe_hw *hw); s32 ngbe_init_ops_pf(struct ngbe_hw *hw); s32 ngbe_init_phy(struct ngbe_hw *hw); +s32 ngbe_enable_rx_dma(struct ngbe_hw *hw, u32 regval); void ngbe_map_device_id(struct ngbe_hw *hw); #endif /* _NGBE_HW_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h index 601fb85b91..134d2019e1 100644 --- a/drivers/net/ngbe/base/ngbe_type.h +++ b/drivers/net/ngbe/base/ngbe_type.h @@ -102,6 +102,9 @@ struct ngbe_mac_info { s32 (*start_hw)(struct ngbe_hw *hw); s32 (*stop_hw)(struct ngbe_hw *hw); s32 (*get_mac_addr)(struct ngbe_hw *hw, u8 *mac_addr); + s32 (*enable_rx_dma)(struct ngbe_hw *hw, u32 regval); + s32 (*disable_sec_rx_path)(struct ngbe_hw *hw); + s32 (*enable_sec_rx_path)(struct ngbe_hw *hw); s32 (*acquire_swfw_sync)(struct ngbe_hw *hw, u32 mask); void (*release_swfw_sync)(struct ngbe_hw *hw, u32 mask); @@ -196,6 +199,8 @@ struct ngbe_hw { u16 nb_rx_queues; u16 nb_tx_queues; + u32 q_rx_regs[8 * 4]; + u32 q_tx_regs[8 * 4]; bool is_pf; }; diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index 3812663591..2b551c00c7 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -435,6 +435,12 @@ ngbe_dev_start(struct rte_eth_dev *dev) goto error; } + err = ngbe_dev_rxtx_start(dev); + if (err < 0) { + PMD_INIT_LOG(ERR, "Unable to start rxtx queues"); + goto error; + } + /* Skip link setup if loopback mode is enabled. */ if (hw->is_pf && dev->data->dev_conf.lpbk_mode) goto skip_link_setup; @@ -1116,6 +1122,10 @@ static const struct eth_dev_ops ngbe_eth_dev_ops = { .dev_start = ngbe_dev_start, .link_update = ngbe_dev_link_update, .dev_supported_ptypes_get = ngbe_dev_supported_ptypes_get, + .rx_queue_start = ngbe_dev_rx_queue_start, + .rx_queue_stop = ngbe_dev_rx_queue_stop, + .tx_queue_start = ngbe_dev_tx_queue_start, + .tx_queue_stop = ngbe_dev_tx_queue_stop, .rx_queue_setup = ngbe_dev_rx_queue_setup, .rx_queue_release = ngbe_dev_rx_queue_release, .tx_queue_setup = ngbe_dev_tx_queue_setup, diff --git a/drivers/net/ngbe/ngbe_ethdev.h b/drivers/net/ngbe/ngbe_ethdev.h index 0b8dba571b..97ced40e4b 100644 --- a/drivers/net/ngbe/ngbe_ethdev.h +++ b/drivers/net/ngbe/ngbe_ethdev.h @@ -78,6 +78,21 @@ int ngbe_dev_rx_init(struct rte_eth_dev *dev); void ngbe_dev_tx_init(struct rte_eth_dev *dev); +int ngbe_dev_rxtx_start(struct rte_eth_dev *dev); + +void ngbe_dev_save_rx_queue(struct ngbe_hw *hw, uint16_t rx_queue_id); +void ngbe_dev_store_rx_queue(struct ngbe_hw *hw, uint16_t rx_queue_id); +void ngbe_dev_save_tx_queue(struct ngbe_hw *hw, uint16_t tx_queue_id); +void ngbe_dev_store_tx_queue(struct ngbe_hw *hw, uint16_t tx_queue_id); + +int ngbe_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id); + +int ngbe_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id); + +int ngbe_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id); + +int ngbe_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id); + uint16_t ngbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts); diff --git a/drivers/net/ngbe/ngbe_rxtx.c b/drivers/net/ngbe/ngbe_rxtx.c index 3f3f2cab06..daa2d7ae4d 100644 --- a/drivers/net/ngbe/ngbe_rxtx.c +++ b/drivers/net/ngbe/ngbe_rxtx.c @@ -2236,6 +2236,38 @@ ngbe_dev_rx_queue_setup(struct rte_eth_dev *dev, return 0; } +static int __rte_cold +ngbe_alloc_rx_queue_mbufs(struct ngbe_rx_queue *rxq) +{ + struct ngbe_rx_entry *rxe = rxq->sw_ring; + uint64_t dma_addr; + unsigned int i; + + /* Initialize software ring entries */ + for (i = 0; i < rxq->nb_rx_desc; i++) { + volatile struct ngbe_rx_desc *rxd; + struct rte_mbuf *mbuf = rte_mbuf_raw_alloc(rxq->mb_pool); + + if (mbuf == NULL) { + PMD_INIT_LOG(ERR, "RX mbuf alloc failed queue_id=%u", + (unsigned int)rxq->queue_id); + return -ENOMEM; + } + + mbuf->data_off = RTE_PKTMBUF_HEADROOM; + mbuf->port = rxq->port_id; + + dma_addr = + rte_cpu_to_le_64(rte_mbuf_data_iova_default(mbuf)); + rxd = &rxq->rx_ring[i]; + NGBE_RXD_HDRADDR(rxd, 0); + NGBE_RXD_PKTADDR(rxd, dma_addr); + rxe[i].mbuf = mbuf; + } + + return 0; +} + void __rte_cold ngbe_set_rx_function(struct rte_eth_dev *dev) { @@ -2473,3 +2505,278 @@ ngbe_dev_tx_init(struct rte_eth_dev *dev) } } +/* + * Set up link loopback mode Tx->Rx. + */ +static inline void __rte_cold +ngbe_setup_loopback_link(struct ngbe_hw *hw) +{ + PMD_INIT_FUNC_TRACE(); + + wr32m(hw, NGBE_MACRXCFG, NGBE_MACRXCFG_LB, NGBE_MACRXCFG_LB); + + msec_delay(50); +} + +/* + * Start Transmit and Receive Units. + */ +int __rte_cold +ngbe_dev_rxtx_start(struct rte_eth_dev *dev) +{ + struct ngbe_hw *hw; + struct ngbe_tx_queue *txq; + struct ngbe_rx_queue *rxq; + uint32_t dmatxctl; + uint32_t rxctrl; + uint16_t i; + int ret = 0; + + PMD_INIT_FUNC_TRACE(); + hw = NGBE_DEV_HW(dev); + + for (i = 0; i < dev->data->nb_tx_queues; i++) { + txq = dev->data->tx_queues[i]; + /* Setup Transmit Threshold Registers */ + wr32m(hw, NGBE_TXCFG(txq->reg_idx), + NGBE_TXCFG_HTHRESH_MASK | + NGBE_TXCFG_WTHRESH_MASK, + NGBE_TXCFG_HTHRESH(txq->hthresh) | + NGBE_TXCFG_WTHRESH(txq->wthresh)); + } + + dmatxctl = rd32(hw, NGBE_DMATXCTRL); + dmatxctl |= NGBE_DMATXCTRL_ENA; + wr32(hw, NGBE_DMATXCTRL, dmatxctl); + + for (i = 0; i < dev->data->nb_tx_queues; i++) { + txq = dev->data->tx_queues[i]; + if (!txq->tx_deferred_start) { + ret = ngbe_dev_tx_queue_start(dev, i); + if (ret < 0) + return ret; + } + } + + for (i = 0; i < dev->data->nb_rx_queues; i++) { + rxq = dev->data->rx_queues[i]; + if (!rxq->rx_deferred_start) { + ret = ngbe_dev_rx_queue_start(dev, i); + if (ret < 0) + return ret; + } + } + + /* Enable Receive engine */ + rxctrl = rd32(hw, NGBE_PBRXCTL); + rxctrl |= NGBE_PBRXCTL_ENA; + hw->mac.enable_rx_dma(hw, rxctrl); + + /* If loopback mode is enabled, set up the link accordingly */ + if (hw->is_pf && dev->data->dev_conf.lpbk_mode) + ngbe_setup_loopback_link(hw); + + return 0; +} + +void +ngbe_dev_save_rx_queue(struct ngbe_hw *hw, uint16_t rx_queue_id) +{ + u32 *reg = &hw->q_rx_regs[rx_queue_id * 8]; + *(reg++) = rd32(hw, NGBE_RXBAL(rx_queue_id)); + *(reg++) = rd32(hw, NGBE_RXBAH(rx_queue_id)); + *(reg++) = rd32(hw, NGBE_RXCFG(rx_queue_id)); +} + +void +ngbe_dev_store_rx_queue(struct ngbe_hw *hw, uint16_t rx_queue_id) +{ + u32 *reg = &hw->q_rx_regs[rx_queue_id * 8]; + wr32(hw, NGBE_RXBAL(rx_queue_id), *(reg++)); + wr32(hw, NGBE_RXBAH(rx_queue_id), *(reg++)); + wr32(hw, NGBE_RXCFG(rx_queue_id), *(reg++) & ~NGBE_RXCFG_ENA); +} + +void +ngbe_dev_save_tx_queue(struct ngbe_hw *hw, uint16_t tx_queue_id) +{ + u32 *reg = &hw->q_tx_regs[tx_queue_id * 8]; + *(reg++) = rd32(hw, NGBE_TXBAL(tx_queue_id)); + *(reg++) = rd32(hw, NGBE_TXBAH(tx_queue_id)); + *(reg++) = rd32(hw, NGBE_TXCFG(tx_queue_id)); +} + +void +ngbe_dev_store_tx_queue(struct ngbe_hw *hw, uint16_t tx_queue_id) +{ + u32 *reg = &hw->q_tx_regs[tx_queue_id * 8]; + wr32(hw, NGBE_TXBAL(tx_queue_id), *(reg++)); + wr32(hw, NGBE_TXBAH(tx_queue_id), *(reg++)); + wr32(hw, NGBE_TXCFG(tx_queue_id), *(reg++) & ~NGBE_TXCFG_ENA); +} + +/* + * Start Receive Units for specified queue. + */ +int __rte_cold +ngbe_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id) +{ + struct ngbe_hw *hw = NGBE_DEV_HW(dev); + struct ngbe_rx_queue *rxq; + uint32_t rxdctl; + int poll_ms; + + PMD_INIT_FUNC_TRACE(); + + rxq = dev->data->rx_queues[rx_queue_id]; + + /* Allocate buffers for descriptor rings */ + if (ngbe_alloc_rx_queue_mbufs(rxq) != 0) { + PMD_INIT_LOG(ERR, "Could not alloc mbuf for queue:%d", + rx_queue_id); + return -1; + } + rxdctl = rd32(hw, NGBE_RXCFG(rxq->reg_idx)); + rxdctl |= NGBE_RXCFG_ENA; + wr32(hw, NGBE_RXCFG(rxq->reg_idx), rxdctl); + + /* Wait until RX Enable ready */ + poll_ms = RTE_NGBE_REGISTER_POLL_WAIT_10_MS; + do { + rte_delay_ms(1); + rxdctl = rd32(hw, NGBE_RXCFG(rxq->reg_idx)); + } while (--poll_ms && !(rxdctl & NGBE_RXCFG_ENA)); + if (!poll_ms) + PMD_INIT_LOG(ERR, "Could not enable Rx Queue %d", rx_queue_id); + rte_wmb(); + wr32(hw, NGBE_RXRP(rxq->reg_idx), 0); + wr32(hw, NGBE_RXWP(rxq->reg_idx), rxq->nb_rx_desc - 1); + dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED; + + return 0; +} + +/* + * Stop Receive Units for specified queue. + */ +int __rte_cold +ngbe_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id) +{ + struct ngbe_hw *hw = NGBE_DEV_HW(dev); + struct ngbe_adapter *adapter = NGBE_DEV_ADAPTER(dev); + struct ngbe_rx_queue *rxq; + uint32_t rxdctl; + int poll_ms; + + PMD_INIT_FUNC_TRACE(); + + rxq = dev->data->rx_queues[rx_queue_id]; + + ngbe_dev_save_rx_queue(hw, rxq->reg_idx); + wr32m(hw, NGBE_RXCFG(rxq->reg_idx), NGBE_RXCFG_ENA, 0); + + /* Wait until RX Enable bit clear */ + poll_ms = RTE_NGBE_REGISTER_POLL_WAIT_10_MS; + do { + rte_delay_ms(1); + rxdctl = rd32(hw, NGBE_RXCFG(rxq->reg_idx)); + } while (--poll_ms && (rxdctl & NGBE_RXCFG_ENA)); + if (!poll_ms) + PMD_INIT_LOG(ERR, "Could not disable Rx Queue %d", rx_queue_id); + + rte_delay_us(RTE_NGBE_WAIT_100_US); + ngbe_dev_store_rx_queue(hw, rxq->reg_idx); + + ngbe_rx_queue_release_mbufs(rxq); + ngbe_reset_rx_queue(adapter, rxq); + dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED; + + return 0; +} + +/* + * Start Transmit Units for specified queue. + */ +int __rte_cold +ngbe_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id) +{ + struct ngbe_hw *hw = NGBE_DEV_HW(dev); + struct ngbe_tx_queue *txq; + uint32_t txdctl; + int poll_ms; + + PMD_INIT_FUNC_TRACE(); + + txq = dev->data->tx_queues[tx_queue_id]; + wr32m(hw, NGBE_TXCFG(txq->reg_idx), NGBE_TXCFG_ENA, NGBE_TXCFG_ENA); + + /* Wait until TX Enable ready */ + poll_ms = RTE_NGBE_REGISTER_POLL_WAIT_10_MS; + do { + rte_delay_ms(1); + txdctl = rd32(hw, NGBE_TXCFG(txq->reg_idx)); + } while (--poll_ms && !(txdctl & NGBE_TXCFG_ENA)); + if (!poll_ms) + PMD_INIT_LOG(ERR, "Could not enable " + "Tx Queue %d", tx_queue_id); + + rte_wmb(); + wr32(hw, NGBE_TXWP(txq->reg_idx), txq->tx_tail); + dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED; + + return 0; +} + +/* + * Stop Transmit Units for specified queue. + */ +int __rte_cold +ngbe_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id) +{ + struct ngbe_hw *hw = NGBE_DEV_HW(dev); + struct ngbe_tx_queue *txq; + uint32_t txdctl; + uint32_t txtdh, txtdt; + int poll_ms; + + PMD_INIT_FUNC_TRACE(); + + txq = dev->data->tx_queues[tx_queue_id]; + + /* Wait until TX queue is empty */ + poll_ms = RTE_NGBE_REGISTER_POLL_WAIT_10_MS; + do { + rte_delay_us(RTE_NGBE_WAIT_100_US); + txtdh = rd32(hw, NGBE_TXRP(txq->reg_idx)); + txtdt = rd32(hw, NGBE_TXWP(txq->reg_idx)); + } while (--poll_ms && (txtdh != txtdt)); + if (!poll_ms) + PMD_INIT_LOG(ERR, + "Tx Queue %d is not empty when stopping.", + tx_queue_id); + + ngbe_dev_save_tx_queue(hw, txq->reg_idx); + wr32m(hw, NGBE_TXCFG(txq->reg_idx), NGBE_TXCFG_ENA, 0); + + /* Wait until TX Enable bit clear */ + poll_ms = RTE_NGBE_REGISTER_POLL_WAIT_10_MS; + do { + rte_delay_ms(1); + txdctl = rd32(hw, NGBE_TXCFG(txq->reg_idx)); + } while (--poll_ms && (txdctl & NGBE_TXCFG_ENA)); + if (!poll_ms) + PMD_INIT_LOG(ERR, "Could not disable Tx Queue %d", + tx_queue_id); + + rte_delay_us(RTE_NGBE_WAIT_100_US); + ngbe_dev_store_tx_queue(hw, txq->reg_idx); + + if (txq->ops != NULL) { + txq->ops->release_mbufs(txq); + txq->ops->reset(txq); + } + dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED; + + return 0; +} + diff --git a/drivers/net/ngbe/ngbe_rxtx.h b/drivers/net/ngbe/ngbe_rxtx.h index 2cb98e2497..48241bd634 100644 --- a/drivers/net/ngbe/ngbe_rxtx.h +++ b/drivers/net/ngbe/ngbe_rxtx.h @@ -208,6 +208,9 @@ struct ngbe_tx_desc { #define rte_packet_prefetch(p) rte_prefetch1(p) +#define RTE_NGBE_REGISTER_POLL_WAIT_10_MS 10 +#define RTE_NGBE_WAIT_100_US 100 + #define NGBE_TX_MAX_SEG 40 /** -- 2.27.0