LCOV - code coverage report
Current view: top level - drivers/net/zxdh - zxdh_common.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 158 0.0 %
Date: 2024-12-01 18:57:19 Functions: 0 16 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 58 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2024 ZTE Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <stdint.h>
       6                 :            : #include <string.h>
       7                 :            : 
       8                 :            : #include <ethdev_driver.h>
       9                 :            : #include <rte_malloc.h>
      10                 :            : #include <rte_memcpy.h>
      11                 :            : 
      12                 :            : #include "zxdh_ethdev.h"
      13                 :            : #include "zxdh_logs.h"
      14                 :            : #include "zxdh_msg.h"
      15                 :            : #include "zxdh_common.h"
      16                 :            : 
      17                 :            : #define ZXDH_MSG_RSP_SIZE_MAX         512
      18                 :            : 
      19                 :            : #define ZXDH_COMMON_TABLE_READ        0
      20                 :            : #define ZXDH_COMMON_TABLE_WRITE       1
      21                 :            : 
      22                 :            : #define ZXDH_COMMON_FIELD_PHYPORT     6
      23                 :            : #define ZXDH_COMMON_FIELD_DATACH      3
      24                 :            : 
      25                 :            : #define ZXDH_RSC_TBL_CONTENT_LEN_MAX  (257 * 2)
      26                 :            : 
      27                 :            : #define ZXDH_REPS_HEADER_OFFSET       4
      28                 :            : #define ZXDH_TBL_MSG_PRO_SUCCESS      0xaa
      29                 :            : 
      30                 :            : struct zxdh_common_msg {
      31                 :            :         uint8_t  type;    /* 0:read table 1:write table */
      32                 :            :         uint8_t  field;
      33                 :            :         uint16_t pcie_id;
      34                 :            :         uint16_t slen;    /* Data length for write table */
      35                 :            :         uint16_t reserved;
      36                 :            : } __rte_packed;
      37                 :            : 
      38                 :            : struct zxdh_common_rsp_hdr {
      39                 :            :         uint8_t  rsp_status;
      40                 :            :         uint16_t rsp_len;
      41                 :            :         uint8_t  reserved;
      42                 :            :         uint8_t  payload_status;
      43                 :            :         uint8_t  rsv;
      44                 :            :         uint16_t payload_len;
      45                 :            : } __rte_packed;
      46                 :            : 
      47                 :            : struct zxdh_tbl_msg_header {
      48                 :            :         uint8_t  type;
      49                 :            :         uint8_t  field;
      50                 :            :         uint16_t pcieid;
      51                 :            :         uint16_t slen;
      52                 :            :         uint16_t rsv;
      53                 :            : };
      54                 :            : 
      55                 :            : struct zxdh_tbl_msg_reps_header {
      56                 :            :         uint8_t  check;
      57                 :            :         uint8_t  rsv;
      58                 :            :         uint16_t len;
      59                 :            : };
      60                 :            : 
      61                 :            : static int32_t
      62                 :          0 : zxdh_fill_common_msg(struct zxdh_hw *hw, struct zxdh_pci_bar_msg *desc,
      63                 :            :                 uint8_t type, uint8_t field,
      64                 :            :                 void *buff, uint16_t buff_size)
      65                 :            : {
      66                 :          0 :         uint64_t msg_len = sizeof(struct zxdh_common_msg) + buff_size;
      67                 :            : 
      68                 :          0 :         desc->payload_addr = rte_zmalloc(NULL, msg_len, 0);
      69         [ #  # ]:          0 :         if (unlikely(desc->payload_addr == NULL)) {
      70                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate msg_data");
      71                 :          0 :                 return -ENOMEM;
      72                 :            :         }
      73                 :            :         memset(desc->payload_addr, 0, msg_len);
      74                 :          0 :         desc->payload_len = msg_len;
      75                 :            :         struct zxdh_common_msg *msg_data = (struct zxdh_common_msg *)desc->payload_addr;
      76                 :            : 
      77                 :          0 :         msg_data->type = type;
      78                 :          0 :         msg_data->field = field;
      79                 :          0 :         msg_data->pcie_id = hw->pcie_id;
      80                 :          0 :         msg_data->slen = buff_size;
      81         [ #  # ]:          0 :         if (buff_size != 0)
      82         [ #  # ]:          0 :                 rte_memcpy(msg_data + 1, buff, buff_size);
      83                 :            : 
      84                 :            :         return 0;
      85                 :            : }
      86                 :            : 
      87                 :            : static int32_t
      88                 :          0 : zxdh_send_command(struct zxdh_hw *hw, struct zxdh_pci_bar_msg *desc,
      89                 :            :                 enum ZXDH_BAR_MODULE_ID module_id,
      90                 :            :                 struct zxdh_msg_recviver_mem *msg_rsp)
      91                 :            : {
      92                 :          0 :         desc->virt_addr = (uint64_t)(hw->bar_addr[ZXDH_BAR0_INDEX] + ZXDH_CTRLCH_OFFSET);
      93         [ #  # ]:          0 :         desc->src = hw->is_pf ? ZXDH_MSG_CHAN_END_PF : ZXDH_MSG_CHAN_END_VF;
      94                 :          0 :         desc->dst = ZXDH_MSG_CHAN_END_RISC;
      95                 :          0 :         desc->module_id = module_id;
      96                 :          0 :         desc->src_pcieid = hw->pcie_id;
      97                 :            : 
      98                 :          0 :         msg_rsp->buffer_len  = ZXDH_MSG_RSP_SIZE_MAX;
      99                 :          0 :         msg_rsp->recv_buffer = rte_zmalloc(NULL, msg_rsp->buffer_len, 0);
     100         [ #  # ]:          0 :         if (unlikely(msg_rsp->recv_buffer == NULL)) {
     101                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate messages response");
     102                 :          0 :                 return -ENOMEM;
     103                 :            :         }
     104                 :            : 
     105         [ #  # ]:          0 :         if (zxdh_bar_chan_sync_msg_send(desc, msg_rsp) != ZXDH_BAR_MSG_OK) {
     106                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to send sync messages or receive response");
     107                 :          0 :                 rte_free(msg_rsp->recv_buffer);
     108                 :          0 :                 return -1;
     109                 :            :         }
     110                 :            : 
     111                 :            :         return 0;
     112                 :            : }
     113                 :            : 
     114                 :            : static int32_t
     115                 :          0 : zxdh_common_rsp_check(struct zxdh_msg_recviver_mem *msg_rsp,
     116                 :            :                 void *buff, uint16_t len)
     117                 :            : {
     118                 :          0 :         struct zxdh_common_rsp_hdr *rsp_hdr = (struct zxdh_common_rsp_hdr *)msg_rsp->recv_buffer;
     119                 :            : 
     120   [ #  #  #  # ]:          0 :         if (rsp_hdr->payload_status != 0xaa || rsp_hdr->payload_len != len) {
     121                 :          0 :                 PMD_DRV_LOG(ERR, "Common response is invalid, status:0x%x rsp_len:%d",
     122                 :            :                                         rsp_hdr->payload_status, rsp_hdr->payload_len);
     123                 :          0 :                 return -1;
     124                 :            :         }
     125         [ #  # ]:          0 :         if (len != 0)
     126         [ #  # ]:          0 :                 rte_memcpy(buff, rsp_hdr + 1, len);
     127                 :            : 
     128                 :            :         return 0;
     129                 :            : }
     130                 :            : 
     131                 :            : static int32_t
     132                 :          0 : zxdh_common_table_read(struct zxdh_hw *hw, uint8_t field,
     133                 :            :                 void *buff, uint16_t buff_size)
     134                 :            : {
     135                 :            :         struct zxdh_msg_recviver_mem msg_rsp;
     136                 :            :         struct zxdh_pci_bar_msg desc;
     137                 :            :         int32_t ret = 0;
     138                 :            : 
     139         [ #  # ]:          0 :         if (!hw->msg_chan_init) {
     140                 :          0 :                 PMD_DRV_LOG(ERR, "Bar messages channel not initialized");
     141                 :          0 :                 return -1;
     142                 :            :         }
     143                 :            : 
     144                 :          0 :         ret = zxdh_fill_common_msg(hw, &desc, ZXDH_COMMON_TABLE_READ, field, NULL, 0);
     145         [ #  # ]:          0 :         if (ret != 0) {
     146                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to fill common msg");
     147                 :          0 :                 return ret;
     148                 :            :         }
     149                 :            : 
     150                 :          0 :         ret = zxdh_send_command(hw, &desc, ZXDH_BAR_MODULE_TBL, &msg_rsp);
     151         [ #  # ]:          0 :         if (ret != 0)
     152                 :          0 :                 goto free_msg_data;
     153                 :            : 
     154                 :          0 :         ret = zxdh_common_rsp_check(&msg_rsp, buff, buff_size);
     155                 :            :         if (ret != 0)
     156                 :            :                 goto free_rsp_data;
     157                 :            : 
     158                 :            : free_rsp_data:
     159                 :          0 :         rte_free(msg_rsp.recv_buffer);
     160                 :          0 : free_msg_data:
     161                 :          0 :         rte_free(desc.payload_addr);
     162                 :          0 :         return ret;
     163                 :            : }
     164                 :            : 
     165                 :            : int32_t
     166                 :          0 : zxdh_phyport_get(struct rte_eth_dev *dev, uint8_t *phyport)
     167                 :            : {
     168                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     169                 :            : 
     170                 :          0 :         int32_t ret = zxdh_common_table_read(hw, ZXDH_COMMON_FIELD_PHYPORT,
     171                 :            :                                         (void *)phyport, sizeof(*phyport));
     172                 :          0 :         return ret;
     173                 :            : }
     174                 :            : 
     175                 :            : static inline void
     176                 :            : zxdh_fill_res_para(struct rte_eth_dev *dev, struct zxdh_res_para *param)
     177                 :            : {
     178                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     179                 :            : 
     180                 :          0 :         param->pcie_id   = hw->pcie_id;
     181                 :          0 :         param->virt_addr = hw->bar_addr[0] + ZXDH_CTRLCH_OFFSET;
     182                 :          0 :         param->src_type  = ZXDH_BAR_MODULE_TBL;
     183                 :            : }
     184                 :            : 
     185                 :            : static int
     186                 :          0 : zxdh_get_res_info(struct zxdh_res_para *dev, uint8_t field, uint8_t *res, uint16_t *len)
     187                 :            : {
     188                 :          0 :         struct zxdh_pci_bar_msg in = {0};
     189                 :          0 :         uint8_t recv_buf[ZXDH_RSC_TBL_CONTENT_LEN_MAX + 8] = {0};
     190                 :            :         int ret = 0;
     191                 :            : 
     192         [ #  # ]:          0 :         if (!res || !dev)
     193                 :            :                 return ZXDH_BAR_MSG_ERR_NULL;
     194                 :            : 
     195                 :          0 :         struct zxdh_tbl_msg_header tbl_msg = {
     196                 :            :                 .type = ZXDH_TBL_TYPE_READ,
     197                 :            :                 .field = field,
     198                 :          0 :                 .pcieid = dev->pcie_id,
     199                 :            :                 .slen = 0,
     200                 :            :                 .rsv = 0,
     201                 :            :         };
     202                 :            : 
     203                 :          0 :         in.virt_addr = dev->virt_addr;
     204                 :          0 :         in.payload_addr = &tbl_msg;
     205                 :          0 :         in.payload_len = sizeof(tbl_msg);
     206                 :          0 :         in.src = dev->src_type;
     207                 :          0 :         in.dst = ZXDH_MSG_CHAN_END_RISC;
     208                 :          0 :         in.module_id = ZXDH_BAR_MODULE_TBL;
     209                 :          0 :         in.src_pcieid = dev->pcie_id;
     210                 :            : 
     211                 :          0 :         struct zxdh_msg_recviver_mem result = {
     212                 :            :                 .recv_buffer = recv_buf,
     213                 :            :                 .buffer_len = sizeof(recv_buf),
     214                 :            :         };
     215                 :          0 :         ret = zxdh_bar_chan_sync_msg_send(&in, &result);
     216                 :            : 
     217         [ #  # ]:          0 :         if (ret != ZXDH_BAR_MSG_OK) {
     218                 :          0 :                 PMD_DRV_LOG(ERR,
     219                 :            :                         "send sync_msg failed. pcieid: 0x%x, ret: %d.", dev->pcie_id, ret);
     220                 :          0 :                 return ret;
     221                 :            :         }
     222                 :            :         struct zxdh_tbl_msg_reps_header *tbl_reps =
     223                 :            :                 (struct zxdh_tbl_msg_reps_header *)(recv_buf + ZXDH_REPS_HEADER_OFFSET);
     224                 :            : 
     225         [ #  # ]:          0 :         if (tbl_reps->check != ZXDH_TBL_MSG_PRO_SUCCESS) {
     226                 :          0 :                 PMD_DRV_LOG(ERR,
     227                 :            :                         "get resource_field failed. pcieid: 0x%x, ret: %d.", dev->pcie_id, ret);
     228                 :          0 :                 return ret;
     229                 :            :         }
     230                 :          0 :         *len = tbl_reps->len;
     231         [ #  # ]:          0 :         rte_memcpy(res, (recv_buf + ZXDH_REPS_HEADER_OFFSET +
     232                 :            :                 sizeof(struct zxdh_tbl_msg_reps_header)), *len);
     233                 :            :         return ret;
     234                 :            : }
     235                 :            : 
     236                 :            : static int
     237                 :          0 : zxdh_get_res_panel_id(struct zxdh_res_para *in, uint8_t *panel_id)
     238                 :            : {
     239                 :          0 :         uint8_t reps = 0;
     240                 :          0 :         uint16_t reps_len = 0;
     241                 :            : 
     242         [ #  # ]:          0 :         if (zxdh_get_res_info(in, ZXDH_TBL_FIELD_PNLID, &reps, &reps_len) != ZXDH_BAR_MSG_OK)
     243                 :            :                 return -1;
     244                 :            : 
     245                 :          0 :         *panel_id = reps;
     246                 :          0 :         return ZXDH_BAR_MSG_OK;
     247                 :            : }
     248                 :            : 
     249                 :            : int32_t
     250                 :          0 : zxdh_panelid_get(struct rte_eth_dev *dev, uint8_t *panelid)
     251                 :            : {
     252                 :            :         struct zxdh_res_para param;
     253                 :            : 
     254                 :            :         zxdh_fill_res_para(dev, &param);
     255                 :          0 :         int32_t ret = zxdh_get_res_panel_id(&param, panelid);
     256                 :          0 :         return ret;
     257                 :            : }
     258                 :            : 
     259                 :            : uint32_t
     260                 :          0 : zxdh_read_bar_reg(struct rte_eth_dev *dev, uint32_t bar, uint32_t reg)
     261                 :            : {
     262                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     263                 :          0 :         uint64_t baseaddr = (uint64_t)(hw->bar_addr[bar]);
     264                 :          0 :         uint32_t val      = *((volatile uint32_t *)(baseaddr + reg));
     265                 :          0 :         return val;
     266                 :            : }
     267                 :            : 
     268                 :            : void
     269                 :          0 : zxdh_write_bar_reg(struct rte_eth_dev *dev, uint32_t bar, uint32_t reg, uint32_t val)
     270                 :            : {
     271                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     272                 :          0 :         uint64_t baseaddr = (uint64_t)(hw->bar_addr[bar]);
     273                 :          0 :         *((volatile uint32_t *)(baseaddr + reg)) = val;
     274                 :          0 : }
     275                 :            : 
     276                 :            : static bool
     277                 :            : zxdh_try_lock(struct zxdh_hw *hw)
     278                 :            : {
     279                 :          0 :         uint32_t var = zxdh_read_comm_reg((uint64_t)hw->common_cfg, ZXDH_VF_LOCK_REG);
     280                 :            : 
     281                 :            :         /* check whether lock is used */
     282         [ #  # ]:          0 :         if (!(var & ZXDH_VF_LOCK_ENABLE_MASK))
     283                 :            :                 return false;
     284                 :            : 
     285                 :            :         return true;
     286                 :            : }
     287                 :            : 
     288                 :            : int32_t
     289                 :          0 : zxdh_timedlock(struct zxdh_hw *hw, uint32_t us)
     290                 :            : {
     291                 :            :         uint16_t timeout = 0;
     292                 :            : 
     293         [ #  # ]:          0 :         while ((timeout++) < ZXDH_ACQUIRE_CHANNEL_NUM_MAX) {
     294                 :          0 :                 rte_delay_us_block(us);
     295                 :            :                 /* acquire hw lock */
     296                 :          0 :                 if (!zxdh_try_lock(hw)) {
     297                 :          0 :                         PMD_DRV_LOG(ERR, "Acquiring hw lock got failed, timeout: %d", timeout);
     298                 :          0 :                         continue;
     299                 :            :                 }
     300                 :            :                 break;
     301                 :            :         }
     302         [ #  # ]:          0 :         if (timeout >= ZXDH_ACQUIRE_CHANNEL_NUM_MAX) {
     303                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to acquire channel");
     304                 :          0 :                 return -1;
     305                 :            :         }
     306                 :            :         return 0;
     307                 :            : }
     308                 :            : 
     309                 :            : void
     310                 :          0 : zxdh_release_lock(struct zxdh_hw *hw)
     311                 :            : {
     312                 :          0 :         uint32_t var = zxdh_read_comm_reg((uint64_t)hw->common_cfg, ZXDH_VF_LOCK_REG);
     313                 :            : 
     314         [ #  # ]:          0 :         if (var & ZXDH_VF_LOCK_ENABLE_MASK) {
     315                 :          0 :                 var &= ~ZXDH_VF_LOCK_ENABLE_MASK;
     316                 :          0 :                 zxdh_write_comm_reg((uint64_t)hw->common_cfg, ZXDH_VF_LOCK_REG, var);
     317                 :            :         }
     318                 :          0 : }
     319                 :            : 
     320                 :            : uint32_t
     321                 :          0 : zxdh_read_comm_reg(uint64_t pci_comm_cfg_baseaddr, uint32_t reg)
     322                 :            : {
     323                 :          0 :         uint32_t val = *((volatile uint32_t *)(pci_comm_cfg_baseaddr + reg));
     324                 :          0 :         return val;
     325                 :            : }
     326                 :            : 
     327                 :            : void
     328                 :          0 : zxdh_write_comm_reg(uint64_t pci_comm_cfg_baseaddr, uint32_t reg, uint32_t val)
     329                 :            : {
     330                 :          0 :         *((volatile uint32_t *)(pci_comm_cfg_baseaddr + reg)) = val;
     331                 :          0 : }
     332                 :            : 
     333                 :            : static int32_t
     334                 :          0 : zxdh_common_table_write(struct zxdh_hw *hw, uint8_t field,
     335                 :            :                         void *buff, uint16_t buff_size)
     336                 :            : {
     337                 :            :         struct zxdh_pci_bar_msg desc;
     338                 :            :         struct zxdh_msg_recviver_mem msg_rsp;
     339                 :            :         int32_t ret = 0;
     340                 :            : 
     341         [ #  # ]:          0 :         if (!hw->msg_chan_init) {
     342                 :          0 :                 PMD_DRV_LOG(ERR, "Bar messages channel not initialized");
     343                 :          0 :                 return -1;
     344                 :            :         }
     345         [ #  # ]:          0 :         if (buff_size != 0 && buff == NULL) {
     346                 :          0 :                 PMD_DRV_LOG(ERR, "Buff is invalid");
     347                 :          0 :                 return -1;
     348                 :            :         }
     349                 :            : 
     350                 :          0 :         ret = zxdh_fill_common_msg(hw, &desc, ZXDH_COMMON_TABLE_WRITE,
     351                 :            :                                         field, buff, buff_size);
     352                 :            : 
     353         [ #  # ]:          0 :         if (ret != 0) {
     354                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to fill common msg");
     355                 :          0 :                 return ret;
     356                 :            :         }
     357                 :            : 
     358                 :          0 :         ret = zxdh_send_command(hw, &desc, ZXDH_BAR_MODULE_TBL, &msg_rsp);
     359         [ #  # ]:          0 :         if (ret != 0)
     360                 :          0 :                 goto free_msg_data;
     361                 :            : 
     362                 :          0 :         ret = zxdh_common_rsp_check(&msg_rsp, NULL, 0);
     363                 :            :         if (ret != 0)
     364                 :            :                 goto free_rsp_data;
     365                 :            : 
     366                 :            : free_rsp_data:
     367                 :          0 :         rte_free(msg_rsp.recv_buffer);
     368                 :          0 : free_msg_data:
     369                 :          0 :         rte_free(desc.payload_addr);
     370                 :          0 :         return ret;
     371                 :            : }
     372                 :            : 
     373                 :            : int32_t
     374                 :          0 : zxdh_datach_set(struct rte_eth_dev *dev)
     375                 :            : {
     376                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     377                 :          0 :         uint16_t buff_size = (hw->queue_num + 1) * 2;
     378                 :            :         int32_t ret = 0;
     379                 :            :         uint16_t i;
     380                 :            : 
     381                 :          0 :         void *buff = rte_zmalloc(NULL, buff_size, 0);
     382         [ #  # ]:          0 :         if (unlikely(buff == NULL)) {
     383                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate buff");
     384                 :          0 :                 return -ENOMEM;
     385                 :            :         }
     386                 :            :         memset(buff, 0, buff_size);
     387                 :            :         uint16_t *pdata = (uint16_t *)buff;
     388                 :          0 :         *pdata++ = hw->queue_num;
     389                 :            : 
     390         [ #  # ]:          0 :         for (i = 0; i < hw->queue_num; i++)
     391                 :          0 :                 *(pdata + i) = hw->channel_context[i].ph_chno;
     392                 :            : 
     393                 :          0 :         ret = zxdh_common_table_write(hw, ZXDH_COMMON_FIELD_DATACH,
     394                 :            :                                                 (void *)buff, buff_size);
     395         [ #  # ]:          0 :         if (ret != 0)
     396                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to setup data channel of common table");
     397                 :            : 
     398                 :          0 :         rte_free(buff);
     399                 :          0 :         return ret;
     400                 :            : }

Generated by: LCOV version 1.14