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_eqs.h"
10 #include "hinic_pmd_mgmt.h"
11 #include "hinic_pmd_mbox.h"
13 #define HINIC_MBOX_INT_DST_FUNC_SHIFT 0
14 #define HINIC_MBOX_INT_DST_AEQN_SHIFT 10
15 #define HINIC_MBOX_INT_SRC_RESP_AEQN_SHIFT 12
16 #define HINIC_MBOX_INT_STAT_DMA_SHIFT 14
17 /* The size of data to be send (unit of 4 bytes) */
18 #define HINIC_MBOX_INT_TX_SIZE_SHIFT 20
19 /* SO_RO(strong order, relax order) */
20 #define HINIC_MBOX_INT_STAT_DMA_SO_RO_SHIFT 25
21 #define HINIC_MBOX_INT_WB_EN_SHIFT 28
24 #define HINIC_MBOX_INT_DST_FUNC_MASK 0x3FF
25 #define HINIC_MBOX_INT_DST_AEQN_MASK 0x3
26 #define HINIC_MBOX_INT_SRC_RESP_AEQN_MASK 0x3
27 #define HINIC_MBOX_INT_STAT_DMA_MASK 0x3F
28 #define HINIC_MBOX_INT_TX_SIZE_MASK 0x1F
29 #define HINIC_MBOX_INT_STAT_DMA_SO_RO_MASK 0x3
30 #define HINIC_MBOX_INT_WB_EN_MASK 0x1
32 #define HINIC_MBOX_INT_SET(val, field) \
33 (((val) & HINIC_MBOX_INT_##field##_MASK) << \
34 HINIC_MBOX_INT_##field##_SHIFT)
36 enum hinic_mbox_tx_status {
41 #define HINIC_MBOX_CTRL_TRIGGER_AEQE_SHIFT 0
42 /* specifies the issue request for the message data.
43 * 0 - Tx request is done;
44 * 1 - Tx request is in process.
46 #define HINIC_MBOX_CTRL_TX_STATUS_SHIFT 1
48 #define HINIC_MBOX_CTRL_TRIGGER_AEQE_MASK 0x1
49 #define HINIC_MBOX_CTRL_TX_STATUS_MASK 0x1
51 #define HINIC_MBOX_CTRL_SET(val, field) \
52 (((val) & HINIC_MBOX_CTRL_##field##_MASK) << \
53 HINIC_MBOX_CTRL_##field##_SHIFT)
55 #define HINIC_MBOX_HEADER_MSG_LEN_SHIFT 0
56 #define HINIC_MBOX_HEADER_MODULE_SHIFT 11
57 #define HINIC_MBOX_HEADER_SEG_LEN_SHIFT 16
58 #define HINIC_MBOX_HEADER_NO_ACK_SHIFT 22
59 #define HINIC_MBOX_HEADER_SEQID_SHIFT 24
60 #define HINIC_MBOX_HEADER_LAST_SHIFT 30
62 #define HINIC_MBOX_HEADER_DIRECTION_SHIFT 31
63 #define HINIC_MBOX_HEADER_CMD_SHIFT 32
64 #define HINIC_MBOX_HEADER_MSG_ID_SHIFT 40
65 #define HINIC_MBOX_HEADER_STATUS_SHIFT 48
66 #define HINIC_MBOX_HEADER_SRC_GLB_FUNC_IDX_SHIFT 54
68 #define HINIC_MBOX_HEADER_MSG_LEN_MASK 0x7FF
69 #define HINIC_MBOX_HEADER_MODULE_MASK 0x1F
70 #define HINIC_MBOX_HEADER_SEG_LEN_MASK 0x3F
71 #define HINIC_MBOX_HEADER_NO_ACK_MASK 0x1
72 #define HINIC_MBOX_HEADER_SEQID_MASK 0x3F
73 #define HINIC_MBOX_HEADER_LAST_MASK 0x1
74 #define HINIC_MBOX_HEADER_DIRECTION_MASK 0x1
75 #define HINIC_MBOX_HEADER_CMD_MASK 0xFF
76 #define HINIC_MBOX_HEADER_MSG_ID_MASK 0xFF
77 #define HINIC_MBOX_HEADER_STATUS_MASK 0x3F
78 #define HINIC_MBOX_HEADER_SRC_GLB_FUNC_IDX_MASK 0x3FF
80 #define HINIC_MBOX_HEADER_GET(val, field) \
81 (((val) >> HINIC_MBOX_HEADER_##field##_SHIFT) & \
82 HINIC_MBOX_HEADER_##field##_MASK)
83 #define HINIC_MBOX_HEADER_SET(val, field) \
84 ((u64)((val) & HINIC_MBOX_HEADER_##field##_MASK) << \
85 HINIC_MBOX_HEADER_##field##_SHIFT)
87 #define HINIC_MBOX_COMP_TIME_MS 8000U
88 #define MBOX_MSG_POLLING_TIMEOUT_MS 5000
90 /* The size unit is Bytes */
91 #define HINIC_MBOX_DATA_SIZE 2040
92 #define MBOX_MAX_BUF_SZ 2048UL
93 #define MBOX_HEADER_SZ 8
95 /* MBOX size is 64B, 8B for mbox_header, 4B reserved */
96 #define MBOX_SEG_LEN 48
97 #define MBOX_SEG_LEN_ALIGN 4
98 #define MBOX_WB_STATUS_LEN 16UL
101 /* mbox write back status is 16B, only first 4B is used */
102 #define MBOX_WB_STATUS_ERRCODE_MASK 0xFFFF
103 #define MBOX_WB_STATUS_MASK 0xFF
104 #define MBOX_WB_ERROR_CODE_MASK 0xFF00
105 #define MBOX_WB_STATUS_FINISHED_SUCCESS 0xFF
106 #define MBOX_WB_STATUS_FINISHED_WITH_ERR 0xFE
107 #define MBOX_WB_STATUS_NOT_FINISHED 0x00
109 #define MBOX_STATUS_FINISHED(wb) \
110 (((wb) & MBOX_WB_STATUS_MASK) != MBOX_WB_STATUS_NOT_FINISHED)
111 #define MBOX_STATUS_SUCCESS(wb) \
112 (((wb) & MBOX_WB_STATUS_MASK) == MBOX_WB_STATUS_FINISHED_SUCCESS)
113 #define MBOX_STATUS_ERRCODE(wb) \
114 ((wb) & MBOX_WB_ERROR_CODE_MASK)
116 #define SEQ_ID_START_VAL 0
118 #define DST_AEQ_IDX_DEFAULT_VAL 0
119 #define SRC_AEQ_IDX_DEFAULT_VAL 0
120 #define NO_DMA_ATTRIBUTE_VAL 0
122 #define MBOX_MSG_NO_DATA_LEN 1
124 #define FUNC_ID_OFF_SET_8B 8
125 #define FUNC_ID_OFF_SET_10B 10
127 #define MBOX_BODY_FROM_HDR(header) ((u8 *)(header) + MBOX_HEADER_SZ)
128 #define MBOX_AREA(hwif) \
129 ((hwif)->cfg_regs_base + HINIC_FUNC_CSR_MAILBOX_DATA_OFF)
131 #define MBOX_RESPONSE_ERROR 0x1
132 #define MBOX_MSG_ID_MASK 0xFF
133 #define MBOX_MSG_ID(func_to_func) ((func_to_func)->send_msg_id)
135 enum hinic_hwif_direction_type {
136 /* driver send msg to up or up send msg to driver*/
137 HINIC_HWIF_DIRECT_SEND = 0,
138 /* after driver/up send msg to each other, then up/driver ack the msg */
143 MBOX_SEND_MSG_POLL = 1
151 enum mbox_ordering_type {
156 enum mbox_write_back_type {
161 enum mbox_aeq_trig_type {
166 static int send_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func,
167 enum hinic_mod_type mod, u16 cmd, void *msg,
168 u16 msg_len, u16 dst_func,
169 enum hinic_hwif_direction_type direction,
170 enum hinic_mbox_ack_type ack_type,
171 struct mbox_msg_info *msg_info);
173 static int recv_vf_mbox_handler(struct hinic_mbox_func_to_func *func_to_func,
174 struct hinic_recv_mbox *recv_mbox,
175 void *buf_out, u16 *out_size, void *param)
180 switch (recv_mbox->mod) {
182 hinic_comm_async_event_handle(func_to_func->hwdev,
183 recv_mbox->cmd, recv_mbox->mbox,
187 case HINIC_MOD_L2NIC:
188 hinic_l2nic_async_event_handle(func_to_func->hwdev, param,
189 recv_mbox->cmd, recv_mbox->mbox,
194 PMD_DRV_LOG(ERR, "No handler, mod: %d", recv_mbox->mod);
195 rc = HINIC_MBOX_VF_CMD_ERROR;
202 static void set_mbx_msg_status(struct mbox_msg_info *msg_info, int status)
204 if (status == HINIC_DEV_BUSY_ACTIVE_FW)
205 msg_info->status = HINIC_MBOX_PF_BUSY_ACTIVE_FW;
206 else if (status == HINIC_MBOX_VF_CMD_ERROR)
207 msg_info->status = HINIC_MBOX_VF_CMD_ERROR;
209 msg_info->status = HINIC_MBOX_PF_SEND_ERR;
212 static void recv_func_mbox_handler(struct hinic_mbox_func_to_func *func_to_func,
213 struct hinic_recv_mbox *recv_mbox,
214 u16 src_func_idx, void *param)
216 struct hinic_hwdev *dev = func_to_func->hwdev;
217 struct mbox_msg_info msg_info = { 0 };
218 u16 out_size = MBOX_MAX_BUF_SZ;
219 void *buf_out = recv_mbox->buf_out;
222 if (HINIC_IS_VF(dev)) {
223 err = recv_vf_mbox_handler(func_to_func, recv_mbox, buf_out,
227 PMD_DRV_LOG(ERR, "PMD doesn't support non-VF handle mailbox message");
230 if (!out_size || err)
231 out_size = MBOX_MSG_NO_DATA_LEN;
233 if (recv_mbox->ack_type == MBOX_ACK) {
234 msg_info.msg_id = recv_mbox->msg_info.msg_id;
235 set_mbx_msg_status(&msg_info, err);
236 send_mbox_to_func(func_to_func, recv_mbox->mod, recv_mbox->cmd,
237 buf_out, out_size, src_func_idx,
238 HINIC_HWIF_RESPONSE, MBOX_ACK, &msg_info);
242 static bool check_mbox_seq_id_and_seg_len(struct hinic_recv_mbox *recv_mbox,
243 u8 seq_id, u8 seg_len)
245 if (seq_id > HINIC_SEQ_ID_MAX_VAL || seg_len > HINIC_MSG_SEG_LEN)
249 recv_mbox->sed_id = seq_id;
251 if (seq_id != recv_mbox->sed_id + 1) {
252 recv_mbox->sed_id = 0;
256 recv_mbox->sed_id = seq_id;
262 static void clear_mbox_status(struct hinic_send_mbox *mbox)
264 /* clear mailbox write back status */
265 *mbox->wb_status = 0;
269 static void mbox_copy_header(struct hinic_send_mbox *mbox, u64 *header)
271 u32 *data = (u32 *)header;
272 u32 i, idx_max = MBOX_HEADER_SZ / sizeof(u32);
274 for (i = 0; i < idx_max; i++)
275 __raw_writel(*(data + i), mbox->data + i * sizeof(u32));
279 mbox_copy_send_data(struct hinic_send_mbox *mbox, void *seg, u16 seg_len)
281 u32 *data = (u32 *)seg;
282 u32 data_len, chk_sz = sizeof(u32);
284 u8 mbox_max_buf[MBOX_SEG_LEN] = {0};
286 /* The mbox message should be aligned in 4 bytes. */
287 if (seg_len % chk_sz) {
288 memcpy(mbox_max_buf, seg, seg_len);
289 data = (u32 *)mbox_max_buf;
293 idx_max = ALIGN(data_len, chk_sz) / chk_sz;
295 for (i = 0; i < idx_max; i++)
296 __raw_writel(*(data + i),
297 mbox->data + MBOX_HEADER_SZ + i * sizeof(u32));
300 static int mbox_msg_ack_aeqn(struct hinic_hwdev *hwdev)
302 u16 aeq_num = HINIC_HWIF_NUM_AEQS(hwdev->hwif);
305 if (aeq_num >= HINIC_MAX_AEQS - 1) {
306 msg_ack_aeqn = HINIC_AEQN_2;
307 } else if (aeq_num == HINIC_MIN_AEQS) {
308 /* This is used for ovs */
309 msg_ack_aeqn = HINIC_AEQN_1;
311 PMD_DRV_LOG(ERR, "Warning: Invalid aeq num: %d\n", aeq_num);
318 static u16 mbox_msg_dst_aeqn(struct hinic_hwdev *hwdev,
319 enum hinic_hwif_direction_type seq_dir)
323 if (seq_dir == HINIC_HWIF_DIRECT_SEND)
324 dst_aeqn = HINIC_AEQN_0;
326 dst_aeqn = mbox_msg_ack_aeqn(hwdev);
331 static int mbox_seg_ack_aeqn(struct hinic_hwdev *hwdev)
333 return mbox_msg_ack_aeqn(hwdev);
336 static void write_mbox_msg_attr(struct hinic_mbox_func_to_func *func_to_func,
337 u16 dst_func, u16 dst_aeqn, u16 seg_ack_aeqn,
338 __rte_unused u16 seg_len, int poll)
340 u32 mbox_int, mbox_ctrl;
342 mbox_int = HINIC_MBOX_INT_SET(dst_func, DST_FUNC) |
343 HINIC_MBOX_INT_SET(dst_aeqn, DST_AEQN) |
344 /* N/A in polling mode */
345 HINIC_MBOX_INT_SET(seg_ack_aeqn, SRC_RESP_AEQN) |
346 HINIC_MBOX_INT_SET(NO_DMA_ATTRIBUTE_VAL, STAT_DMA) |
347 HINIC_MBOX_INT_SET(ALIGN(MBOX_SIZE, MBOX_SEG_LEN_ALIGN) >> 2,
349 HINIC_MBOX_INT_SET(STRONG_ORDER, STAT_DMA_SO_RO) |
350 HINIC_MBOX_INT_SET(WRITE_BACK, WB_EN);
352 hinic_hwif_write_reg(func_to_func->hwdev->hwif,
353 HINIC_FUNC_CSR_MAILBOX_INT_OFFSET_OFF, mbox_int);
356 mbox_ctrl = HINIC_MBOX_CTRL_SET(TX_IN_PROGRESS, TX_STATUS);
359 mbox_ctrl |= HINIC_MBOX_CTRL_SET(NOT_TRIGGER, TRIGGER_AEQE);
361 mbox_ctrl |= HINIC_MBOX_CTRL_SET(TRIGGER, TRIGGER_AEQE);
363 hinic_hwif_write_reg(func_to_func->hwdev->hwif,
364 HINIC_FUNC_CSR_MAILBOX_CONTROL_OFF, mbox_ctrl);
367 static int init_mbox_info(struct hinic_recv_mbox *mbox_info)
371 mbox_info->mbox = kzalloc(MBOX_MAX_BUF_SZ, GFP_KERNEL);
372 if (!mbox_info->mbox) {
373 PMD_DRV_LOG(ERR, "Alloc mbox buf_in mem failed\n");
377 mbox_info->buf_out = kzalloc(MBOX_MAX_BUF_SZ, GFP_KERNEL);
378 if (!mbox_info->buf_out) {
379 PMD_DRV_LOG(ERR, "Alloc mbox buf_out mem failed\n");
381 goto alloc_buf_out_err;
387 kfree(mbox_info->mbox);
392 static void clean_mbox_info(struct hinic_recv_mbox *mbox_info)
394 kfree(mbox_info->buf_out);
395 kfree(mbox_info->mbox);
398 static int alloc_mbox_info(struct hinic_recv_mbox *mbox_info)
403 for (func_idx = 0; func_idx < HINIC_MAX_FUNCTIONS; func_idx++) {
404 err = init_mbox_info(&mbox_info[func_idx]);
406 PMD_DRV_LOG(ERR, "Initialize function[%d] mailbox information failed, err: %d",
408 goto init_mbox_info_err;
415 for (i = 0; i < func_idx; i++)
416 clean_mbox_info(&mbox_info[i]);
421 static void free_mbox_info(struct hinic_recv_mbox *mbox_info)
425 for (func_idx = 0; func_idx < HINIC_MAX_FUNCTIONS; func_idx++)
426 clean_mbox_info(&mbox_info[func_idx]);
429 static void prepare_send_mbox(struct hinic_mbox_func_to_func *func_to_func)
431 struct hinic_send_mbox *send_mbox = &func_to_func->send_mbox;
433 send_mbox->data = MBOX_AREA(func_to_func->hwdev->hwif);
436 static int alloc_mbox_wb_status(struct hinic_mbox_func_to_func *func_to_func)
438 struct hinic_send_mbox *send_mbox = &func_to_func->send_mbox;
439 struct hinic_hwdev *hwdev = func_to_func->hwdev;
440 struct hinic_hwif *hwif = hwdev->hwif;
443 send_mbox->wb_vaddr = dma_zalloc_coherent(hwdev, MBOX_WB_STATUS_LEN,
444 &send_mbox->wb_paddr, SOCKET_ID_ANY);
445 if (!send_mbox->wb_vaddr) {
446 PMD_DRV_LOG(ERR, "Allocating memory for mailbox wb status failed");
449 send_mbox->wb_status = (volatile u64 *)send_mbox->wb_vaddr;
451 addr_h = upper_32_bits(send_mbox->wb_paddr);
452 addr_l = lower_32_bits(send_mbox->wb_paddr);
453 hinic_hwif_write_reg(hwif, HINIC_FUNC_CSR_MAILBOX_RESULT_H_OFF, addr_h);
454 hinic_hwif_write_reg(hwif, HINIC_FUNC_CSR_MAILBOX_RESULT_L_OFF, addr_l);
459 static void free_mbox_wb_status(struct hinic_mbox_func_to_func *func_to_func)
461 struct hinic_send_mbox *send_mbox = &func_to_func->send_mbox;
462 struct hinic_hwdev *hwdev = func_to_func->hwdev;
463 struct hinic_hwif *hwif = hwdev->hwif;
465 hinic_hwif_write_reg(hwif, HINIC_FUNC_CSR_MAILBOX_RESULT_H_OFF, 0);
466 hinic_hwif_write_reg(hwif, HINIC_FUNC_CSR_MAILBOX_RESULT_L_OFF, 0);
468 dma_free_coherent(hwdev, MBOX_WB_STATUS_LEN,
469 send_mbox->wb_vaddr, send_mbox->wb_paddr);
472 static int recv_mbox_handler(struct hinic_mbox_func_to_func *func_to_func,
473 void *header, struct hinic_recv_mbox *recv_mbox, void *param)
475 u64 mbox_header = *((u64 *)header);
476 void *mbox_body = MBOX_BODY_FROM_HDR(header);
478 enum hinic_hwif_direction_type direction;
481 seq_id = HINIC_MBOX_HEADER_GET(mbox_header, SEQID);
482 seg_len = HINIC_MBOX_HEADER_GET(mbox_header, SEG_LEN);
483 direction = HINIC_MBOX_HEADER_GET(mbox_header, DIRECTION);
484 src_func_idx = HINIC_MBOX_HEADER_GET(mbox_header, SRC_GLB_FUNC_IDX);
486 if (!check_mbox_seq_id_and_seg_len(recv_mbox, seq_id, seg_len)) {
488 "Mailbox sequence and segment check failed, src func id: 0x%x, front id: 0x%x, current id: 0x%x, seg len: 0x%x\n",
489 src_func_idx, recv_mbox->sed_id, seq_id, seg_len);
493 memcpy((u8 *)recv_mbox->mbox + seq_id * HINIC_MSG_SEG_LEN,
496 if (!HINIC_MBOX_HEADER_GET(mbox_header, LAST))
499 recv_mbox->sed_id = 0;
500 recv_mbox->cmd = HINIC_MBOX_HEADER_GET(mbox_header, CMD);
501 recv_mbox->mod = HINIC_MBOX_HEADER_GET(mbox_header, MODULE);
502 recv_mbox->mbox_len = HINIC_MBOX_HEADER_GET(mbox_header, MSG_LEN);
503 recv_mbox->ack_type = HINIC_MBOX_HEADER_GET(mbox_header, NO_ACK);
504 recv_mbox->msg_info.msg_id = HINIC_MBOX_HEADER_GET(mbox_header, MSG_ID);
505 recv_mbox->msg_info.status = HINIC_MBOX_HEADER_GET(mbox_header, STATUS);
507 if (direction == HINIC_HWIF_RESPONSE) {
508 if (recv_mbox->msg_info.msg_id == func_to_func->send_msg_id &&
509 func_to_func->event_flag == EVENT_START) {
513 PMD_DRV_LOG(ERR, "Mbox response timeout, current send msg id(0x%x), recv msg id(0x%x), status(0x%x)",
514 func_to_func->send_msg_id, recv_mbox->msg_info.msg_id,
515 recv_mbox->msg_info.status);
519 recv_func_mbox_handler(func_to_func, recv_mbox, src_func_idx, param);
525 * hinic_mbox_func_aeqe_handler - Process mbox info from func which is
529 * Pointer to hradware nic device.
533 * The size of aeqe descriptor.
535 * customized parameter.
538 * 0 on success, negative error value otherwise.
540 int hinic_mbox_func_aeqe_handler(void *handle, u8 *header,
541 __rte_unused u8 size, void *param)
543 struct hinic_mbox_func_to_func *func_to_func =
544 ((struct hinic_hwdev *)handle)->func_to_func;
545 struct hinic_recv_mbox *recv_mbox;
546 u64 mbox_header = *((u64 *)header);
547 u16 src = HINIC_MBOX_HEADER_GET(mbox_header, SRC_GLB_FUNC_IDX);
549 if (src >= HINIC_MAX_FUNCTIONS) {
550 PMD_DRV_LOG(ERR, "Mailbox source function id: %d is invalid",
555 recv_mbox = (HINIC_MBOX_HEADER_GET(mbox_header, DIRECTION) ==
556 HINIC_HWIF_DIRECT_SEND) ?
557 &func_to_func->mbox_send[src] :
558 &func_to_func->mbox_resp[src];
560 return recv_mbox_handler(func_to_func, (u64 *)header, recv_mbox, param);
563 static u16 get_mbox_status(struct hinic_send_mbox *mbox)
565 /* write back is 16B, but only use first 4B */
566 u64 wb_val = be64_to_cpu(*mbox->wb_status);
568 rte_rmb(); /* verify reading before check */
570 return (u16)(wb_val & MBOX_WB_STATUS_ERRCODE_MASK);
573 static void dump_mox_reg(struct hinic_hwdev *hwdev)
577 val = hinic_hwif_read_reg(hwdev->hwif,
578 HINIC_FUNC_CSR_MAILBOX_CONTROL_OFF);
579 PMD_DRV_LOG(WARNING, "Mailbox control reg: 0x%x", val);
580 val = hinic_hwif_read_reg(hwdev->hwif,
581 HINIC_FUNC_CSR_MAILBOX_INT_OFFSET_OFF);
582 PMD_DRV_LOG(WARNING, "Mailbox interrupt offset: 0x%x", val);
585 static int send_mbox_seg(struct hinic_mbox_func_to_func *func_to_func,
586 u64 header, u16 dst_func, void *seg, u16 seg_len)
588 struct hinic_send_mbox *send_mbox = &func_to_func->send_mbox;
589 struct hinic_hwdev *hwdev = func_to_func->hwdev;
590 u16 seq_dir = HINIC_MBOX_HEADER_GET(header, DIRECTION);
591 u16 dst_aeqn, seg_ack_aeqn;
592 u16 err_code, wb_status = 0;
595 dst_aeqn = mbox_msg_dst_aeqn(hwdev, seq_dir);
596 seg_ack_aeqn = mbox_seg_ack_aeqn(hwdev);
598 clear_mbox_status(send_mbox);
600 mbox_copy_header(send_mbox, &header);
602 mbox_copy_send_data(send_mbox, seg, seg_len);
604 write_mbox_msg_attr(func_to_func, dst_func, dst_aeqn, seg_ack_aeqn,
605 seg_len, MBOX_SEND_MSG_POLL);
609 while (cnt < MBOX_MSG_POLLING_TIMEOUT_MS) {
610 wb_status = get_mbox_status(send_mbox);
611 if (MBOX_STATUS_FINISHED(wb_status))
614 rte_delay_ms(1); /* loop every ms */
618 if (cnt == MBOX_MSG_POLLING_TIMEOUT_MS) {
619 PMD_DRV_LOG(ERR, "Send mailbox segment timeout, wb status: 0x%x",
625 if (!MBOX_STATUS_SUCCESS(wb_status)) {
626 PMD_DRV_LOG(ERR, "Send mailbox segment to function %d error, wb status: 0x%x",
627 dst_func, wb_status);
629 * err_code: 0 responses no errors, other values can
632 err_code = MBOX_STATUS_ERRCODE(wb_status);
633 return err_code ? err_code : -EFAULT;
639 static void set_mbox_to_func_event(struct hinic_mbox_func_to_func *func_to_func,
640 enum mbox_event_state event_flag)
642 spin_lock(&func_to_func->mbox_lock);
643 func_to_func->event_flag = event_flag;
644 spin_unlock(&func_to_func->mbox_lock);
647 static int send_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func,
648 enum hinic_mod_type mod, u16 cmd, void *msg,
649 u16 msg_len, u16 dst_func,
650 enum hinic_hwif_direction_type direction,
651 enum hinic_mbox_ack_type ack_type,
652 struct mbox_msg_info *msg_info)
654 struct hinic_hwdev *hwdev = func_to_func->hwdev;
657 u16 seg_len = HINIC_MSG_SEG_LEN;
659 u8 *msg_seg = (u8 *)msg;
662 err = hinic_mutex_lock(&func_to_func->msg_send_mutex);
666 header = HINIC_MBOX_HEADER_SET(msg_len, MSG_LEN) |
667 HINIC_MBOX_HEADER_SET(mod, MODULE) |
668 HINIC_MBOX_HEADER_SET(seg_len, SEG_LEN) |
669 HINIC_MBOX_HEADER_SET(ack_type, NO_ACK) |
670 HINIC_MBOX_HEADER_SET(SEQ_ID_START_VAL, SEQID) |
671 HINIC_MBOX_HEADER_SET(NOT_LAST_SEG, LAST) |
672 HINIC_MBOX_HEADER_SET(direction, DIRECTION) |
673 HINIC_MBOX_HEADER_SET(cmd, CMD) |
674 HINIC_MBOX_HEADER_SET(msg_info->msg_id, MSG_ID) |
675 HINIC_MBOX_HEADER_SET(msg_info->status, STATUS) |
676 HINIC_MBOX_HEADER_SET(hinic_global_func_id(hwdev),
679 while (!(HINIC_MBOX_HEADER_GET(header, LAST))) {
680 if (left <= HINIC_MSG_SEG_LEN) {
682 ~(HINIC_MBOX_HEADER_SET(HINIC_MBOX_HEADER_SEG_LEN_MASK,
684 header |= HINIC_MBOX_HEADER_SET(left, SEG_LEN);
685 header |= HINIC_MBOX_HEADER_SET(LAST_SEG, LAST);
690 err = send_mbox_seg(func_to_func, header, dst_func, msg_seg,
693 PMD_DRV_LOG(ERR, "Fail to send mbox seg, err: %d", err);
697 left -= HINIC_MSG_SEG_LEN;
698 msg_seg += HINIC_MSG_SEG_LEN;
701 header &= ~(HINIC_MBOX_HEADER_SET(HINIC_MBOX_HEADER_SEQID_MASK,
703 header |= HINIC_MBOX_HEADER_SET(seq_id, SEQID);
707 (void)hinic_mutex_unlock(&func_to_func->msg_send_mutex);
712 static int hinic_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func,
713 enum hinic_mod_type mod, u16 cmd, u16 dst_func,
714 void *buf_in, u16 in_size, void *buf_out, u16 *out_size,
717 struct hinic_recv_mbox *mbox_for_resp =
718 &func_to_func->mbox_resp[dst_func];
719 struct mbox_msg_info msg_info = {0};
723 err = hinic_mutex_lock(&func_to_func->mbox_send_mutex);
727 msg_info.msg_id = (MBOX_MSG_ID(func_to_func) + 1) & MBOX_MSG_ID_MASK;
728 MBOX_MSG_ID(func_to_func) = msg_info.msg_id;
730 set_mbox_to_func_event(func_to_func, EVENT_START);
732 err = send_mbox_to_func(func_to_func, mod, cmd, buf_in, in_size,
733 dst_func, HINIC_HWIF_DIRECT_SEND,
734 MBOX_ACK, &msg_info);
738 time = msecs_to_jiffies(timeout ? timeout : HINIC_MBOX_COMP_TIME_MS);
739 err = hinic_aeq_poll_msg(func_to_func->ack_aeq, time, NULL);
741 set_mbox_to_func_event(func_to_func, EVENT_TIMEOUT);
742 PMD_DRV_LOG(ERR, "Send mailbox message time out");
747 set_mbox_to_func_event(func_to_func, EVENT_END);
749 if (mbox_for_resp->msg_info.status) {
750 err = mbox_for_resp->msg_info.status;
751 if (err != HINIC_MBOX_PF_BUSY_ACTIVE_FW)
752 PMD_DRV_LOG(ERR, "Mailbox response error: 0x%x",
753 mbox_for_resp->msg_info.status);
755 PMD_DRV_LOG(ERR, "Chip is in active, PF can't process VF message");
761 if (mbox_for_resp->mbox_len && buf_out && out_size) {
762 if (mbox_for_resp->mbox_len <= *out_size) {
763 memcpy(buf_out, mbox_for_resp->mbox,
764 mbox_for_resp->mbox_len);
765 *out_size = mbox_for_resp->mbox_len;
767 PMD_DRV_LOG(ERR, "Mailbox response message len[%u] overflow",
768 mbox_for_resp->mbox_len);
776 (void)hinic_mutex_unlock(&func_to_func->mbox_send_mutex);
782 mbox_func_params_valid(__rte_unused struct hinic_mbox_func_to_func *mbox_obj,
783 void *buf_in, u16 in_size)
785 if (!buf_in || !in_size)
788 if (in_size > HINIC_MBOX_DATA_SIZE) {
789 PMD_DRV_LOG(ERR, "Mailbox message len(%d) exceed limit(%d)",
790 in_size, HINIC_MBOX_DATA_SIZE);
797 static u8 hinic_pf_id_of_vf(void *hwdev)
799 struct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif;
800 return hwif->attr.port_to_port_idx;
804 * hinic_mbox_to_pf - Send mbox info to pf and need pf to response.
807 * Pointer to hardware nic device.
809 * Mode type of hardware.
811 * The command sent to pf.
815 * Input parameter size.
819 * Output parameter size.
824 * 0 on success, negative error value otherwise.
826 int hinic_mbox_to_pf(struct hinic_hwdev *hwdev,
827 enum hinic_mod_type mod, u8 cmd, void *buf_in,
828 u16 in_size, void *buf_out, u16 *out_size, u32 timeout)
830 struct hinic_mbox_func_to_func *func_to_func = hwdev->func_to_func;
833 err = mbox_func_params_valid(func_to_func, buf_in, in_size);
835 PMD_DRV_LOG(ERR, "Mailbox parameters check failed: %d", err);
839 if (!HINIC_IS_VF(hwdev)) {
840 PMD_DRV_LOG(ERR, "Input function type error, func_type: %d",
841 hinic_func_type(hwdev));
845 return hinic_mbox_to_func(func_to_func, mod, cmd,
846 hinic_pf_id_of_vf(hwdev), buf_in, in_size,
847 buf_out, out_size, timeout);
851 * hinic_mbox_to_pf_no_ack - Send mbox info to pf and do not need pf to response
854 * Pointer to hardware nic device.
856 * Mode type of hardware.
858 * The command sent to pf.
862 * Input parameter size.
865 * 0 on success, negative error value otherwise.
867 int hinic_mbox_to_pf_no_ack(struct hinic_hwdev *hwdev, enum hinic_mod_type mod,
868 u8 cmd, void *buf_in, u16 in_size)
871 struct mbox_msg_info msg_info = {0};
873 err = hinic_mutex_lock(&hwdev->func_to_func->mbox_send_mutex);
877 err = send_mbox_to_func(hwdev->func_to_func, mod, cmd, buf_in, in_size,
878 hinic_pf_id_of_vf(hwdev), HINIC_HWIF_DIRECT_SEND,
879 MBOX_NO_ACK, &msg_info);
881 PMD_DRV_LOG(ERR, "Send mailbox no ack failed, err: %d", err);
883 (void)hinic_mutex_unlock(&hwdev->func_to_func->mbox_send_mutex);
888 static int hinic_func_to_func_init(struct hinic_hwdev *hwdev)
890 struct hinic_mbox_func_to_func *func_to_func;
893 func_to_func = kzalloc(sizeof(*func_to_func), GFP_KERNEL);
895 PMD_DRV_LOG(ERR, "Allocating memory for func_to_func object failed");
898 hwdev->func_to_func = func_to_func;
899 func_to_func->hwdev = hwdev;
900 (void)hinic_mutex_init(&func_to_func->mbox_send_mutex, NULL);
901 (void)hinic_mutex_init(&func_to_func->msg_send_mutex, NULL);
903 err = alloc_mbox_info(func_to_func->mbox_send);
905 PMD_DRV_LOG(ERR, "Allocating memory for mailbox sending failed");
906 goto alloc_mbox_for_send_err;
909 err = alloc_mbox_info(func_to_func->mbox_resp);
911 PMD_DRV_LOG(ERR, "Allocating memory for mailbox responding failed");
912 goto alloc_mbox_for_resp_err;
915 err = alloc_mbox_wb_status(func_to_func);
917 goto alloc_wb_status_err;
919 prepare_send_mbox(func_to_func);
924 free_mbox_info(func_to_func->mbox_resp);
926 alloc_mbox_for_resp_err:
927 free_mbox_info(func_to_func->mbox_send);
929 alloc_mbox_for_send_err:
936 * hinic_comm_func_to_func_free - Uninitialize func to func resource.
939 * Pointer to hardware nic device.
941 void hinic_comm_func_to_func_free(struct hinic_hwdev *hwdev)
943 struct hinic_mbox_func_to_func *func_to_func = hwdev->func_to_func;
945 free_mbox_wb_status(func_to_func);
946 free_mbox_info(func_to_func->mbox_resp);
947 free_mbox_info(func_to_func->mbox_send);
948 (void)hinic_mutex_destroy(&func_to_func->mbox_send_mutex);
949 (void)hinic_mutex_destroy(&func_to_func->msg_send_mutex);
954 * hinic_comm_func_to_func_init - Initialize func to func resource.
957 * Pointer to hardware nic device.
959 int hinic_comm_func_to_func_init(struct hinic_hwdev *hwdev)
964 rc = hinic_func_to_func_init(hwdev);
968 msg_ack_aeqn = mbox_msg_ack_aeqn(hwdev);
970 hwdev->func_to_func->ack_aeq = &hwdev->aeqs->aeq[msg_ack_aeqn];
971 hwdev->func_to_func->recv_aeq = &hwdev->aeqs->aeq[HINIC_AEQN_0];