LCOV - code coverage report
Current view: top level - drivers/net/hinic3/base - hinic3_mgmt.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 99 0.0 %
Date: 2025-11-01 17:50:34 Functions: 0 7 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 40 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2025 Huawei Technologies Co., Ltd
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "hinic3_compat.h"
       6                 :            : #include "hinic3_hwdev.h"
       7                 :            : #include "hinic3_mbox.h"
       8                 :            : #include "hinic3_nic_event.h"
       9                 :            : 
      10                 :            : #define HINIC3_MSG_TO_MGMT_MAX_LEN 2016
      11                 :            : 
      12                 :            : #define MAX_PF_MGMT_BUF_SIZE 2048UL
      13                 :            : #define SEGMENT_LEN          48
      14                 :            : #define MGMT_MSG_MAX_SEQ_ID \
      15                 :            :         (RTE_ALIGN(HINIC3_MSG_TO_MGMT_MAX_LEN, SEGMENT_LEN) / SEGMENT_LEN)
      16                 :            : 
      17                 :            : #define BUF_OUT_DEFAULT_SIZE 1
      18                 :            : 
      19                 :            : #define MGMT_MSG_SIZE_MIN     20
      20                 :            : #define MGMT_MSG_SIZE_STEP    16
      21                 :            : #define MGMT_MSG_RSVD_FOR_DEV 8
      22                 :            : 
      23                 :            : static void
      24                 :            : send_mgmt_ack(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt, enum hinic3_mod_type mod,
      25                 :            :               struct hinic3_handler_info *handler_info, uint16_t msg_id)
      26                 :            : {
      27                 :          0 :         if (!handler_info->in_size)
      28                 :          0 :                 handler_info->in_size = BUF_OUT_DEFAULT_SIZE;
      29                 :            : 
      30                 :          0 :         hinic3_response_mbox_to_mgmt(pf_to_mgmt->hwdev, mod, handler_info, msg_id);
      31                 :          0 : }
      32                 :            : 
      33                 :            : static bool
      34                 :            : check_mgmt_seq_id_and_seg_len(struct hinic3_recv_msg *recv_msg, uint8_t seq_id,
      35                 :            :                               uint8_t seg_len, uint16_t msg_id)
      36                 :            : {
      37                 :          0 :         if (seq_id > MGMT_MSG_MAX_SEQ_ID || seg_len > SEGMENT_LEN)
      38                 :            :                 return false;
      39                 :            : 
      40         [ #  # ]:          0 :         if (seq_id == 0) {
      41                 :          0 :                 recv_msg->seq_id = seq_id;
      42                 :          0 :                 recv_msg->msg_id = msg_id;
      43                 :            :         } else {
      44         [ #  # ]:          0 :                 if ((seq_id != recv_msg->seq_id + 1) ||
      45         [ #  # ]:          0 :                     msg_id != recv_msg->msg_id) {
      46                 :          0 :                         recv_msg->seq_id = 0;
      47                 :            :                         return false;
      48                 :            :                 }
      49                 :            : 
      50                 :          0 :                 recv_msg->seq_id = seq_id;
      51                 :            :         }
      52                 :            : 
      53                 :            :         return true;
      54                 :            : }
      55                 :            : 
      56                 :            : static void
      57                 :          0 : hinic3_mgmt_recv_msg_handler(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt,
      58                 :            :                              struct hinic3_recv_msg *recv_msg,
      59                 :            :                              __rte_unused void *param)
      60                 :            : {
      61                 :          0 :         void *buf_out = pf_to_mgmt->mgmt_ack_buf;
      62                 :            :         bool ack_first = false;
      63                 :          0 :         uint16_t out_size = 0;
      64                 :            : 
      65                 :          0 :         struct hinic3_handler_info handler_info = {
      66                 :          0 :                 .cmd = recv_msg->cmd,
      67                 :          0 :                 .buf_in = recv_msg->msg,
      68   [ #  #  #  # ]:          0 :                 .in_size = recv_msg->msg_len,
      69                 :            :                 .buf_out = buf_out,
      70                 :            :                 .out_size = &out_size,
      71                 :            :                 .dst_func = HINIC3_MGMT_SRC_ID,
      72                 :            :                 .direction = HINIC3_MSG_RESPONSE,
      73                 :            :                 .ack_type = HINIC3_MSG_NO_ACK,
      74                 :            :         };
      75                 :            : 
      76                 :            :         memset(buf_out, 0, MAX_PF_MGMT_BUF_SIZE);
      77                 :            : 
      78                 :            :         /* Select the corresponding processing function according to the mod. */
      79   [ #  #  #  # ]:          0 :         switch (recv_msg->mod) {
      80                 :          0 :         case HINIC3_MOD_COMM:
      81                 :          0 :                 hinic3_pf_handle_mgmt_comm_event(pf_to_mgmt->hwdev,
      82                 :            :                                                  pf_to_mgmt, &handler_info);
      83                 :          0 :                 break;
      84                 :          0 :         case HINIC3_MOD_L2NIC:
      85                 :          0 :                 hinic3_pf_event_handler(pf_to_mgmt->hwdev,
      86                 :            :                                         pf_to_mgmt, &handler_info);
      87                 :          0 :                 break;
      88                 :          0 :         case HINIC3_MOD_HILINK:
      89                 :          0 :                 hinic3_pf_mag_event_handler(pf_to_mgmt->hwdev,
      90                 :            :                                             pf_to_mgmt, &handler_info);
      91                 :          0 :                 break;
      92                 :            : 
      93                 :          0 :         default:
      94                 :          0 :                 PMD_DRV_LOG(ERR,
      95                 :            :                             "Not support mod, maybe need to response, mod: %d",
      96                 :            :                             recv_msg->mod);
      97                 :          0 :                 break;
      98                 :            :         }
      99                 :            : 
     100         [ #  # ]:          0 :         if (!ack_first && !recv_msg->async_mgmt_to_pf)
     101                 :            :                 /* Mgmt sends async msg, sends the response. */
     102         [ #  # ]:          0 :                 send_mgmt_ack(pf_to_mgmt, recv_msg->mod, &handler_info, recv_msg->msg_id);
     103                 :          0 : }
     104                 :            : 
     105                 :            : /**
     106                 :            :  * Handler a recv message from mgmt channel.
     107                 :            :  *
     108                 :            :  * @param[in] pf_to_mgmt
     109                 :            :  * PF to mgmt channel.
     110                 :            :  * @param[in] recv_msg
     111                 :            :  * Received message details.
     112                 :            :  * @param[in] param
     113                 :            :  * Customized parameter.
     114                 :            :  * @return
     115                 :            :  * 0 : When aeqe is response message.
     116                 :            :  * -1 : Default result, when wrong message or not last message.
     117                 :            :  */
     118                 :            : static int
     119                 :          0 : recv_mgmt_msg_handler(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt, uint8_t *header,
     120                 :            :                       struct hinic3_recv_msg *recv_msg, void *param)
     121                 :            : {
     122                 :          0 :         uint64_t mbox_header = *((uint64_t *)header);
     123                 :          0 :         void *msg_body = header + sizeof(mbox_header);
     124                 :            :         uint8_t seq_id, seq_len;
     125                 :            :         uint32_t offset;
     126                 :            :         uint16_t msg_id;
     127                 :            : 
     128                 :            :         /* Don't need to get anything from hw when cmd is async. */
     129         [ #  # ]:          0 :         if (HINIC3_MSG_HEADER_GET(mbox_header, DIRECTION) ==
     130                 :            :             HINIC3_MSG_RESPONSE)
     131                 :            :                 return 0;
     132                 :            : 
     133                 :          0 :         seq_len = HINIC3_MSG_HEADER_GET(mbox_header, SEG_LEN);
     134                 :          0 :         seq_id = HINIC3_MSG_HEADER_GET(mbox_header, SEQID);
     135                 :          0 :         msg_id = HINIC3_MSG_HEADER_GET(mbox_header, MSG_ID);
     136                 :            : 
     137                 :            :         /* Check the consistency between seq_id and seg_len. */
     138         [ #  # ]:          0 :         if (!check_mgmt_seq_id_and_seg_len(recv_msg, seq_id, seq_len, msg_id)) {
     139                 :          0 :                 PMD_DRV_LOG(ERR, "Mgmt msg sequence id and segment length check failed");
     140                 :          0 :                 PMD_DRV_LOG(ERR,
     141                 :            :                             "front seq_id: 0x%x, current seq_id: 0x%x, seq_len: 0x%x front msg_id: %d, cur msg_id: %d",
     142                 :            :                             recv_msg->seq_id, seq_id, seq_len, recv_msg->msg_id, msg_id);
     143                 :            :                 /* Set seq_id to invalid seq_id. */
     144                 :          0 :                 recv_msg->seq_id = MGMT_MSG_MAX_SEQ_ID;
     145                 :          0 :                 return HINIC3_MSG_HANDLER_RES;
     146                 :            :         }
     147                 :            : 
     148                 :          0 :         offset = seq_id * SEGMENT_LEN;
     149         [ #  # ]:          0 :         memcpy((uint8_t *)recv_msg->msg + offset, msg_body, seq_len);
     150                 :            : 
     151         [ #  # ]:          0 :         if (!HINIC3_MSG_HEADER_GET(mbox_header, LAST))
     152                 :            :                 return HINIC3_MSG_HANDLER_RES;
     153                 :            :         /* Setting the message receiving information. */
     154                 :          0 :         recv_msg->cmd = HINIC3_MSG_HEADER_GET(mbox_header, CMD);
     155                 :          0 :         recv_msg->mod = HINIC3_MSG_HEADER_GET(mbox_header, MODULE);
     156                 :          0 :         recv_msg->async_mgmt_to_pf = HINIC3_MSG_HEADER_GET(mbox_header, NO_ACK);
     157                 :          0 :         recv_msg->msg_len = HINIC3_MSG_HEADER_GET(mbox_header, MSG_LEN);
     158                 :          0 :         recv_msg->msg_id = HINIC3_MSG_HEADER_GET(mbox_header, MSG_ID);
     159                 :          0 :         recv_msg->seq_id = MGMT_MSG_MAX_SEQ_ID;
     160                 :            : 
     161                 :          0 :         hinic3_mgmt_recv_msg_handler(pf_to_mgmt, recv_msg, param);
     162                 :            : 
     163                 :          0 :         return HINIC3_MSG_HANDLER_RES;
     164                 :            : }
     165                 :            : 
     166                 :            : /**
     167                 :            :  * Handler for a aeqe from mgmt channel.
     168                 :            :  *
     169                 :            :  * @param[in] hwdev
     170                 :            :  * The pointer to the private hardware device.
     171                 :            :  * @param[in] header
     172                 :            :  * The header of the message.
     173                 :            :  * @param[in] size
     174                 :            :  * Indicate size.
     175                 :            :  * @param[in] param
     176                 :            :  * Customized parameter.
     177                 :            :  * @return
     178                 :            :  * zero: When aeqe is response message
     179                 :            :  * negative: When wrong message or not last message.
     180                 :            :  */
     181                 :            : int
     182                 :          0 : hinic3_mgmt_msg_aeqe_handler(struct hinic3_hwdev *hwdev, uint8_t *header,
     183                 :            :                              uint8_t size, void *param)
     184                 :            : {
     185                 :            :         struct hinic3_msg_pf_to_mgmt *pf_to_mgmt = NULL;
     186                 :            :         struct hinic3_recv_msg *recv_msg = NULL;
     187                 :            :         bool is_send_dir = false;
     188                 :            : 
     189                 :            :         /* For mbox message, invoke the mailbox processing function. */
     190         [ #  # ]:          0 :         if ((HINIC3_MSG_HEADER_GET(*(uint64_t *)header, SOURCE) ==
     191                 :            :              HINIC3_MSG_FROM_MBOX)) {
     192                 :          0 :                 return hinic3_mbox_func_aeqe_handler(hwdev, header, size, param);
     193                 :            :         }
     194                 :            : 
     195                 :          0 :         pf_to_mgmt = hwdev->pf_to_mgmt;
     196                 :            : 
     197                 :          0 :         is_send_dir = (HINIC3_MSG_HEADER_GET(*(uint64_t *)header, DIRECTION) ==
     198                 :            :                        HINIC3_MSG_DIRECT_SEND) ? true : false;
     199                 :            : 
     200                 :            :         /* Determine whether a message is received or responded. */
     201                 :            :         recv_msg = is_send_dir ? &pf_to_mgmt->recv_msg_from_mgmt
     202         [ #  # ]:          0 :                                : &pf_to_mgmt->recv_resp_msg_from_mgmt;
     203                 :            : 
     204                 :          0 :         return recv_mgmt_msg_handler(pf_to_mgmt, header, recv_msg, param);
     205                 :            : }
     206                 :            : 
     207                 :            : /**
     208                 :            :  * Allocate received message memory.
     209                 :            :  *
     210                 :            :  * @param[in] recv_msg
     211                 :            :  * Pointer that will hold the allocated data.
     212                 :            :  * @return
     213                 :            :  * 0 on success, non-zero on failure.
     214                 :            :  */
     215                 :            : static int
     216                 :            : alloc_recv_msg(struct hinic3_recv_msg *recv_msg)
     217                 :            : {
     218                 :          0 :         recv_msg->seq_id = MGMT_MSG_MAX_SEQ_ID;
     219                 :            : 
     220                 :          0 :         recv_msg->msg = rte_zmalloc("recv_msg", MAX_PF_MGMT_BUF_SIZE,
     221                 :            :                                     HINIC3_MEM_ALLOC_ALIGN_MIN);
     222   [ #  #  #  # ]:          0 :         if (!recv_msg->msg)
     223                 :            :                 return -ENOMEM;
     224                 :            : 
     225                 :            :         return 0;
     226                 :            : }
     227                 :            : 
     228                 :            : static void
     229                 :            : free_recv_msg(struct hinic3_recv_msg *recv_msg)
     230                 :            : {
     231                 :          0 :         rte_free(recv_msg->msg);
     232                 :          0 : }
     233                 :            : 
     234                 :            : /**
     235                 :            :  * Allocate all the message buffers of PF to mgmt channel.
     236                 :            :  *
     237                 :            :  * @param[in] pf_to_mgmt
     238                 :            :  * PF to mgmt channel.
     239                 :            :  * @return
     240                 :            :  * 0 on success, non-zero on failure.
     241                 :            :  */
     242                 :            : static int
     243                 :          0 : alloc_msg_buf(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt)
     244                 :            : {
     245                 :            :         int err;
     246                 :            : 
     247                 :            :         err = alloc_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
     248                 :            :         if (err) {
     249                 :          0 :                 PMD_DRV_LOG(ERR, "Allocate recv msg failed");
     250                 :          0 :                 return err;
     251                 :            :         }
     252                 :            : 
     253                 :            :         err = alloc_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
     254                 :            :         if (err) {
     255                 :          0 :                 PMD_DRV_LOG(ERR, "Allocate resp recv msg failed");
     256                 :          0 :                 goto alloc_msg_for_resp_err;
     257                 :            :         }
     258                 :            : 
     259                 :          0 :         pf_to_mgmt->mgmt_ack_buf = rte_zmalloc("mgmt_ack_buf",
     260                 :            :                                                MAX_PF_MGMT_BUF_SIZE,
     261                 :            :                                                HINIC3_MEM_ALLOC_ALIGN_MIN);
     262         [ #  # ]:          0 :         if (!pf_to_mgmt->mgmt_ack_buf) {
     263                 :            :                 err = -ENOMEM;
     264                 :          0 :                 goto ack_msg_buf_err;
     265                 :            :         }
     266                 :            : 
     267                 :            :         return 0;
     268                 :            : 
     269                 :            : ack_msg_buf_err:
     270                 :            :         free_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
     271                 :            : 
     272                 :          0 : alloc_msg_for_resp_err:
     273                 :            :         free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
     274                 :          0 :         return err;
     275                 :            : }
     276                 :            : 
     277                 :            : /**
     278                 :            :  * Free all the message buffers of PF to mgmt channel.
     279                 :            :  *
     280                 :            :  * @param[in] pf_to_mgmt
     281                 :            :  * PF to mgmt channel.
     282                 :            :  */
     283                 :            : static void
     284                 :          0 : free_msg_buf(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt)
     285                 :            : {
     286                 :          0 :         rte_free(pf_to_mgmt->mgmt_ack_buf);
     287                 :            :         free_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
     288                 :            :         free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
     289                 :          0 : }
     290                 :            : 
     291                 :            : /**
     292                 :            :  * Initialize PF to mgmt channel.
     293                 :            :  *
     294                 :            :  * @param[in] hwdev
     295                 :            :  * The pointer to the private hardware device.
     296                 :            :  * @return
     297                 :            :  * 0 on success, non-zero on failure.
     298                 :            :  */
     299                 :            : int
     300                 :          0 : hinic3_pf_to_mgmt_init(struct hinic3_hwdev *hwdev)
     301                 :            : {
     302                 :            :         struct hinic3_msg_pf_to_mgmt *pf_to_mgmt;
     303                 :            :         int err;
     304                 :            : 
     305                 :          0 :         pf_to_mgmt = rte_zmalloc("pf_to_mgmt", sizeof(*pf_to_mgmt),
     306                 :            :                                  HINIC3_MEM_ALLOC_ALIGN_MIN);
     307         [ #  # ]:          0 :         if (!pf_to_mgmt)
     308                 :            :                 return -ENOMEM;
     309                 :            : 
     310                 :          0 :         hwdev->pf_to_mgmt = pf_to_mgmt;
     311                 :          0 :         pf_to_mgmt->hwdev = hwdev;
     312                 :            : 
     313                 :          0 :         err = alloc_msg_buf(pf_to_mgmt);
     314         [ #  # ]:          0 :         if (err) {
     315                 :          0 :                 PMD_DRV_LOG(ERR, "Allocate msg buffers failed");
     316                 :          0 :                 goto alloc_msg_buf_err;
     317                 :            :         }
     318                 :            : 
     319                 :            :         return 0;
     320                 :            : 
     321                 :            : alloc_msg_buf_err:
     322                 :          0 :         rte_free(pf_to_mgmt);
     323                 :            : 
     324                 :          0 :         return err;
     325                 :            : }
     326                 :            : 
     327                 :            : /**
     328                 :            :  * Free PF to mgmt channel.
     329                 :            :  *
     330                 :            :  * @param[in] hwdev
     331                 :            :  * The pointer to the private hardware device.
     332                 :            :  */
     333                 :            : void
     334                 :          0 : hinic3_pf_to_mgmt_free(struct hinic3_hwdev *hwdev)
     335                 :            : {
     336                 :          0 :         struct hinic3_msg_pf_to_mgmt *pf_to_mgmt = hwdev->pf_to_mgmt;
     337                 :            : 
     338                 :          0 :         free_msg_buf(pf_to_mgmt);
     339                 :          0 :         rte_free(pf_to_mgmt);
     340                 :          0 : }

Generated by: LCOV version 1.14