LCOV - code coverage report
Current view: top level - drivers/net/hinic/base - hinic_pmd_mbox.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 312 0.0 %
Date: 2024-02-14 00:53:57 Functions: 0 22 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 133 0.0 %

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

Generated by: LCOV version 1.14