1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017 Huawei Technologies Co., Ltd
11 #include "base/hinic_compat.h"
12 #include "base/hinic_pmd_hwdev.h"
13 #include "base/hinic_pmd_hwif.h"
14 #include "base/hinic_pmd_wq.h"
15 #include "base/hinic_pmd_nicio.h"
16 #include "hinic_pmd_ethdev.h"
17 #include "hinic_pmd_tx.h"
20 void hinic_free_all_tx_skbs(struct hinic_txq *txq)
23 struct hinic_nic_dev *nic_dev = txq->nic_dev;
24 struct hinic_tx_info *tx_info;
25 int free_wqebbs = hinic_get_sq_free_wqebbs(nic_dev->hwdev,
28 while (free_wqebbs < txq->q_depth) {
29 ci = hinic_get_sq_local_ci(nic_dev->hwdev, txq->q_id);
31 tx_info = &txq->tx_info[ci];
33 if (unlikely(tx_info->cpy_mbuf != NULL)) {
34 rte_pktmbuf_free(tx_info->cpy_mbuf);
35 tx_info->cpy_mbuf = NULL;
38 rte_pktmbuf_free(tx_info->mbuf);
39 hinic_update_sq_local_ci(nic_dev->hwdev, txq->q_id,
42 free_wqebbs += tx_info->wqebb_cnt;
47 void hinic_free_all_tx_resources(struct rte_eth_dev *eth_dev)
50 struct hinic_nic_dev *nic_dev =
51 HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
53 for (q_id = 0; q_id < nic_dev->num_sq; q_id++) {
54 eth_dev->data->tx_queues[q_id] = NULL;
56 if (nic_dev->txqs[q_id] == NULL)
59 /* stop tx queue free tx mbuf */
60 hinic_free_all_tx_skbs(nic_dev->txqs[q_id]);
61 hinic_free_tx_resources(nic_dev->txqs[q_id]);
64 kfree(nic_dev->txqs[q_id]);
65 nic_dev->txqs[q_id] = NULL;
69 void hinic_free_all_tx_mbuf(struct rte_eth_dev *eth_dev)
72 struct hinic_nic_dev *nic_dev =
73 HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
75 for (q_id = 0; q_id < nic_dev->num_sq; q_id++)
76 /* stop tx queue free tx mbuf */
77 hinic_free_all_tx_skbs(nic_dev->txqs[q_id]);
80 int hinic_setup_tx_resources(struct hinic_txq *txq)
84 tx_info_sz = txq->q_depth * sizeof(*txq->tx_info);
85 txq->tx_info = kzalloc_aligned(tx_info_sz, GFP_KERNEL);
92 void hinic_free_tx_resources(struct hinic_txq *txq)
94 if (txq->tx_info == NULL)
101 int hinic_create_sq(struct hinic_hwdev *hwdev, u16 q_id, u16 sq_depth)
104 struct hinic_nic_io *nic_io = hwdev->nic_io;
105 struct hinic_qp *qp = &nic_io->qps[q_id];
106 struct hinic_sq *sq = &qp->sq;
107 void __iomem *db_addr;
108 volatile u32 *ci_addr;
110 sq->sq_depth = sq_depth;
111 nic_io->sq_depth = sq_depth;
114 err = hinic_wq_allocate(nic_io->hwdev, &nic_io->sq_wq[q_id],
115 HINIC_SQ_WQEBB_SHIFT, nic_io->sq_depth);
117 PMD_DRV_LOG(ERR, "Failed to allocate WQ for SQ");
121 /* alloc sq doorbell space */
122 err = hinic_alloc_db_addr(nic_io->hwdev, &db_addr);
124 PMD_DRV_LOG(ERR, "Failed to init db addr");
128 /* clear hardware ci */
129 ci_addr = (volatile u32 *)HINIC_CI_VADDR(nic_io->ci_vaddr_base, q_id);
133 sq->wq = &nic_io->sq_wq[q_id];
135 sq->cons_idx_addr = (volatile u16 *)ci_addr;
136 sq->db_addr = db_addr;
141 hinic_wq_free(nic_io->hwdev, &nic_io->sq_wq[q_id]);
146 void hinic_destroy_sq(struct hinic_hwdev *hwdev, u16 q_id)
148 struct hinic_nic_io *nic_io;
151 nic_io = hwdev->nic_io;
152 qp = &nic_io->qps[q_id];
154 if (qp->sq.wq == NULL)
157 hinic_free_db_addr(nic_io->hwdev, qp->sq.db_addr);
158 hinic_wq_free(nic_io->hwdev, qp->sq.wq);