From: Luca Boccassi <bl...@debian.org> This reset function will detach then re-attach the device, reconfigure it, and re-setup the Rx/Tx queues.
Signed-off-by: Luca Boccassi <bl...@debian.org> --- drivers/net/i40e/i40e_ethdev.h | 3 +++ drivers/net/i40e/i40e_ethdev_vf.c | 56 ++++++++++++++++++++++++++++++++++++--- drivers/net/i40e/i40e_rxtx.c | 11 ++++++++ drivers/net/i40e/i40e_rxtx.h | 4 +++ 4 files changed, 70 insertions(+), 4 deletions(-) diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h index 2f1905e13..45714959a 100644 --- a/drivers/net/i40e/i40e_ethdev.h +++ b/drivers/net/i40e/i40e_ethdev.h @@ -1047,6 +1047,9 @@ struct i40e_adapter { struct rte_timecounter rx_tstamp_tc; struct rte_timecounter tx_tstamp_tc; + /* For VF reset */ + uint8_t reset_number; + /* ptype mapping table */ uint32_t ptype_tbl[I40E_MAX_PKT_TYPE] __rte_cache_min_aligned; /* flow type to pctype mapping table */ diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c index 9f1487509..333ddb4ca 100644 --- a/drivers/net/i40e/i40e_ethdev_vf.c +++ b/drivers/net/i40e/i40e_ethdev_vf.c @@ -2294,21 +2294,69 @@ i40evf_dev_close(struct rte_eth_dev *dev) i40evf_disable_irq0(hw); } -/* - * Reset VF device only to re-initialize resources in PMD layer - */ +static void +i40e_vf_queue_reset(struct rte_eth_dev *dev) +{ + uint16_t i; + + for (i = 0; i < dev->data->nb_rx_queues; i++) { + struct i40e_rx_queue *rxq = dev->data->rx_queues[i]; + + if (rxq->q_set) { + i40e_dev_rx_queue_setup(dev, + rxq->queue_id, + rxq->nb_rx_desc, + rxq->socket_id, + &rxq->rxconf, + rxq->mp); + } + } + for (i = 0; i < dev->data->nb_tx_queues; i++) { + struct i40e_tx_queue *txq = dev->data->tx_queues[i]; + + if (txq->q_set) { + i40e_dev_tx_queue_setup(dev, + txq->queue_id, + txq->nb_tx_desc, + txq->socket_id, + &txq->txconf); + } + } +} + static int i40evf_dev_reset(struct rte_eth_dev *dev) { int ret; + struct i40e_adapter *adapter = + I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); + if (!dev->data->dev_started) + return -EAGAIN; + + adapter->reset_number = 1; + i40evf_dev_close(dev); + PMD_DRV_LOG(DEBUG, "i40evf dev close complete"); ret = i40evf_dev_uninit(dev); if (ret) return ret; + PMD_DRV_LOG(DEBUG, "i40evf dev detached"); + memset(dev->data->dev_private, 0, + (uint64_t)&adapter->reset_number - (uint64_t)adapter); + i40evf_dev_configure(dev); ret = i40evf_dev_init(dev); + if (ret) + return ret; + PMD_DRV_LOG(DEBUG, "i40evf dev attached"); - return ret; + i40e_vf_queue_reset(dev); + PMD_DRV_LOG(DEBUG, "i40evf queue reset"); + i40evf_dev_start(dev); + PMD_DRV_LOG(DEBUG, "i40evf dev restart"); + adapter->reset_number = 0; + + return 0; } static int diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c index f21c1c5d2..3d5125260 100644 --- a/drivers/net/i40e/i40e_rxtx.c +++ b/drivers/net/i40e/i40e_rxtx.c @@ -1745,6 +1745,7 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev, uint32_t ring_size; uint16_t len, i; uint16_t reg_idx, base, bsf, tc_mapping; + struct rte_eth_rxconf conf = *rx_conf; int q_offset, use_def_burst_func = 1; if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) { @@ -1789,6 +1790,8 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev, return -ENOMEM; } rxq->mp = mp; + rxq->socket_id = socket_id; + rxq->rxconf = conf; rxq->nb_rx_desc = nb_desc; rxq->rx_free_thresh = rx_conf->rx_free_thresh; rxq->queue_id = queue_idx; @@ -2024,6 +2027,8 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t reg_idx, i, base, bsf, tc_mapping; int q_offset; + struct rte_eth_txconf conf = *tx_conf; + if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) { vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); vsi = &vf->vsi; @@ -2149,6 +2154,8 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev, } txq->nb_tx_desc = nb_desc; + txq->socket_id = socket_id; + txq->txconf = conf; txq->tx_rs_thresh = tx_rs_thresh; txq->tx_free_thresh = tx_free_thresh; txq->pthresh = tx_conf->tx_thresh.pthresh; @@ -2628,8 +2635,12 @@ void i40e_dev_free_queues(struct rte_eth_dev *dev) { uint16_t i; + struct i40e_adapter *adapter = + I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); PMD_INIT_FUNC_TRACE(); + if (adapter->reset_number) + return; for (i = 0; i < dev->data->nb_rx_queues; i++) { if (!dev->data->rx_queues[i]) diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h index 06c6a6592..43e227a52 100644 --- a/drivers/net/i40e/i40e_rxtx.h +++ b/drivers/net/i40e/i40e_rxtx.h @@ -136,6 +136,8 @@ struct i40e_rx_queue { bool rx_deferred_start; /**< don't start this queue in dev start */ uint16_t rx_using_sse; /**<flag indicate the usage of vPMD for rx */ uint8_t dcb_tc; /**< Traffic class of rx queue */ + uint8_t socket_id; + struct rte_eth_rxconf rxconf; }; struct i40e_tx_entry { @@ -177,6 +179,8 @@ struct i40e_tx_queue { bool q_set; /**< indicate if tx queue has been configured */ bool tx_deferred_start; /**< don't start this queue in dev start */ uint8_t dcb_tc; /**< Traffic class of tx queue */ + uint8_t socket_id; + struct rte_eth_txconf txconf; }; /** Offload features */ -- 2.11.0