net/hinic/base: add mbox command channel for SR-IOV
[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 #define MBOX_MSG_ID_INC(func_to_func)   (MBOX_MSG_ID(func_to_func) =    \
135                         (MBOX_MSG_ID(func_to_func) + 1) & MBOX_MSG_ID_MASK)
136
137 enum hinic_hwif_direction_type {
138         /* driver send msg to up or up send msg to drier*/
139         HINIC_HWIF_DIRECT_SEND = 0,
140         /* after driver/up send msg to each other, then up/driver ack the msg */
141         HINIC_HWIF_RESPONSE,
142 };
143
144 enum mbox_send_mod {
145         MBOX_SEND_MSG_POLL = 1
146 };
147
148 enum mbox_seg_type {
149         NOT_LAST_SEG,
150         LAST_SEG,
151 };
152
153 enum mbox_ordering_type {
154         STRONG_ORDER,
155         RELAX_ORDER,
156 };
157
158 enum mbox_write_back_type {
159         NOT_WRITE_BACK = 0,
160         WRITE_BACK,
161 };
162
163 enum mbox_aeq_trig_type {
164         NOT_TRIGGER,
165         TRIGGER,
166 };
167
168 static int send_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func,
169                                 enum hinic_mod_type mod, u16 cmd, void *msg,
170                                 u16 msg_len, u16 dst_func,
171                                 enum hinic_hwif_direction_type direction,
172                                 enum hinic_mbox_ack_type ack_type,
173                                 struct mbox_msg_info *msg_info);
174
175 static int recv_vf_mbox_handler(struct hinic_mbox_func_to_func *func_to_func,
176                                 struct hinic_recv_mbox *recv_mbox,
177                                 void *buf_out, u16 *out_size, void *param)
178 {
179         int rc = 0;
180         *out_size = 0;
181
182         switch (recv_mbox->mod) {
183         case HINIC_MOD_COMM:
184                 hinic_comm_async_event_handle(func_to_func->hwdev,
185                                                 recv_mbox->cmd, recv_mbox->mbox,
186                                                 recv_mbox->mbox_len,
187                                                 buf_out, out_size);
188                 break;
189         case HINIC_MOD_L2NIC:
190                 hinic_l2nic_async_event_handle(func_to_func->hwdev, param,
191                                                 recv_mbox->cmd, recv_mbox->mbox,
192                                                 recv_mbox->mbox_len,
193                                                 buf_out, out_size);
194                 break;
195         default:
196                 PMD_DRV_LOG(ERR, "No handler, mod = %d",
197                                 recv_mbox->mod);
198                 rc = HINIC_MBOX_VF_CMD_ERROR;
199                 break;
200         }
201
202         return rc;
203 }
204
205 static void set_mbx_msg_status(struct mbox_msg_info *msg_info, int status)
206 {
207         if (status == HINIC_DEV_BUSY_ACTIVE_FW)
208                 msg_info->status = HINIC_MBOX_PF_BUSY_ACTIVE_FW;
209         else if (status == HINIC_MBOX_VF_CMD_ERROR)
210                 msg_info->status = HINIC_MBOX_VF_CMD_ERROR;
211         else if (status)
212                 msg_info->status = HINIC_MBOX_PF_SEND_ERR;
213 }
214
215 static void recv_func_mbox_handler(struct hinic_mbox_func_to_func *func_to_func,
216                                 struct hinic_recv_mbox *recv_mbox,
217                                 u16 src_func_idx, void *param)
218 {
219         struct hinic_hwdev *dev = func_to_func->hwdev;
220         struct mbox_msg_info msg_info = { 0 };
221         u16 out_size = MBOX_MAX_BUF_SZ;
222         void *buf_out = recv_mbox->buf_out;
223         int err = 0;
224
225         if (HINIC_IS_VF(dev)) {
226                 err = recv_vf_mbox_handler(func_to_func, recv_mbox, buf_out,
227                                                 &out_size, param);
228         } else {
229                 err = -EINVAL;
230                 PMD_DRV_LOG(ERR, "PMD doesn't support non-VF handle mailbox message");
231         }
232
233         if (!out_size || err)
234                 out_size = MBOX_MSG_NO_DATA_LEN;
235
236         if (recv_mbox->ack_type == MBOX_ACK) {
237                 msg_info.msg_id = recv_mbox->msg_info.msg_id;
238                 set_mbx_msg_status(&msg_info, err);
239                 send_mbox_to_func(func_to_func, recv_mbox->mod, recv_mbox->cmd,
240                                 buf_out, out_size, src_func_idx,
241                                 HINIC_HWIF_RESPONSE, MBOX_ACK, &msg_info);
242         }
243 }
244
245 static bool check_mbox_seq_id_and_seg_len(struct hinic_recv_mbox *recv_mbox,
246                                           u8 seq_id, u8 seg_len)
247 {
248         if (seq_id > HINIC_SEQ_ID_MAX_VAL || seg_len > HINIC_MSG_SEG_LEN)
249                 return false;
250
251         if (seq_id == 0) {
252                 recv_mbox->sed_id = seq_id;
253         } else {
254                 if (seq_id != recv_mbox->sed_id + 1) {
255                         recv_mbox->sed_id = 0;
256                         return false;
257                 }
258
259                 recv_mbox->sed_id = seq_id;
260         }
261
262         return true;
263 }
264
265 static void clear_mbox_status(struct hinic_send_mbox *mbox)
266 {
267         /* clear mailbox write back status */
268         *mbox->wb_status = 0;
269         rte_wmb();
270 }
271
272 static void mbox_copy_header(struct hinic_send_mbox *mbox, u64 *header)
273 {
274         u32 *data = (u32 *)header;
275         u32 i, idx_max = MBOX_HEADER_SZ / sizeof(u32);
276
277         for (i = 0; i < idx_max; i++)
278                 __raw_writel(*(data + i), mbox->data + i * sizeof(u32));
279 }
280
281 static void
282 mbox_copy_send_data(struct hinic_send_mbox *mbox, void *seg, u16 seg_len)
283 {
284         u32 *data = (u32 *)seg;
285         u32 data_len, chk_sz = sizeof(u32);
286         u32 i, idx_max;
287         u8 mbox_max_buf[MBOX_SEG_LEN] = {0};
288
289         /* The mbox message should be aligned in 4 bytes. */
290         if (seg_len % chk_sz) {
291                 memcpy(mbox_max_buf, seg, seg_len);
292                 data = (u32 *)mbox_max_buf;
293         }
294
295         data_len = seg_len;
296         idx_max = ALIGN(data_len, chk_sz) / chk_sz;
297
298         for (i = 0; i < idx_max; i++)
299                 __raw_writel(*(data + i),
300                                 mbox->data + MBOX_HEADER_SZ + i * sizeof(u32));
301 }
302
303 static void write_mbox_msg_attr(struct hinic_mbox_func_to_func *func_to_func,
304                         u16 dst_func, u16 dst_aeqn,
305                         __rte_unused u16 seg_len, int poll)
306 {
307         u32 mbox_int, mbox_ctrl;
308
309         mbox_int = HINIC_MBOX_INT_SET(dst_func, DST_FUNC) |
310                 HINIC_MBOX_INT_SET(dst_aeqn, DST_AEQN) |
311                 HINIC_MBOX_INT_SET(HINIC_MBOX_RSP_AEQN, SRC_RESP_AEQN) |
312                 HINIC_MBOX_INT_SET(NO_DMA_ATTRIBUTE_VAL, STAT_DMA) |
313                 HINIC_MBOX_INT_SET(ALIGN(MBOX_SIZE, MBOX_SEG_LEN_ALIGN) >> 2,
314                                         TX_SIZE) |
315                 HINIC_MBOX_INT_SET(STRONG_ORDER, STAT_DMA_SO_RO) |
316                 HINIC_MBOX_INT_SET(WRITE_BACK, WB_EN);
317
318         hinic_hwif_write_reg(func_to_func->hwdev->hwif,
319                         HINIC_FUNC_CSR_MAILBOX_INT_OFFSET_OFF, mbox_int);
320
321         rte_wmb();
322         mbox_ctrl = HINIC_MBOX_CTRL_SET(TX_IN_PROGRESS, TX_STATUS);
323
324         if (poll)
325                 mbox_ctrl |= HINIC_MBOX_CTRL_SET(NOT_TRIGGER, TRIGGER_AEQE);
326         else
327                 mbox_ctrl |= HINIC_MBOX_CTRL_SET(TRIGGER, TRIGGER_AEQE);
328
329         hinic_hwif_write_reg(func_to_func->hwdev->hwif,
330                                 HINIC_FUNC_CSR_MAILBOX_CONTROL_OFF, mbox_ctrl);
331 }
332
333 static int init_mbox_info(struct hinic_recv_mbox *mbox_info)
334 {
335         int err;
336
337         mbox_info->mbox = kzalloc(MBOX_MAX_BUF_SZ, GFP_KERNEL);
338         if (!mbox_info->mbox) {
339                 PMD_DRV_LOG(ERR, "Alloc mbox buf_in mem failed\n");
340                 return -ENOMEM;
341         }
342
343         mbox_info->buf_out = kzalloc(MBOX_MAX_BUF_SZ, GFP_KERNEL);
344         if (!mbox_info->buf_out) {
345                 PMD_DRV_LOG(ERR, "Alloc mbox buf_out mem failed\n");
346                 err = -ENOMEM;
347                 goto alloc_buf_out_err;
348         }
349
350         return 0;
351
352 alloc_buf_out_err:
353         kfree(mbox_info->mbox);
354
355         return err;
356 }
357
358 static void clean_mbox_info(struct hinic_recv_mbox *mbox_info)
359 {
360         kfree(mbox_info->buf_out);
361         kfree(mbox_info->mbox);
362 }
363
364 static int alloc_mbox_info(struct hinic_recv_mbox *mbox_info)
365 {
366         u16 func_idx, i;
367         int err;
368
369         for (func_idx = 0; func_idx < HINIC_MAX_FUNCTIONS; func_idx++) {
370                 err = init_mbox_info(&mbox_info[func_idx]);
371                 if (err) {
372                         PMD_DRV_LOG(ERR, "Initialize function[%d] mailbox information failed, err: %d",
373                                     func_idx, err);
374                         goto init_mbox_info_err;
375                 }
376         }
377
378         return 0;
379
380 init_mbox_info_err:
381         for (i = 0; i < func_idx; i++)
382                 clean_mbox_info(&mbox_info[i]);
383
384         return err;
385 }
386
387 static void free_mbox_info(struct hinic_recv_mbox *mbox_info)
388 {
389         u16 func_idx;
390
391         for (func_idx = 0; func_idx < HINIC_MAX_FUNCTIONS; func_idx++)
392                 clean_mbox_info(&mbox_info[func_idx]);
393 }
394
395 static void prepare_send_mbox(struct hinic_mbox_func_to_func *func_to_func)
396 {
397         struct hinic_send_mbox *send_mbox = &func_to_func->send_mbox;
398
399         send_mbox->data = MBOX_AREA(func_to_func->hwdev->hwif);
400 }
401
402 static int alloc_mbox_wb_status(struct hinic_mbox_func_to_func *func_to_func)
403 {
404         struct hinic_send_mbox *send_mbox = &func_to_func->send_mbox;
405         struct hinic_hwdev *hwdev = func_to_func->hwdev;
406         struct hinic_hwif *hwif = hwdev->hwif;
407         u32 addr_h, addr_l;
408
409         send_mbox->wb_vaddr = dma_zalloc_coherent(hwdev,
410                                   MBOX_WB_STATUS_LEN,
411                                   &send_mbox->wb_paddr,
412                                   GFP_KERNEL);
413         if (!send_mbox->wb_vaddr) {
414                 PMD_DRV_LOG(ERR, "Allocating memory for mailbox wb status failed");
415                 return -ENOMEM;
416         }
417         send_mbox->wb_status = (volatile u64 *)send_mbox->wb_vaddr;
418
419         addr_h = upper_32_bits(send_mbox->wb_paddr);
420         addr_l = lower_32_bits(send_mbox->wb_paddr);
421         hinic_hwif_write_reg(hwif, HINIC_FUNC_CSR_MAILBOX_RESULT_H_OFF, addr_h);
422         hinic_hwif_write_reg(hwif, HINIC_FUNC_CSR_MAILBOX_RESULT_L_OFF, addr_l);
423
424         return 0;
425 }
426
427 static void free_mbox_wb_status(struct hinic_mbox_func_to_func *func_to_func)
428 {
429         struct hinic_send_mbox *send_mbox = &func_to_func->send_mbox;
430         struct hinic_hwdev *hwdev = func_to_func->hwdev;
431         struct hinic_hwif *hwif = hwdev->hwif;
432
433         hinic_hwif_write_reg(hwif, HINIC_FUNC_CSR_MAILBOX_RESULT_H_OFF, 0);
434         hinic_hwif_write_reg(hwif, HINIC_FUNC_CSR_MAILBOX_RESULT_L_OFF, 0);
435
436         dma_free_coherent(hwdev, MBOX_WB_STATUS_LEN,
437                                 send_mbox->wb_vaddr, send_mbox->wb_paddr);
438 }
439
440 static int recv_mbox_handler(struct hinic_mbox_func_to_func *func_to_func,
441                 void *header, struct hinic_recv_mbox *recv_mbox, void *param)
442 {
443         u64 mbox_header = *((u64 *)header);
444         void *mbox_body = MBOX_BODY_FROM_HDR(header);
445         u16 src_func_idx;
446         enum hinic_hwif_direction_type direction;
447         u8 seq_id, seg_len;
448
449         seq_id = HINIC_MBOX_HEADER_GET(mbox_header, SEQID);
450         seg_len = HINIC_MBOX_HEADER_GET(mbox_header, SEG_LEN);
451         direction = HINIC_MBOX_HEADER_GET(mbox_header, DIRECTION);
452         src_func_idx = HINIC_MBOX_HEADER_GET(mbox_header, SRC_GLB_FUNC_IDX);
453
454         if (!check_mbox_seq_id_and_seg_len(recv_mbox, seq_id, seg_len)) {
455                 PMD_DRV_LOG(ERR,
456                         "Mailbox sequence and segment check failed, src func id: 0x%x, front id: 0x%x, current id: 0x%x, seg len: 0x%x\n",
457                         src_func_idx, recv_mbox->sed_id, seq_id, seg_len);
458                 return HINIC_ERROR;
459         }
460
461         memcpy((u8 *)recv_mbox->mbox + seq_id * HINIC_MSG_SEG_LEN,
462                 mbox_body, seg_len);
463
464         if (!HINIC_MBOX_HEADER_GET(mbox_header, LAST))
465                 return HINIC_ERROR;
466
467         recv_mbox->sed_id = 0;
468         recv_mbox->cmd = HINIC_MBOX_HEADER_GET(mbox_header, CMD);
469         recv_mbox->mod = HINIC_MBOX_HEADER_GET(mbox_header, MODULE);
470         recv_mbox->mbox_len = HINIC_MBOX_HEADER_GET(mbox_header, MSG_LEN);
471         recv_mbox->ack_type = HINIC_MBOX_HEADER_GET(mbox_header, NO_ACK);
472         recv_mbox->msg_info.msg_id = HINIC_MBOX_HEADER_GET(mbox_header, MSG_ID);
473         recv_mbox->msg_info.status = HINIC_MBOX_HEADER_GET(mbox_header, STATUS);
474
475         if (direction == HINIC_HWIF_RESPONSE) {
476                 if (recv_mbox->msg_info.msg_id == func_to_func->send_msg_id &&
477                         func_to_func->event_flag == EVENT_START) {
478                         return HINIC_OK;
479                 }
480
481                 PMD_DRV_LOG(ERR, "Mbox response timeout, current send msg id(0x%x), recv msg id(0x%x), status(0x%x)",
482                         func_to_func->send_msg_id, recv_mbox->msg_info.msg_id,
483                         recv_mbox->msg_info.status);
484                 return HINIC_ERROR;
485         }
486
487         recv_func_mbox_handler(func_to_func, recv_mbox, src_func_idx, param);
488
489         return HINIC_ERROR;
490 }
491
492 /**
493  * hinic_mbox_func_aeqe_handler - Process mbox info from func which is
494  * sent by aeqe.
495  *
496  * @param handle
497  *   Pointer to hradware nic device.
498  * @param header
499  *   Mbox header info.
500  * @param size
501  *   The size of aeqe descriptor.
502  * @param param
503  *   customized parameter.
504  *
505  * @return
506  *   0 on success, negative error value otherwise.
507  */
508 int hinic_mbox_func_aeqe_handler(void *handle, u8 *header,
509                                         __rte_unused u8 size, void *param)
510 {
511         struct hinic_mbox_func_to_func *func_to_func =
512                                 ((struct hinic_hwdev *)handle)->func_to_func;
513         struct hinic_recv_mbox *recv_mbox;
514         u64 mbox_header = *((u64 *)header);
515         u16 src = HINIC_MBOX_HEADER_GET(mbox_header, SRC_GLB_FUNC_IDX);
516
517         if (src >= HINIC_MAX_FUNCTIONS) {
518                 PMD_DRV_LOG(ERR, "Mailbox source function id: %d is invalid",
519                                 src);
520                 return HINIC_ERROR;
521         }
522
523         recv_mbox = (HINIC_MBOX_HEADER_GET(mbox_header, DIRECTION) ==
524                         HINIC_HWIF_DIRECT_SEND) ?
525                         &func_to_func->mbox_send[src] :
526                         &func_to_func->mbox_resp[src];
527
528         return recv_mbox_handler(func_to_func, (u64 *)header, recv_mbox, param);
529 }
530
531 static u16 get_mbox_status(struct hinic_send_mbox *mbox)
532 {
533         /* write back is 16B, but only use first 4B */
534         u64 wb_val = be64_to_cpu(*mbox->wb_status);
535
536         rte_rmb(); /* verify reading before check */
537
538         return (u16)(wb_val & MBOX_WB_STATUS_ERRCODE_MASK);
539 }
540
541 static void dump_mox_reg(struct hinic_hwdev *hwdev)
542 {
543         u32 val;
544
545         val = hinic_hwif_read_reg(hwdev->hwif,
546                                         HINIC_FUNC_CSR_MAILBOX_CONTROL_OFF);
547         PMD_DRV_LOG(WARNING, "Mailbox control reg: 0x%x", val);
548         val = hinic_hwif_read_reg(hwdev->hwif,
549                                         HINIC_FUNC_CSR_MAILBOX_INT_OFFSET_OFF);
550         PMD_DRV_LOG(WARNING, "Mailbox interrupt offset: 0x%x", val);
551 }
552
553 static int send_mbox_seg(struct hinic_mbox_func_to_func *func_to_func,
554                          u64 header, u16 dst_func, void *seg, u16 seg_len)
555 {
556         struct hinic_send_mbox *send_mbox = &func_to_func->send_mbox;
557         struct hinic_hwdev *hwdev = func_to_func->hwdev;
558         u16 seq_dir = HINIC_MBOX_HEADER_GET(header, DIRECTION);
559         u16 dst_aeqn = (seq_dir == HINIC_HWIF_DIRECT_SEND) ?
560                                 HINIC_MBOX_RECV_AEQN : HINIC_MBOX_RSP_AEQN;
561         u16 err_code, wb_status = 0;
562         u32 cnt = 0;
563
564         clear_mbox_status(send_mbox);
565
566         mbox_copy_header(send_mbox, &header);
567
568         mbox_copy_send_data(send_mbox, seg, seg_len);
569
570         write_mbox_msg_attr(func_to_func, dst_func, dst_aeqn, seg_len,
571                             MBOX_SEND_MSG_POLL);
572
573         rte_wmb();
574
575         while (cnt < MBOX_MSG_POLLING_TIMEOUT_MS) {
576                 wb_status = get_mbox_status(send_mbox);
577                 if (MBOX_STATUS_FINISHED(wb_status))
578                         break;
579
580                 rte_delay_ms(1); /* loop every ms */
581                 cnt++;
582         }
583
584         if (cnt == MBOX_MSG_POLLING_TIMEOUT_MS) {
585                 PMD_DRV_LOG(ERR, "Send mailbox segment timeout, wb status: 0x%x",
586                                 wb_status);
587                 dump_mox_reg(hwdev);
588                 return -ETIMEDOUT;
589         }
590
591         if (!MBOX_STATUS_SUCCESS(wb_status)) {
592                 PMD_DRV_LOG(ERR, "Send mailbox segment to function %d error, wb status: 0x%x",
593                                 dst_func, wb_status);
594                 /*
595                  * err_code: 0 responses no errors, other values can
596                  * refer to FS doc.
597                  */
598                 err_code = MBOX_STATUS_ERRCODE(wb_status);
599                 return err_code ? err_code : -EFAULT;
600         }
601
602         return 0;
603 }
604
605 static void set_mbox_to_func_event(struct hinic_mbox_func_to_func *func_to_func,
606                                    enum mbox_event_state event_flag)
607 {
608         spin_lock(&func_to_func->mbox_lock);
609         func_to_func->event_flag = event_flag;
610         spin_unlock(&func_to_func->mbox_lock);
611 }
612
613 static int send_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func,
614                                 enum hinic_mod_type mod, u16 cmd, void *msg,
615                                 u16 msg_len, u16 dst_func,
616                                 enum hinic_hwif_direction_type direction,
617                                 enum hinic_mbox_ack_type ack_type,
618                                 struct mbox_msg_info *msg_info)
619 {
620         struct hinic_hwdev *hwdev = func_to_func->hwdev;
621         int err = 0;
622         u32 seq_id = 0;
623         u16 seg_len = HINIC_MSG_SEG_LEN;
624         u16 left = msg_len;
625         u8 *msg_seg = (u8 *)msg;
626         u64 header = 0;
627
628         err = hinic_mutex_lock(&func_to_func->msg_send_mutex);
629         if (err)
630                 return err;
631
632         header = HINIC_MBOX_HEADER_SET(msg_len, MSG_LEN) |
633                 HINIC_MBOX_HEADER_SET(mod, MODULE) |
634                 HINIC_MBOX_HEADER_SET(seg_len, SEG_LEN) |
635                 HINIC_MBOX_HEADER_SET(ack_type, NO_ACK) |
636                 HINIC_MBOX_HEADER_SET(SEQ_ID_START_VAL, SEQID) |
637                 HINIC_MBOX_HEADER_SET(NOT_LAST_SEG, LAST) |
638                 HINIC_MBOX_HEADER_SET(direction, DIRECTION) |
639                 HINIC_MBOX_HEADER_SET(cmd, CMD) |
640                 HINIC_MBOX_HEADER_SET(msg_info->msg_id, MSG_ID) |
641                 HINIC_MBOX_HEADER_SET(msg_info->status, STATUS) |
642                 HINIC_MBOX_HEADER_SET(hinic_global_func_id(hwdev),
643                                         SRC_GLB_FUNC_IDX);
644
645         while (!(HINIC_MBOX_HEADER_GET(header, LAST))) {
646                 if (left <= HINIC_MSG_SEG_LEN) {
647                         header &=
648                         ~(HINIC_MBOX_HEADER_SET(HINIC_MBOX_HEADER_SEG_LEN_MASK,
649                                                 SEG_LEN));
650                         header |= HINIC_MBOX_HEADER_SET(left, SEG_LEN);
651                         header |= HINIC_MBOX_HEADER_SET(LAST_SEG, LAST);
652
653                         seg_len = left;
654                 }
655
656                 err = send_mbox_seg(func_to_func, header, dst_func, msg_seg,
657                                     seg_len);
658                 if (err) {
659                         PMD_DRV_LOG(ERR, "Fail to send mbox seg, err: %d", err);
660                         goto send_err;
661                 }
662
663                 left -= HINIC_MSG_SEG_LEN;
664                 msg_seg += HINIC_MSG_SEG_LEN;
665
666                 seq_id++;
667                 header &= ~(HINIC_MBOX_HEADER_SET(HINIC_MBOX_HEADER_SEQID_MASK,
668                                                         SEQID));
669                 header |= HINIC_MBOX_HEADER_SET(seq_id, SEQID);
670         }
671
672 send_err:
673         (void)hinic_mutex_unlock(&func_to_func->msg_send_mutex);
674
675         return err;
676 }
677
678 static int hinic_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func,
679                         enum hinic_mod_type mod, u16 cmd, u16 dst_func,
680                         void *buf_in, u16 in_size, void *buf_out, u16 *out_size,
681                         u32 timeout)
682 {
683         struct hinic_recv_mbox *mbox_for_resp =
684                                         &func_to_func->mbox_resp[dst_func];
685         struct mbox_msg_info msg_info = {0};
686         u32 time;
687         int err;
688
689         err = hinic_mutex_lock(&func_to_func->mbox_send_mutex);
690         if (err)
691                 return err;
692
693         msg_info.msg_id = MBOX_MSG_ID_INC(func_to_func);
694
695         set_mbox_to_func_event(func_to_func, EVENT_START);
696
697         err = send_mbox_to_func(func_to_func, mod, cmd, buf_in, in_size,
698                                 dst_func, HINIC_HWIF_DIRECT_SEND,
699                                 MBOX_ACK, &msg_info);
700         if (err)
701                 goto send_err;
702
703         time = msecs_to_jiffies(timeout ? timeout : HINIC_MBOX_COMP_TIME_MS);
704         err = hinic_aeq_poll_msg(func_to_func->rsp_aeq, time, NULL);
705         if (err) {
706                 set_mbox_to_func_event(func_to_func, EVENT_TIMEOUT);
707                 PMD_DRV_LOG(ERR, "Send mailbox message time out");
708                 err = -ETIMEDOUT;
709                 goto send_err;
710         }
711
712         set_mbox_to_func_event(func_to_func, EVENT_END);
713
714         if (mbox_for_resp->msg_info.status) {
715                 err = mbox_for_resp->msg_info.status;
716                 if (err != HINIC_MBOX_PF_BUSY_ACTIVE_FW)
717                         PMD_DRV_LOG(ERR, "Mailbox response error: 0x%x",
718                                         mbox_for_resp->msg_info.status);
719                 else
720                         PMD_DRV_LOG(ERR, "Chip is in active, PF can't process VF message");
721                 goto send_err;
722         }
723
724         rte_rmb();
725
726         if (mbox_for_resp->mbox_len && buf_out && out_size) {
727                 if (mbox_for_resp->mbox_len <= *out_size) {
728                         memcpy(buf_out, mbox_for_resp->mbox,
729                                 mbox_for_resp->mbox_len);
730                         *out_size = mbox_for_resp->mbox_len;
731                 } else {
732                         PMD_DRV_LOG(ERR, "Mailbox response message len[%u] overflow",
733                                         mbox_for_resp->mbox_len);
734                         err = -ERANGE;
735                 }
736         }
737
738 send_err:
739         if (err && out_size)
740                 *out_size = 0;
741         (void)hinic_mutex_unlock(&func_to_func->mbox_send_mutex);
742
743         return err;
744 }
745
746 static int
747 mbox_func_params_valid(__rte_unused struct hinic_mbox_func_to_func *mbox_obj,
748                         void *buf_in, u16 in_size)
749 {
750         if (!buf_in || !in_size)
751                 return -EINVAL;
752
753         if (in_size > HINIC_MBOX_DATA_SIZE) {
754                 PMD_DRV_LOG(ERR, "Mailbox message len(%d) exceed limit(%d)",
755                                 in_size, HINIC_MBOX_DATA_SIZE);
756                 return -EINVAL;
757         }
758
759         return 0;
760 }
761
762 static u8 hinic_pf_id_of_vf(void *hwdev)
763 {
764         struct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif;
765         return hwif->attr.port_to_port_idx;
766 }
767
768 /**
769  * hinic_mbox_to_pf - Send mbox info to pf and need pf to response.
770  *
771  * @param hwdev
772  *   Pointer to hardware nic device.
773  * @param mod
774  *   Mode type of hardware.
775  * @param cmd
776  *   The command sent to pf.
777  * @param buf_in
778  *   Input parameter.
779  * @param in_size
780  *   Input parameter size.
781  * @param buf_out
782  *   Output parameter.
783  * @param out_size
784  *   Output parameter size.
785  * @param timeout
786  *   Timeout.
787  *
788  * @return
789  *   0 on success, negative error value otherwise.
790  */
791 int hinic_mbox_to_pf(struct hinic_hwdev *hwdev,
792                       enum hinic_mod_type mod, u8 cmd, void *buf_in,
793                       u16 in_size, void *buf_out, u16 *out_size, u32 timeout)
794 {
795         struct hinic_mbox_func_to_func *func_to_func = hwdev->func_to_func;
796         int err;
797
798         err = mbox_func_params_valid(func_to_func, buf_in, in_size);
799         if (err) {
800                 PMD_DRV_LOG(ERR, "Mailbox parameters check failed: %d", err);
801                 return err;
802         }
803
804         if (!HINIC_IS_VF(hwdev)) {
805                 PMD_DRV_LOG(ERR, "Input function type error, func_type: %d",
806                                 hinic_func_type(hwdev));
807                 return -EINVAL;
808         }
809
810         return hinic_mbox_to_func(func_to_func, mod, cmd,
811                                    hinic_pf_id_of_vf(hwdev), buf_in, in_size,
812                                    buf_out, out_size, timeout);
813 }
814
815 /**
816  * hinic_mbox_to_pf_no_ack - Send mbox info to pf and do not need pf to response
817  *
818  * @param hwdev
819  *   Pointer to hardware nic device.
820  * @param mod
821  *   Mode type of hardware.
822  * @param cmd
823  *   The command sent to pf.
824  * @param buf_in
825  *   Input parameter.
826  * @param in_size
827  *   Input parameter size.
828  *
829  * @return
830  *   0 on success, negative error value otherwise.
831  */
832 int hinic_mbox_to_pf_no_ack(struct hinic_hwdev *hwdev, enum hinic_mod_type mod,
833                         u8 cmd, void *buf_in, u16 in_size)
834 {
835         int err;
836         struct mbox_msg_info msg_info = {0};
837
838         err = hinic_mutex_lock(&hwdev->func_to_func->mbox_send_mutex);
839         if (err)
840                 return err;
841
842         err = send_mbox_to_func(hwdev->func_to_func, mod, cmd, buf_in, in_size,
843                         hinic_pf_id_of_vf(hwdev), HINIC_HWIF_DIRECT_SEND,
844                         MBOX_NO_ACK, &msg_info);
845         if (err)
846                 PMD_DRV_LOG(ERR, "Send mailbox no ack failed, err: %d", err);
847
848         (void)hinic_mutex_unlock(&hwdev->func_to_func->mbox_send_mutex);
849
850         return err;
851 }
852
853 static int hinic_func_to_func_init(struct hinic_hwdev *hwdev)
854 {
855         struct hinic_mbox_func_to_func *func_to_func;
856         int err;
857
858         func_to_func = kzalloc(sizeof(*func_to_func), GFP_KERNEL);
859         if (!func_to_func) {
860                 PMD_DRV_LOG(ERR, "Allocating memory for func_to_func object failed");
861                 return -ENOMEM;
862         }
863         hwdev->func_to_func = func_to_func;
864         func_to_func->hwdev = hwdev;
865         (void)hinic_mutex_init(&func_to_func->mbox_send_mutex, NULL);
866         (void)hinic_mutex_init(&func_to_func->msg_send_mutex, NULL);
867
868         err = alloc_mbox_info(func_to_func->mbox_send);
869         if (err) {
870                 PMD_DRV_LOG(ERR, "Allocating memory for mailbox sending failed");
871                 goto alloc_mbox_for_send_err;
872         }
873
874         err = alloc_mbox_info(func_to_func->mbox_resp);
875         if (err) {
876                 PMD_DRV_LOG(ERR, "Allocating memory for mailbox responsing failed");
877                 goto alloc_mbox_for_resp_err;
878         }
879
880         err = alloc_mbox_wb_status(func_to_func);
881         if (err)
882                 goto alloc_wb_status_err;
883
884         prepare_send_mbox(func_to_func);
885
886         return 0;
887
888 alloc_wb_status_err:
889         free_mbox_info(func_to_func->mbox_resp);
890
891 alloc_mbox_for_resp_err:
892         free_mbox_info(func_to_func->mbox_send);
893
894 alloc_mbox_for_send_err:
895         kfree(func_to_func);
896
897         return err;
898 }
899
900 /**
901  * hinic_comm_func_to_func_free - Uninitialize func to func resource.
902  *
903  * @param hwdev
904  *   Pointer to hardware nic device.
905  */
906 void hinic_comm_func_to_func_free(struct hinic_hwdev *hwdev)
907 {
908         struct hinic_mbox_func_to_func *func_to_func = hwdev->func_to_func;
909
910         free_mbox_wb_status(func_to_func);
911         free_mbox_info(func_to_func->mbox_resp);
912         free_mbox_info(func_to_func->mbox_send);
913         (void)hinic_mutex_destroy(&func_to_func->mbox_send_mutex);
914         (void)hinic_mutex_destroy(&func_to_func->msg_send_mutex);
915         kfree(func_to_func);
916 }
917
918 /**
919  * hinic_comm_func_to_func_init - Initialize func to func resource.
920  *
921  * @param hwdev
922  *   Pointer to hardware nic device.
923  */
924 int hinic_comm_func_to_func_init(struct hinic_hwdev *hwdev)
925 {
926         int rc;
927
928         rc = hinic_func_to_func_init(hwdev);
929         if (rc)
930                 return rc;
931
932         hwdev->func_to_func->rsp_aeq = &hwdev->aeqs->aeq[HINIC_MBOX_RSP_AEQN];
933         hwdev->func_to_func->recv_aeq = &hwdev->aeqs->aeq[HINIC_MBOX_RECV_AEQN];
934
935         return 0;
936 }
937