Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2024 ZTE Corporation
3 : : */
4 : :
5 : : #include <stdbool.h>
6 : :
7 : : #include <rte_common.h>
8 : : #include <rte_memcpy.h>
9 : : #include <rte_spinlock.h>
10 : : #include <rte_cycles.h>
11 : : #include <inttypes.h>
12 : : #include <rte_malloc.h>
13 : :
14 : : #include "zxdh_ethdev.h"
15 : : #include "zxdh_logs.h"
16 : : #include "zxdh_msg.h"
17 : :
18 : : #define ZXDH_REPS_INFO_FLAG_USABLE 0x00
19 : : #define ZXDH_BAR_SEQID_NUM_MAX 256
20 : : #define ZXDH_REPS_INFO_FLAG_USED 0xa0
21 : :
22 : : #define ZXDH_PCIEID_IS_PF_MASK (0x0800)
23 : : #define ZXDH_PCIEID_PF_IDX_MASK (0x0700)
24 : : #define ZXDH_PCIEID_VF_IDX_MASK (0x00ff)
25 : : #define ZXDH_PCIEID_EP_IDX_MASK (0x7000)
26 : : /* PCIEID bit field offset */
27 : : #define ZXDH_PCIEID_PF_IDX_OFFSET (8)
28 : : #define ZXDH_PCIEID_EP_IDX_OFFSET (12)
29 : :
30 : : #define ZXDH_MULTIPLY_BY_8(x) ((x) << 3)
31 : : #define ZXDH_MULTIPLY_BY_32(x) ((x) << 5)
32 : : #define ZXDH_MULTIPLY_BY_256(x) ((x) << 8)
33 : :
34 : : #define ZXDH_MAX_EP_NUM (4)
35 : : #define ZXDH_MAX_HARD_SPINLOCK_NUM (511)
36 : :
37 : : #define ZXDH_LOCK_PRIMARY_ID_MASK (0x8000)
38 : : /* bar offset */
39 : : #define ZXDH_BAR0_CHAN_RISC_OFFSET (0x2000)
40 : : #define ZXDH_BAR0_CHAN_PFVF_OFFSET (0x3000)
41 : : #define ZXDH_BAR0_SPINLOCK_OFFSET (0x4000)
42 : : #define ZXDH_FW_SHRD_OFFSET (0x5000)
43 : : #define ZXDH_FW_SHRD_INNER_HW_LABEL_PAT (0x800)
44 : : #define ZXDH_HW_LABEL_OFFSET \
45 : : (ZXDH_FW_SHRD_OFFSET + ZXDH_FW_SHRD_INNER_HW_LABEL_PAT)
46 : :
47 : : #define ZXDH_CHAN_RISC_SPINLOCK_OFFSET \
48 : : (ZXDH_BAR0_SPINLOCK_OFFSET - ZXDH_BAR0_CHAN_RISC_OFFSET)
49 : : #define ZXDH_CHAN_PFVF_SPINLOCK_OFFSET \
50 : : (ZXDH_BAR0_SPINLOCK_OFFSET - ZXDH_BAR0_CHAN_PFVF_OFFSET)
51 : : #define ZXDH_CHAN_RISC_LABEL_OFFSET \
52 : : (ZXDH_HW_LABEL_OFFSET - ZXDH_BAR0_CHAN_RISC_OFFSET)
53 : : #define ZXDH_CHAN_PFVF_LABEL_OFFSET \
54 : : (ZXDH_HW_LABEL_OFFSET - ZXDH_BAR0_CHAN_PFVF_OFFSET)
55 : :
56 : : #define ZXDH_REPS_HEADER_LEN_OFFSET 1
57 : : #define ZXDH_REPS_HEADER_PAYLOAD_OFFSET 4
58 : : #define ZXDH_REPS_HEADER_REPLYED 0xff
59 : :
60 : : #define ZXDH_BAR_MSG_CHAN_USABLE 0
61 : : #define ZXDH_BAR_MSG_CHAN_USED 1
62 : :
63 : : #define ZXDH_BAR_MSG_POL_MASK (0x10)
64 : : #define ZXDH_BAR_MSG_POL_OFFSET (4)
65 : :
66 : : #define ZXDH_BAR_ALIGN_WORD_MASK 0xfffffffc
67 : : #define ZXDH_BAR_MSG_VALID_MASK 1
68 : : #define ZXDH_BAR_MSG_VALID_OFFSET 0
69 : :
70 : : #define ZXDH_BAR_PF_NUM 7
71 : : #define ZXDH_BAR_VF_NUM 256
72 : : #define ZXDH_BAR_INDEX_PF_TO_VF 0
73 : : #define ZXDH_BAR_INDEX_MPF_TO_MPF 0xff
74 : : #define ZXDH_BAR_INDEX_MPF_TO_PFVF 0
75 : : #define ZXDH_BAR_INDEX_PFVF_TO_MPF 0
76 : :
77 : : #define ZXDH_MAX_HARD_SPINLOCK_ASK_TIMES (1000)
78 : : #define ZXDH_SPINLOCK_POLLING_SPAN_US (100)
79 : :
80 : : #define ZXDH_BAR_MSG_SRC_NUM 3
81 : : #define ZXDH_BAR_MSG_SRC_MPF 0
82 : : #define ZXDH_BAR_MSG_SRC_PF 1
83 : : #define ZXDH_BAR_MSG_SRC_VF 2
84 : : #define ZXDH_BAR_MSG_SRC_ERR 0xff
85 : : #define ZXDH_BAR_MSG_DST_NUM 3
86 : : #define ZXDH_BAR_MSG_DST_RISC 0
87 : : #define ZXDH_BAR_MSG_DST_MPF 2
88 : : #define ZXDH_BAR_MSG_DST_PFVF 1
89 : : #define ZXDH_BAR_MSG_DST_ERR 0xff
90 : :
91 : : #define ZXDH_LOCK_TYPE_HARD (1)
92 : : #define ZXDH_LOCK_TYPE_SOFT (0)
93 : : #define ZXDH_BAR_INDEX_TO_RISC 0
94 : :
95 : : #define ZXDH_BAR_CHAN_INDEX_SEND 0
96 : : #define ZXDH_BAR_CHAN_INDEX_RECV 1
97 : :
98 : : #define ZXDH_BAR_CHAN_MSG_SYNC 0
99 : : #define ZXDH_BAR_CHAN_MSG_NO_EMEC 0
100 : : #define ZXDH_BAR_CHAN_MSG_EMEC 1
101 : : #define ZXDH_BAR_CHAN_MSG_NO_ACK 0
102 : : #define ZXDH_BAR_CHAN_MSG_ACK 1
103 : :
104 : : uint8_t subchan_id_tbl[ZXDH_BAR_MSG_SRC_NUM][ZXDH_BAR_MSG_DST_NUM] = {
105 : : {ZXDH_BAR_CHAN_INDEX_SEND, ZXDH_BAR_CHAN_INDEX_SEND, ZXDH_BAR_CHAN_INDEX_SEND},
106 : : {ZXDH_BAR_CHAN_INDEX_SEND, ZXDH_BAR_CHAN_INDEX_SEND, ZXDH_BAR_CHAN_INDEX_RECV},
107 : : {ZXDH_BAR_CHAN_INDEX_SEND, ZXDH_BAR_CHAN_INDEX_RECV, ZXDH_BAR_CHAN_INDEX_RECV}
108 : : };
109 : :
110 : : uint8_t chan_id_tbl[ZXDH_BAR_MSG_SRC_NUM][ZXDH_BAR_MSG_DST_NUM] = {
111 : : {ZXDH_BAR_INDEX_TO_RISC, ZXDH_BAR_INDEX_MPF_TO_PFVF, ZXDH_BAR_INDEX_MPF_TO_MPF},
112 : : {ZXDH_BAR_INDEX_TO_RISC, ZXDH_BAR_INDEX_PF_TO_VF, ZXDH_BAR_INDEX_PFVF_TO_MPF},
113 : : {ZXDH_BAR_INDEX_TO_RISC, ZXDH_BAR_INDEX_PF_TO_VF, ZXDH_BAR_INDEX_PFVF_TO_MPF}
114 : : };
115 : :
116 : : uint8_t lock_type_tbl[ZXDH_BAR_MSG_SRC_NUM][ZXDH_BAR_MSG_DST_NUM] = {
117 : : {ZXDH_LOCK_TYPE_HARD, ZXDH_LOCK_TYPE_HARD, ZXDH_LOCK_TYPE_HARD},
118 : : {ZXDH_LOCK_TYPE_SOFT, ZXDH_LOCK_TYPE_SOFT, ZXDH_LOCK_TYPE_HARD},
119 : : {ZXDH_LOCK_TYPE_HARD, ZXDH_LOCK_TYPE_HARD, ZXDH_LOCK_TYPE_HARD}
120 : : };
121 : :
122 : : struct zxdh_dev_stat {
123 : : bool is_mpf_scanned;
124 : : bool is_res_init;
125 : : int16_t dev_cnt; /* probe cnt */
126 : : };
127 : :
128 : : struct zxdh_seqid_item {
129 : : void *reps_addr;
130 : : uint16_t id;
131 : : uint16_t buffer_len;
132 : : uint16_t flag;
133 : : };
134 : :
135 : : struct zxdh_seqid_ring {
136 : : uint16_t cur_id;
137 : : rte_spinlock_t lock;
138 : : struct zxdh_seqid_item reps_info_tbl[ZXDH_BAR_SEQID_NUM_MAX];
139 : : };
140 : :
141 : : static struct zxdh_dev_stat g_dev_stat;
142 : : static struct zxdh_seqid_ring g_seqid_ring;
143 : : static uint8_t tmp_msg_header[ZXDH_BAR_MSG_ADDR_CHAN_INTERVAL];
144 : : static rte_spinlock_t chan_lock;
145 : :
146 : : zxdh_bar_chan_msg_recv_callback msg_recv_func_tbl[ZXDH_BAR_MSG_MODULE_NUM];
147 : :
148 : : static inline const char
149 : 0 : *zxdh_module_id_name(int val)
150 : : {
151 [ # # # # : 0 : switch (val) {
# # # # #
# # # # #
# # # # #
# # # #
# ]
152 : : case ZXDH_BAR_MODULE_DBG: return "ZXDH_BAR_MODULE_DBG";
153 : 0 : case ZXDH_BAR_MODULE_TBL: return "ZXDH_BAR_MODULE_TBL";
154 : 0 : case ZXDH_BAR_MODULE_MISX: return "ZXDH_BAR_MODULE_MISX";
155 : 0 : case ZXDH_BAR_MODULE_SDA: return "ZXDH_BAR_MODULE_SDA";
156 : 0 : case ZXDH_BAR_MODULE_RDMA: return "ZXDH_BAR_MODULE_RDMA";
157 : 0 : case ZXDH_BAR_MODULE_DEMO: return "ZXDH_BAR_MODULE_DEMO";
158 : 0 : case ZXDH_BAR_MODULE_SMMU: return "ZXDH_BAR_MODULE_SMMU";
159 : 0 : case ZXDH_BAR_MODULE_MAC: return "ZXDH_BAR_MODULE_MAC";
160 : 0 : case ZXDH_BAR_MODULE_VDPA: return "ZXDH_BAR_MODULE_VDPA";
161 : 0 : case ZXDH_BAR_MODULE_VQM: return "ZXDH_BAR_MODULE_VQM";
162 : 0 : case ZXDH_BAR_MODULE_NP: return "ZXDH_BAR_MODULE_NP";
163 : 0 : case ZXDH_BAR_MODULE_VPORT: return "ZXDH_BAR_MODULE_VPORT";
164 : 0 : case ZXDH_BAR_MODULE_BDF: return "ZXDH_BAR_MODULE_BDF";
165 : 0 : case ZXDH_BAR_MODULE_RISC_READY: return "ZXDH_BAR_MODULE_RISC_READY";
166 : 0 : case ZXDH_BAR_MODULE_REVERSE: return "ZXDH_BAR_MODULE_REVERSE";
167 : 0 : case ZXDH_BAR_MDOULE_NVME: return "ZXDH_BAR_MDOULE_NVME";
168 : 0 : case ZXDH_BAR_MDOULE_NPSDK: return "ZXDH_BAR_MDOULE_NPSDK";
169 : 0 : case ZXDH_BAR_MODULE_NP_TODO: return "ZXDH_BAR_MODULE_NP_TODO";
170 : 0 : case ZXDH_MODULE_BAR_MSG_TO_PF: return "ZXDH_MODULE_BAR_MSG_TO_PF";
171 : 0 : case ZXDH_MODULE_BAR_MSG_TO_VF: return "ZXDH_MODULE_BAR_MSG_TO_VF";
172 : 0 : case ZXDH_MODULE_FLASH: return "ZXDH_MODULE_FLASH";
173 : 0 : case ZXDH_BAR_MODULE_OFFSET_GET: return "ZXDH_BAR_MODULE_OFFSET_GET";
174 : 0 : case ZXDH_BAR_EVENT_OVS_WITH_VCB: return "ZXDH_BAR_EVENT_OVS_WITH_VCB";
175 : 0 : default: return "NA";
176 : : }
177 : : }
178 : :
179 : : static uint16_t
180 : : zxdh_pcie_id_to_hard_lock(uint16_t src_pcieid, uint8_t dst)
181 : : {
182 : : uint16_t lock_id = 0;
183 : 0 : uint16_t pf_idx = (src_pcieid & ZXDH_PCIEID_PF_IDX_MASK) >> ZXDH_PCIEID_PF_IDX_OFFSET;
184 : 0 : uint16_t ep_idx = (src_pcieid & ZXDH_PCIEID_EP_IDX_MASK) >> ZXDH_PCIEID_EP_IDX_OFFSET;
185 : :
186 : 0 : switch (dst) {
187 : : /* msg to risc */
188 : 0 : case ZXDH_MSG_CHAN_END_RISC:
189 : 0 : lock_id = ZXDH_MULTIPLY_BY_8(ep_idx) + pf_idx;
190 : 0 : break;
191 : : /* msg to pf/vf */
192 : 0 : case ZXDH_MSG_CHAN_END_VF:
193 : : case ZXDH_MSG_CHAN_END_PF:
194 : 0 : lock_id = ZXDH_MULTIPLY_BY_8(ep_idx) + pf_idx +
195 : : ZXDH_MULTIPLY_BY_8(1 + ZXDH_MAX_EP_NUM);
196 : 0 : break;
197 : : default:
198 : : lock_id = 0;
199 : : break;
200 : : }
201 : : if (lock_id >= ZXDH_MAX_HARD_SPINLOCK_NUM)
202 : : lock_id = 0;
203 : :
204 : : return lock_id;
205 : : }
206 : :
207 : : static void
208 : : label_write(uint64_t label_lock_addr, uint32_t lock_id, uint16_t value)
209 : : {
210 : 0 : *(volatile uint16_t *)(label_lock_addr + lock_id * 2) = value;
211 : 0 : }
212 : :
213 : : static void
214 : : spinlock_write(uint64_t virt_lock_addr, uint32_t lock_id, uint8_t data)
215 : : {
216 : 0 : *(volatile uint8_t *)((uint64_t)virt_lock_addr + (uint64_t)lock_id) = data;
217 : : }
218 : :
219 : : static uint8_t
220 : : spinlock_read(uint64_t virt_lock_addr, uint32_t lock_id)
221 : : {
222 : 0 : return *(volatile uint8_t *)((uint64_t)virt_lock_addr + (uint64_t)lock_id);
223 : : }
224 : :
225 : : static int32_t
226 : 0 : zxdh_spinlock_lock(uint32_t virt_lock_id, uint64_t virt_addr,
227 : : uint64_t label_addr, uint16_t primary_id)
228 : : {
229 : : uint32_t lock_rd_cnt = 0;
230 : :
231 : : do {
232 : : /* read to lock */
233 : : uint8_t spl_val = spinlock_read(virt_addr, virt_lock_id);
234 : :
235 [ # # ]: 0 : if (spl_val == 0) {
236 : : label_write((uint64_t)label_addr, virt_lock_id, primary_id);
237 : : break;
238 : : }
239 : 0 : rte_delay_us_block(ZXDH_SPINLOCK_POLLING_SPAN_US);
240 : 0 : lock_rd_cnt++;
241 [ # # ]: 0 : } while (lock_rd_cnt < ZXDH_MAX_HARD_SPINLOCK_ASK_TIMES);
242 [ # # ]: 0 : if (lock_rd_cnt >= ZXDH_MAX_HARD_SPINLOCK_ASK_TIMES)
243 : 0 : return -1;
244 : :
245 : : return 0;
246 : : }
247 : :
248 : : static int32_t
249 : : zxdh_spinlock_unlock(uint32_t virt_lock_id, uint64_t virt_addr, uint64_t label_addr)
250 : : {
251 : : label_write((uint64_t)label_addr, virt_lock_id, 0);
252 : : spinlock_write(virt_addr, virt_lock_id, 0);
253 : 0 : return 0;
254 : : }
255 : :
256 : : /**
257 : : * Fun: PF init hard_spinlock addr
258 : : */
259 : : static int
260 : 0 : bar_chan_pf_init_spinlock(uint16_t pcie_id, uint64_t bar_base_addr)
261 : : {
262 : 0 : int lock_id = zxdh_pcie_id_to_hard_lock(pcie_id, ZXDH_MSG_CHAN_END_RISC);
263 : :
264 : 0 : zxdh_spinlock_unlock(lock_id, bar_base_addr + ZXDH_BAR0_SPINLOCK_OFFSET,
265 : : bar_base_addr + ZXDH_HW_LABEL_OFFSET);
266 : : lock_id = zxdh_pcie_id_to_hard_lock(pcie_id, ZXDH_MSG_CHAN_END_VF);
267 : 0 : zxdh_spinlock_unlock(lock_id, bar_base_addr + ZXDH_BAR0_SPINLOCK_OFFSET,
268 : : bar_base_addr + ZXDH_HW_LABEL_OFFSET);
269 : 0 : return 0;
270 : : }
271 : :
272 : : int
273 : 0 : zxdh_msg_chan_hwlock_init(struct rte_eth_dev *dev)
274 : : {
275 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
276 : :
277 [ # # ]: 0 : if (!hw->is_pf)
278 : : return 0;
279 : 0 : return bar_chan_pf_init_spinlock(hw->pcie_id, (uint64_t)(hw->bar_addr[ZXDH_BAR0_INDEX]));
280 : : }
281 : :
282 : : int
283 : 0 : zxdh_msg_chan_init(void)
284 : : {
285 : : uint16_t seq_id = 0;
286 : :
287 : 0 : g_dev_stat.dev_cnt++;
288 [ # # ]: 0 : if (g_dev_stat.is_res_init)
289 : : return ZXDH_BAR_MSG_OK;
290 : :
291 : : rte_spinlock_init(&chan_lock);
292 : 0 : g_seqid_ring.cur_id = 0;
293 : : rte_spinlock_init(&g_seqid_ring.lock);
294 : :
295 [ # # ]: 0 : for (seq_id = 0; seq_id < ZXDH_BAR_SEQID_NUM_MAX; seq_id++) {
296 : 0 : struct zxdh_seqid_item *reps_info = &g_seqid_ring.reps_info_tbl[seq_id];
297 : :
298 : 0 : reps_info->id = seq_id;
299 : 0 : reps_info->flag = ZXDH_REPS_INFO_FLAG_USABLE;
300 : : }
301 : 0 : g_dev_stat.is_res_init = true;
302 : 0 : return ZXDH_BAR_MSG_OK;
303 : : }
304 : :
305 : : int
306 : 0 : zxdh_bar_msg_chan_exit(void)
307 : : {
308 [ # # # # ]: 0 : if (!g_dev_stat.is_res_init || (--g_dev_stat.dev_cnt > 0))
309 : 0 : return ZXDH_BAR_MSG_OK;
310 : :
311 : 0 : g_dev_stat.is_res_init = false;
312 : 0 : return ZXDH_BAR_MSG_OK;
313 : : }
314 : :
315 : : static int
316 : 0 : zxdh_bar_chan_msgid_allocate(uint16_t *msgid)
317 : : {
318 : : struct zxdh_seqid_item *seqid_reps_info = NULL;
319 : :
320 : : rte_spinlock_lock(&g_seqid_ring.lock);
321 : 0 : uint16_t g_id = g_seqid_ring.cur_id;
322 : : uint16_t count = 0;
323 : : int rc = 0;
324 : :
325 : : do {
326 : 0 : count++;
327 : 0 : ++g_id;
328 : 0 : g_id %= ZXDH_BAR_SEQID_NUM_MAX;
329 : 0 : seqid_reps_info = &g_seqid_ring.reps_info_tbl[g_id];
330 [ # # # # ]: 0 : } while ((seqid_reps_info->flag != ZXDH_REPS_INFO_FLAG_USABLE) &&
331 : : (count < ZXDH_BAR_SEQID_NUM_MAX));
332 : :
333 [ # # ]: 0 : if (count >= ZXDH_BAR_SEQID_NUM_MAX) {
334 : : rc = -1;
335 : 0 : goto out;
336 : : }
337 : 0 : seqid_reps_info->flag = ZXDH_REPS_INFO_FLAG_USED;
338 : 0 : g_seqid_ring.cur_id = g_id;
339 : 0 : *msgid = g_id;
340 : : rc = ZXDH_BAR_MSG_OK;
341 : :
342 : 0 : out:
343 : : rte_spinlock_unlock(&g_seqid_ring.lock);
344 : 0 : return rc;
345 : : }
346 : :
347 : : static uint16_t
348 : 0 : zxdh_bar_chan_save_recv_info(struct zxdh_msg_recviver_mem *result, uint16_t *msg_id)
349 : : {
350 : 0 : int ret = zxdh_bar_chan_msgid_allocate(msg_id);
351 : :
352 [ # # ]: 0 : if (ret != ZXDH_BAR_MSG_OK)
353 : : return ZXDH_BAR_MSG_ERR_MSGID;
354 : :
355 : 0 : PMD_MSG_LOG(DEBUG, "allocate msg_id: %u", *msg_id);
356 : 0 : struct zxdh_seqid_item *reps_info = &g_seqid_ring.reps_info_tbl[*msg_id];
357 : :
358 : 0 : reps_info->reps_addr = result->recv_buffer;
359 : 0 : reps_info->buffer_len = result->buffer_len;
360 : 0 : return ZXDH_BAR_MSG_OK;
361 : : }
362 : :
363 : : static uint8_t
364 : : zxdh_bar_msg_src_index_trans(uint8_t src)
365 : : {
366 : : uint8_t src_index = 0;
367 : :
368 : : switch (src) {
369 : : case ZXDH_MSG_CHAN_END_MPF:
370 : : src_index = ZXDH_BAR_MSG_SRC_MPF;
371 : : break;
372 : : case ZXDH_MSG_CHAN_END_PF:
373 : : src_index = ZXDH_BAR_MSG_SRC_PF;
374 : : break;
375 : : case ZXDH_MSG_CHAN_END_VF:
376 : : src_index = ZXDH_BAR_MSG_SRC_VF;
377 : : break;
378 : : default:
379 : : src_index = ZXDH_BAR_MSG_SRC_ERR;
380 : : break;
381 : : }
382 : : return src_index;
383 : : }
384 : :
385 : : static uint8_t
386 : : zxdh_bar_msg_dst_index_trans(uint8_t dst)
387 : : {
388 : : uint8_t dst_index = 0;
389 : :
390 : : switch (dst) {
391 : : case ZXDH_MSG_CHAN_END_MPF:
392 : : dst_index = ZXDH_BAR_MSG_DST_MPF;
393 : : break;
394 : : case ZXDH_MSG_CHAN_END_PF:
395 : : dst_index = ZXDH_BAR_MSG_DST_PFVF;
396 : : break;
397 : : case ZXDH_MSG_CHAN_END_VF:
398 : : dst_index = ZXDH_BAR_MSG_DST_PFVF;
399 : : break;
400 : : case ZXDH_MSG_CHAN_END_RISC:
401 : : dst_index = ZXDH_BAR_MSG_DST_RISC;
402 : : break;
403 : : default:
404 : : dst_index = ZXDH_BAR_MSG_SRC_ERR;
405 : : break;
406 : : }
407 : : return dst_index;
408 : : }
409 : :
410 : : static int
411 : 0 : zxdh_bar_chan_send_para_check(struct zxdh_pci_bar_msg *in,
412 : : struct zxdh_msg_recviver_mem *result)
413 : : {
414 : : uint8_t src_index = 0;
415 : : uint8_t dst_index = 0;
416 : :
417 [ # # ]: 0 : if (in == NULL || result == NULL) {
418 : 0 : PMD_MSG_LOG(ERR, "send para ERR: null para.");
419 : 0 : return ZXDH_BAR_MSG_ERR_NULL_PARA;
420 : : }
421 [ # # ]: 0 : src_index = zxdh_bar_msg_src_index_trans(in->src);
422 [ # # ]: 0 : dst_index = zxdh_bar_msg_dst_index_trans(in->dst);
423 : :
424 [ # # ]: 0 : if (src_index == ZXDH_BAR_MSG_SRC_ERR || dst_index == ZXDH_BAR_MSG_DST_ERR) {
425 : 0 : PMD_MSG_LOG(ERR, "send para ERR: chan doesn't exist.");
426 : 0 : return ZXDH_BAR_MSG_ERR_TYPE;
427 : : }
428 [ # # ]: 0 : if (in->module_id >= ZXDH_BAR_MSG_MODULE_NUM) {
429 : 0 : PMD_MSG_LOG(ERR, "send para ERR: invalid module_id: %d.", in->module_id);
430 : 0 : return ZXDH_BAR_MSG_ERR_MODULE;
431 : : }
432 [ # # ]: 0 : if (in->payload_addr == NULL) {
433 : 0 : PMD_MSG_LOG(ERR, "send para ERR: null message.");
434 : 0 : return ZXDH_BAR_MSG_ERR_BODY_NULL;
435 : : }
436 [ # # ]: 0 : if (in->payload_len > ZXDH_BAR_MSG_PAYLOAD_MAX_LEN) {
437 : 0 : PMD_MSG_LOG(ERR, "send para ERR: len %d is too long.", in->payload_len);
438 : 0 : return ZXDH_BAR_MSG_ERR_LEN;
439 : : }
440 [ # # # # ]: 0 : if (in->virt_addr == 0 || result->recv_buffer == NULL) {
441 : 0 : PMD_MSG_LOG(ERR, "send para ERR: virt_addr or recv_buffer is NULL.");
442 : 0 : return ZXDH_BAR_MSG_ERR_VIRTADDR_NULL;
443 : : }
444 [ # # ]: 0 : if (result->buffer_len < ZXDH_REPS_HEADER_PAYLOAD_OFFSET)
445 : 0 : PMD_MSG_LOG(ERR, "recv buffer len is short than minimal 4 bytes");
446 : :
447 : : return ZXDH_BAR_MSG_OK;
448 : : }
449 : :
450 : : static uint64_t
451 : : zxdh_subchan_addr_cal(uint64_t virt_addr, uint8_t chan_id, uint8_t subchan_id)
452 : : {
453 : 0 : return virt_addr + (2 * chan_id + subchan_id) * ZXDH_BAR_MSG_ADDR_CHAN_INTERVAL;
454 : : }
455 : :
456 : : static uint16_t
457 : 0 : zxdh_bar_chan_subchan_addr_get(struct zxdh_pci_bar_msg *in, uint64_t *subchan_addr)
458 : : {
459 [ # # ]: 0 : uint8_t src_index = zxdh_bar_msg_src_index_trans(in->src);
460 [ # # ]: 0 : uint8_t dst_index = zxdh_bar_msg_dst_index_trans(in->dst);
461 : 0 : uint16_t chan_id = chan_id_tbl[src_index][dst_index];
462 : 0 : uint16_t subchan_id = subchan_id_tbl[src_index][dst_index];
463 : :
464 : 0 : *subchan_addr = zxdh_subchan_addr_cal(in->virt_addr, chan_id, subchan_id);
465 : 0 : return ZXDH_BAR_MSG_OK;
466 : : }
467 : :
468 : : static int
469 : 0 : zxdh_bar_hard_lock(uint16_t src_pcieid, uint8_t dst, uint64_t virt_addr)
470 : : {
471 : : int ret = 0;
472 [ # # # ]: 0 : uint16_t lockid = zxdh_pcie_id_to_hard_lock(src_pcieid, dst);
473 : :
474 : 0 : PMD_MSG_LOG(DEBUG, "dev pcieid: 0x%x lock, get hardlockid: %u", src_pcieid, lockid);
475 [ # # ]: 0 : if (dst == ZXDH_MSG_CHAN_END_RISC)
476 : 0 : ret = zxdh_spinlock_lock(lockid, virt_addr + ZXDH_CHAN_RISC_SPINLOCK_OFFSET,
477 : : virt_addr + ZXDH_CHAN_RISC_LABEL_OFFSET,
478 : : src_pcieid | ZXDH_LOCK_PRIMARY_ID_MASK);
479 : : else
480 : 0 : ret = zxdh_spinlock_lock(lockid, virt_addr + ZXDH_CHAN_PFVF_SPINLOCK_OFFSET,
481 : : virt_addr + ZXDH_CHAN_PFVF_LABEL_OFFSET,
482 : : src_pcieid | ZXDH_LOCK_PRIMARY_ID_MASK);
483 : :
484 : 0 : return ret;
485 : : }
486 : :
487 : : static void
488 : 0 : zxdh_bar_hard_unlock(uint16_t src_pcieid, uint8_t dst, uint64_t virt_addr)
489 : : {
490 [ # # # ]: 0 : uint16_t lockid = zxdh_pcie_id_to_hard_lock(src_pcieid, dst);
491 : :
492 : 0 : PMD_MSG_LOG(DEBUG, "dev pcieid: 0x%x unlock, get hardlockid: %u", src_pcieid, lockid);
493 [ # # ]: 0 : if (dst == ZXDH_MSG_CHAN_END_RISC)
494 : 0 : zxdh_spinlock_unlock(lockid, virt_addr + ZXDH_CHAN_RISC_SPINLOCK_OFFSET,
495 : : virt_addr + ZXDH_CHAN_RISC_LABEL_OFFSET);
496 : : else
497 : 0 : zxdh_spinlock_unlock(lockid, virt_addr + ZXDH_CHAN_PFVF_SPINLOCK_OFFSET,
498 : : virt_addr + ZXDH_CHAN_PFVF_LABEL_OFFSET);
499 : 0 : }
500 : :
501 : : static int
502 [ # # ]: 0 : zxdh_bar_chan_lock(uint8_t src, uint8_t dst, uint16_t src_pcieid, uint64_t virt_addr)
503 : : {
504 : : int ret = 0;
505 : : uint8_t src_index = zxdh_bar_msg_src_index_trans(src);
506 [ # # ]: 0 : uint8_t dst_index = zxdh_bar_msg_dst_index_trans(dst);
507 : :
508 [ # # ]: 0 : if (src_index == ZXDH_BAR_MSG_SRC_ERR || dst_index == ZXDH_BAR_MSG_DST_ERR) {
509 : 0 : PMD_MSG_LOG(ERR, "lock ERR: chan doesn't exist.");
510 : 0 : return ZXDH_BAR_MSG_ERR_TYPE;
511 : : }
512 : :
513 : 0 : ret = zxdh_bar_hard_lock(src_pcieid, dst, virt_addr);
514 [ # # ]: 0 : if (ret != 0)
515 : 0 : PMD_MSG_LOG(ERR, "dev: 0x%x failed to lock.", src_pcieid);
516 : :
517 : : return ret;
518 : : }
519 : :
520 : : static int
521 [ # # ]: 0 : zxdh_bar_chan_unlock(uint8_t src, uint8_t dst, uint16_t src_pcieid, uint64_t virt_addr)
522 : : {
523 : : uint8_t src_index = zxdh_bar_msg_src_index_trans(src);
524 [ # # ]: 0 : uint8_t dst_index = zxdh_bar_msg_dst_index_trans(dst);
525 : :
526 [ # # ]: 0 : if (src_index == ZXDH_BAR_MSG_SRC_ERR || dst_index == ZXDH_BAR_MSG_DST_ERR) {
527 : 0 : PMD_MSG_LOG(ERR, "unlock ERR: chan doesn't exist.");
528 : 0 : return ZXDH_BAR_MSG_ERR_TYPE;
529 : : }
530 : :
531 : 0 : zxdh_bar_hard_unlock(src_pcieid, dst, virt_addr);
532 : :
533 : 0 : return ZXDH_BAR_MSG_OK;
534 : : }
535 : :
536 : : static void
537 : 0 : zxdh_bar_chan_msgid_free(uint16_t msg_id)
538 : : {
539 : 0 : struct zxdh_seqid_item *seqid_reps_info = &g_seqid_ring.reps_info_tbl[msg_id];
540 : :
541 : : rte_spinlock_lock(&g_seqid_ring.lock);
542 : 0 : seqid_reps_info->flag = ZXDH_REPS_INFO_FLAG_USABLE;
543 : 0 : PMD_MSG_LOG(DEBUG, "free msg_id: %u", msg_id);
544 : : rte_spinlock_unlock(&g_seqid_ring.lock);
545 : 0 : }
546 : :
547 : : static int
548 : 0 : zxdh_bar_chan_reg_write(uint64_t subchan_addr, uint32_t offset, uint32_t data)
549 : : {
550 : 0 : uint32_t algin_offset = (offset & ZXDH_BAR_ALIGN_WORD_MASK);
551 : :
552 [ # # ]: 0 : if (unlikely(algin_offset >= ZXDH_BAR_MSG_ADDR_CHAN_INTERVAL)) {
553 : 0 : PMD_MSG_LOG(ERR, "algin_offset exceeds channel size!");
554 : 0 : return -1;
555 : : }
556 : 0 : *(uint32_t *)(subchan_addr + algin_offset) = data;
557 : 0 : return 0;
558 : : }
559 : :
560 : : static int
561 : 0 : zxdh_bar_chan_reg_read(uint64_t subchan_addr, uint32_t offset, uint32_t *pdata)
562 : : {
563 : 0 : uint32_t algin_offset = (offset & ZXDH_BAR_ALIGN_WORD_MASK);
564 : :
565 [ # # ]: 0 : if (unlikely(algin_offset >= ZXDH_BAR_MSG_ADDR_CHAN_INTERVAL)) {
566 : 0 : PMD_MSG_LOG(ERR, "algin_offset exceeds channel size!");
567 : 0 : return -1;
568 : : }
569 : 0 : *pdata = *(uint32_t *)(subchan_addr + algin_offset);
570 : 0 : return 0;
571 : : }
572 : :
573 : : static uint16_t
574 : 0 : zxdh_bar_chan_msg_header_set(uint64_t subchan_addr,
575 : : struct zxdh_bar_msg_header *msg_header)
576 : : {
577 : : uint32_t *data = (uint32_t *)msg_header;
578 : : uint16_t i;
579 : :
580 [ # # # # ]: 0 : for (i = 0; i < (ZXDH_BAR_MSG_PLAYLOAD_OFFSET >> 2); i++)
581 : 0 : zxdh_bar_chan_reg_write(subchan_addr, i * 4, *(data + i));
582 : :
583 : 0 : return ZXDH_BAR_MSG_OK;
584 : : }
585 : :
586 : : static uint16_t
587 : : zxdh_bar_chan_msg_header_get(uint64_t subchan_addr,
588 : : struct zxdh_bar_msg_header *msg_header)
589 : : {
590 : : uint32_t *data = (uint32_t *)msg_header;
591 : : uint16_t i;
592 : :
593 [ # # # # : 0 : for (i = 0; i < (ZXDH_BAR_MSG_PLAYLOAD_OFFSET >> 2); i++)
# # ]
594 : 0 : zxdh_bar_chan_reg_read(subchan_addr, i * 4, data + i);
595 : :
596 : : return ZXDH_BAR_MSG_OK;
597 : : }
598 : :
599 : : static uint16_t
600 : 0 : zxdh_bar_chan_msg_payload_set(uint64_t subchan_addr, uint8_t *msg, uint16_t len)
601 : : {
602 : : uint32_t *data = (uint32_t *)msg;
603 : 0 : uint32_t count = (len >> 2);
604 : 0 : uint32_t remain = (len & 0x3);
605 : : uint32_t remain_data = 0;
606 : : uint32_t i;
607 : :
608 [ # # ]: 0 : for (i = 0; i < count; i++)
609 : 0 : zxdh_bar_chan_reg_write(subchan_addr, 4 * i +
610 : 0 : ZXDH_BAR_MSG_PLAYLOAD_OFFSET, *(data + i));
611 [ # # ]: 0 : if (remain) {
612 [ # # ]: 0 : for (i = 0; i < remain; i++)
613 : 0 : remain_data |= *((uint8_t *)(msg + len - remain + i)) << (8 * i);
614 : :
615 : 0 : zxdh_bar_chan_reg_write(subchan_addr, 4 * count +
616 : : ZXDH_BAR_MSG_PLAYLOAD_OFFSET, remain_data);
617 : : }
618 : 0 : return ZXDH_BAR_MSG_OK;
619 : : }
620 : :
621 : : static uint16_t
622 : 0 : zxdh_bar_chan_msg_payload_get(uint64_t subchan_addr, uint8_t *msg, uint16_t len)
623 : : {
624 : : uint32_t *data = (uint32_t *)msg;
625 : 0 : uint32_t count = (len >> 2);
626 : 0 : uint32_t remain_data = 0;
627 : 0 : uint32_t remain = (len & 0x3);
628 : : uint32_t i;
629 : :
630 [ # # ]: 0 : for (i = 0; i < count; i++)
631 : 0 : zxdh_bar_chan_reg_read(subchan_addr, 4 * i +
632 : 0 : ZXDH_BAR_MSG_PLAYLOAD_OFFSET, (data + i));
633 [ # # ]: 0 : if (remain) {
634 : 0 : zxdh_bar_chan_reg_read(subchan_addr, 4 * count +
635 : : ZXDH_BAR_MSG_PLAYLOAD_OFFSET, &remain_data);
636 [ # # ]: 0 : for (i = 0; i < remain; i++)
637 : 0 : *((uint8_t *)(msg + (len - remain + i))) = remain_data >> (8 * i);
638 : : }
639 : 0 : return ZXDH_BAR_MSG_OK;
640 : : }
641 : :
642 : : static uint16_t
643 : : zxdh_bar_chan_msg_valid_set(uint64_t subchan_addr, uint8_t valid_label)
644 : : {
645 : : uint32_t data;
646 : :
647 : : zxdh_bar_chan_reg_read(subchan_addr, ZXDH_BAR_MSG_VALID_OFFSET, &data);
648 : 0 : data &= (~ZXDH_BAR_MSG_VALID_MASK);
649 : 0 : data |= (uint32_t)valid_label;
650 : : zxdh_bar_chan_reg_write(subchan_addr, ZXDH_BAR_MSG_VALID_OFFSET, data);
651 : : return ZXDH_BAR_MSG_OK;
652 : : }
653 : :
654 : : static uint16_t
655 : 0 : zxdh_bar_chan_msg_send(uint64_t subchan_addr, void *payload_addr,
656 : : uint16_t payload_len, struct zxdh_bar_msg_header *msg_header)
657 : : {
658 : : uint16_t ret = 0;
659 : : ret = zxdh_bar_chan_msg_header_set(subchan_addr, msg_header);
660 : :
661 : : ret = zxdh_bar_chan_msg_header_get(subchan_addr,
662 : : (struct zxdh_bar_msg_header *)tmp_msg_header);
663 : :
664 : 0 : ret = zxdh_bar_chan_msg_payload_set(subchan_addr,
665 : : (uint8_t *)(payload_addr), payload_len);
666 : :
667 : 0 : ret = zxdh_bar_chan_msg_payload_get(subchan_addr,
668 : : tmp_msg_header, payload_len);
669 : :
670 : : ret = zxdh_bar_chan_msg_valid_set(subchan_addr, ZXDH_BAR_MSG_CHAN_USED);
671 : 0 : return ret;
672 : : }
673 : :
674 : : static uint16_t
675 : : zxdh_bar_msg_valid_stat_get(uint64_t subchan_addr)
676 : : {
677 : : uint32_t data;
678 : :
679 : : zxdh_bar_chan_reg_read(subchan_addr, ZXDH_BAR_MSG_VALID_OFFSET, &data);
680 [ # # ]: 0 : if (ZXDH_BAR_MSG_CHAN_USABLE == (data & ZXDH_BAR_MSG_VALID_MASK))
681 : 0 : return ZXDH_BAR_MSG_CHAN_USABLE;
682 : :
683 : : return ZXDH_BAR_MSG_CHAN_USED;
684 : : }
685 : :
686 : : static uint16_t
687 : : zxdh_bar_chan_msg_poltag_set(uint64_t subchan_addr, uint8_t label)
688 : : {
689 : : uint32_t data;
690 : :
691 : : zxdh_bar_chan_reg_read(subchan_addr, ZXDH_BAR_MSG_VALID_OFFSET, &data);
692 : 0 : data &= (~(uint32_t)ZXDH_BAR_MSG_POL_MASK);
693 : : data |= ((uint32_t)label << ZXDH_BAR_MSG_POL_OFFSET);
694 : : zxdh_bar_chan_reg_write(subchan_addr, ZXDH_BAR_MSG_VALID_OFFSET, data);
695 : : return ZXDH_BAR_MSG_OK;
696 : : }
697 : :
698 : : static uint16_t
699 : 0 : zxdh_bar_chan_sync_msg_reps_get(uint64_t subchan_addr,
700 : : uint64_t recv_buffer, uint16_t buffer_len)
701 : : {
702 : 0 : struct zxdh_bar_msg_header msg_header = {0};
703 : : uint16_t msg_id = 0;
704 : : uint16_t msg_len = 0;
705 : :
706 : : zxdh_bar_chan_msg_header_get(subchan_addr, &msg_header);
707 : 0 : msg_id = msg_header.msg_id;
708 : 0 : struct zxdh_seqid_item *reps_info = &g_seqid_ring.reps_info_tbl[msg_id];
709 : :
710 [ # # ]: 0 : if (reps_info->flag != ZXDH_REPS_INFO_FLAG_USED) {
711 : 0 : PMD_MSG_LOG(ERR, "msg_id %u unused", msg_id);
712 : 0 : return ZXDH_BAR_MSG_ERR_REPLY;
713 : : }
714 : 0 : msg_len = msg_header.len;
715 : :
716 [ # # ]: 0 : if (msg_len > buffer_len - 4) {
717 : 0 : PMD_MSG_LOG(ERR, "recv buffer len is: %u, but reply msg len is: %u",
718 : : buffer_len, msg_len + 4);
719 : 0 : return ZXDH_BAR_MSG_ERR_REPSBUFF_LEN;
720 : : }
721 : 0 : uint8_t *recv_msg = (uint8_t *)recv_buffer;
722 : :
723 : 0 : zxdh_bar_chan_msg_payload_get(subchan_addr,
724 : : recv_msg + ZXDH_REPS_HEADER_PAYLOAD_OFFSET, msg_len);
725 : 0 : *(uint16_t *)(recv_msg + ZXDH_REPS_HEADER_LEN_OFFSET) = msg_len;
726 : 0 : *recv_msg = ZXDH_REPS_HEADER_REPLYED; /* set reps's valid */
727 : 0 : return ZXDH_BAR_MSG_OK;
728 : : }
729 : :
730 : : int
731 : 0 : zxdh_bar_chan_sync_msg_send(struct zxdh_pci_bar_msg *in, struct zxdh_msg_recviver_mem *result)
732 : : {
733 : 0 : struct zxdh_bar_msg_header msg_header = {0};
734 : 0 : uint16_t seq_id = 0;
735 : 0 : uint64_t subchan_addr = 0;
736 : : uint32_t time_out_cnt = 0;
737 : : uint16_t valid = 0;
738 : : int ret = 0;
739 : :
740 : 0 : ret = zxdh_bar_chan_send_para_check(in, result);
741 [ # # ]: 0 : if (ret != ZXDH_BAR_MSG_OK)
742 : 0 : goto exit;
743 : :
744 : 0 : ret = zxdh_bar_chan_save_recv_info(result, &seq_id);
745 [ # # ]: 0 : if (ret != ZXDH_BAR_MSG_OK)
746 : 0 : goto exit;
747 : :
748 : 0 : zxdh_bar_chan_subchan_addr_get(in, &subchan_addr);
749 : :
750 : : msg_header.sync = ZXDH_BAR_CHAN_MSG_SYNC;
751 : 0 : msg_header.emec = in->emec;
752 : : msg_header.usr = 0;
753 : : msg_header.rsv = 0;
754 : 0 : msg_header.module_id = in->module_id;
755 : 0 : msg_header.len = in->payload_len;
756 : 0 : msg_header.msg_id = seq_id;
757 : 0 : msg_header.src_pcieid = in->src_pcieid;
758 : 0 : msg_header.dst_pcieid = in->dst_pcieid;
759 : :
760 : 0 : ret = zxdh_bar_chan_lock(in->src, in->dst, in->src_pcieid, in->virt_addr);
761 [ # # ]: 0 : if (ret != ZXDH_BAR_MSG_OK) {
762 : 0 : zxdh_bar_chan_msgid_free(seq_id);
763 : 0 : goto exit;
764 : : }
765 : 0 : zxdh_bar_chan_msg_send(subchan_addr, in->payload_addr, in->payload_len, &msg_header);
766 : :
767 : : do {
768 : 0 : rte_delay_us_block(ZXDH_BAR_MSG_POLLING_SPAN);
769 : : valid = zxdh_bar_msg_valid_stat_get(subchan_addr);
770 : 0 : ++time_out_cnt;
771 [ # # ]: 0 : } while ((time_out_cnt < ZXDH_BAR_MSG_TIMEOUT_TH) && (valid == ZXDH_BAR_MSG_CHAN_USED));
772 : :
773 [ # # ]: 0 : if (time_out_cnt == ZXDH_BAR_MSG_TIMEOUT_TH && valid != ZXDH_BAR_MSG_CHAN_USABLE) {
774 : : zxdh_bar_chan_msg_valid_set(subchan_addr, ZXDH_BAR_MSG_CHAN_USABLE);
775 : : zxdh_bar_chan_msg_poltag_set(subchan_addr, 0);
776 : 0 : PMD_MSG_LOG(ERR, "BAR MSG ERR: chan type time out.");
777 : : ret = ZXDH_BAR_MSG_ERR_TIME_OUT;
778 : : } else {
779 : 0 : ret = zxdh_bar_chan_sync_msg_reps_get(subchan_addr,
780 : 0 : (uint64_t)result->recv_buffer, result->buffer_len);
781 : : }
782 : 0 : zxdh_bar_chan_msgid_free(seq_id);
783 : 0 : zxdh_bar_chan_unlock(in->src, in->dst, in->src_pcieid, in->virt_addr);
784 : :
785 : 0 : exit:
786 : 0 : return ret;
787 : : }
788 : :
789 : : static int
790 : : zxdh_bar_get_sum(uint8_t *ptr, uint8_t len)
791 : : {
792 : : uint64_t sum = 0;
793 : : int idx;
794 : :
795 [ # # ]: 0 : for (idx = 0; idx < len; idx++)
796 : 0 : sum += *(ptr + idx);
797 : :
798 : 0 : return (uint16_t)sum;
799 : : }
800 : :
801 : : static int
802 : 0 : zxdh_bar_chan_enable(struct zxdh_msix_para *para, uint16_t *vport)
803 : : {
804 : 0 : struct zxdh_bar_recv_msg recv_msg = {0};
805 : : int ret = 0;
806 : : int check_token = 0;
807 : : int sum_res = 0;
808 : :
809 [ # # ]: 0 : if (!para)
810 : : return ZXDH_BAR_MSG_ERR_NULL;
811 : :
812 : 0 : struct zxdh_msix_msg msix_msg = {
813 : 0 : .pcie_id = para->pcie_id,
814 : 0 : .vector_risc = para->vector_risc,
815 : 0 : .vector_pfvf = para->vector_pfvf,
816 : 0 : .vector_mpf = para->vector_mpf,
817 : : };
818 : 0 : struct zxdh_pci_bar_msg in = {
819 : 0 : .virt_addr = para->virt_addr,
820 : : .payload_addr = &msix_msg,
821 : : .payload_len = sizeof(msix_msg),
822 : : .emec = 0,
823 : 0 : .src = para->driver_type,
824 : : .dst = ZXDH_MSG_CHAN_END_RISC,
825 : : .module_id = ZXDH_BAR_MODULE_MISX,
826 : : .src_pcieid = para->pcie_id,
827 : : .dst_pcieid = 0,
828 : : .usr = 0,
829 : : };
830 : :
831 : 0 : struct zxdh_msg_recviver_mem result = {
832 : : .recv_buffer = &recv_msg,
833 : : .buffer_len = sizeof(recv_msg),
834 : : };
835 : :
836 : 0 : ret = zxdh_bar_chan_sync_msg_send(&in, &result);
837 [ # # ]: 0 : if (ret != ZXDH_BAR_MSG_OK)
838 : 0 : return -ret;
839 : :
840 : 0 : check_token = recv_msg.msix_reps.check;
841 : : sum_res = zxdh_bar_get_sum((uint8_t *)&msix_msg, sizeof(msix_msg));
842 : :
843 [ # # ]: 0 : if (check_token != sum_res) {
844 : 0 : PMD_MSG_LOG(ERR, "expect token: 0x%x, get token: 0x%x.", sum_res, check_token);
845 : 0 : return ZXDH_BAR_MSG_ERR_REPLY;
846 : : }
847 : 0 : *vport = recv_msg.msix_reps.vport;
848 : 0 : PMD_MSG_LOG(DEBUG, "vport of pcieid: 0x%x get success.", para->pcie_id);
849 : 0 : return ZXDH_BAR_MSG_OK;
850 : : }
851 : :
852 : : int
853 : 0 : zxdh_msg_chan_enable(struct rte_eth_dev *dev)
854 : : {
855 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
856 : 0 : struct zxdh_msix_para misx_info = {
857 : : .vector_risc = ZXDH_MSIX_FROM_RISCV,
858 : : .vector_pfvf = ZXDH_MSIX_FROM_PFVF,
859 : : .vector_mpf = ZXDH_MSIX_FROM_MPF,
860 : 0 : .pcie_id = hw->pcie_id,
861 : 0 : .driver_type = hw->is_pf ? ZXDH_MSG_CHAN_END_PF : ZXDH_MSG_CHAN_END_VF,
862 [ # # ]: 0 : .virt_addr = (uint64_t)(hw->bar_addr[ZXDH_BAR0_INDEX] + ZXDH_CTRLCH_OFFSET),
863 : : };
864 : :
865 : 0 : return zxdh_bar_chan_enable(&misx_info, &hw->vport.vport);
866 : : }
867 : :
868 : : static uint64_t
869 [ # # ]: 0 : zxdh_recv_addr_get(uint8_t src_type, uint8_t dst_type, uint64_t virt_addr)
870 : : {
871 : : uint8_t chan_id = 0;
872 : : uint8_t subchan_id = 0;
873 : : uint8_t src = 0;
874 : : uint8_t dst = 0;
875 : :
876 : : src = zxdh_bar_msg_dst_index_trans(src_type);
877 : : dst = zxdh_bar_msg_src_index_trans(dst_type);
878 [ # # ]: 0 : if (src == ZXDH_BAR_MSG_SRC_ERR || dst == ZXDH_BAR_MSG_DST_ERR)
879 : : return 0;
880 : :
881 : 0 : chan_id = chan_id_tbl[dst][src];
882 : 0 : subchan_id = 1 - subchan_id_tbl[dst][src];
883 : :
884 : 0 : return zxdh_subchan_addr_cal(virt_addr, chan_id, subchan_id);
885 : : }
886 : :
887 : : static void
888 : 0 : zxdh_bar_msg_ack_async_msg_proc(struct zxdh_bar_msg_header *msg_header,
889 : : uint8_t *receiver_buff)
890 : : {
891 : 0 : struct zxdh_seqid_item *reps_info = &g_seqid_ring.reps_info_tbl[msg_header->msg_id];
892 : :
893 [ # # ]: 0 : if (reps_info->flag != ZXDH_REPS_INFO_FLAG_USED) {
894 : 0 : PMD_MSG_LOG(ERR, "msg_id: %u is released", msg_header->msg_id);
895 : 0 : return;
896 : : }
897 [ # # ]: 0 : if (msg_header->len > reps_info->buffer_len - 4) {
898 : 0 : PMD_MSG_LOG(ERR, "reps_buf_len is %u, but reps_msg_len is %u",
899 : : reps_info->buffer_len, msg_header->len + 4);
900 : 0 : goto free_id;
901 : : }
902 : 0 : uint8_t *reps_buffer = (uint8_t *)reps_info->reps_addr;
903 : :
904 [ # # ]: 0 : rte_memcpy(reps_buffer + 4, receiver_buff, msg_header->len);
905 : 0 : *(uint16_t *)(reps_buffer + 1) = msg_header->len;
906 : 0 : *(uint8_t *)(reps_info->reps_addr) = ZXDH_REPS_HEADER_REPLYED;
907 : :
908 : 0 : free_id:
909 : 0 : zxdh_bar_chan_msgid_free(msg_header->msg_id);
910 : : }
911 : :
912 : : static void
913 : 0 : zxdh_bar_msg_sync_msg_proc(uint64_t reply_addr,
914 : : struct zxdh_bar_msg_header *msg_header,
915 : : uint8_t *receiver_buff, void *dev)
916 : : {
917 : 0 : uint16_t reps_len = 0;
918 : : uint8_t *reps_buffer = NULL;
919 : :
920 : 0 : reps_buffer = rte_malloc(NULL, ZXDH_BAR_MSG_PAYLOAD_MAX_LEN, 0);
921 [ # # ]: 0 : if (reps_buffer == NULL)
922 : 0 : return;
923 : :
924 : 0 : zxdh_bar_chan_msg_recv_callback recv_func = msg_recv_func_tbl[msg_header->module_id];
925 : :
926 : 0 : recv_func(receiver_buff, msg_header->len, reps_buffer, &reps_len, dev);
927 : 0 : msg_header->ack = ZXDH_BAR_CHAN_MSG_ACK;
928 : 0 : msg_header->len = reps_len;
929 : 0 : zxdh_bar_chan_msg_header_set(reply_addr, msg_header);
930 : 0 : zxdh_bar_chan_msg_payload_set(reply_addr, reps_buffer, reps_len);
931 : : zxdh_bar_chan_msg_valid_set(reply_addr, ZXDH_BAR_MSG_CHAN_USABLE);
932 : 0 : rte_free(reps_buffer);
933 : : }
934 : :
935 : : static uint64_t
936 [ # # ]: 0 : zxdh_reply_addr_get(uint8_t sync, uint8_t src_type,
937 : : uint8_t dst_type, uint64_t virt_addr)
938 : : {
939 : : uint64_t recv_rep_addr = 0;
940 : : uint8_t chan_id = 0;
941 : : uint8_t subchan_id = 0;
942 : : uint8_t src = 0;
943 : : uint8_t dst = 0;
944 : :
945 : : src = zxdh_bar_msg_dst_index_trans(src_type);
946 : : dst = zxdh_bar_msg_src_index_trans(dst_type);
947 [ # # ]: 0 : if (src == ZXDH_BAR_MSG_SRC_ERR || dst == ZXDH_BAR_MSG_DST_ERR)
948 : : return 0;
949 : :
950 : 0 : chan_id = chan_id_tbl[dst][src];
951 : 0 : subchan_id = 1 - subchan_id_tbl[dst][src];
952 : :
953 [ # # ]: 0 : if (sync == ZXDH_BAR_CHAN_MSG_SYNC)
954 : 0 : recv_rep_addr = zxdh_subchan_addr_cal(virt_addr, chan_id, subchan_id);
955 : : else
956 : 0 : recv_rep_addr = zxdh_subchan_addr_cal(virt_addr, chan_id, 1 - subchan_id);
957 : :
958 : : return recv_rep_addr;
959 : : }
960 : :
961 : : static uint16_t
962 : 0 : zxdh_bar_chan_msg_header_check(struct zxdh_bar_msg_header *msg_header)
963 : : {
964 : : uint16_t len = 0;
965 : : uint8_t module_id = 0;
966 : :
967 [ # # ]: 0 : if (msg_header->valid != ZXDH_BAR_MSG_CHAN_USED) {
968 : 0 : PMD_MSG_LOG(ERR, "recv header ERR: valid label is not used.");
969 : 0 : return ZXDH_BAR_MSG_ERR_MODULE;
970 : : }
971 : 0 : module_id = msg_header->module_id;
972 : :
973 [ # # ]: 0 : if (module_id >= (uint8_t)ZXDH_BAR_MSG_MODULE_NUM) {
974 : 0 : PMD_MSG_LOG(ERR, "recv header ERR: invalid module_id: %u.", module_id);
975 : 0 : return ZXDH_BAR_MSG_ERR_MODULE;
976 : : }
977 : 0 : len = msg_header->len;
978 : :
979 [ # # ]: 0 : if (len > ZXDH_BAR_MSG_PAYLOAD_MAX_LEN) {
980 : 0 : PMD_MSG_LOG(ERR, "recv header ERR: invalid mesg len: %u.", len);
981 : 0 : return ZXDH_BAR_MSG_ERR_LEN;
982 : : }
983 [ # # ]: 0 : if (msg_recv_func_tbl[msg_header->module_id] == NULL) {
984 : 0 : PMD_MSG_LOG(ERR, "recv header ERR: module:%s(%u) doesn't register",
985 : : zxdh_module_id_name(module_id), module_id);
986 : 0 : return ZXDH_BAR_MSG_ERR_MODULE_NOEXIST;
987 : : }
988 : : return ZXDH_BAR_MSG_OK;
989 : : }
990 : :
991 : : int
992 : 0 : zxdh_bar_irq_recv(uint8_t src, uint8_t dst, uint64_t virt_addr, void *dev)
993 : : {
994 : 0 : struct zxdh_bar_msg_header msg_header = {0};
995 : : uint64_t recv_addr = 0;
996 : : uint64_t reps_addr = 0;
997 : : uint16_t ret = 0;
998 : : uint8_t *recved_msg = NULL;
999 : :
1000 : 0 : recv_addr = zxdh_recv_addr_get(src, dst, virt_addr);
1001 [ # # ]: 0 : if (recv_addr == 0) {
1002 : 0 : PMD_MSG_LOG(ERR, "invalid driver type(src:%u, dst:%u).", src, dst);
1003 : 0 : return -1;
1004 : : }
1005 : :
1006 : : zxdh_bar_chan_msg_header_get(recv_addr, &msg_header);
1007 : 0 : ret = zxdh_bar_chan_msg_header_check(&msg_header);
1008 : :
1009 [ # # ]: 0 : if (ret != ZXDH_BAR_MSG_OK) {
1010 : 0 : PMD_MSG_LOG(ERR, "recv msg_head err, ret: %u.", ret);
1011 : 0 : return -1;
1012 : : }
1013 : :
1014 : 0 : recved_msg = rte_malloc(NULL, msg_header.len, 0);
1015 [ # # ]: 0 : if (recved_msg == NULL) {
1016 : 0 : PMD_MSG_LOG(ERR, "malloc temp buff failed.");
1017 : 0 : return -1;
1018 : : }
1019 : 0 : zxdh_bar_chan_msg_payload_get(recv_addr, recved_msg, msg_header.len);
1020 : :
1021 : 0 : reps_addr = zxdh_reply_addr_get(msg_header.sync, src, dst, virt_addr);
1022 : :
1023 [ # # ]: 0 : if (msg_header.sync == ZXDH_BAR_CHAN_MSG_SYNC) {
1024 : 0 : zxdh_bar_msg_sync_msg_proc(reps_addr, &msg_header, recved_msg, dev);
1025 : 0 : goto exit;
1026 : : }
1027 : : zxdh_bar_chan_msg_valid_set(recv_addr, ZXDH_BAR_MSG_CHAN_USABLE);
1028 [ # # ]: 0 : if (msg_header.ack == ZXDH_BAR_CHAN_MSG_ACK) {
1029 : 0 : zxdh_bar_msg_ack_async_msg_proc(&msg_header, recved_msg);
1030 : 0 : goto exit;
1031 : : }
1032 : : return 0;
1033 : :
1034 : 0 : exit:
1035 : 0 : rte_free(recved_msg);
1036 : 0 : return ZXDH_BAR_MSG_OK;
1037 : : }
|