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 922B8A0C48; Mon, 14 Jun 2021 22:44:33 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 186664067E; Mon, 14 Jun 2021 22:44:33 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 775DB4067A for ; Mon, 14 Jun 2021 22:44:32 +0200 (CEST) Received: from [192.168.1.71] (unknown [188.170.85.171]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by shelob.oktetlabs.ru (Postfix) with ESMTPSA id B27637F504; Mon, 14 Jun 2021 23:44:31 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru B27637F504 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=oktetlabs.ru; s=default; t=1623703472; bh=+02v0y+3+V1XXH48rk7pJ2ShEXhnTjwfhDns/yTZ0sA=; h=Subject:To:References:From:Date:In-Reply-To; b=DtUPCfYLflo0ybXp88icQ9GJu0LR5nmlfhCGtNkFhSJvjhSrW9W0hu/g4Cc8RerP0 uMNwrgIAknUyz6GoigLOg15bJaQS/Gj4km8d5mLM7KWpSfhGPJF9OiHa8levzHpYIf 5j+CWOIqLJcQ7kTHUaNHbAjJzW/Bh3OtGwBtFjwY= To: Jiawen Wu , dev@dpdk.org References: <20210602094108.1575640-1-jiawenwu@trustnetic.com> <20210602094108.1575640-24-jiawenwu@trustnetic.com> From: Andrew Rybchenko Message-ID: <93ff48bb-434c-29b4-b0b0-41e673dfbd26@oktetlabs.ru> Date: Mon, 14 Jun 2021 23:44:29 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.10.0 MIME-Version: 1.0 In-Reply-To: <20210602094108.1575640-24-jiawenwu@trustnetic.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit Subject: Re: [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" On 6/2/21 12:41 PM, Jiawen Wu wrote: > Support to start and stop receive and transmit unit for specified > queues. Before the patch attempt to setup Rx or Tx queue with deferred start should return an error. > > 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; > + } > + It is a part of device start procedure which is required even when deferrred start is not supported. May be separate patch which adds Tx queues start to device start. And similar for Rx. > /* 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, These callbacks really belongs to deferred start feature. May be it makes sense to seprate Rx and Tx in different patches. > .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; Please, add a comment to explain why volatile is required. > + 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", RX -> Rx port_id should be logged as well > + (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); > +} Loopback support is a separate feature. > + > +/* > + * 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) { tx_deferred_start is not a bool, so, should be compared vs 0 > + 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) { rx_deferred_start is not a bool, so, should be compared vs 0 > + 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); Loopback support is a separate feature. Before the patch request for loopback mode should return an error. > + > + 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 */ RX -> Rx > + 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) Compare vs 0 > + 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 */ RX -> Rx > + 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) Compare vs 0 > + 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 */ TX -> Tx > + 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) Compare vs 0 > + 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 */ TX -> Tx > + 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) Compare vs 0 > + 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 */ TX -> Tx > + 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) Compare vs 0 > + 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 > > /** >