xref: /dpdk/drivers/net/zxdh/zxdh_queue.c (revision 70d49e4b97702155b4b4f52623f7a154efddf2c8)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2024 ZTE Corporation
3  */
4 
5 #include <stdint.h>
6 #include <rte_malloc.h>
7 #include <rte_mbuf.h>
8 
9 #include "zxdh_queue.h"
10 #include "zxdh_logs.h"
11 #include "zxdh_pci.h"
12 #include "zxdh_common.h"
13 #include "zxdh_msg.h"
14 
15 struct rte_mbuf *
16 zxdh_virtqueue_detach_unused(struct zxdh_virtqueue *vq)
17 {
18 	struct rte_mbuf *cookie = NULL;
19 	int32_t          idx    = 0;
20 
21 	if (vq == NULL)
22 		return NULL;
23 
24 	for (idx = 0; idx < vq->vq_nentries; idx++) {
25 		cookie = vq->vq_descx[idx].cookie;
26 		if (cookie != NULL) {
27 			vq->vq_descx[idx].cookie = NULL;
28 			return cookie;
29 		}
30 	}
31 	return NULL;
32 }
33 
34 static int32_t
35 zxdh_release_channel(struct rte_eth_dev *dev)
36 {
37 	struct zxdh_hw *hw = dev->data->dev_private;
38 	uint16_t nr_vq = hw->queue_num;
39 	uint32_t var  = 0;
40 	uint32_t addr = 0;
41 	uint32_t widx = 0;
42 	uint32_t bidx = 0;
43 	uint16_t pch  = 0;
44 	uint16_t lch  = 0;
45 	int32_t ret = 0;
46 
47 	ret = zxdh_timedlock(hw, 1000);
48 	if (ret) {
49 		PMD_DRV_LOG(ERR, "Acquiring hw lock got failed, timeout");
50 		return -1;
51 	}
52 
53 	for (lch = 0; lch < nr_vq; lch++) {
54 		if (hw->channel_context[lch].valid == 0) {
55 			PMD_DRV_LOG(DEBUG, "Logic channel %d does not need to release", lch);
56 			continue;
57 		}
58 
59 		pch  = hw->channel_context[lch].ph_chno;
60 		widx = pch / 32;
61 		bidx = pch % 32;
62 
63 		addr = ZXDH_QUERES_SHARE_BASE + (widx * sizeof(uint32_t));
64 		var  = zxdh_read_bar_reg(dev, ZXDH_BAR0_INDEX, addr);
65 		var &= ~(1 << bidx);
66 		zxdh_write_bar_reg(dev, ZXDH_BAR0_INDEX, addr, var);
67 
68 		hw->channel_context[lch].valid = 0;
69 		hw->channel_context[lch].ph_chno = 0;
70 	}
71 
72 	zxdh_release_lock(hw);
73 
74 	return 0;
75 }
76 
77 int32_t
78 zxdh_get_queue_type(uint16_t vtpci_queue_idx)
79 {
80 	if (vtpci_queue_idx % 2 == 0)
81 		return ZXDH_VTNET_RQ;
82 	else
83 		return ZXDH_VTNET_TQ;
84 }
85 
86 int32_t
87 zxdh_free_queues(struct rte_eth_dev *dev)
88 {
89 	struct zxdh_hw *hw = dev->data->dev_private;
90 	uint16_t nr_vq = hw->queue_num;
91 	struct zxdh_virtqueue *vq = NULL;
92 	int32_t queue_type = 0;
93 	uint16_t i = 0;
94 
95 	if (hw->vqs == NULL)
96 		return 0;
97 
98 	if (zxdh_release_channel(dev) < 0) {
99 		PMD_DRV_LOG(ERR, "Failed to clear coi table");
100 		return -1;
101 	}
102 
103 	for (i = 0; i < nr_vq; i++) {
104 		vq = hw->vqs[i];
105 		if (vq == NULL)
106 			continue;
107 
108 		ZXDH_VTPCI_OPS(hw)->del_queue(hw, vq);
109 		queue_type = zxdh_get_queue_type(i);
110 		if (queue_type == ZXDH_VTNET_RQ) {
111 			rte_free(vq->sw_ring);
112 			rte_memzone_free(vq->rxq.mz);
113 		} else if (queue_type == ZXDH_VTNET_TQ) {
114 			rte_memzone_free(vq->txq.mz);
115 			rte_memzone_free(vq->txq.zxdh_net_hdr_mz);
116 		}
117 
118 		rte_free(vq);
119 		hw->vqs[i] = NULL;
120 		PMD_DRV_LOG(DEBUG, "Release to queue %d success!", i);
121 	}
122 
123 	rte_free(hw->vqs);
124 	hw->vqs = NULL;
125 
126 	return 0;
127 }
128