Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2025 Huawei Technologies Co., Ltd
3 : : */
4 : :
5 : : #include "hinic3_compat.h"
6 : : #include "hinic3_cmd.h"
7 : : #include "hinic3_cmdq.h"
8 : : #include "hinic3_cmdq_enhance.h"
9 : : #include "hinic3_hwdev.h"
10 : : #include "hinic3_hwif.h"
11 : : #include "hinic3_mgmt.h"
12 : : #include "hinic3_wq.h"
13 : : #include "hinic3_nic_cfg.h"
14 : :
15 : : #define CMDQ_CMD_TIMEOUT 5000 /**< Millisecond. */
16 : :
17 : : #define UPPER_8_BITS(data) (((data) >> 8) & 0xFF)
18 : : #define LOWER_8_BITS(data) ((data) & 0xFF)
19 : :
20 : : #define CMDQ_DB_INFO_HI_PROD_IDX_SHIFT 0
21 : : #define CMDQ_DB_INFO_HI_PROD_IDX_MASK 0xFFU
22 : :
23 : : #define CMDQ_DB_INFO_SET(val, member) \
24 : : ((((uint32_t)(val)) & CMDQ_DB_INFO_##member##_MASK) \
25 : : << CMDQ_DB_INFO_##member##_SHIFT)
26 : : #define CMDQ_DB_INFO_UPPER_32(val) ((uint64_t)(val) << 32)
27 : :
28 : : #define CMDQ_DB_HEAD_QUEUE_TYPE_SHIFT 23
29 : : #define CMDQ_DB_HEAD_CMDQ_TYPE_SHIFT 24
30 : : #define CMDQ_DB_HEAD_SRC_TYPE_SHIFT 27
31 : : #define CMDQ_DB_HEAD_QUEUE_TYPE_MASK 0x1U
32 : : #define CMDQ_DB_HEAD_CMDQ_TYPE_MASK 0x7U
33 : : #define CMDQ_DB_HEAD_SRC_TYPE_MASK 0x1FU
34 : : #define CMDQ_DB_HEAD_SET(val, member) \
35 : : ((((uint32_t)(val)) & CMDQ_DB_HEAD_##member##_MASK) \
36 : : << CMDQ_DB_HEAD_##member##_SHIFT)
37 : :
38 : : #define CMDQ_CTRL_PI_SHIFT 0
39 : : #define CMDQ_CTRL_CMD_SHIFT 16
40 : : #define CMDQ_CTRL_MOD_SHIFT 24
41 : : #define CMDQ_CTRL_ACK_TYPE_SHIFT 29
42 : : #define CMDQ_CTRL_HW_BUSY_BIT_SHIFT 31
43 : :
44 : : #define CMDQ_CTRL_PI_MASK 0xFFFFU
45 : : #define CMDQ_CTRL_CMD_MASK 0xFFU
46 : : #define CMDQ_CTRL_MOD_MASK 0x1FU
47 : : #define CMDQ_CTRL_ACK_TYPE_MASK 0x3U
48 : : #define CMDQ_CTRL_HW_BUSY_BIT_MASK 0x1U
49 : :
50 : : #define CMDQ_CTRL_SET(val, member) \
51 : : (((uint32_t)(val) & CMDQ_CTRL_##member##_MASK) << CMDQ_CTRL_##member##_SHIFT)
52 : :
53 : : #define CMDQ_CTRL_GET(val, member) \
54 : : (((val) >> CMDQ_CTRL_##member##_SHIFT) & CMDQ_CTRL_##member##_MASK)
55 : :
56 : : #define CMDQ_WQE_HEADER_BUFDESC_LEN_SHIFT 0
57 : : #define CMDQ_WQE_HEADER_COMPLETE_FMT_SHIFT 15
58 : : #define CMDQ_WQE_HEADER_DATA_FMT_SHIFT 22
59 : : #define CMDQ_WQE_HEADER_COMPLETE_REQ_SHIFT 23
60 : : #define CMDQ_WQE_HEADER_COMPLETE_SECT_LEN_SHIFT 27
61 : : #define CMDQ_WQE_HEADER_CTRL_LEN_SHIFT 29
62 : : #define CMDQ_WQE_HEADER_HW_BUSY_BIT_SHIFT 31
63 : :
64 : : #define CMDQ_WQE_HEADER_BUFDESC_LEN_MASK 0xFFU
65 : : #define CMDQ_WQE_HEADER_COMPLETE_FMT_MASK 0x1U
66 : : #define CMDQ_WQE_HEADER_DATA_FMT_MASK 0x1U
67 : : #define CMDQ_WQE_HEADER_COMPLETE_REQ_MASK 0x1U
68 : : #define CMDQ_WQE_HEADER_COMPLETE_SECT_LEN_MASK 0x3U
69 : : #define CMDQ_WQE_HEADER_CTRL_LEN_MASK 0x3U
70 : : #define CMDQ_WQE_HEADER_HW_BUSY_BIT_MASK 0x1U
71 : :
72 : : #define CMDQ_WQE_HEADER_SET(val, member) \
73 : : (((uint32_t)(val) & CMDQ_WQE_HEADER_##member##_MASK) \
74 : : << CMDQ_WQE_HEADER_##member##_SHIFT)
75 : :
76 : : #define CMDQ_WQE_HEADER_GET(val, member) \
77 : : (((val) >> CMDQ_WQE_HEADER_##member##_SHIFT) & \
78 : : CMDQ_WQE_HEADER_##member##_MASK)
79 : :
80 : : #define CMDQ_CTXT_CURR_WQE_PAGE_PFN_SHIFT 0
81 : : #define CMDQ_CTXT_EQ_ID_SHIFT 53
82 : : #define CMDQ_CTXT_CEQ_ARM_SHIFT 61
83 : : #define CMDQ_CTXT_CEQ_EN_SHIFT 62
84 : : #define CMDQ_CTXT_HW_BUSY_BIT_SHIFT 63
85 : :
86 : : #define CMDQ_CTXT_CURR_WQE_PAGE_PFN_MASK 0xFFFFFFFFFFFFF
87 : : #define CMDQ_CTXT_EQ_ID_MASK 0xFF
88 : : #define CMDQ_CTXT_CEQ_ARM_MASK 0x1
89 : : #define CMDQ_CTXT_CEQ_EN_MASK 0x1
90 : : #define CMDQ_CTXT_HW_BUSY_BIT_MASK 0x1
91 : :
92 : : #define CMDQ_CTXT_PAGE_INFO_SET(val, member) \
93 : : (((uint64_t)(val) & CMDQ_CTXT_##member##_MASK) << CMDQ_CTXT_##member##_SHIFT)
94 : :
95 : : #define CMDQ_CTXT_WQ_BLOCK_PFN_SHIFT 0
96 : : #define CMDQ_CTXT_CI_SHIFT 52
97 : :
98 : : #define CMDQ_CTXT_WQ_BLOCK_PFN_MASK 0xFFFFFFFFFFFFF
99 : : #define CMDQ_CTXT_CI_MASK 0xFFF
100 : :
101 : : #define CMDQ_CTXT_BLOCK_INFO_SET(val, member) \
102 : : (((uint64_t)(val) & CMDQ_CTXT_##member##_MASK) << CMDQ_CTXT_##member##_SHIFT)
103 : :
104 : : #define SAVED_DATA_ARM_SHIFT 31
105 : :
106 : : #define SAVED_DATA_ARM_MASK 0x1U
107 : :
108 : : #define SAVED_DATA_SET(val, member) \
109 : : (((val) & SAVED_DATA_##member##_MASK) << SAVED_DATA_##member##_SHIFT)
110 : :
111 : : #define SAVED_DATA_CLEAR(val, member) \
112 : : ((val) & (~(SAVED_DATA_##member##_MASK << SAVED_DATA_##member##_SHIFT)))
113 : :
114 : : #define WQE_ERRCODE_VAL_SHIFT 0
115 : :
116 : : #define WQE_ERRCODE_VAL_MASK 0x7FFFFFFF
117 : :
118 : : #define WQE_ERRCODE_GET(val, member) \
119 : : (((val) >> WQE_ERRCODE_##member##_SHIFT) & WQE_ERRCODE_##member##_MASK)
120 : :
121 : : #define WQE_COMPLETED(ctrl_info) CMDQ_CTRL_GET(ctrl_info, HW_BUSY_BIT)
122 : :
123 : : #define WQE_HEADER(wqe) ((struct hinic3_cmdq_header *)(wqe))
124 : :
125 : : #define CMDQ_DB_PI_OFF(pi) (LOWER_8_BITS(pi) << 3)
126 : :
127 : : #define CMDQ_DB_ADDR(db_base, pi) ((db_base) + CMDQ_DB_PI_OFF(pi))
128 : :
129 : : #define FIRST_DATA_TO_WRITE_LAST sizeof(uint64_t)
130 : :
131 : : #define WQE_LCMDQ_SIZE 64
132 : : #define WQE_SCMDQ_SIZE 64
133 : : #define WQE_ENHANCE_CMDQ_SIZE 32
134 : :
135 : : #define COMPLETE_LEN 3
136 : :
137 : : #define CMDQ_WQEBB_SIZE 64
138 : : #define CMDQ_WQEBB_SHIFT 6
139 : : #define CMDQ_ENHANCE_WQEBB_SHIFT 4
140 : :
141 : : #define CMDQ_WQE_SIZE 64
142 : :
143 : : #define HINIC3_CMDQ_WQ_BUF_SIZE 4096
144 : :
145 : : #define WQE_NUM_WQEBBS(wqe_size, wq) \
146 : : ({ \
147 : : typeof(wq) __wq = (wq); \
148 : : (uint16_t)(RTE_ALIGN((uint32_t)(wqe_size), __wq->wqebb_size) / \
149 : : __wq->wqebb_size); \
150 : : })
151 : :
152 : : #define cmdq_to_cmdqs(cmdq) \
153 : : ({ \
154 : : typeof(cmdq) __cmdq = (cmdq); \
155 : : container_of(__cmdq - __cmdq->cmdq_type, struct hinic3_cmdqs, \
156 : : __cmdq[0]); \
157 : : })
158 : :
159 : : #define WAIT_CMDQ_ENABLE_TIMEOUT 300
160 : :
161 : : static int hinic3_cmdq_poll_msg(struct hinic3_cmdq *cmdq, uint32_t timeout);
162 : :
163 : : bool
164 : 0 : hinic3_cmdq_idle(struct hinic3_cmdq *cmdq)
165 : : {
166 : 0 : struct hinic3_wq *wq = cmdq->wq;
167 : :
168 : 0 : return rte_atomic_load_explicit(&wq->delta, rte_memory_order_seq_cst) ==
169 : 0 : wq->q_depth;
170 : : }
171 : :
172 : : struct hinic3_cmd_buf *
173 : 0 : hinic3_alloc_cmd_buf(struct hinic3_hwdev *hwdev)
174 : : {
175 : 0 : struct hinic3_cmdqs *cmdqs = hwdev->cmdqs;
176 : : struct hinic3_cmd_buf *cmd_buf;
177 : :
178 : 0 : cmd_buf = rte_zmalloc(NULL, sizeof(*cmd_buf), 0);
179 [ # # ]: 0 : if (!cmd_buf) {
180 : 0 : PMD_DRV_LOG(ERR, "Allocate cmd buffer failed");
181 : 0 : return NULL;
182 : : }
183 : :
184 : 0 : cmd_buf->mbuf = rte_pktmbuf_alloc(cmdqs->cmd_buf_pool);
185 [ # # ]: 0 : if (!cmd_buf->mbuf) {
186 : 0 : PMD_DRV_LOG(ERR, "Allocate cmd from the pool failed");
187 : 0 : goto alloc_pci_buf_err;
188 : : }
189 : :
190 : 0 : cmd_buf->dma_addr = rte_mbuf_data_iova(cmd_buf->mbuf);
191 : 0 : cmd_buf->buf = rte_pktmbuf_mtod(cmd_buf->mbuf, void *);
192 : :
193 : 0 : return cmd_buf;
194 : :
195 : : alloc_pci_buf_err:
196 : 0 : rte_free(cmd_buf);
197 : 0 : return NULL;
198 : : }
199 : :
200 : : void
201 : 0 : hinic3_free_cmd_buf(struct hinic3_cmd_buf *cmd_buf)
202 : : {
203 : 0 : rte_pktmbuf_free(cmd_buf->mbuf);
204 : 0 : rte_free(cmd_buf);
205 : 0 : }
206 : :
207 : : static void
208 : : cmdq_set_completion(struct hinic3_cmdq_completion *complete,
209 : : struct hinic3_cmd_buf *buf_out)
210 : : {
211 : : struct hinic3_sge_resp *sge_resp = &complete->sge_resp;
212 : :
213 : 0 : hinic3_set_sge(&sge_resp->sge, buf_out->dma_addr, HINIC3_CMDQ_BUF_SIZE);
214 : 0 : }
215 : :
216 : : static void
217 : : cmdq_set_lcmd_bufdesc(struct hinic3_cmdq_wqe_lcmd *wqe,
218 : : struct hinic3_cmd_buf *buf_in)
219 : : {
220 : 0 : hinic3_set_sge(&wqe->buf_desc.sge, buf_in->dma_addr, buf_in->size);
221 : : }
222 : :
223 : : static void
224 : 0 : cmdq_set_db(struct hinic3_cmdq *cmdq, enum hinic3_cmdq_type cmdq_type,
225 : : uint16_t prod_idx)
226 : : {
227 : 0 : uint64_t db = CMDQ_DB_INFO_SET(UPPER_8_BITS(prod_idx), HI_PROD_IDX);
228 : :
229 : 0 : db = CMDQ_DB_INFO_UPPER_32(db) |
230 : 0 : CMDQ_DB_HEAD_SET(HINIC3_DB_CMDQ_TYPE, QUEUE_TYPE) |
231 : 0 : CMDQ_DB_HEAD_SET(cmdq_type, CMDQ_TYPE) |
232 : : CMDQ_DB_HEAD_SET(HINIC3_DB_SRC_CMDQ_TYPE, SRC_TYPE);
233 : :
234 : : /**< Write all before the doorbell. */
235 : : rte_atomic_thread_fence(rte_memory_order_release);
236 : : /* Hardware will do endianness converting. */
237 : 0 : rte_write64(db, CMDQ_DB_ADDR(cmdq->db_base, prod_idx));
238 : 0 : }
239 : :
240 : : static void
241 : 0 : cmdq_wqe_fill(void *dst, void *src, int wqe_size)
242 : : {
243 : 0 : memcpy((void *)((uint8_t *)dst + FIRST_DATA_TO_WRITE_LAST),
244 : 0 : (void *)((uint8_t *)src + FIRST_DATA_TO_WRITE_LAST),
245 : : wqe_size - FIRST_DATA_TO_WRITE_LAST);
246 : :
247 : : /* The first 8 bytes should be written last. */
248 : : rte_atomic_thread_fence(rte_memory_order_release);
249 : :
250 : 0 : *(uint64_t *)dst = *(uint64_t *)src;
251 : 0 : }
252 : :
253 : : static void
254 : 0 : cmdq_prepare_wqe_ctrl(struct hinic3_cmdq_wqe *wqe, int wrapped,
255 : : enum hinic3_mod_type mod, uint8_t cmd, uint16_t prod_idx,
256 : : enum completion_format complete_format,
257 : : enum data_format local_data_format,
258 : : enum bufdesc_len buf_len)
259 : : {
260 : : struct hinic3_ctrl *ctrl = NULL;
261 : : enum ctrl_sect_len ctrl_len;
262 : : struct hinic3_cmdq_wqe_lcmd *wqe_lcmd = NULL;
263 : : struct hinic3_cmdq_wqe_scmd *wqe_scmd = NULL;
264 : 0 : uint32_t saved_data = WQE_HEADER(wqe)->saved_data;
265 : :
266 [ # # ]: 0 : if (local_data_format == DATA_SGE) {
267 : : wqe_lcmd = &wqe->wqe_lcmd;
268 : :
269 : 0 : wqe_lcmd->status.status_info = 0;
270 : 0 : ctrl = &wqe_lcmd->ctrl;
271 : : ctrl_len = CTRL_SECT_LEN;
272 : : } else {
273 : : wqe_scmd = &wqe->inline_wqe.wqe_scmd;
274 : :
275 : 0 : wqe_scmd->status.status_info = 0;
276 : 0 : ctrl = &wqe_scmd->ctrl;
277 : : ctrl_len = CTRL_DIRECT_SECT_LEN;
278 : : }
279 : :
280 : 0 : ctrl->ctrl_info = CMDQ_CTRL_SET(prod_idx, PI) |
281 : 0 : CMDQ_CTRL_SET(cmd, CMD) | CMDQ_CTRL_SET(mod, MOD) |
282 : : CMDQ_CTRL_SET(HINIC3_ACK_TYPE_CMDQ, ACK_TYPE);
283 : :
284 : 0 : WQE_HEADER(wqe)->header_info =
285 : 0 : CMDQ_WQE_HEADER_SET(buf_len, BUFDESC_LEN) |
286 : 0 : CMDQ_WQE_HEADER_SET(complete_format, COMPLETE_FMT) |
287 : 0 : CMDQ_WQE_HEADER_SET(local_data_format, DATA_FMT) |
288 : : CMDQ_WQE_HEADER_SET(CEQ_SET, COMPLETE_REQ) |
289 : 0 : CMDQ_WQE_HEADER_SET(COMPLETE_LEN, COMPLETE_SECT_LEN) |
290 : 0 : CMDQ_WQE_HEADER_SET(ctrl_len, CTRL_LEN) |
291 : 0 : CMDQ_WQE_HEADER_SET((uint32_t)wrapped, HW_BUSY_BIT);
292 : :
293 : 0 : saved_data &= SAVED_DATA_CLEAR(saved_data, ARM);
294 [ # # ]: 0 : if (cmd == CMDQ_SET_ARM_CMD && mod == HINIC3_MOD_COMM)
295 : 0 : WQE_HEADER(wqe)->saved_data = saved_data |
296 : : SAVED_DATA_SET(1, ARM);
297 : : else
298 : 0 : WQE_HEADER(wqe)->saved_data = saved_data;
299 : 0 : }
300 : :
301 : : static void
302 : 0 : cmdq_set_lcmd_wqe(struct hinic3_cmdq_wqe *wqe, enum cmdq_cmd_type cmd_type,
303 : : struct hinic3_cmd_buf *buf_in, struct hinic3_cmd_buf *buf_out,
304 : : int wrapped, enum hinic3_mod_type mod, uint8_t cmd, uint16_t prod_idx)
305 : : {
306 : : struct hinic3_cmdq_wqe_lcmd *wqe_lcmd = &wqe->wqe_lcmd;
307 : : enum completion_format complete_format = COMPLETE_DIRECT;
308 : :
309 [ # # # # ]: 0 : switch (cmd_type) {
310 : 0 : case SYNC_CMD_DIRECT_RESP:
311 : : complete_format = COMPLETE_DIRECT;
312 : 0 : wqe_lcmd->completion.direct_resp = 0;
313 : 0 : break;
314 : 0 : case SYNC_CMD_SGE_RESP:
315 [ # # ]: 0 : if (buf_out) {
316 : : complete_format = COMPLETE_SGE;
317 : : cmdq_set_completion(&wqe_lcmd->completion, buf_out);
318 : : }
319 : : break;
320 : 0 : case ASYNC_CMD:
321 : : complete_format = COMPLETE_DIRECT;
322 : 0 : wqe_lcmd->completion.direct_resp = 0;
323 : 0 : wqe_lcmd->buf_desc.saved_async_buf = (uint64_t)(buf_in);
324 : 0 : break;
325 : 0 : default:
326 : 0 : PMD_DRV_LOG(ERR, "Invalid cmdq_cmd_type");
327 : 0 : break;
328 : : }
329 : :
330 : 0 : cmdq_prepare_wqe_ctrl(wqe, wrapped, mod, cmd, prod_idx, complete_format,
331 : : DATA_SGE, BUFDESC_LCMD_LEN);
332 : :
333 : : cmdq_set_lcmd_bufdesc(wqe_lcmd, buf_in);
334 : 0 : }
335 : :
336 : : static void
337 : 0 : cmdq_sync_wqe_prepare(struct hinic3_cmdq *cmdq, uint8_t mod, uint8_t cmd,
338 : : struct hinic3_cmd_buf *buf_in, struct hinic3_cmd_buf *buf_out,
339 : : struct hinic3_cmdq_wqe *curr_wqe, uint16_t curr_pi,
340 : : enum hinic3_cmdq_cmd_type nic_cmd_type)
341 : : {
342 : : struct hinic3_cmdq_wqe wqe;
343 : : int wrapped, wqe_size;
344 : : enum cmdq_cmd_type cmd_type;
345 : :
346 : 0 : wqe_size = cmdq->cmdqs->cmdq_mode == HINIC3_NORMAL_CMDQ ?
347 [ # # ]: 0 : WQE_LCMDQ_SIZE : WQE_ENHANCE_CMDQ_SIZE;
348 : :
349 [ # # ]: 0 : memset(&wqe, 0, (uint32_t)wqe_size);
350 : :
351 : 0 : wrapped = cmdq->wrapped;
352 : :
353 : 0 : cmd_type = (nic_cmd_type == HINIC3_CMD_TYPE_DIRECT_RESP) ?
354 : 0 : SYNC_CMD_DIRECT_RESP : SYNC_CMD_SGE_RESP;
355 [ # # ]: 0 : if (cmdq->cmdqs->cmdq_mode == HINIC3_NORMAL_CMDQ)
356 : 0 : cmdq_set_lcmd_wqe(&wqe, cmd_type, buf_in, buf_out, wrapped, mod, cmd, curr_pi);
357 : : else
358 : 0 : hinic3_enhance_cmdq_set_wqe(&wqe, cmd_type, buf_in, buf_out, wrapped, mod, cmd);
359 : :
360 : : /* The data written to HW should be in Big Endian Format */
361 : : hinic3_cpu_to_hw(&wqe, wqe_size);
362 : :
363 : 0 : cmdq_wqe_fill(curr_wqe, &wqe, wqe_size);
364 : 0 : }
365 : :
366 : : #define NUM_WQEBBS_FOR_CMDQ_WQE 1
367 : : #define NUM_WQEBBS_FOR_ENHANCE_CMDQ_WQE 2
368 : :
369 : 0 : static int cmdq_sync_cmd(struct hinic3_cmdq *cmdq, enum hinic3_mod_type mod, uint8_t cmd,
370 : : struct hinic3_cmd_buf *buf_in, struct hinic3_cmd_buf *buf_out,
371 : : uint64_t *out_param, uint32_t timeout,
372 : : enum hinic3_cmdq_cmd_type nic_cmd_type)
373 : : {
374 : 0 : struct hinic3_wq *wq = cmdq->wq;
375 : : struct hinic3_cmdq_wqe *curr_wqe = NULL;
376 : : uint16_t curr_prod_idx, next_prod_idx, num_wqebbs;
377 : : uint32_t time;
378 : : uint64_t *direct_resp = NULL;
379 : : int err;
380 : :
381 [ # # ]: 0 : num_wqebbs = (cmdq->cmdqs->cmdq_mode == HINIC3_NORMAL_CMDQ) ?
382 : : NUM_WQEBBS_FOR_CMDQ_WQE : NUM_WQEBBS_FOR_ENHANCE_CMDQ_WQE;
383 : :
384 : : /* Keep wrapped and doorbell index correct */
385 : 0 : rte_spinlock_lock(&cmdq->cmdq_lock);
386 : :
387 : 0 : curr_wqe = hinic3_get_wqe(cmdq->wq, num_wqebbs, &curr_prod_idx);
388 [ # # ]: 0 : if (!curr_wqe) {
389 : : err = -EBUSY;
390 : 0 : goto cmdq_unlock;
391 : : }
392 : :
393 : 0 : cmdq_sync_wqe_prepare(cmdq, mod, cmd, buf_in, buf_out,
394 : : curr_wqe, curr_prod_idx, nic_cmd_type);
395 : :
396 : 0 : cmdq->cmd_infos[curr_prod_idx].cmd_type = nic_cmd_type;
397 : :
398 : 0 : next_prod_idx = curr_prod_idx + num_wqebbs;
399 [ # # ]: 0 : if (next_prod_idx >= wq->q_depth) {
400 : 0 : cmdq->wrapped = !cmdq->wrapped;
401 : 0 : next_prod_idx -= wq->q_depth;
402 : : }
403 : 0 : cmdq_set_db(cmdq, HINIC3_CMDQ_SYNC, next_prod_idx);
404 [ # # ]: 0 : time = msecs_to_cycles(timeout ? timeout : CMDQ_CMD_TIMEOUT);
405 : 0 : err = hinic3_cmdq_poll_msg(cmdq, time);
406 [ # # ]: 0 : if (err) {
407 : 0 : PMD_DRV_LOG(ERR, "Cmdq poll msg ack failed, prod idx: 0x%x", curr_prod_idx);
408 : : err = -ETIMEDOUT;
409 : 0 : goto cmdq_unlock;
410 : : }
411 : :
412 : : rte_atomic_thread_fence(rte_memory_order_acquire); /* Read error code after completion */
413 : :
414 [ # # ]: 0 : if (out_param) {
415 [ # # ]: 0 : if (cmdq->cmdqs->cmdq_mode == HINIC3_NORMAL_CMDQ)
416 : 0 : direct_resp =
417 : : (uint64_t *)(&curr_wqe->wqe_lcmd.completion.direct_resp);
418 : : else
419 : 0 : direct_resp = (uint64_t *)
420 : : (&curr_wqe->enhanced_cmdq_wqe.completion.sge_resp_lo_addr);
421 : :
422 [ # # ]: 0 : *out_param = rte_cpu_to_be_64(*direct_resp);
423 : : }
424 : :
425 [ # # ]: 0 : if (cmdq->errcode[curr_prod_idx])
426 : : err = cmdq->errcode[curr_prod_idx];
427 : :
428 : 0 : cmdq_unlock:
429 : : rte_spinlock_unlock(&cmdq->cmdq_lock);
430 : :
431 : 0 : return err;
432 : : }
433 : :
434 : : static int
435 : 0 : cmdq_params_valid(struct hinic3_hwdev *hwdev, struct hinic3_cmd_buf *buf_in)
436 : : {
437 [ # # ]: 0 : if (!buf_in || !hwdev) {
438 : 0 : PMD_DRV_LOG(ERR, "Invalid CMDQ buffer or hwdev is NULL");
439 : 0 : return -EINVAL;
440 : : }
441 : :
442 [ # # ]: 0 : if (buf_in->size == 0 || buf_in->size > HINIC3_CMDQ_BUF_SIZE) {
443 : 0 : PMD_DRV_LOG(ERR, "Invalid CMDQ buffer size: 0x%x",
444 : : buf_in->size);
445 : 0 : return -EINVAL;
446 : : }
447 : :
448 : : return 0;
449 : : }
450 : :
451 : : static int
452 : 0 : wait_cmdqs_enable(struct hinic3_cmdqs *cmdqs)
453 : : {
454 : : uint64_t end;
455 : :
456 : 0 : end = cycles + msecs_to_cycles(WAIT_CMDQ_ENABLE_TIMEOUT);
457 : : do {
458 [ # # ]: 0 : if (cmdqs->status & HINIC3_CMDQ_ENABLE)
459 : : return 0;
460 [ # # ]: 0 : } while (time_before(cycles, end));
461 : :
462 : : return -EBUSY;
463 : : }
464 : :
465 : : int
466 : 0 : hinic3_cmdq_direct_resp(struct hinic3_hwdev *hwdev, enum hinic3_mod_type mod, uint8_t cmd,
467 : : struct hinic3_cmd_buf *buf_in,
468 : : uint64_t *out_param, uint32_t timeout)
469 : : {
470 : 0 : struct hinic3_cmdqs *cmdqs = hwdev->cmdqs;
471 : : int err;
472 : :
473 : 0 : err = cmdq_params_valid(hwdev, buf_in);
474 [ # # ]: 0 : if (err) {
475 : 0 : PMD_DRV_LOG(ERR, "Invalid cmdq parameters");
476 : 0 : return err;
477 : : }
478 : :
479 : 0 : err = wait_cmdqs_enable(cmdqs);
480 [ # # ]: 0 : if (err) {
481 : 0 : PMD_DRV_LOG(ERR, "Cmdq is disabled");
482 : 0 : return err;
483 : : }
484 : :
485 : 0 : return cmdq_sync_cmd(&cmdqs->cmdq[HINIC3_CMDQ_SYNC], mod, cmd, buf_in,
486 : : NULL, out_param, timeout, HINIC3_CMD_TYPE_DIRECT_RESP);
487 : : }
488 : :
489 : : int
490 : 0 : hinic3_cmdq_detail_resp(struct hinic3_hwdev *hwdev, enum hinic3_mod_type mod, uint8_t cmd,
491 : : struct hinic3_cmd_buf *buf_in, struct hinic3_cmd_buf *buf_out, uint32_t timeout)
492 : : {
493 : 0 : struct hinic3_cmdqs *cmdqs = hwdev->cmdqs;
494 : : int err;
495 : :
496 : 0 : err = cmdq_params_valid(hwdev, buf_in);
497 [ # # ]: 0 : if (err) {
498 : 0 : PMD_DRV_LOG(ERR, "Invalid cmdq parameters");
499 : 0 : return err;
500 : : }
501 : :
502 : 0 : err = wait_cmdqs_enable(cmdqs);
503 [ # # ]: 0 : if (err) {
504 : 0 : PMD_DRV_LOG(ERR, "Cmdq is disabled");
505 : 0 : return err;
506 : : }
507 : :
508 : 0 : return cmdq_sync_cmd(&cmdqs->cmdq[HINIC3_CMDQ_SYNC], mod, cmd, buf_in, buf_out,
509 : : NULL, timeout, HINIC3_CMD_TYPE_SGE_RESP);
510 : : }
511 : :
512 : : static void
513 : : cmdq_update_errcode(struct hinic3_cmdq *cmdq, uint16_t prod_idx, int errcode)
514 : : {
515 : 0 : cmdq->errcode[prod_idx] = errcode;
516 : : }
517 : :
518 : : static void
519 : 0 : clear_wqe_complete_bit(struct hinic3_cmdq *cmdq, struct hinic3_cmdq_wqe *wqe)
520 : : {
521 : : struct hinic3_ctrl *ctrl = NULL;
522 : 0 : uint32_t header_info = hinic3_hw_cpu32(WQE_HEADER(wqe)->header_info);
523 : : uint16_t num_wqebbs;
524 : : enum data_format df;
525 [ # # ]: 0 : if (cmdq->cmdqs->cmdq_mode == HINIC3_NORMAL_CMDQ) {
526 : 0 : df = CMDQ_WQE_HEADER_GET(header_info, DATA_FMT);
527 [ # # ]: 0 : if (df == DATA_SGE)
528 : 0 : ctrl = &wqe->wqe_lcmd.ctrl;
529 : : else
530 : 0 : ctrl = &wqe->inline_wqe.wqe_scmd.ctrl;
531 : 0 : ctrl->ctrl_info = 0; /* clear HW busy bit */
532 : : num_wqebbs = NUM_WQEBBS_FOR_CMDQ_WQE;
533 : : } else {
534 : 0 : wqe->enhanced_cmdq_wqe.completion.cs_format = 0; /* clear HW busy bit */
535 : : num_wqebbs = NUM_WQEBBS_FOR_ENHANCE_CMDQ_WQE;
536 : : }
537 : :
538 : : rte_atomic_thread_fence(rte_memory_order_release); /**< Verify wqe is cleared. */
539 : :
540 : 0 : hinic3_put_wqe(cmdq->wq, num_wqebbs);
541 : 0 : }
542 : :
543 : : static void
544 : : cmdq_init_queue_ctxt(struct hinic3_cmdq *cmdq,
545 : : struct hinic3_cmdq_ctxt_info *ctxt_info)
546 : : {
547 : 0 : struct hinic3_wq *wq = cmdq->wq;
548 : : uint64_t wq_first_page_paddr, pfn;
549 : :
550 : 0 : uint16_t start_ci = (uint16_t)(wq->cons_idx);
551 : :
552 : : /* The data in the HW is in Big Endian Format. */
553 : 0 : wq_first_page_paddr = wq->queue_buf_paddr;
554 : :
555 : 0 : pfn = CMDQ_PFN(wq_first_page_paddr, RTE_PGSIZE_4K);
556 : 0 : ctxt_info->curr_wqe_page_pfn =
557 : : CMDQ_CTXT_PAGE_INFO_SET(1, HW_BUSY_BIT) |
558 : : CMDQ_CTXT_PAGE_INFO_SET(0, CEQ_EN) |
559 : : CMDQ_CTXT_PAGE_INFO_SET(0, CEQ_ARM) |
560 : 0 : CMDQ_CTXT_PAGE_INFO_SET(HINIC3_CEQ_ID_CMDQ, EQ_ID) |
561 : : CMDQ_CTXT_PAGE_INFO_SET(pfn, CURR_WQE_PAGE_PFN);
562 : :
563 : 0 : ctxt_info->wq_block_pfn = CMDQ_CTXT_BLOCK_INFO_SET(start_ci, CI) |
564 : : CMDQ_CTXT_BLOCK_INFO_SET(pfn, WQ_BLOCK_PFN);
565 : 0 : }
566 : :
567 : : static int
568 : 0 : init_cmdq(struct hinic3_cmdq *cmdq, struct hinic3_hwdev *hwdev,
569 : : struct hinic3_wq *wq, enum hinic3_cmdq_type q_type)
570 : : {
571 : : int err = 0;
572 : : size_t errcode_size;
573 : : size_t cmd_infos_size;
574 : :
575 : 0 : cmdq->wq = wq;
576 : 0 : cmdq->cmdq_type = q_type;
577 : 0 : cmdq->wrapped = 1;
578 : :
579 : : rte_spinlock_init(&cmdq->cmdq_lock);
580 : :
581 : 0 : errcode_size = wq->q_depth * sizeof(*cmdq->errcode);
582 : 0 : cmdq->errcode = rte_zmalloc(NULL, errcode_size, 0);
583 [ # # ]: 0 : if (!cmdq->errcode) {
584 : 0 : PMD_DRV_LOG(ERR, "Allocate errcode for cmdq failed");
585 : 0 : return -ENOMEM;
586 : : }
587 : :
588 : 0 : cmd_infos_size = wq->q_depth * sizeof(*cmdq->cmd_infos);
589 : 0 : cmdq->cmd_infos = rte_zmalloc(NULL, cmd_infos_size, 0);
590 [ # # ]: 0 : if (!cmdq->cmd_infos) {
591 : 0 : PMD_DRV_LOG(ERR, "Allocate cmd info for cmdq failed");
592 : : err = -ENOMEM;
593 : 0 : goto cmd_infos_err;
594 : : }
595 : :
596 : 0 : cmdq->db_base = hwdev->cmdqs->cmdqs_db_base;
597 : :
598 : 0 : return 0;
599 : :
600 : : cmd_infos_err:
601 : 0 : rte_free(cmdq->errcode);
602 : :
603 : 0 : return err;
604 : : }
605 : :
606 : : static void
607 : : free_cmdq(struct hinic3_cmdq *cmdq)
608 : : {
609 : 0 : rte_free(cmdq->cmd_infos);
610 : 0 : rte_free(cmdq->errcode);
611 : : }
612 : :
613 : : static int
614 : 0 : hinic3_set_cmdq_ctxts(struct hinic3_hwdev *hwdev)
615 : : {
616 : 0 : struct hinic3_cmdqs *cmdqs = hwdev->cmdqs;
617 : 0 : struct hinic3_cmd_cmdq_ctxt cmdq_ctxt = {0};
618 : : enum hinic3_cmdq_type cmdq_type = HINIC3_CMDQ_SYNC;
619 : 0 : uint16_t out_size = sizeof(cmdq_ctxt);
620 : : uint16_t cmd;
621 : : int err;
622 : :
623 [ # # ]: 0 : for (; cmdq_type < HINIC3_MAX_CMDQ_TYPES; cmdq_type++) {
624 [ # # ]: 0 : if (hwdev->cmdqs->cmdq_mode == HINIC3_NORMAL_CMDQ) {
625 : 0 : cmdq_ctxt.ctxt_info = cmdqs->cmdq[cmdq_type].cmdq_ctxt;
626 : : cmd = HINIC3_MGMT_CMD_SET_CMDQ_CTXT;
627 : : } else {
628 : 0 : cmdq_ctxt.enhance_ctxt_info = cmdqs->cmdq[cmdq_type].cmdq_enhance_ctxt;
629 : : cmd = HINIC3_MGMT_CMD_SET_ENHANCE_CMDQ_CTXT;
630 : : }
631 : 0 : cmdq_ctxt.func_idx = hinic3_global_func_id(hwdev);
632 : 0 : cmdq_ctxt.cmdq_id = cmdq_type;
633 : :
634 : 0 : err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_COMM, cmd,
635 : : &cmdq_ctxt, sizeof(cmdq_ctxt),
636 : : &cmdq_ctxt, &out_size);
637 [ # # # # : 0 : if (err || !out_size || cmdq_ctxt.status) {
# # ]
638 : 0 : PMD_DRV_LOG(ERR, "Set cmdq ctxt failed, err: %d, status: 0x%x, out_size: 0x%x",
639 : : err, cmdq_ctxt.status, out_size);
640 : 0 : return -EFAULT;
641 : : }
642 : : }
643 : :
644 : 0 : cmdqs->status |= HINIC3_CMDQ_ENABLE;
645 : :
646 : 0 : return 0;
647 : : }
648 : :
649 : : int
650 : 0 : hinic3_reinit_cmdq_ctxts(struct hinic3_hwdev *hwdev)
651 : : {
652 : 0 : struct hinic3_cmdqs *cmdqs = hwdev->cmdqs;
653 : : enum hinic3_cmdq_type cmdq_type;
654 : :
655 [ # # ]: 0 : for (cmdq_type = HINIC3_CMDQ_SYNC; cmdq_type < HINIC3_MAX_CMDQ_TYPES; cmdq_type++) {
656 : 0 : cmdqs->cmdq[cmdq_type].wrapped = 1;
657 : 0 : hinic3_wq_wqe_pg_clear(cmdqs->cmdq[cmdq_type].wq);
658 : : }
659 : :
660 : 0 : return hinic3_set_cmdq_ctxts(hwdev);
661 : : }
662 : :
663 : : static int
664 : 0 : hinic3_set_cmdqs(struct hinic3_hwdev *hwdev, struct hinic3_cmdqs *cmdqs)
665 : : {
666 : 0 : void *db_base = NULL;
667 : : enum hinic3_cmdq_type type, cmdq_type;
668 : : int err;
669 : :
670 : 0 : err = hinic3_alloc_db_addr(hwdev, &db_base, HINIC3_DB_TYPE_CMDQ);
671 [ # # ]: 0 : if (err) {
672 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate doorbell address");
673 : 0 : goto alloc_db_err;
674 : : }
675 : :
676 : 0 : cmdqs->cmdqs_db_base = (uint8_t *)db_base;
677 : :
678 [ # # ]: 0 : for (cmdq_type = HINIC3_CMDQ_SYNC; cmdq_type < HINIC3_MAX_CMDQ_TYPES; cmdq_type++) {
679 : 0 : cmdqs->cmdq[cmdq_type].cmdqs = cmdqs;
680 : 0 : err = init_cmdq(&cmdqs->cmdq[cmdq_type], hwdev,
681 : 0 : &cmdqs->saved_wqs[cmdq_type], cmdq_type);
682 [ # # ]: 0 : if (err) {
683 : 0 : PMD_DRV_LOG(ERR, "Initialize cmdq failed");
684 : 0 : goto init_cmdq_err;
685 : : }
686 : :
687 [ # # ]: 0 : if (cmdqs->cmdq_mode == HINIC3_NORMAL_CMDQ)
688 : : cmdq_init_queue_ctxt(&cmdqs->cmdq[cmdq_type],
689 : : &cmdqs->cmdq[cmdq_type].cmdq_ctxt);
690 : : else
691 : 0 : hinic3_enhance_cmdq_init_queue_ctxt(&cmdqs->cmdq[cmdq_type]);
692 : : }
693 : :
694 : 0 : err = hinic3_set_cmdq_ctxts(hwdev);
695 [ # # ]: 0 : if (err)
696 : 0 : goto init_cmdq_err;
697 : :
698 : : return 0;
699 : :
700 : 0 : init_cmdq_err:
701 [ # # ]: 0 : for (type = HINIC3_CMDQ_SYNC; type < cmdq_type; type++)
702 : : free_cmdq(&cmdqs->cmdq[type]);
703 : :
704 : 0 : alloc_db_err:
705 : 0 : hinic3_cmdq_free(cmdqs->saved_wqs, HINIC3_MAX_CMDQ_TYPES);
706 : 0 : return -ENOMEM;
707 : : }
708 : :
709 : : int
710 : 0 : hinic3_cmdq_init(struct hinic3_hwdev *hwdev)
711 : : {
712 : : struct hinic3_cmdqs *cmdqs = NULL;
713 : : size_t saved_wqs_size;
714 : : char cmdq_pool_name[RTE_MEMPOOL_NAMESIZE];
715 : : uint32_t wqebb_shift;
716 : : int err;
717 : :
718 : 0 : cmdqs = rte_zmalloc(NULL, sizeof(*cmdqs), 0);
719 [ # # ]: 0 : if (!cmdqs)
720 : : return -ENOMEM;
721 : :
722 : 0 : hwdev->cmdqs = cmdqs;
723 : 0 : cmdqs->hwdev = hwdev;
724 : :
725 [ # # ]: 0 : if (HINIC3_SUPPORT_ONLY_ENHANCE_CMDQ(hwdev))
726 : 0 : cmdqs->cmdq_mode = HINIC3_ENHANCE_CMDQ;
727 : : else
728 : 0 : cmdqs->cmdq_mode = HINIC3_NORMAL_CMDQ;
729 : :
730 : 0 : wqebb_shift = (cmdqs->cmdq_mode == HINIC3_ENHANCE_CMDQ) ?
731 [ # # ]: 0 : CMDQ_ENHANCE_WQEBB_SHIFT : CMDQ_WQEBB_SHIFT;
732 : :
733 : : saved_wqs_size = HINIC3_MAX_CMDQ_TYPES * sizeof(struct hinic3_wq);
734 : 0 : cmdqs->saved_wqs = rte_zmalloc(NULL, saved_wqs_size, 0);
735 [ # # ]: 0 : if (!cmdqs->saved_wqs) {
736 : 0 : PMD_DRV_LOG(ERR, "Allocate saved wqs failed");
737 : : err = -ENOMEM;
738 : 0 : goto alloc_wqs_err;
739 : : }
740 : :
741 : : memset(cmdq_pool_name, 0, RTE_MEMPOOL_NAMESIZE);
742 : 0 : snprintf(cmdq_pool_name, sizeof(cmdq_pool_name), "hinic3_cmdq_%u", hwdev->port_id);
743 : :
744 : 0 : cmdqs->cmd_buf_pool = rte_pktmbuf_pool_create(cmdq_pool_name,
745 : : HINIC3_CMDQ_DEPTH * HINIC3_MAX_CMDQ_TYPES, 0, 0,
746 : 0 : HINIC3_CMDQ_BUF_SIZE, (int)rte_socket_id());
747 [ # # ]: 0 : if (!cmdqs->cmd_buf_pool) {
748 : 0 : PMD_DRV_LOG(ERR, "Create cmdq buffer pool failed");
749 : : err = -ENOMEM;
750 : 0 : goto pool_create_err;
751 : : }
752 : :
753 : 0 : err = hinic3_cmdq_alloc(cmdqs->saved_wqs, hwdev, HINIC3_MAX_CMDQ_TYPES,
754 : : HINIC3_CMDQ_WQ_BUF_SIZE, wqebb_shift, HINIC3_CMDQ_DEPTH);
755 [ # # ]: 0 : if (err) {
756 : 0 : PMD_DRV_LOG(ERR, "Allocate cmdq failed");
757 : 0 : goto cmdq_alloc_err;
758 : : }
759 : :
760 : 0 : err = hinic3_set_cmdqs(hwdev, cmdqs);
761 [ # # ]: 0 : if (err) {
762 : 0 : PMD_DRV_LOG(ERR, "set_cmdqs failed");
763 : 0 : goto cmdq_alloc_err;
764 : : }
765 : : return 0;
766 : :
767 : 0 : cmdq_alloc_err:
768 : 0 : rte_mempool_free(cmdqs->cmd_buf_pool);
769 : :
770 : 0 : pool_create_err:
771 : 0 : rte_free(cmdqs->saved_wqs);
772 : :
773 : 0 : alloc_wqs_err:
774 : 0 : rte_free(cmdqs);
775 : :
776 : 0 : return err;
777 : : }
778 : :
779 : : void
780 : 0 : hinic3_cmdqs_free(struct hinic3_hwdev *hwdev)
781 : : {
782 : 0 : struct hinic3_cmdqs *cmdqs = hwdev->cmdqs;
783 : : enum hinic3_cmdq_type cmdq_type = HINIC3_CMDQ_SYNC;
784 : :
785 : 0 : cmdqs->status &= ~HINIC3_CMDQ_ENABLE;
786 : :
787 [ # # ]: 0 : for (; cmdq_type < HINIC3_MAX_CMDQ_TYPES; cmdq_type++)
788 : : free_cmdq(&cmdqs->cmdq[cmdq_type]);
789 : :
790 : 0 : hinic3_cmdq_free(cmdqs->saved_wqs, HINIC3_MAX_CMDQ_TYPES);
791 : 0 : rte_mempool_free(cmdqs->cmd_buf_pool);
792 : 0 : rte_free(cmdqs->saved_wqs);
793 : 0 : rte_free(cmdqs);
794 : 0 : }
795 : :
796 : : static int
797 : : hinic3_check_cmdq_done(struct hinic3_cmdq *cmdq, struct hinic3_cmdq_wqe *wqe)
798 : : {
799 : : struct hinic3_ctrl *ctrl = NULL;
800 : : uint32_t ctrl_info;
801 : :
802 [ # # ]: 0 : if (cmdq->cmdqs->cmdq_mode == HINIC3_NORMAL_CMDQ) {
803 : : /* Only arm bit using scmd wqe, the wqe is lcmd. */
804 : : ctrl = &wqe->wqe_lcmd.ctrl;
805 : 0 : ctrl_info = hinic3_hw_cpu32((ctrl)->ctrl_info);
806 : :
807 [ # # ]: 0 : if (!WQE_COMPLETED(ctrl_info))
808 : : return -EBUSY;
809 : : } else {
810 : 0 : ctrl_info = wqe->enhanced_cmdq_wqe.completion.cs_format;
811 : : ctrl_info = hinic3_hw_cpu32(ctrl_info);
812 : :
813 [ # # ]: 0 : if (!ENHANCE_CMDQ_WQE_CS_GET(ctrl_info, HW_BUSY))
814 : : return -EBUSY;
815 : : }
816 : : return 0;
817 : : }
818 : :
819 : : static int
820 : 0 : hinic3_cmdq_poll_msg(struct hinic3_cmdq *cmdq, uint32_t timeout)
821 : : {
822 : : struct hinic3_cmdq_wqe *wqe = NULL;
823 : : struct hinic3_cmdq_wqe_lcmd *wqe_lcmd = NULL;
824 : : struct hinic3_cmdq_cmd_info *cmd_info = NULL;
825 : : uint32_t status_info;
826 : : uint16_t ci;
827 : : int errcode;
828 : : uint64_t end;
829 : : int done = 0;
830 : : int err = 0;
831 : :
832 : 0 : wqe = hinic3_read_wqe(cmdq->wq, 1, &ci);
833 [ # # ]: 0 : if (!wqe) {
834 : 0 : PMD_DRV_LOG(ERR, "No outstanding cmdq msg");
835 : 0 : return -EINVAL;
836 : : }
837 : :
838 : 0 : cmd_info = &cmdq->cmd_infos[ci];
839 [ # # ]: 0 : if (cmd_info->cmd_type == HINIC3_CMD_TYPE_NONE) {
840 : 0 : PMD_DRV_LOG(ERR,
841 : : "Cmdq msg has not been filled and send to hw, or get TMO msg ack. cmdq ci: %u",
842 : : ci);
843 : 0 : return -EINVAL;
844 : : }
845 : :
846 : : /* Only arm bit using scmd wqe, the wqe is lcmd. */
847 : 0 : end = cycles + msecs_to_cycles(timeout);
848 : : do {
849 : : if (hinic3_check_cmdq_done(cmdq, wqe) == 0) {
850 : : done = 1;
851 : : break;
852 : : }
853 : :
854 : 0 : rte_delay_us(1);
855 [ # # ]: 0 : } while (time_before(cycles, end));
856 : :
857 [ # # ]: 0 : if (done) {
858 [ # # ]: 0 : if (cmdq->cmdqs->cmdq_mode == HINIC3_NORMAL_CMDQ) {
859 : : wqe_lcmd = &wqe->wqe_lcmd;
860 : 0 : status_info = hinic3_hw_cpu32(wqe_lcmd->status.status_info);
861 : 0 : errcode = WQE_ERRCODE_GET(status_info, VAL);
862 : : } else {
863 : 0 : status_info = hinic3_hw_cpu32(wqe->enhanced_cmdq_wqe.completion.cs_format);
864 : 0 : errcode = ENHANCE_CMDQ_WQE_CS_GET(status_info, ERR_CODE);
865 : : }
866 : 0 : cmdq_update_errcode(cmdq, ci, errcode);
867 : 0 : clear_wqe_complete_bit(cmdq, wqe);
868 : : err = 0;
869 : : } else {
870 : 0 : PMD_DRV_LOG(ERR, "Poll cmdq msg time out, ci: %u", ci);
871 : : err = -ETIMEDOUT;
872 : : }
873 : :
874 : : /* Set this cmd invalid. */
875 : 0 : cmd_info->cmd_type = HINIC3_CMD_TYPE_NONE;
876 : :
877 : 0 : return err;
878 : : }
|