net/hinic/base: support two or more AEQS for chip
[dpdk.git] / drivers / net / hinic / base / hinic_pmd_mbox.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017 Huawei Technologies Co., Ltd
3  */
4
5 #include "hinic_compat.h"
6 #include "hinic_csr.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"
12
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
22
23
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
31
32 #define HINIC_MBOX_INT_SET(val, field)  \
33                         (((val) & HINIC_MBOX_INT_##field##_MASK) << \
34                         HINIC_MBOX_INT_##field##_SHIFT)
35
36 enum hinic_mbox_tx_status {
37         TX_DONE = 0,
38         TX_IN_PROGRESS,
39 };
40
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.
45  */
46 #define HINIC_MBOX_CTRL_TX_STATUS_SHIFT                         1
47
48 #define HINIC_MBOX_CTRL_TRIGGER_AEQE_MASK                       0x1
49 #define HINIC_MBOX_CTRL_TX_STATUS_MASK                          0x1
50
51 #define HINIC_MBOX_CTRL_SET(val, field) \
52                         (((val) & HINIC_MBOX_CTRL_##field##_MASK) << \
53                         HINIC_MBOX_CTRL_##field##_SHIFT)
54
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
61
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
67
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
79
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)
86
87 #define HINIC_MBOX_COMP_TIME_MS                 8000U
88 #define MBOX_MSG_POLLING_TIMEOUT_MS             5000
89
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
94
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
99 #define MBOX_SIZE                               64
100
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
108
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)
115
116 #define SEQ_ID_START_VAL                        0
117
118 #define DST_AEQ_IDX_DEFAULT_VAL                 0
119 #define SRC_AEQ_IDX_DEFAULT_VAL                 0
120 #define NO_DMA_ATTRIBUTE_VAL                    0
121
122 #define MBOX_MSG_NO_DATA_LEN                    1
123
124 #define FUNC_ID_OFF_SET_8B              8
125 #define FUNC_ID_OFF_SET_10B             10
126
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)
130
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)
134
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 */
139         HINIC_HWIF_RESPONSE,
140 };
141
142 enum mbox_send_mod {
143         MBOX_SEND_MSG_POLL = 1
144 };
145
146 enum mbox_seg_type {
147         NOT_LAST_SEG,
148         LAST_SEG,
149 };
150
151 enum mbox_ordering_type {
152         STRONG_ORDER,
153         RELAX_ORDER,
154 };
155
156 enum mbox_write_back_type {
157         NOT_WRITE_BACK = 0,
158         WRITE_BACK,
159 };
160
161 enum mbox_aeq_trig_type {
162         NOT_TRIGGER,
163         TRIGGER,
164 };
165
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);
172
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)
176 {
177         int rc = 0;
178         *out_size = 0;
179
180         switch (recv_mbox->mod) {
181         case HINIC_MOD_COMM:
182                 hinic_comm_async_event_handle(func_to_func->hwdev,
183                                                 recv_mbox->cmd, recv_mbox->mbox,
184                                                 recv_mbox->mbox_len,
185                                                 buf_out, out_size);
186                 break;
187         case HINIC_MOD_L2NIC:
188                 hinic_l2nic_async_event_handle(func_to_func->hwdev, param,
189                                                 recv_mbox->cmd, recv_mbox->mbox,
190                                                 recv_mbox->mbox_len,
191                                                 buf_out, out_size);
192                 break;
193         default:
194                 PMD_DRV_LOG(ERR, "No handler, mod: %d", recv_mbox->mod);
195                 rc = HINIC_MBOX_VF_CMD_ERROR;
196                 break;
197         }
198
199         return rc;
200 }
201
202 static void set_mbx_msg_status(struct mbox_msg_info *msg_info, int status)
203 {
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;
208         else if (status)
209                 msg_info->status = HINIC_MBOX_PF_SEND_ERR;
210 }
211
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)
215 {
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;
220         int err = 0;
221
222         if (HINIC_IS_VF(dev)) {
223                 err = recv_vf_mbox_handler(func_to_func, recv_mbox, buf_out,
224                                                 &out_size, param);
225         } else {
226                 err = -EINVAL;
227                 PMD_DRV_LOG(ERR, "PMD doesn't support non-VF handle mailbox message");
228         }
229
230         if (!out_size || err)
231                 out_size = MBOX_MSG_NO_DATA_LEN;
232
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);
239         }
240 }
241
242 static bool check_mbox_seq_id_and_seg_len(struct hinic_recv_mbox *recv_mbox,
243                                           u8 seq_id, u8 seg_len)
244 {
245         if (seq_id > HINIC_SEQ_ID_MAX_VAL || seg_len > HINIC_MSG_SEG_LEN)
246                 return false;
247
248         if (seq_id == 0) {
249                 recv_mbox->sed_id = seq_id;
250         } else {
251                 if (seq_id != recv_mbox->sed_id + 1) {
252                         recv_mbox->sed_id = 0;
253                         return false;
254                 }
255
256                 recv_mbox->sed_id = seq_id;
257         }
258
259         return true;
260 }
261
262 static void clear_mbox_status(struct hinic_send_mbox *mbox)
263 {
264         /* clear mailbox write back status */
265         *mbox->wb_status = 0;
266         rte_wmb();
267 }
268
269 static void mbox_copy_header(struct hinic_send_mbox *mbox, u64 *header)
270 {
271         u32 *data = (u32 *)header;
272         u32 i, idx_max = MBOX_HEADER_SZ / sizeof(u32);
273
274         for (i = 0; i < idx_max; i++)
275                 __raw_writel(*(data + i), mbox->data + i * sizeof(u32));
276 }
277
278 static void
279 mbox_copy_send_data(struct hinic_send_mbox *mbox, void *seg, u16 seg_len)
280 {
281         u32 *data = (u32 *)seg;
282         u32 data_len, chk_sz = sizeof(u32);
283         u32 i, idx_max;
284         u8 mbox_max_buf[MBOX_SEG_LEN] = {0};
285
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;
290         }
291
292         data_len = seg_len;
293         idx_max = ALIGN(data_len, chk_sz) / chk_sz;
294
295         for (i = 0; i < idx_max; i++)
296                 __raw_writel(*(data + i),
297                                 mbox->data + MBOX_HEADER_SZ + i * sizeof(u32));
298 }
299
300 static int mbox_msg_ack_aeqn(struct hinic_hwdev *hwdev)
301 {
302         u16 aeq_num = HINIC_HWIF_NUM_AEQS(hwdev->hwif);
303         int msg_ack_aeqn;
304
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;
310         } else {
311                 PMD_DRV_LOG(ERR, "Warning: Invalid aeq num: %d\n", aeq_num);
312                 msg_ack_aeqn = -1;
313         }
314
315         return msg_ack_aeqn;
316 }
317
318 static u16 mbox_msg_dst_aeqn(struct hinic_hwdev *hwdev,
319                         enum hinic_hwif_direction_type seq_dir)
320 {
321         u16 dst_aeqn;
322
323         if (seq_dir == HINIC_HWIF_DIRECT_SEND)
324                 dst_aeqn = HINIC_AEQN_0;
325         else
326                 dst_aeqn = mbox_msg_ack_aeqn(hwdev);
327
328         return dst_aeqn;
329 }
330
331 static int mbox_seg_ack_aeqn(struct hinic_hwdev *hwdev)
332 {
333         return mbox_msg_ack_aeqn(hwdev);
334 }
335
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)
339 {
340         u32 mbox_int, mbox_ctrl;
341
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,
348                                         TX_SIZE) |
349                 HINIC_MBOX_INT_SET(STRONG_ORDER, STAT_DMA_SO_RO) |
350                 HINIC_MBOX_INT_SET(WRITE_BACK, WB_EN);
351
352         hinic_hwif_write_reg(func_to_func->hwdev->hwif,
353                         HINIC_FUNC_CSR_MAILBOX_INT_OFFSET_OFF, mbox_int);
354
355         rte_wmb();
356         mbox_ctrl = HINIC_MBOX_CTRL_SET(TX_IN_PROGRESS, TX_STATUS);
357
358         if (poll)
359                 mbox_ctrl |= HINIC_MBOX_CTRL_SET(NOT_TRIGGER, TRIGGER_AEQE);
360         else
361                 mbox_ctrl |= HINIC_MBOX_CTRL_SET(TRIGGER, TRIGGER_AEQE);
362
363         hinic_hwif_write_reg(func_to_func->hwdev->hwif,
364                                 HINIC_FUNC_CSR_MAILBOX_CONTROL_OFF, mbox_ctrl);
365 }
366
367 static int init_mbox_info(struct hinic_recv_mbox *mbox_info)
368 {
369         int err;
370
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");
374                 return -ENOMEM;
375         }
376
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");
380                 err = -ENOMEM;
381                 goto alloc_buf_out_err;
382         }
383
384         return 0;
385
386 alloc_buf_out_err:
387         kfree(mbox_info->mbox);
388
389         return err;
390 }
391
392 static void clean_mbox_info(struct hinic_recv_mbox *mbox_info)
393 {
394         kfree(mbox_info->buf_out);
395         kfree(mbox_info->mbox);
396 }
397
398 static int alloc_mbox_info(struct hinic_recv_mbox *mbox_info)
399 {
400         u16 func_idx, i;
401         int err;
402
403         for (func_idx = 0; func_idx < HINIC_MAX_FUNCTIONS; func_idx++) {
404                 err = init_mbox_info(&mbox_info[func_idx]);
405                 if (err) {
406                         PMD_DRV_LOG(ERR, "Initialize function[%d] mailbox information failed, err: %d",
407                                     func_idx, err);
408                         goto init_mbox_info_err;
409                 }
410         }
411
412         return 0;
413
414 init_mbox_info_err:
415         for (i = 0; i < func_idx; i++)
416                 clean_mbox_info(&mbox_info[i]);
417
418         return err;
419 }
420
421 static void free_mbox_info(struct hinic_recv_mbox *mbox_info)
422 {
423         u16 func_idx;
424
425         for (func_idx = 0; func_idx < HINIC_MAX_FUNCTIONS; func_idx++)
426                 clean_mbox_info(&mbox_info[func_idx]);
427 }
428
429 static void prepare_send_mbox(struct hinic_mbox_func_to_func *func_to_func)
430 {
431         struct hinic_send_mbox *send_mbox = &func_to_func->send_mbox;
432
433         send_mbox->data = MBOX_AREA(func_to_func->hwdev->hwif);
434 }
435
436 static int alloc_mbox_wb_status(struct hinic_mbox_func_to_func *func_to_func)
437 {
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;
441         u32 addr_h, addr_l;
442
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");
447                 return -ENOMEM;
448         }
449         send_mbox->wb_status = (volatile u64 *)send_mbox->wb_vaddr;
450
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);
455
456         return 0;
457 }
458
459 static void free_mbox_wb_status(struct hinic_mbox_func_to_func *func_to_func)
460 {
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;
464
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);
467
468         dma_free_coherent(hwdev, MBOX_WB_STATUS_LEN,
469                                 send_mbox->wb_vaddr, send_mbox->wb_paddr);
470 }
471
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)
474 {
475         u64 mbox_header = *((u64 *)header);
476         void *mbox_body = MBOX_BODY_FROM_HDR(header);
477         u16 src_func_idx;
478         enum hinic_hwif_direction_type direction;
479         u8 seq_id, seg_len;
480
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);
485
486         if (!check_mbox_seq_id_and_seg_len(recv_mbox, seq_id, seg_len)) {
487                 PMD_DRV_LOG(ERR,
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);
490                 return HINIC_ERROR;
491         }
492
493         memcpy((u8 *)recv_mbox->mbox + seq_id * HINIC_MSG_SEG_LEN,
494                 mbox_body, seg_len);
495
496         if (!HINIC_MBOX_HEADER_GET(mbox_header, LAST))
497                 return HINIC_ERROR;
498
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);
506
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) {
510                         return HINIC_OK;
511                 }
512
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);
516                 return HINIC_ERROR;
517         }
518
519         recv_func_mbox_handler(func_to_func, recv_mbox, src_func_idx, param);
520
521         return HINIC_ERROR;
522 }
523
524 /**
525  * hinic_mbox_func_aeqe_handler - Process mbox info from func which is
526  * sent by aeqe.
527  *
528  * @param handle
529  *   Pointer to hradware nic device.
530  * @param header
531  *   Mbox header info.
532  * @param size
533  *   The size of aeqe descriptor.
534  * @param param
535  *   customized parameter.
536  *
537  * @return
538  *   0 on success, negative error value otherwise.
539  */
540 int hinic_mbox_func_aeqe_handler(void *handle, u8 *header,
541                                         __rte_unused u8 size, void *param)
542 {
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);
548
549         if (src >= HINIC_MAX_FUNCTIONS) {
550                 PMD_DRV_LOG(ERR, "Mailbox source function id: %d is invalid",
551                                 src);
552                 return HINIC_ERROR;
553         }
554
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];
559
560         return recv_mbox_handler(func_to_func, (u64 *)header, recv_mbox, param);
561 }
562
563 static u16 get_mbox_status(struct hinic_send_mbox *mbox)
564 {
565         /* write back is 16B, but only use first 4B */
566         u64 wb_val = be64_to_cpu(*mbox->wb_status);
567
568         rte_rmb(); /* verify reading before check */
569
570         return (u16)(wb_val & MBOX_WB_STATUS_ERRCODE_MASK);
571 }
572
573 static void dump_mox_reg(struct hinic_hwdev *hwdev)
574 {
575         u32 val;
576
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);
583 }
584
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)
587 {
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;
593         u32 cnt = 0;
594
595         dst_aeqn = mbox_msg_dst_aeqn(hwdev, seq_dir);
596         seg_ack_aeqn = mbox_seg_ack_aeqn(hwdev);
597
598         clear_mbox_status(send_mbox);
599
600         mbox_copy_header(send_mbox, &header);
601
602         mbox_copy_send_data(send_mbox, seg, seg_len);
603
604         write_mbox_msg_attr(func_to_func, dst_func, dst_aeqn, seg_ack_aeqn,
605                                 seg_len, MBOX_SEND_MSG_POLL);
606
607         rte_wmb();
608
609         while (cnt < MBOX_MSG_POLLING_TIMEOUT_MS) {
610                 wb_status = get_mbox_status(send_mbox);
611                 if (MBOX_STATUS_FINISHED(wb_status))
612                         break;
613
614                 rte_delay_ms(1); /* loop every ms */
615                 cnt++;
616         }
617
618         if (cnt == MBOX_MSG_POLLING_TIMEOUT_MS) {
619                 PMD_DRV_LOG(ERR, "Send mailbox segment timeout, wb status: 0x%x",
620                                 wb_status);
621                 dump_mox_reg(hwdev);
622                 return -ETIMEDOUT;
623         }
624
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);
628                 /*
629                  * err_code: 0 responses no errors, other values can
630                  * refer to FS doc.
631                  */
632                 err_code = MBOX_STATUS_ERRCODE(wb_status);
633                 return err_code ? err_code : -EFAULT;
634         }
635
636         return 0;
637 }
638
639 static void set_mbox_to_func_event(struct hinic_mbox_func_to_func *func_to_func,
640                                    enum mbox_event_state event_flag)
641 {
642         spin_lock(&func_to_func->mbox_lock);
643         func_to_func->event_flag = event_flag;
644         spin_unlock(&func_to_func->mbox_lock);
645 }
646
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)
653 {
654         struct hinic_hwdev *hwdev = func_to_func->hwdev;
655         int err = 0;
656         u32 seq_id = 0;
657         u16 seg_len = HINIC_MSG_SEG_LEN;
658         u16 left = msg_len;
659         u8 *msg_seg = (u8 *)msg;
660         u64 header = 0;
661
662         err = hinic_mutex_lock(&func_to_func->msg_send_mutex);
663         if (err)
664                 return err;
665
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),
677                                         SRC_GLB_FUNC_IDX);
678
679         while (!(HINIC_MBOX_HEADER_GET(header, LAST))) {
680                 if (left <= HINIC_MSG_SEG_LEN) {
681                         header &=
682                         ~(HINIC_MBOX_HEADER_SET(HINIC_MBOX_HEADER_SEG_LEN_MASK,
683                                                 SEG_LEN));
684                         header |= HINIC_MBOX_HEADER_SET(left, SEG_LEN);
685                         header |= HINIC_MBOX_HEADER_SET(LAST_SEG, LAST);
686
687                         seg_len = left;
688                 }
689
690                 err = send_mbox_seg(func_to_func, header, dst_func, msg_seg,
691                                     seg_len);
692                 if (err) {
693                         PMD_DRV_LOG(ERR, "Fail to send mbox seg, err: %d", err);
694                         goto send_err;
695                 }
696
697                 left -= HINIC_MSG_SEG_LEN;
698                 msg_seg += HINIC_MSG_SEG_LEN;
699
700                 seq_id++;
701                 header &= ~(HINIC_MBOX_HEADER_SET(HINIC_MBOX_HEADER_SEQID_MASK,
702                                                         SEQID));
703                 header |= HINIC_MBOX_HEADER_SET(seq_id, SEQID);
704         }
705
706 send_err:
707         (void)hinic_mutex_unlock(&func_to_func->msg_send_mutex);
708
709         return err;
710 }
711
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,
715                         u32 timeout)
716 {
717         struct hinic_recv_mbox *mbox_for_resp =
718                                         &func_to_func->mbox_resp[dst_func];
719         struct mbox_msg_info msg_info = {0};
720         u32 time;
721         int err;
722
723         err = hinic_mutex_lock(&func_to_func->mbox_send_mutex);
724         if (err)
725                 return err;
726
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;
729
730         set_mbox_to_func_event(func_to_func, EVENT_START);
731
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);
735         if (err)
736                 goto send_err;
737
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);
740         if (err) {
741                 set_mbox_to_func_event(func_to_func, EVENT_TIMEOUT);
742                 PMD_DRV_LOG(ERR, "Send mailbox message time out");
743                 err = -ETIMEDOUT;
744                 goto send_err;
745         }
746
747         set_mbox_to_func_event(func_to_func, EVENT_END);
748
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);
754                 else
755                         PMD_DRV_LOG(ERR, "Chip is in active, PF can't process VF message");
756                 goto send_err;
757         }
758
759         rte_rmb();
760
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;
766                 } else {
767                         PMD_DRV_LOG(ERR, "Mailbox response message len[%u] overflow",
768                                         mbox_for_resp->mbox_len);
769                         err = -ERANGE;
770                 }
771         }
772
773 send_err:
774         if (err && out_size)
775                 *out_size = 0;
776         (void)hinic_mutex_unlock(&func_to_func->mbox_send_mutex);
777
778         return err;
779 }
780
781 static int
782 mbox_func_params_valid(__rte_unused struct hinic_mbox_func_to_func *mbox_obj,
783                         void *buf_in, u16 in_size)
784 {
785         if (!buf_in || !in_size)
786                 return -EINVAL;
787
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);
791                 return -EINVAL;
792         }
793
794         return 0;
795 }
796
797 static u8 hinic_pf_id_of_vf(void *hwdev)
798 {
799         struct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif;
800         return hwif->attr.port_to_port_idx;
801 }
802
803 /**
804  * hinic_mbox_to_pf - Send mbox info to pf and need pf to response.
805  *
806  * @param hwdev
807  *   Pointer to hardware nic device.
808  * @param mod
809  *   Mode type of hardware.
810  * @param cmd
811  *   The command sent to pf.
812  * @param buf_in
813  *   Input parameter.
814  * @param in_size
815  *   Input parameter size.
816  * @param buf_out
817  *   Output parameter.
818  * @param out_size
819  *   Output parameter size.
820  * @param timeout
821  *   Timeout.
822  *
823  * @return
824  *   0 on success, negative error value otherwise.
825  */
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)
829 {
830         struct hinic_mbox_func_to_func *func_to_func = hwdev->func_to_func;
831         int err;
832
833         err = mbox_func_params_valid(func_to_func, buf_in, in_size);
834         if (err) {
835                 PMD_DRV_LOG(ERR, "Mailbox parameters check failed: %d", err);
836                 return err;
837         }
838
839         if (!HINIC_IS_VF(hwdev)) {
840                 PMD_DRV_LOG(ERR, "Input function type error, func_type: %d",
841                                 hinic_func_type(hwdev));
842                 return -EINVAL;
843         }
844
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);
848 }
849
850 /**
851  * hinic_mbox_to_pf_no_ack - Send mbox info to pf and do not need pf to response
852  *
853  * @param hwdev
854  *   Pointer to hardware nic device.
855  * @param mod
856  *   Mode type of hardware.
857  * @param cmd
858  *   The command sent to pf.
859  * @param buf_in
860  *   Input parameter.
861  * @param in_size
862  *   Input parameter size.
863  *
864  * @return
865  *   0 on success, negative error value otherwise.
866  */
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)
869 {
870         int err;
871         struct mbox_msg_info msg_info = {0};
872
873         err = hinic_mutex_lock(&hwdev->func_to_func->mbox_send_mutex);
874         if (err)
875                 return err;
876
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);
880         if (err)
881                 PMD_DRV_LOG(ERR, "Send mailbox no ack failed, err: %d", err);
882
883         (void)hinic_mutex_unlock(&hwdev->func_to_func->mbox_send_mutex);
884
885         return err;
886 }
887
888 static int hinic_func_to_func_init(struct hinic_hwdev *hwdev)
889 {
890         struct hinic_mbox_func_to_func *func_to_func;
891         int err;
892
893         func_to_func = kzalloc(sizeof(*func_to_func), GFP_KERNEL);
894         if (!func_to_func) {
895                 PMD_DRV_LOG(ERR, "Allocating memory for func_to_func object failed");
896                 return -ENOMEM;
897         }
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);
902
903         err = alloc_mbox_info(func_to_func->mbox_send);
904         if (err) {
905                 PMD_DRV_LOG(ERR, "Allocating memory for mailbox sending failed");
906                 goto alloc_mbox_for_send_err;
907         }
908
909         err = alloc_mbox_info(func_to_func->mbox_resp);
910         if (err) {
911                 PMD_DRV_LOG(ERR, "Allocating memory for mailbox responding failed");
912                 goto alloc_mbox_for_resp_err;
913         }
914
915         err = alloc_mbox_wb_status(func_to_func);
916         if (err)
917                 goto alloc_wb_status_err;
918
919         prepare_send_mbox(func_to_func);
920
921         return 0;
922
923 alloc_wb_status_err:
924         free_mbox_info(func_to_func->mbox_resp);
925
926 alloc_mbox_for_resp_err:
927         free_mbox_info(func_to_func->mbox_send);
928
929 alloc_mbox_for_send_err:
930         kfree(func_to_func);
931
932         return err;
933 }
934
935 /**
936  * hinic_comm_func_to_func_free - Uninitialize func to func resource.
937  *
938  * @param hwdev
939  *   Pointer to hardware nic device.
940  */
941 void hinic_comm_func_to_func_free(struct hinic_hwdev *hwdev)
942 {
943         struct hinic_mbox_func_to_func *func_to_func = hwdev->func_to_func;
944
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);
950         kfree(func_to_func);
951 }
952
953 /**
954  * hinic_comm_func_to_func_init - Initialize func to func resource.
955  *
956  * @param hwdev
957  *   Pointer to hardware nic device.
958  */
959 int hinic_comm_func_to_func_init(struct hinic_hwdev *hwdev)
960 {
961         int rc;
962         u16 msg_ack_aeqn;
963
964         rc = hinic_func_to_func_init(hwdev);
965         if (rc)
966                 return rc;
967
968         msg_ack_aeqn = mbox_msg_ack_aeqn(hwdev);
969
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];
972
973         return 0;
974 }
975