optimize queue res alloc/free process. Signed-off-by: Junlong Wang --- drivers/net/zxdh/zxdh_common.c | 29 +++-- drivers/net/zxdh/zxdh_ethdev.c | 201 ++++++++++++++++++++--------- drivers/net/zxdh/zxdh_ethdev.h | 14 +- drivers/net/zxdh/zxdh_ethdev_ops.c | 13 +- drivers/net/zxdh/zxdh_pci.c | 10 -- drivers/net/zxdh/zxdh_queue.c | 123 +++++++++++------- 6 files changed, 254 insertions(+), 136 deletions(-) diff --git a/drivers/net/zxdh/zxdh_common.c b/drivers/net/zxdh/zxdh_common.c index 7158bd735d..0c9696e7ce 100644 --- a/drivers/net/zxdh/zxdh_common.c +++ b/drivers/net/zxdh/zxdh_common.c @@ -398,27 +398,32 @@ int32_t zxdh_datach_set(struct rte_eth_dev *dev) { struct zxdh_hw *hw = dev->data->dev_private; - uint16_t buff_size = (hw->queue_num + 1) * 2; - int32_t ret = 0; - uint16_t i; + uint16_t rxq_num = hw->rx_qnum; + uint16_t txq_num = hw->tx_qnum; + uint16_t nr_vq = (rxq_num > txq_num) ? 2 * rxq_num : 2 * txq_num; + uint16_t buff_size = (nr_vq % ZXDH_QUEUES_NUM_MAX + 1) * sizeof(uint16_t); + int ret = 0; + uint16_t *pdata, i; void *buff = rte_zmalloc(NULL, buff_size, 0); + if (unlikely(buff == NULL)) { PMD_DRV_LOG(ERR, "Failed to allocate buff"); return -ENOMEM; } - memset(buff, 0, buff_size); - uint16_t *pdata = (uint16_t *)buff; - *pdata++ = hw->queue_num; - for (i = 0; i < hw->queue_num; i++) - *(pdata + i) = hw->channel_context[i].ph_chno; + pdata = (uint16_t *)buff; + *pdata++ = nr_vq; + for (i = 0; i < hw->rx_qnum; i++) + *(pdata + i * 2) = hw->channel_context[i * 2].ph_chno; + for (i = 0; i < hw->tx_qnum; i++) + *(pdata + i * 2 + 1) = hw->channel_context[i * 2 + 1].ph_chno; + ret = zxdh_common_table_write(hw, ZXDH_COMMON_FIELD_DATACH, (void *)buff, buff_size); - ret = zxdh_common_table_write(hw, ZXDH_COMMON_FIELD_DATACH, - (void *)buff, buff_size); if (ret != 0) - PMD_DRV_LOG(ERR, "Failed to setup data channel of common table"); - + PMD_DRV_LOG(ERR, "Failed to setup data channel of common table. code:%d", ret); + hw->que_set_flag = 1; rte_free(buff); + return ret; } diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c index fc1bff6b44..c76818d015 100644 --- a/drivers/net/zxdh/zxdh_ethdev.c +++ b/drivers/net/zxdh/zxdh_ethdev.c @@ -27,6 +27,10 @@ struct zxdh_dev_shared_data g_dev_sd[ZXDH_SLOT_MAX]; #define ZXDH_INVALID_DTBQUE 0xFFFF #define ZXDH_INVALID_SLOT_IDX 0xFFFF +#define ZXDH_PF_QUEUE_PAIRS_ADDR 0x5742 +#define ZXDH_VF_QUEUE_PAIRS_ADDR 0x5744 +#define ZXDH_QUEUE_POOL_ADDR 0x56A0 + uint16_t zxdh_vport_to_vfid(union zxdh_virport_num v) { @@ -90,10 +94,11 @@ zxdh_queues_unbind_intr(struct rte_eth_dev *dev) struct zxdh_hw *hw = dev->data->dev_private; int32_t i; - for (i = 0; i < dev->data->nb_rx_queues; ++i) { + for (i = 0; i < dev->data->nb_rx_queues; ++i) ZXDH_VTPCI_OPS(hw)->set_queue_irq(hw, hw->vqs[i * 2], ZXDH_MSI_NO_VECTOR); + + for (i = 0; i < dev->data->nb_tx_queues; ++i) ZXDH_VTPCI_OPS(hw)->set_queue_irq(hw, hw->vqs[i * 2 + 1], ZXDH_MSI_NO_VECTOR); - } } @@ -467,33 +472,30 @@ static void zxdh_dev_free_mbufs(struct rte_eth_dev *dev) { struct zxdh_hw *hw = dev->data->dev_private; - uint16_t nr_vq = hw->queue_num; - uint32_t i = 0; - - const char *type = NULL; - struct zxdh_virtqueue *vq = NULL; - struct rte_mbuf *buf = NULL; - int32_t queue_type = 0; + struct zxdh_virtqueue *vq; + struct rte_mbuf *buf; + int i; if (hw->vqs == NULL) return; - for (i = 0; i < nr_vq; i++) { - vq = hw->vqs[i]; + for (i = 0; i < hw->rx_qnum; i++) { + vq = hw->vqs[i * 2]; if (!vq) continue; - - queue_type = zxdh_get_queue_type(i); - if (queue_type == ZXDH_VTNET_RQ) - type = "rxq"; - else if (queue_type == ZXDH_VTNET_TQ) - type = "txq"; - else + while ((buf = zxdh_queue_detach_unused(vq)) != NULL) + rte_pktmbuf_free(buf); + PMD_DRV_LOG(DEBUG, "freeing %s[%d] used and unused buf", + "rxq", i * 2); + } + for (i = 0; i < hw->tx_qnum; i++) { + vq = hw->vqs[i * 2 + 1]; + if (!vq) continue; - PMD_DRV_LOG(DEBUG, "Before freeing %s[%d] used and unused buf", type, i); - while ((buf = zxdh_queue_detach_unused(vq)) != NULL) rte_pktmbuf_free(buf); + PMD_DRV_LOG(DEBUG, "freeing %s[%d] used and unused buf", + "txq", i * 2 + 1); } } @@ -501,10 +503,16 @@ static int32_t zxdh_get_available_channel(struct rte_eth_dev *dev, uint8_t queue_type) { struct zxdh_hw *hw = dev->data->dev_private; - uint16_t base = (queue_type == ZXDH_VTNET_RQ) ? 0 : 1; - uint16_t i = 0; - uint16_t j = 0; - uint16_t done = 0; + uint16_t base = (queue_type == ZXDH_VTNET_RQ) ? 0 : 1; /* txq only polls odd bits*/ + uint16_t j = 0; + uint16_t done = 0; + uint32_t phy_vq_reg = 0; + uint16_t total_queue_num = hw->queue_pool_count * 2; + uint16_t start_qp_id = hw->queue_pool_start * 2; + uint32_t phy_vq_reg_oft = start_qp_id / 32; + uint32_t inval_bit = start_qp_id % 32; + uint32_t res_bit = (total_queue_num + inval_bit) % 32; + uint32_t vq_reg_num = (total_queue_num + inval_bit) / 32 + (res_bit ? 1 : 0); int32_t ret = 0; ret = zxdh_timedlock(hw, 1000); @@ -513,23 +521,49 @@ zxdh_get_available_channel(struct rte_eth_dev *dev, uint8_t queue_type) return -1; } - /* Iterate COI table and find free channel */ - for (i = ZXDH_QUEUES_BASE / 32; i < ZXDH_TOTAL_QUEUES_NUM / 32; i++) { - uint32_t addr = ZXDH_QUERES_SHARE_BASE + (i * sizeof(uint32_t)); + for (phy_vq_reg = 0; phy_vq_reg < vq_reg_num; phy_vq_reg++) { + uint32_t addr = ZXDH_QUERES_SHARE_BASE + + (phy_vq_reg + phy_vq_reg_oft) * sizeof(uint32_t); uint32_t var = zxdh_read_bar_reg(dev, ZXDH_BAR0_INDEX, addr); - - for (j = base; j < 32; j += 2) { - /* Got the available channel & update COI table */ - if ((var & (1 << j)) == 0) { - var |= (1 << j); - zxdh_write_bar_reg(dev, ZXDH_BAR0_INDEX, addr, var); - done = 1; + if (phy_vq_reg == 0) { + for (j = (inval_bit + base); j < 32; j += 2) { + /* Got the available channel & update COI table */ + if ((var & (1 << j)) == 0) { + var |= (1 << j); + zxdh_write_bar_reg(dev, ZXDH_BAR0_INDEX, addr, var); + done = 1; + break; + } + } + if (done) + break; + } else if ((phy_vq_reg == (vq_reg_num - 1)) && (res_bit != 0)) { + for (j = base; j < res_bit; j += 2) { + /* Got the available channel & update COI table */ + if ((var & (1 << j)) == 0) { + var |= (1 << j); + zxdh_write_bar_reg(dev, ZXDH_BAR0_INDEX, addr, var); + done = 1; + break; + } + } + if (done) break; + } else { + for (j = base; j < 32; j += 2) { + /* Got the available channel & update COI table */ + if ((var & (1 << j)) == 0) { + var |= (1 << j); + zxdh_write_bar_reg(dev, ZXDH_BAR0_INDEX, addr, var); + done = 1; + break; + } } + if (done) + break; } - if (done) - break; } + zxdh_release_lock(hw); /* check for no channel condition */ if (done != 1) { @@ -537,7 +571,7 @@ zxdh_get_available_channel(struct rte_eth_dev *dev, uint8_t queue_type) return -1; } /* reruen available channel ID */ - return (i * 32) + j; + return (phy_vq_reg + phy_vq_reg_oft) * 32 + j; } static int32_t @@ -742,29 +776,46 @@ zxdh_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_logic_qidx) } static int32_t -zxdh_alloc_queues(struct rte_eth_dev *dev, uint16_t nr_vq) +zxdh_alloc_queues(struct rte_eth_dev *dev) { - uint16_t lch; struct zxdh_hw *hw = dev->data->dev_private; - + u_int16_t rxq_num = hw->rx_qnum; + u_int16_t txq_num = hw->tx_qnum; + uint16_t nr_vq = (rxq_num > txq_num) ? 2 * rxq_num : 2 * txq_num; hw->vqs = rte_zmalloc(NULL, sizeof(struct zxdh_virtqueue *) * nr_vq, 0); + uint16_t lch, i; + if (!hw->vqs) { - PMD_DRV_LOG(ERR, "Failed to allocate vqs"); + PMD_DRV_LOG(ERR, "Failed to allocate %d vqs", nr_vq); return -ENOMEM; } - for (lch = 0; lch < nr_vq; lch++) { + for (i = 0 ; i < rxq_num; i++) { + lch = i * 2; if (zxdh_acquire_channel(dev, lch) < 0) { PMD_DRV_LOG(ERR, "Failed to acquire the channels"); - zxdh_free_queues(dev); - return -1; + goto free; } if (zxdh_init_queue(dev, lch) < 0) { PMD_DRV_LOG(ERR, "Failed to alloc virtio queue"); - zxdh_free_queues(dev); - return -1; + goto free; + } + } + for (i = 0 ; i < txq_num; i++) { + lch = i * 2 + 1; + if (zxdh_acquire_channel(dev, lch) < 0) { + PMD_DRV_LOG(ERR, "Failed to acquire the channels"); + goto free; + } + if (zxdh_init_queue(dev, lch) < 0) { + PMD_DRV_LOG(ERR, "Failed to alloc virtio queue"); + goto free; } } return 0; + +free: + zxdh_free_queues(dev); + return -1; } static int @@ -841,20 +892,15 @@ zxdh_dev_configure(struct rte_eth_dev *dev) const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; const struct rte_eth_txmode *txmode = &dev->data->dev_conf.txmode; struct zxdh_hw *hw = dev->data->dev_private; - uint32_t nr_vq = 0; int32_t ret = 0; - if (dev->data->nb_rx_queues != dev->data->nb_tx_queues) { - PMD_DRV_LOG(ERR, "nb_rx_queues=%d and nb_tx_queues=%d not equal!", - dev->data->nb_rx_queues, dev->data->nb_tx_queues); - return -EINVAL; - } - if ((dev->data->nb_rx_queues + dev->data->nb_tx_queues) >= ZXDH_QUEUES_NUM_MAX) { - PMD_DRV_LOG(ERR, "nb_rx_queues=%d + nb_tx_queues=%d must < (%d)!", - dev->data->nb_rx_queues, dev->data->nb_tx_queues, - ZXDH_QUEUES_NUM_MAX); + if (dev->data->nb_rx_queues > hw->max_queue_pairs || + dev->data->nb_tx_queues > hw->max_queue_pairs) { + PMD_DRV_LOG(ERR, "nb_rx_queues=%d or nb_tx_queues=%d must < (%d)!", + dev->data->nb_rx_queues, dev->data->nb_tx_queues, hw->max_queue_pairs); return -EINVAL; } + if (rxmode->mq_mode != RTE_ETH_MQ_RX_RSS && rxmode->mq_mode != RTE_ETH_MQ_RX_NONE) { PMD_DRV_LOG(ERR, "Unsupported Rx multi queue mode %d", rxmode->mq_mode); return -EINVAL; @@ -889,9 +935,13 @@ zxdh_dev_configure(struct rte_eth_dev *dev) hw->has_tx_offload = zxdh_tx_offload_enabled(hw); hw->has_rx_offload = zxdh_rx_offload_enabled(hw); - nr_vq = dev->data->nb_rx_queues + dev->data->nb_tx_queues; - if (nr_vq == hw->queue_num) + if (dev->data->nb_rx_queues == hw->rx_qnum && + dev->data->nb_tx_queues == hw->tx_qnum) { + PMD_DRV_LOG(DEBUG, "The queuw not need to change. queue_rx %d queue_tx %d", + hw->rx_qnum, hw->tx_qnum); + /*no que changed */ goto end; + } PMD_DRV_LOG(DEBUG, "queue changed need reset"); /* Reset the device although not necessary at startup */ @@ -908,8 +958,9 @@ zxdh_dev_configure(struct rte_eth_dev *dev) zxdh_free_queues(dev); } - hw->queue_num = nr_vq; - ret = zxdh_alloc_queues(dev, nr_vq); + hw->rx_qnum = dev->data->nb_rx_queues; + hw->tx_qnum = dev->data->nb_tx_queues; + ret = zxdh_alloc_queues(dev); if (ret < 0) return ret; @@ -1501,6 +1552,35 @@ zxdh_tables_init(struct rte_eth_dev *dev) return ret; } +static void +zxdh_queue_res_get(struct rte_eth_dev *eth_dev) +{ + struct zxdh_hw *hw = eth_dev->data->dev_private; + uint32_t value = 0; + uint16_t offset = 0; + + if (hw->is_pf) { + hw->max_queue_pairs = *(volatile uint8_t *)(hw->bar_addr[0] + + ZXDH_PF_QUEUE_PAIRS_ADDR); + PMD_DRV_LOG(DEBUG, "is_pf max_queue_pairs is %x", hw->max_queue_pairs); + } else { + hw->max_queue_pairs = *(volatile uint8_t *)(hw->bar_addr[0] + + ZXDH_VF_QUEUE_PAIRS_ADDR + offset); + PMD_DRV_LOG(DEBUG, "is_vf max_queue_pairs is %x", hw->max_queue_pairs); + } + + /* pf/vf read queue start id and queue_max cfg */ + value = *(volatile uint32_t *)(hw->bar_addr[0] + ZXDH_QUEUE_POOL_ADDR + offset * 4); + hw->queue_pool_count = value & 0x0000ffff; + hw->queue_pool_start = value >> 16; + if (hw->max_queue_pairs > ZXDH_RX_QUEUES_MAX || hw->max_queue_pairs == 0) + hw->max_queue_pairs = ZXDH_RX_QUEUES_MAX; + if (hw->queue_pool_count > ZXDH_TOTAL_QUEUES_NUM / 2 || hw->queue_pool_count == 0) + hw->queue_pool_count = ZXDH_TOTAL_QUEUES_NUM / 2; + if (hw->queue_pool_start > ZXDH_TOTAL_QUEUES_NUM / 2) + hw->queue_pool_start = 0; +} + static int zxdh_eth_dev_init(struct rte_eth_dev *eth_dev) { @@ -1574,6 +1654,7 @@ zxdh_eth_dev_init(struct rte_eth_dev *eth_dev) if (ret) goto err_zxdh_init; + zxdh_queue_res_get(eth_dev); ret = zxdh_configure_intr(eth_dev); if (ret != 0) goto err_zxdh_init; diff --git a/drivers/net/zxdh/zxdh_ethdev.h b/drivers/net/zxdh/zxdh_ethdev.h index 6c9cc58a9a..c42f638c8d 100644 --- a/drivers/net/zxdh/zxdh_ethdev.h +++ b/drivers/net/zxdh/zxdh_ethdev.h @@ -23,8 +23,8 @@ #define ZXDH_MAX_MAC_ADDRS (ZXDH_MAX_UC_MAC_ADDRS + ZXDH_MAX_MC_MAC_ADDRS) #define ZXDH_NUM_BARS 2 -#define ZXDH_RX_QUEUES_MAX 128U -#define ZXDH_TX_QUEUES_MAX 128U +#define ZXDH_RX_QUEUES_MAX 127U +#define ZXDH_TX_QUEUES_MAX 127U #define ZXDH_MIN_RX_BUFSIZE 64 #define ZXDH_MAX_RX_PKTLEN 14000U #define ZXDH_QUEUE_DEPTH 1024 @@ -71,16 +71,17 @@ struct zxdh_hw { uint64_t bar_addr[ZXDH_NUM_BARS]; uint64_t host_features; uint64_t guest_features; - uint32_t max_queue_pairs; uint32_t speed; uint32_t speed_mode; uint32_t notify_off_multiplier; union zxdh_virport_num vport; + uint16_t max_queue_pairs; uint16_t pcie_id; uint16_t device_id; uint16_t port_id; uint16_t vfid; - uint16_t queue_num; + uint16_t rx_qnum; + uint16_t tx_qnum; uint16_t mc_num; uint16_t uc_num; @@ -107,6 +108,11 @@ struct zxdh_hw { uint8_t rss_enable; uint8_t rss_init; uint16_t slot_id; + + uint8_t que_set_flag; + uint16_t queue_pool_count; + uint16_t queue_pool_start; + uint8_t rsv[3]; }; struct zxdh_dtb_shared_data { diff --git a/drivers/net/zxdh/zxdh_ethdev_ops.c b/drivers/net/zxdh/zxdh_ethdev_ops.c index c3c5045281..6ed6c6cfdc 100644 --- a/drivers/net/zxdh/zxdh_ethdev_ops.c +++ b/drivers/net/zxdh/zxdh_ethdev_ops.c @@ -936,14 +936,15 @@ zxdh_dev_rss_reta_update(struct rte_eth_dev *dev, static uint16_t zxdh_hw_qid_to_logic_qid(struct rte_eth_dev *dev, uint16_t qid) { - struct zxdh_hw *hw = (struct zxdh_hw *)dev->data->dev_private; - uint16_t rx_queues = dev->data->nb_rx_queues; + struct zxdh_hw *priv = (struct zxdh_hw *)dev->data->dev_private; uint16_t i; - for (i = 0; i < rx_queues; i++) { - if (qid == hw->channel_context[i * 2].ph_chno) - return i; + for (i = 0; i < priv->max_queue_pairs * 2 ; i++) { + if (priv->channel_context[i].valid) + if (qid == priv->channel_context[i].ph_chno) + return i; } + return ZXDH_INVALID_LOGIC_QID; } @@ -1001,7 +1002,7 @@ zxdh_dev_rss_reta_query(struct rte_eth_dev *dev, reta_table->reta[i], qid_logic); return -EINVAL; } - reta_conf[idx].reta[i % RTE_ETH_RETA_GROUP_SIZE] = qid_logic; + reta_conf[idx].reta[i % RTE_ETH_RETA_GROUP_SIZE] = qid_logic >> 1; } return 0; } diff --git a/drivers/net/zxdh/zxdh_pci.c b/drivers/net/zxdh/zxdh_pci.c index 959b1b8cff..3d1a3ff0dd 100644 --- a/drivers/net/zxdh/zxdh_pci.c +++ b/drivers/net/zxdh/zxdh_pci.c @@ -396,7 +396,6 @@ zxdh_get_pci_dev_config(struct zxdh_hw *hw) { uint64_t guest_features = 0; uint64_t nego_features = 0; - uint32_t max_queue_pairs = 0; hw->host_features = zxdh_pci_get_features(hw); @@ -411,15 +410,6 @@ zxdh_get_pci_dev_config(struct zxdh_hw *hw) } else { rte_eth_random_addr(&hw->mac_addr[0]); } - - zxdh_pci_read_dev_config(hw, offsetof(struct zxdh_net_config, max_virtqueue_pairs), - &max_queue_pairs, sizeof(max_queue_pairs)); - - if (max_queue_pairs == 0) - hw->max_queue_pairs = ZXDH_RX_QUEUES_MAX; - else - hw->max_queue_pairs = RTE_MIN(ZXDH_RX_QUEUES_MAX, max_queue_pairs); - PMD_DRV_LOG(DEBUG, "set max queue pairs %d", hw->max_queue_pairs); } enum zxdh_msix_status zxdh_pci_msix_detect(struct rte_pci_device *dev) diff --git a/drivers/net/zxdh/zxdh_queue.c b/drivers/net/zxdh/zxdh_queue.c index 8c8f2605f6..3e3bac2efc 100644 --- a/drivers/net/zxdh/zxdh_queue.c +++ b/drivers/net/zxdh/zxdh_queue.c @@ -36,44 +36,75 @@ zxdh_queue_detach_unused(struct zxdh_virtqueue *vq) return NULL; } +static void +zxdh_clear_channel(struct rte_eth_dev *dev, uint16_t lch) +{ + struct zxdh_hw *hw = dev->data->dev_private; + uint16_t pch; + uint32_t var, addr, widx, bidx; + + if (hw->channel_context[lch].valid == 0) + return; + /* get coi table offset and index */ + pch = hw->channel_context[lch].ph_chno; + widx = pch / 32; + bidx = pch % 32; + addr = ZXDH_QUERES_SHARE_BASE + (widx * sizeof(uint32_t)); + var = zxdh_read_bar_reg(dev, ZXDH_BAR0_INDEX, addr); + var &= ~(1 << bidx); + zxdh_write_bar_reg(dev, ZXDH_BAR0_INDEX, addr, var); + hw->channel_context[lch].valid = 0; + hw->channel_context[lch].ph_chno = 0; + PMD_DRV_LOG(DEBUG, " phyque %d release end ", pch); +} + static int32_t zxdh_release_channel(struct rte_eth_dev *dev) { struct zxdh_hw *hw = dev->data->dev_private; - uint16_t nr_vq = hw->queue_num; - uint32_t var = 0; - uint32_t addr = 0; - uint32_t widx = 0; - uint32_t bidx = 0; - uint16_t pch = 0; - uint16_t lch = 0; + u_int16_t rxq_num = hw->rx_qnum; + u_int16_t txq_num = hw->tx_qnum; + uint16_t lch, i; int32_t ret = 0; + if (hw->que_set_flag == 1) { + for (i = 0; i < rxq_num; i++) { + lch = i * 2; + PMD_DRV_LOG(DEBUG, "free success!"); + if (hw->channel_context[lch].valid == 0) + continue; + PMD_DRV_LOG(DEBUG, "phyque %d no need to release backend do it", + hw->channel_context[lch].ph_chno); + hw->channel_context[lch].valid = 0; + hw->channel_context[lch].ph_chno = 0; + } + for (i = 0; i < txq_num; i++) { + lch = i * 2 + 1; + PMD_DRV_LOG(DEBUG, "free success!"); + if (hw->channel_context[lch].valid == 0) + continue; + PMD_DRV_LOG(DEBUG, "phyque %d no need to release backend do it", + hw->channel_context[lch].ph_chno); + hw->channel_context[lch].valid = 0; + hw->channel_context[lch].ph_chno = 0; + } + hw->que_set_flag = 0; + return 0; + } ret = zxdh_timedlock(hw, 1000); if (ret) { PMD_DRV_LOG(ERR, "Acquiring hw lock got failed, timeout"); return -1; } - for (lch = 0; lch < nr_vq; lch++) { - if (hw->channel_context[lch].valid == 0) { - PMD_DRV_LOG(DEBUG, "Logic channel %d does not need to release", lch); - continue; - } - - pch = hw->channel_context[lch].ph_chno; - widx = pch / 32; - bidx = pch % 32; - - addr = ZXDH_QUERES_SHARE_BASE + (widx * sizeof(uint32_t)); - var = zxdh_read_bar_reg(dev, ZXDH_BAR0_INDEX, addr); - var &= ~(1 << bidx); - zxdh_write_bar_reg(dev, ZXDH_BAR0_INDEX, addr, var); - - hw->channel_context[lch].valid = 0; - hw->channel_context[lch].ph_chno = 0; + for (i = 0 ; i < rxq_num ; i++) { + lch = i * 2; + zxdh_clear_channel(dev, lch); + } + for (i = 0; i < txq_num ; i++) { + lch = i * 2 + 1; + zxdh_clear_channel(dev, lch); } - zxdh_release_lock(hw); return 0; @@ -92,37 +123,41 @@ int32_t zxdh_free_queues(struct rte_eth_dev *dev) { struct zxdh_hw *hw = dev->data->dev_private; - uint16_t nr_vq = hw->queue_num; struct zxdh_virtqueue *vq = NULL; - int32_t queue_type = 0; + u_int16_t rxq_num = hw->rx_qnum; + u_int16_t txq_num = hw->tx_qnum; uint16_t i = 0; if (hw->vqs == NULL) return 0; - if (zxdh_release_channel(dev) < 0) { - PMD_DRV_LOG(ERR, "Failed to clear coi table"); - return -1; - } - - for (i = 0; i < nr_vq; i++) { - vq = hw->vqs[i]; + for (i = 0; i < rxq_num; i++) { + vq = hw->vqs[i * 2]; if (vq == NULL) continue; ZXDH_VTPCI_OPS(hw)->del_queue(hw, vq); - queue_type = zxdh_get_queue_type(i); - if (queue_type == ZXDH_VTNET_RQ) { - rte_free(vq->sw_ring); - rte_memzone_free(vq->rxq.mz); - } else if (queue_type == ZXDH_VTNET_TQ) { - rte_memzone_free(vq->txq.mz); - rte_memzone_free(vq->txq.zxdh_net_hdr_mz); - } + rte_memzone_free(vq->rxq.mz); + rte_free(vq); + hw->vqs[i * 2] = NULL; + PMD_MSG_LOG(DEBUG, "Release to queue %d success!", i * 2); + } + for (i = 0; i < txq_num; i++) { + vq = hw->vqs[i * 2 + 1]; + if (vq == NULL) + continue; + ZXDH_VTPCI_OPS(hw)->del_queue(hw, vq); + rte_memzone_free(vq->txq.mz); + rte_memzone_free(vq->txq.zxdh_net_hdr_mz); rte_free(vq); - hw->vqs[i] = NULL; - PMD_DRV_LOG(DEBUG, "Release to queue %d success!", i); + hw->vqs[i * 2 + 1] = NULL; + PMD_DRV_LOG(DEBUG, "Release to queue %d success!", i * 2 + 1); + } + + if (zxdh_release_channel(dev) < 0) { + PMD_DRV_LOG(ERR, "Failed to clear coi table"); + return -1; } rte_free(hw->vqs); -- 2.27.0