1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017 Huawei Technologies Co., Ltd
8 #include "base/hinic_compat.h"
9 #include "base/hinic_pmd_hwdev.h"
10 #include "base/hinic_pmd_wq.h"
11 #include "base/hinic_pmd_niccfg.h"
12 #include "base/hinic_pmd_nicio.h"
13 #include "hinic_pmd_ethdev.h"
14 #include "hinic_pmd_rx.h"
17 void hinic_destroy_rq(struct hinic_hwdev *hwdev, u16 q_id)
19 struct hinic_nic_io *nic_io = hwdev->nic_io;
20 struct hinic_qp *qp = &nic_io->qps[q_id];
21 struct hinic_rq *rq = &qp->rq;
23 if (qp->rq.wq == NULL)
26 dma_free_coherent_volatile(hwdev, HINIC_PAGE_SIZE,
27 (volatile void *)rq->pi_virt_addr,
29 hinic_wq_free(nic_io->hwdev, qp->rq.wq);
33 static void hinic_rx_free_cqe(struct hinic_rxq *rxq)
37 cqe_mem_size = sizeof(struct hinic_rq_cqe) * rxq->q_depth;
38 dma_free_coherent(rxq->nic_dev->hwdev, cqe_mem_size,
39 rxq->cqe_start_vaddr, rxq->cqe_start_paddr);
40 rxq->cqe_start_vaddr = NULL;
43 void hinic_free_rx_resources(struct hinic_rxq *rxq)
45 if (rxq->rx_info == NULL)
48 hinic_rx_free_cqe(rxq);
53 void hinic_free_all_rx_resources(struct rte_eth_dev *eth_dev)
56 struct hinic_nic_dev *nic_dev =
57 HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
59 for (q_id = 0; q_id < nic_dev->num_rq; q_id++) {
60 eth_dev->data->rx_queues[q_id] = NULL;
62 if (nic_dev->rxqs[q_id] == NULL)
65 hinic_free_all_rx_skbs(nic_dev->rxqs[q_id]);
66 hinic_free_rx_resources(nic_dev->rxqs[q_id]);
67 kfree(nic_dev->rxqs[q_id]);
68 nic_dev->rxqs[q_id] = NULL;
73 hinic_add_rq_to_rx_queue_list(struct hinic_nic_dev *nic_dev, u16 queue_id)
75 u8 rss_queue_count = nic_dev->num_rss;
77 RTE_ASSERT(rss_queue_count <= (RTE_DIM(nic_dev->rx_queue_list) - 1));
79 nic_dev->rx_queue_list[rss_queue_count] = queue_id;
84 * hinic_setup_num_qps - determine num_qps from rss_tmpl_id
85 * @nic_dev: pointer to the private ethernet device
86 * Return: 0 on Success, error code otherwise.
88 static int hinic_setup_num_qps(struct hinic_nic_dev *nic_dev)
92 if (!(nic_dev->flags & ETH_MQ_RX_RSS_FLAG)) {
93 nic_dev->flags &= ~ETH_MQ_RX_RSS_FLAG;
95 if (nic_dev->num_rq > 1) {
96 /* get rss template id */
97 err = hinic_rss_template_alloc(nic_dev->hwdev,
98 &nic_dev->rss_tmpl_idx);
100 PMD_DRV_LOG(WARNING, "Alloc rss template failed");
103 nic_dev->flags |= ETH_MQ_RX_RSS_FLAG;
104 for (i = 0; i < nic_dev->num_rq; i++)
105 hinic_add_rq_to_rx_queue_list(nic_dev, i);
112 static void hinic_destroy_num_qps(struct hinic_nic_dev *nic_dev)
114 if (nic_dev->flags & ETH_MQ_RX_RSS_FLAG) {
115 if (hinic_rss_template_free(nic_dev->hwdev,
116 nic_dev->rss_tmpl_idx))
117 PMD_DRV_LOG(WARNING, "Free rss template failed");
119 nic_dev->flags &= ~ETH_MQ_RX_RSS_FLAG;
123 static int hinic_config_mq_rx_rss(struct hinic_nic_dev *nic_dev, bool on)
128 ret = hinic_setup_num_qps(nic_dev);
130 PMD_DRV_LOG(ERR, "Setup num_qps failed");
132 hinic_destroy_num_qps(nic_dev);
138 int hinic_config_mq_mode(struct rte_eth_dev *dev, bool on)
140 struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
141 struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
144 switch (dev_conf->rxmode.mq_mode) {
146 ret = hinic_config_mq_rx_rss(nic_dev, on);
155 void hinic_free_all_rx_skbs(struct hinic_rxq *rxq)
157 struct hinic_nic_dev *nic_dev = rxq->nic_dev;
158 struct hinic_rx_info *rx_info;
160 hinic_get_rq_free_wqebbs(nic_dev->hwdev, rxq->q_id) + 1;
161 volatile struct hinic_rq_cqe *rx_cqe;
164 while (free_wqebbs++ < rxq->q_depth) {
165 ci = hinic_get_rq_local_ci(nic_dev->hwdev, rxq->q_id);
167 rx_cqe = &rxq->rx_cqe[ci];
172 rx_info = &rxq->rx_info[ci];
173 rte_pktmbuf_free(rx_info->mbuf);
174 rx_info->mbuf = NULL;
176 hinic_update_rq_local_ci(nic_dev->hwdev, rxq->q_id, 1);