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