1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017 Huawei Technologies Co., Ltd
5 #include "hinic_compat.h"
7 #include "hinic_pmd_hwdev.h"
8 #include "hinic_pmd_hwif.h"
9 #include "hinic_pmd_mgmt.h"
11 #define BUF_OUT_DEFAULT_SIZE 1
13 #define MAX_PF_MGMT_BUF_SIZE 2048UL
15 #define MGMT_MSG_SIZE_MIN 20
16 #define MGMT_MSG_SIZE_STEP 16
17 #define MGMT_MSG_RSVD_FOR_DEV 8
19 #define MGMT_MSG_TIMEOUT 5000 /* millisecond */
21 #define SYNC_MSG_ID_MASK 0x1FF
22 #define ASYNC_MSG_ID_MASK 0x1FF
23 #define ASYNC_MSG_FLAG 0x200
25 #define MSG_NO_RESP 0xFFFF
27 #define MAX_MSG_SZ 2016
29 #define MSG_SZ_IS_VALID(in_size) ((in_size) <= MAX_MSG_SZ)
31 #define SYNC_MSG_ID(pf_to_mgmt) ((pf_to_mgmt)->sync_msg_id)
33 #define SYNC_MSG_ID_INC(pf_to_mgmt) (SYNC_MSG_ID(pf_to_mgmt) = \
34 (SYNC_MSG_ID(pf_to_mgmt) + 1) & SYNC_MSG_ID_MASK)
36 #define ASYNC_MSG_ID(pf_to_mgmt) ((pf_to_mgmt)->async_msg_id)
38 #define ASYNC_MSG_ID_INC(pf_to_mgmt) (ASYNC_MSG_ID(pf_to_mgmt) = \
39 ((ASYNC_MSG_ID(pf_to_mgmt) + 1) & ASYNC_MSG_ID_MASK) \
42 #define HINIC_SEQ_ID_MAX_VAL 42
43 #define HINIC_MSG_SEG_LEN 48
45 #define GET_CURR_AEQ_ELEM(eq) GET_AEQ_ELEM((eq), (eq)->cons_idx)
47 #define EQ_ELEM_DESC_TYPE_SHIFT 0
48 #define EQ_ELEM_DESC_SRC_SHIFT 7
49 #define EQ_ELEM_DESC_SIZE_SHIFT 8
50 #define EQ_ELEM_DESC_WRAPPED_SHIFT 31
52 #define EQ_ELEM_DESC_TYPE_MASK 0x7FU
53 #define EQ_ELEM_DESC_SRC_MASK 0x1U
54 #define EQ_ELEM_DESC_SIZE_MASK 0xFFU
55 #define EQ_ELEM_DESC_WRAPPED_MASK 0x1U
57 #define EQ_MSIX_RESEND_TIMER_CLEAR 1
59 #define EQ_ELEM_DESC_GET(val, member) \
60 (((val) >> EQ_ELEM_DESC_##member##_SHIFT) & \
61 EQ_ELEM_DESC_##member##_MASK)
63 #define HINIC_MGMT_CHANNEL_STATUS_SHIFT 0x0
64 #define HINIC_MGMT_CHANNEL_STATUS_MASK 0x1
66 #define HINIC_GET_MGMT_CHANNEL_STATUS(val, member) \
67 (((val) >> HINIC_##member##_SHIFT) & HINIC_##member##_MASK)
69 #define HINIC_MSG_TO_MGMT_MAX_LEN 2016
72 * mgmt_msg_len - calculate the total message length
73 * @msg_data_len: the length of the message data
74 * Return: the total message length
76 static u16 mgmt_msg_len(u16 msg_data_len)
78 /* u64 - the size of the header */
79 u16 msg_size = (u16)(MGMT_MSG_RSVD_FOR_DEV + sizeof(u64) +
82 if (msg_size > MGMT_MSG_SIZE_MIN)
83 msg_size = MGMT_MSG_SIZE_MIN +
84 ALIGN((msg_size - MGMT_MSG_SIZE_MIN),
87 msg_size = MGMT_MSG_SIZE_MIN;
93 * prepare_header - prepare the header of the message
94 * @pf_to_mgmt: PF to MGMT channel
95 * @header: pointer of the header to prepare
96 * @msg_len: the length of the message
97 * @mod: module in the chip that will get the message
98 * @ack_type: the type to response
99 * @direction: the direction of the original message
100 * @cmd: the command to do
101 * @msg_id: message id
103 static void prepare_header(struct hinic_msg_pf_to_mgmt *pf_to_mgmt,
104 u64 *header, int msg_len, enum hinic_mod_type mod,
105 enum hinic_msg_ack_type ack_type,
106 enum hinic_msg_direction_type direction,
109 struct hinic_hwif *hwif = pf_to_mgmt->hwdev->hwif;
111 *header = HINIC_MSG_HEADER_SET(msg_len, MSG_LEN) |
112 HINIC_MSG_HEADER_SET(mod, MODULE) |
113 HINIC_MSG_HEADER_SET(msg_len, SEG_LEN) |
114 HINIC_MSG_HEADER_SET(ack_type, NO_ACK) |
115 HINIC_MSG_HEADER_SET(0, ASYNC_MGMT_TO_PF) |
116 HINIC_MSG_HEADER_SET(0, SEQID) |
117 HINIC_MSG_HEADER_SET(LAST_SEGMENT, LAST) |
118 HINIC_MSG_HEADER_SET(direction, DIRECTION) |
119 HINIC_MSG_HEADER_SET(cmd, CMD) |
120 HINIC_MSG_HEADER_SET(HINIC_PCI_INTF_IDX(hwif), PCI_INTF_IDX) |
121 HINIC_MSG_HEADER_SET(hwif->attr.port_to_port_idx, P2P_IDX) |
122 HINIC_MSG_HEADER_SET(msg_id, MSG_ID);
126 * prepare_mgmt_cmd - prepare the mgmt command
127 * @mgmt_cmd: pointer to the command to prepare
128 * @header: pointer of the header to prepare
129 * @msg: the data of the message
130 * @msg_len: the length of the message
132 static void prepare_mgmt_cmd(u8 *mgmt_cmd, u64 *header, void *msg,
135 u32 cmd_buf_max = MAX_PF_MGMT_BUF_SIZE;
137 memset(mgmt_cmd, 0, MGMT_MSG_RSVD_FOR_DEV);
139 mgmt_cmd += MGMT_MSG_RSVD_FOR_DEV;
140 cmd_buf_max -= MGMT_MSG_RSVD_FOR_DEV;
141 memcpy(mgmt_cmd, header, sizeof(*header));
143 mgmt_cmd += sizeof(*header);
144 cmd_buf_max -= sizeof(*header);
145 memcpy(mgmt_cmd, msg, msg_len);
149 * alloc_recv_msg - allocate received message memory
150 * @recv_msg: pointer that will hold the allocated data
151 * Return: 0 - success, negative - failure
153 static int alloc_recv_msg(struct hinic_recv_msg *recv_msg)
157 recv_msg->msg = kzalloc(MAX_PF_MGMT_BUF_SIZE, GFP_KERNEL);
158 if (!recv_msg->msg) {
159 PMD_DRV_LOG(ERR, "Allocate recv msg buf failed");
163 recv_msg->buf_out = kzalloc(MAX_PF_MGMT_BUF_SIZE, GFP_KERNEL);
164 if (!recv_msg->buf_out) {
165 PMD_DRV_LOG(ERR, "Allocate recv msg output buf failed");
167 goto alloc_buf_out_err;
173 kfree(recv_msg->msg);
178 * free_recv_msg - free received message memory
179 * @recv_msg: pointer that holds the allocated data
181 static void free_recv_msg(struct hinic_recv_msg *recv_msg)
183 kfree(recv_msg->buf_out);
184 kfree(recv_msg->msg);
188 * alloc_msg_buf - allocate all the message buffers of PF to MGMT channel
189 * @pf_to_mgmt: PF to MGMT channel
190 * Return: 0 - success, negative - failure
192 static int alloc_msg_buf(struct hinic_msg_pf_to_mgmt *pf_to_mgmt)
196 err = alloc_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
198 PMD_DRV_LOG(ERR, "Allocate recv msg failed");
202 err = alloc_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
204 PMD_DRV_LOG(ERR, "Allocate resp recv msg failed");
205 goto alloc_msg_for_resp_err;
208 pf_to_mgmt->async_msg_buf = kzalloc(MAX_PF_MGMT_BUF_SIZE, GFP_KERNEL);
209 if (!pf_to_mgmt->async_msg_buf) {
210 PMD_DRV_LOG(ERR, "Allocate async msg buf failed");
212 goto async_msg_buf_err;
215 pf_to_mgmt->sync_msg_buf = kzalloc(MAX_PF_MGMT_BUF_SIZE, GFP_KERNEL);
216 if (!pf_to_mgmt->sync_msg_buf) {
217 PMD_DRV_LOG(ERR, "Allocate sync msg buf failed");
219 goto sync_msg_buf_err;
225 kfree(pf_to_mgmt->async_msg_buf);
228 free_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
230 alloc_msg_for_resp_err:
231 free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
237 * free_msg_buf - free all the message buffers of PF to MGMT channel
238 * @pf_to_mgmt: PF to MGMT channel
239 * Return: 0 - success, negative - failure
241 static void free_msg_buf(struct hinic_msg_pf_to_mgmt *pf_to_mgmt)
243 kfree(pf_to_mgmt->sync_msg_buf);
244 kfree(pf_to_mgmt->async_msg_buf);
246 free_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
247 free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
251 * send_msg_to_mgmt_async - send async message
252 * @pf_to_mgmt: PF to MGMT channel
253 * @mod: module in the chip that will get the message
254 * @cmd: command of the message
255 * @msg: the data of the message
256 * @msg_len: the length of the message
257 * @direction: the direction of the original message
258 * @resp_msg_id: message id of response
259 * Return: 0 - success, negative - failure
261 static int send_msg_to_mgmt_async(struct hinic_msg_pf_to_mgmt *pf_to_mgmt,
262 enum hinic_mod_type mod, u8 cmd,
263 void *msg, u16 msg_len,
264 enum hinic_msg_direction_type direction,
267 void *mgmt_cmd = pf_to_mgmt->async_msg_buf;
268 struct hinic_api_cmd_chain *chain;
270 u16 cmd_size = mgmt_msg_len(msg_len);
272 if (direction == HINIC_MSG_RESPONSE)
273 prepare_header(pf_to_mgmt, &header, msg_len, mod, HINIC_MSG_ACK,
274 direction, cmd, resp_msg_id);
276 prepare_header(pf_to_mgmt, &header, msg_len, mod, HINIC_MSG_ACK,
277 direction, cmd, ASYNC_MSG_ID(pf_to_mgmt));
279 prepare_mgmt_cmd((u8 *)mgmt_cmd, &header, msg, msg_len);
281 chain = pf_to_mgmt->cmd_chain[HINIC_API_CMD_WRITE_ASYNC_TO_MGMT_CPU];
283 return hinic_api_cmd_write(chain, HINIC_NODE_ID_MGMT_HOST, mgmt_cmd,
288 * send_msg_to_mgmt_sync - send async message
289 * @pf_to_mgmt: PF to MGMT channel
290 * @mod: module in the chip that will get the message
291 * @cmd: command of the message
293 * @msg_len: the msg data length
294 * @ack_type: indicate mgmt command whether need ack or not
295 * @direction: the direction of the original message
296 * @resp_msg_id: msg id to response for
297 * Return: 0 - success, negative - failure
299 static int send_msg_to_mgmt_sync(struct hinic_msg_pf_to_mgmt *pf_to_mgmt,
300 enum hinic_mod_type mod, u8 cmd,
301 void *msg, u16 msg_len,
302 enum hinic_msg_ack_type ack_type,
303 enum hinic_msg_direction_type direction,
304 __rte_unused u16 resp_msg_id)
306 void *mgmt_cmd = pf_to_mgmt->sync_msg_buf;
307 struct hinic_api_cmd_chain *chain;
309 u16 cmd_size = mgmt_msg_len(msg_len);
311 if (direction == HINIC_MSG_RESPONSE)
312 prepare_header(pf_to_mgmt, &header, msg_len, mod, ack_type,
313 direction, cmd, resp_msg_id);
315 prepare_header(pf_to_mgmt, &header, msg_len, mod, ack_type,
316 direction, cmd, SYNC_MSG_ID(pf_to_mgmt));
318 prepare_mgmt_cmd((u8 *)mgmt_cmd, &header, msg, msg_len);
320 chain = pf_to_mgmt->cmd_chain[HINIC_API_CMD_PMD_WRITE_TO_MGMT];
322 return hinic_api_cmd_write(chain, HINIC_NODE_ID_MGMT_HOST,
327 * hinic_pf_to_mgmt_init - initialize PF to MGMT channel
328 * @hwdev: the pointer to the private hardware device object
329 * Return: 0 - success, negative - failure
331 static int hinic_pf_to_mgmt_init(struct hinic_hwdev *hwdev)
333 struct hinic_msg_pf_to_mgmt *pf_to_mgmt;
336 pf_to_mgmt = kzalloc(sizeof(*pf_to_mgmt), GFP_KERNEL);
338 PMD_DRV_LOG(ERR, "Allocate pf to mgmt mem failed");
342 hwdev->pf_to_mgmt = pf_to_mgmt;
343 pf_to_mgmt->hwdev = hwdev;
345 err = hinic_mutex_init(&pf_to_mgmt->sync_msg_lock, NULL);
349 err = alloc_msg_buf(pf_to_mgmt);
351 PMD_DRV_LOG(ERR, "Allocate msg buffers failed");
352 goto alloc_msg_buf_err;
355 err = hinic_api_cmd_init(hwdev, pf_to_mgmt->cmd_chain);
357 PMD_DRV_LOG(ERR, "Init the api cmd chains failed");
358 goto api_cmd_init_err;
364 free_msg_buf(pf_to_mgmt);
367 hinic_mutex_destroy(&pf_to_mgmt->sync_msg_lock);
376 * hinic_pf_to_mgmt_free - free PF to MGMT channel
377 * @hwdev: the pointer to the private hardware device object
379 static void hinic_pf_to_mgmt_free(struct hinic_hwdev *hwdev)
381 struct hinic_msg_pf_to_mgmt *pf_to_mgmt = hwdev->pf_to_mgmt;
383 hinic_api_cmd_free(pf_to_mgmt->cmd_chain);
384 free_msg_buf(pf_to_mgmt);
385 hinic_mutex_destroy(&pf_to_mgmt->sync_msg_lock);
390 hinic_pf_to_mgmt_sync(struct hinic_hwdev *hwdev,
391 enum hinic_mod_type mod, u8 cmd, void *buf_in, u16 in_size,
392 void *buf_out, u16 *out_size, u32 timeout)
394 struct hinic_msg_pf_to_mgmt *pf_to_mgmt = hwdev->pf_to_mgmt;
395 struct hinic_recv_msg *recv_msg;
399 pthread_mutex_lock(&pf_to_mgmt->sync_msg_lock);
401 SYNC_MSG_ID_INC(pf_to_mgmt);
402 recv_msg = &pf_to_mgmt->recv_resp_msg_from_mgmt;
404 err = send_msg_to_mgmt_sync(pf_to_mgmt, mod, cmd, buf_in, in_size,
405 HINIC_MSG_ACK, HINIC_MSG_DIRECT_SEND,
408 PMD_DRV_LOG(ERR, "Send msg to mgmt failed");
409 goto unlock_sync_msg;
412 timeo = msecs_to_jiffies(timeout ? timeout : MGMT_MSG_TIMEOUT);
413 for (i = 0; i < pf_to_mgmt->rx_aeq->poll_retry_nr; i++) {
414 err = hinic_aeq_poll_msg(pf_to_mgmt->rx_aeq, timeo, NULL);
416 PMD_DRV_LOG(ERR, "Poll mgmt rsp timeout, mod=%d cmd=%d msg_id=%u rc=%d",
417 mod, cmd, pf_to_mgmt->sync_msg_id, err);
419 hinic_dump_aeq_info(hwdev);
420 goto unlock_sync_msg;
422 if (mod == recv_msg->mod && cmd == recv_msg->cmd &&
423 recv_msg->msg_id == pf_to_mgmt->sync_msg_id) {
424 /* the expected response polled */
427 PMD_DRV_LOG(ERR, "AEQ[%d] poll(mod=%d, cmd=%d, msg_id=%u) an "
428 "unexpected(mod=%d, cmd=%d, msg_id=%u) response",
429 pf_to_mgmt->rx_aeq->q_id, mod, cmd,
430 pf_to_mgmt->sync_msg_id, recv_msg->mod,
431 recv_msg->cmd, recv_msg->msg_id);
435 if (i == pf_to_mgmt->rx_aeq->poll_retry_nr) {
436 PMD_DRV_LOG(ERR, "Get %d unexpected mgmt rsp from AEQ[%d], poll mgmt rsp failed",
437 i, pf_to_mgmt->rx_aeq->q_id);
439 goto unlock_sync_msg;
443 if (recv_msg->msg_len && buf_out && out_size) {
444 if (recv_msg->msg_len <= *out_size) {
445 memcpy(buf_out, recv_msg->msg,
447 *out_size = recv_msg->msg_len;
449 PMD_DRV_LOG(ERR, "Mgmt rsp's msg len:%u overflow.",
458 pthread_mutex_unlock(&pf_to_mgmt->sync_msg_lock);
462 static int hinic_get_mgmt_channel_status(void *hwdev)
464 struct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif;
467 val = hinic_hwif_read_reg(hwif, HINIC_ICPL_RESERVD_ADDR);
469 return HINIC_GET_MGMT_CHANNEL_STATUS(val, MGMT_CHANNEL_STATUS);
472 int hinic_msg_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd,
473 void *buf_in, u16 in_size,
474 void *buf_out, u16 *out_size, u32 timeout)
476 int rc = HINIC_ERROR;
478 if (!hwdev || in_size > HINIC_MSG_TO_MGMT_MAX_LEN)
481 /* If status is hot upgrading, don't send message to mgmt */
482 if (hinic_get_mgmt_channel_status(hwdev))
485 rc = hinic_pf_to_mgmt_sync(hwdev, mod, cmd, buf_in,
486 in_size, buf_out, out_size,
492 int hinic_msg_to_mgmt_no_ack(void *hwdev, enum hinic_mod_type mod, u8 cmd,
493 void *buf_in, u16 in_size, __rte_unused void *buf_out,
494 __rte_unused u16 *out_size)
496 struct hinic_msg_pf_to_mgmt *pf_to_mgmt =
497 ((struct hinic_hwdev *)hwdev)->pf_to_mgmt;
500 if (!MSG_SZ_IS_VALID(in_size)) {
501 PMD_DRV_LOG(ERR, "Mgmt msg buffer size is invalid");
505 pthread_mutex_lock(&pf_to_mgmt->sync_msg_lock);
507 err = send_msg_to_mgmt_sync(pf_to_mgmt, mod, cmd, buf_in, in_size,
508 HINIC_MSG_NO_ACK, HINIC_MSG_DIRECT_SEND,
511 pthread_mutex_unlock(&pf_to_mgmt->sync_msg_lock);
516 static bool check_mgmt_seq_id_and_seg_len(struct hinic_recv_msg *recv_msg,
517 u8 seq_id, u8 seg_len)
519 if (seq_id > HINIC_SEQ_ID_MAX_VAL || seg_len > HINIC_MSG_SEG_LEN)
523 recv_msg->sed_id = seq_id;
525 if (seq_id != recv_msg->sed_id + 1) {
526 recv_msg->sed_id = 0;
529 recv_msg->sed_id = seq_id;
536 * hinic_mgmt_recv_msg_handler - handler for message from mgmt cpu
537 * @pf_to_mgmt: PF to MGMT channel
538 * @recv_msg: received message details
539 * @param: customized parameter
541 static void hinic_mgmt_recv_msg_handler(struct hinic_msg_pf_to_mgmt *pf_to_mgmt,
542 struct hinic_recv_msg *recv_msg,
545 void *buf_out = recv_msg->buf_out;
548 switch (recv_msg->mod) {
550 hinic_comm_async_event_handle(pf_to_mgmt->hwdev,
551 recv_msg->cmd, recv_msg->msg,
555 case HINIC_MOD_L2NIC:
556 hinic_l2nic_async_event_handle(pf_to_mgmt->hwdev, param,
557 recv_msg->cmd, recv_msg->msg,
561 case HINIC_MOD_HILINK:
562 hinic_hilink_async_event_handle(pf_to_mgmt->hwdev,
563 recv_msg->cmd, recv_msg->msg,
568 PMD_DRV_LOG(ERR, "No handler, mod = %d", recv_msg->mod);
572 if (!recv_msg->async_mgmt_to_pf) {
574 out_size = BUF_OUT_DEFAULT_SIZE;
576 /* MGMT sent sync msg, send the response */
577 (void)send_msg_to_mgmt_async(pf_to_mgmt, recv_msg->mod,
578 recv_msg->cmd, buf_out, out_size,
585 * recv_mgmt_msg_handler - handler a message from mgmt cpu
586 * @pf_to_mgmt: PF to MGMT channel
587 * @header: the header of the message
588 * @recv_msg: received message details
589 * @param: customized parameter
590 * Return: 0 when aeq is response message, -1 default result,
591 * and when wrong message or not last message
593 static int recv_mgmt_msg_handler(struct hinic_msg_pf_to_mgmt *pf_to_mgmt,
594 u8 *header, struct hinic_recv_msg *recv_msg,
597 u64 msg_header = *((u64 *)header);
598 void *msg_body = header + sizeof(msg_header);
601 u32 msg_buf_max = MAX_PF_MGMT_BUF_SIZE;
603 seq_id = HINIC_MSG_HEADER_GET(msg_header, SEQID);
604 seq_len = HINIC_MSG_HEADER_GET(msg_header, SEG_LEN);
606 if (!check_mgmt_seq_id_and_seg_len(recv_msg, seq_id, seq_len)) {
608 "Mgmt msg sequence and segment check fail, "
609 "func id: 0x%x, front id: 0x%x, current id: 0x%x, seg len: 0x%x",
610 hinic_global_func_id(pf_to_mgmt->hwdev),
611 recv_msg->sed_id, seq_id, seq_len);
612 return HINIC_RECV_NEXT_AEQE;
615 dest_msg = (u8 *)recv_msg->msg + seq_id * HINIC_MSG_SEG_LEN;
616 msg_buf_max -= seq_id * HINIC_MSG_SEG_LEN;
617 memcpy(dest_msg, msg_body, seq_len);
619 if (!HINIC_MSG_HEADER_GET(msg_header, LAST))
620 return HINIC_RECV_NEXT_AEQE;
622 recv_msg->cmd = HINIC_MSG_HEADER_GET(msg_header, CMD);
623 recv_msg->mod = HINIC_MSG_HEADER_GET(msg_header, MODULE);
624 recv_msg->async_mgmt_to_pf = HINIC_MSG_HEADER_GET(msg_header,
626 recv_msg->msg_len = HINIC_MSG_HEADER_GET(msg_header, MSG_LEN);
627 recv_msg->msg_id = HINIC_MSG_HEADER_GET(msg_header, MSG_ID);
629 if (HINIC_MSG_HEADER_GET(msg_header, DIRECTION) == HINIC_MSG_RESPONSE)
630 return HINIC_RECV_DONE;
632 hinic_mgmt_recv_msg_handler(pf_to_mgmt, recv_msg, param);
634 return HINIC_RECV_NEXT_AEQE;
638 * hinic_mgmt_msg_aeqe_handler - handler for a mgmt message event
639 * @hwdev: the pointer to the private hardware device object
640 * @header: the header of the message
642 * @param: customized parameter
643 * Return: 0 when aeq is response message,
644 * -1 default result, and when wrong message or not last message
646 static int hinic_mgmt_msg_aeqe_handler(void *hwdev, u8 *header,
647 __rte_unused u8 size, void *param)
649 struct hinic_msg_pf_to_mgmt *pf_to_mgmt =
650 ((struct hinic_hwdev *)hwdev)->pf_to_mgmt;
651 struct hinic_recv_msg *recv_msg;
653 recv_msg = (HINIC_MSG_HEADER_GET(*(u64 *)header, DIRECTION) ==
654 HINIC_MSG_DIRECT_SEND) ?
655 &pf_to_mgmt->recv_msg_from_mgmt :
656 &pf_to_mgmt->recv_resp_msg_from_mgmt;
658 return recv_mgmt_msg_handler(pf_to_mgmt, header, recv_msg, param);
661 static int hinic_handle_aeqe(void *handle, enum hinic_aeq_type event,
662 u8 *data, u8 size, void *param)
667 case HINIC_MSG_FROM_MGMT_CPU:
668 rc = hinic_mgmt_msg_aeqe_handler(handle, data, size, param);
671 PMD_DRV_LOG(ERR, "Unknown event type: 0x%x, size: %d",
673 rc = HINIC_RECV_NEXT_AEQE;
681 * hinic_aeq_poll_msg - poll one or continue aeqe, and call dedicated process
682 * @eq: aeq of the chip
683 * @timeout: 0 - poll all aeqe in eq, used in interrupt mode,
684 * > 0 - poll aeq until get aeqe with 'last' field set to 1,
685 * used in polling mode.
686 * @param: customized parameter
687 * Return: 0 - Success, EIO - poll timeout, ENODEV - swe not support
689 int hinic_aeq_poll_msg(struct hinic_eq *eq, u32 timeout, void *param)
691 struct hinic_aeq_elem *aeqe_pos;
692 enum hinic_aeq_type event;
696 int done = HINIC_ERROR;
700 for (i = 0; ((timeout == 0) && (i < eq->eq_len)) ||
701 ((timeout > 0) && (done != HINIC_OK) && (i < eq->eq_len)); i++) {
703 end = jiffies + msecs_to_jiffies(timeout);
705 aeqe_pos = GET_CURR_AEQ_ELEM(eq);
708 /* Data in HW is in Big endian Format */
709 aeqe_desc = be32_to_cpu(aeqe_pos->desc);
711 /* HW updates wrapped bit,
712 * when it adds eq element event
714 if (EQ_ELEM_DESC_GET(aeqe_desc, WRAPPED)
722 } while (time_before(jiffies, end));
724 if (err != HINIC_OK) /*poll time out*/
727 event = EQ_ELEM_DESC_GET(aeqe_desc, TYPE);
728 if (EQ_ELEM_DESC_GET(aeqe_desc, SRC)) {
729 PMD_DRV_LOG(ERR, "AEQ sw event not support %d",
734 size = EQ_ELEM_DESC_GET(aeqe_desc, SIZE);
735 done = hinic_handle_aeqe(eq->hwdev, event,
741 if (eq->cons_idx == eq->eq_len) {
743 eq->wrapped = !eq->wrapped;
752 int hinic_comm_pf_to_mgmt_init(struct hinic_hwdev *hwdev)
756 rc = hinic_pf_to_mgmt_init(hwdev);
760 hwdev->pf_to_mgmt->rx_aeq = &hwdev->aeqs->aeq[HINIC_MGMT_RSP_AEQN];
765 void hinic_comm_pf_to_mgmt_free(struct hinic_hwdev *hwdev)
767 hinic_pf_to_mgmt_free(hwdev);
770 void hinic_dev_handle_aeq_event(struct hinic_hwdev *hwdev, void *param)
772 struct hinic_eq *aeq = &hwdev->aeqs->aeq[0];
774 /* clear resend timer cnt register */
775 hinic_misx_intr_clear_resend_bit(hwdev, aeq->eq_irq.msix_entry_idx,
776 EQ_MSIX_RESEND_TIMER_CLEAR);
777 (void)hinic_aeq_poll_msg(aeq, 0, param);