LCOV - code coverage report
Current view: top level - drivers/net/nfp/nfpcore - nfp_nsp.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 204 0.0 %
Date: 2024-04-01 19:00:53 Functions: 0 29 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 90 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2018 Netronome Systems, Inc.
       3                 :            :  * All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "nfp_nsp.h"
       7                 :            : 
       8                 :            : #include <nfp_platform.h>
       9                 :            : #include <rte_common.h>
      10                 :            : 
      11                 :            : #include "nfp_logs.h"
      12                 :            : #include "nfp_resource.h"
      13                 :            : 
      14                 :            : /* Offsets relative to the CSR base */
      15                 :            : #define NSP_STATUS              0x00
      16                 :            : #define   NSP_STATUS_MAGIC      GENMASK_ULL(63, 48)
      17                 :            : #define   NSP_STATUS_MAJOR      GENMASK_ULL(47, 44)
      18                 :            : #define   NSP_STATUS_MINOR      GENMASK_ULL(43, 32)
      19                 :            : #define   NSP_STATUS_CODE       GENMASK_ULL(31, 16)
      20                 :            : #define   NSP_STATUS_RESULT     GENMASK_ULL(15, 8)
      21                 :            : #define   NSP_STATUS_BUSY       RTE_BIT64(0)
      22                 :            : 
      23                 :            : #define NSP_COMMAND             0x08
      24                 :            : #define   NSP_COMMAND_OPTION    GENMASK_ULL(63, 32)
      25                 :            : #define   NSP_COMMAND_VER_MAJOR GENMASK_ULL(31, 28)
      26                 :            : #define   NSP_COMMAND_CODE      GENMASK_ULL(27, 16)
      27                 :            : #define   NSP_COMMAND_DMA_BUF   RTE_BIT64(1)
      28                 :            : #define   NSP_COMMAND_START     RTE_BIT64(0)
      29                 :            : 
      30                 :            : /* CPP address to retrieve the data from */
      31                 :            : #define NSP_BUFFER              0x10
      32                 :            : #define   NSP_BUFFER_CPP        GENMASK_ULL(63, 40)
      33                 :            : #define   NSP_BUFFER_ADDRESS    GENMASK_ULL(39, 0)
      34                 :            : 
      35                 :            : #define NSP_DFLT_BUFFER         0x18
      36                 :            : #define   NSP_DFLT_BUFFER_CPP          GENMASK_ULL(63, 40)
      37                 :            : #define   NSP_DFLT_BUFFER_ADDRESS      GENMASK_ULL(39, 0)
      38                 :            : 
      39                 :            : #define NSP_DFLT_BUFFER_CONFIG  0x20
      40                 :            : #define   NSP_DFLT_BUFFER_SIZE_4KB     GENMASK_ULL(15, 8)
      41                 :            : #define   NSP_DFLT_BUFFER_SIZE_MB      GENMASK_ULL(7, 0)
      42                 :            : 
      43                 :            : #define NSP_MAGIC               0xab10
      44                 :            : 
      45                 :            : /*
      46                 :            :  * ABI major version is bumped separately without resetting minor
      47                 :            :  * version when the change in NSP is not compatible to old driver.
      48                 :            :  */
      49                 :            : #define NSP_MAJOR               1
      50                 :            : 
      51                 :            : /*
      52                 :            :  * ABI minor version is bumped when new feature is introduced
      53                 :            :  * while old driver can still work without this new feature.
      54                 :            :  */
      55                 :            : #define NSP_MINOR               8
      56                 :            : 
      57                 :            : #define NSP_CODE_MAJOR          GENMASK_ULL(15, 12)
      58                 :            : #define NSP_CODE_MINOR          GENMASK_ULL(11, 0)
      59                 :            : 
      60                 :            : #define NFP_FW_LOAD_RET_MAJOR   GENMASK_ULL(15, 8)
      61                 :            : #define NFP_FW_LOAD_RET_MINOR   GENMASK_ULL(23, 16)
      62                 :            : 
      63                 :            : enum nfp_nsp_cmd {
      64                 :            :         SPCODE_NOOP             = 0, /* No operation */
      65                 :            :         SPCODE_SOFT_RESET       = 1, /* Soft reset the NFP */
      66                 :            :         SPCODE_FW_DEFAULT       = 2, /* Load default (UNDI) FW */
      67                 :            :         SPCODE_PHY_INIT         = 3, /* Initialize the PHY */
      68                 :            :         SPCODE_MAC_INIT         = 4, /* Initialize the MAC */
      69                 :            :         SPCODE_PHY_RXADAPT      = 5, /* Re-run PHY RX Adaptation */
      70                 :            :         SPCODE_FW_LOAD          = 6, /* Load fw from buffer, len in option */
      71                 :            :         SPCODE_ETH_RESCAN       = 7, /* Rescan ETHs, write ETH_TABLE to buf */
      72                 :            :         SPCODE_ETH_CONTROL      = 8, /* Update media config from buffer */
      73                 :            :         SPCODE_NSP_WRITE_FLASH  = 11, /* Load and flash image from buffer */
      74                 :            :         SPCODE_NSP_SENSORS      = 12, /* Read NSP sensor(s) */
      75                 :            :         SPCODE_NSP_IDENTIFY     = 13, /* Read NSP version */
      76                 :            :         SPCODE_FW_STORED        = 16, /* If no FW loaded, load flash app FW */
      77                 :            :         SPCODE_HWINFO_LOOKUP    = 17, /* Lookup HWinfo with overwrites etc. */
      78                 :            :         SPCODE_HWINFO_SET       = 18, /* Set HWinfo entry */
      79                 :            :         SPCODE_FW_LOADED        = 19, /* Is application firmware loaded */
      80                 :            :         SPCODE_VERSIONS         = 21, /* Report FW versions */
      81                 :            :         SPCODE_READ_SFF_EEPROM  = 22, /* Read module EEPROM */
      82                 :            :         SPCODE_READ_MEDIA       = 23, /* Get the supported/advertised media for a port */
      83                 :            : };
      84                 :            : 
      85                 :            : static const struct {
      86                 :            :         uint32_t code;
      87                 :            :         const char *msg;
      88                 :            : } nsp_errors[] = {
      89                 :            :         { 6010, "could not map to phy for port" },
      90                 :            :         { 6011, "not an allowed rate/lanes for port" },
      91                 :            :         { 6012, "not an allowed rate/lanes for port" },
      92                 :            :         { 6013, "high/low error, change other port first" },
      93                 :            :         { 6014, "config not found in flash" },
      94                 :            : };
      95                 :            : 
      96                 :            : struct nfp_nsp {
      97                 :            :         struct nfp_cpp *cpp;
      98                 :            :         struct nfp_resource *res;
      99                 :            :         struct {
     100                 :            :                 uint16_t major;
     101                 :            :                 uint16_t minor;
     102                 :            :         } ver;
     103                 :            : 
     104                 :            :         /** Eth table config state */
     105                 :            :         bool modified;
     106                 :            :         uint32_t idx;
     107                 :            :         void *entries;
     108                 :            : };
     109                 :            : 
     110                 :            : /* NFP command argument structure */
     111                 :            : struct nfp_nsp_command_arg {
     112                 :            :         uint16_t code;         /**< NFP SP Command Code */
     113                 :            :         bool dma;              /**< @buf points to a host buffer, not NSP buffer */
     114                 :            :         bool error_quiet;      /**< Don't print command error/warning */
     115                 :            :         uint32_t timeout_sec;  /**< Timeout value to wait for completion in seconds */
     116                 :            :         uint32_t option;       /**< NSP Command Argument */
     117                 :            :         uint64_t buf;          /**< NSP Buffer Address */
     118                 :            :         /** Callback for interpreting option if error occurred */
     119                 :            :         void (*error_cb)(struct nfp_nsp *state, uint32_t ret_val);
     120                 :            : };
     121                 :            : 
     122                 :            : /* NFP command with buffer argument structure */
     123                 :            : struct nfp_nsp_command_buf_arg {
     124                 :            :         struct nfp_nsp_command_arg arg;  /**< NFP command argument structure */
     125                 :            :         const void *in_buf;              /**< Buffer with data for input */
     126                 :            :         void *out_buf;                   /**< Buffer for output data */
     127                 :            :         uint32_t in_size;                /**< Size of @in_buf */
     128                 :            :         uint32_t out_size;               /**< Size of @out_buf */
     129                 :            : };
     130                 :            : 
     131                 :            : struct nfp_cpp *
     132                 :          0 : nfp_nsp_cpp(struct nfp_nsp *state)
     133                 :            : {
     134                 :          0 :         return state->cpp;
     135                 :            : }
     136                 :            : 
     137                 :            : bool
     138                 :          0 : nfp_nsp_config_modified(struct nfp_nsp *state)
     139                 :            : {
     140                 :          0 :         return state->modified;
     141                 :            : }
     142                 :            : 
     143                 :            : void
     144                 :          0 : nfp_nsp_config_set_modified(struct nfp_nsp *state,
     145                 :            :                 bool modified)
     146                 :            : {
     147                 :          0 :         state->modified = modified;
     148                 :          0 : }
     149                 :            : 
     150                 :            : void *
     151                 :          0 : nfp_nsp_config_entries(struct nfp_nsp *state)
     152                 :            : {
     153                 :          0 :         return state->entries;
     154                 :            : }
     155                 :            : 
     156                 :            : uint32_t
     157                 :          0 : nfp_nsp_config_idx(struct nfp_nsp *state)
     158                 :            : {
     159                 :          0 :         return state->idx;
     160                 :            : }
     161                 :            : 
     162                 :            : void
     163                 :          0 : nfp_nsp_config_set_state(struct nfp_nsp *state,
     164                 :            :                 void *entries,
     165                 :            :                 uint32_t idx)
     166                 :            : {
     167                 :          0 :         state->entries = entries;
     168                 :          0 :         state->idx = idx;
     169                 :          0 : }
     170                 :            : 
     171                 :            : void
     172                 :          0 : nfp_nsp_config_clear_state(struct nfp_nsp *state)
     173                 :            : {
     174                 :          0 :         state->entries = NULL;
     175                 :          0 :         state->idx = 0;
     176                 :          0 : }
     177                 :            : 
     178                 :            : static void
     179                 :          0 : nfp_nsp_print_extended_error(uint32_t ret_val)
     180                 :            : {
     181                 :            :         uint32_t i;
     182                 :            : 
     183         [ #  # ]:          0 :         if (ret_val == 0)
     184                 :            :                 return;
     185                 :            : 
     186         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(nsp_errors); i++)
     187         [ #  # ]:          0 :                 if (ret_val == nsp_errors[i].code)
     188                 :          0 :                         PMD_DRV_LOG(ERR, "err msg: %s", nsp_errors[i].msg);
     189                 :            : }
     190                 :            : 
     191                 :            : static int
     192                 :          0 : nfp_nsp_check(struct nfp_nsp *state)
     193                 :            : {
     194                 :            :         int err;
     195                 :            :         uint64_t reg;
     196                 :            :         uint32_t nsp_cpp;
     197                 :            :         uint64_t nsp_status;
     198                 :          0 :         struct nfp_cpp *cpp = state->cpp;
     199                 :            : 
     200                 :          0 :         nsp_cpp = nfp_resource_cpp_id(state->res);
     201                 :          0 :         nsp_status = nfp_resource_address(state->res) + NSP_STATUS;
     202                 :            : 
     203                 :          0 :         err = nfp_cpp_readq(cpp, nsp_cpp, nsp_status, &reg);
     204         [ #  # ]:          0 :         if (err < 0) {
     205                 :          0 :                 PMD_DRV_LOG(ERR, "NSP - CPP readq failed %d", err);
     206                 :          0 :                 return err;
     207                 :            :         }
     208                 :            : 
     209         [ #  # ]:          0 :         if (FIELD_GET(NSP_STATUS_MAGIC, reg) != NSP_MAGIC) {
     210                 :          0 :                 PMD_DRV_LOG(ERR, "Cannot detect NFP Service Processor");
     211                 :          0 :                 return -ENODEV;
     212                 :            :         }
     213                 :            : 
     214                 :          0 :         state->ver.major = FIELD_GET(NSP_STATUS_MAJOR, reg);
     215                 :          0 :         state->ver.minor = FIELD_GET(NSP_STATUS_MINOR, reg);
     216                 :            : 
     217   [ #  #  #  # ]:          0 :         if (state->ver.major > NSP_MAJOR || state->ver.minor < NSP_MINOR) {
     218                 :          0 :                 PMD_DRV_LOG(ERR, "Unsupported ABI %hu.%hu", state->ver.major,
     219                 :            :                                 state->ver.minor);
     220                 :          0 :                 return -EINVAL;
     221                 :            :         }
     222                 :            : 
     223         [ #  # ]:          0 :         if ((reg & NSP_STATUS_BUSY) != 0) {
     224                 :          0 :                 PMD_DRV_LOG(DEBUG, "Service processor busy!");
     225                 :          0 :                 return -EBUSY;
     226                 :            :         }
     227                 :            : 
     228                 :            :         return 0;
     229                 :            : }
     230                 :            : 
     231                 :            : /**
     232                 :            :  * Prepare for communication and lock the NSP resource.
     233                 :            :  *
     234                 :            :  * @param cpp
     235                 :            :  *   NFP CPP Handle
     236                 :            :  */
     237                 :            : struct nfp_nsp *
     238                 :          0 : nfp_nsp_open(struct nfp_cpp *cpp)
     239                 :            : {
     240                 :            :         int err;
     241                 :            :         struct nfp_nsp *state;
     242                 :            :         struct nfp_resource *res;
     243                 :            : 
     244                 :          0 :         res = nfp_resource_acquire(cpp, NFP_RESOURCE_NSP);
     245         [ #  # ]:          0 :         if (res == NULL) {
     246                 :          0 :                 PMD_DRV_LOG(ERR, "NSP - resource acquire failed");
     247                 :          0 :                 return NULL;
     248                 :            :         }
     249                 :            : 
     250                 :          0 :         state = malloc(sizeof(*state));
     251         [ #  # ]:          0 :         if (state == NULL) {
     252                 :          0 :                 nfp_resource_release(res);
     253                 :          0 :                 return NULL;
     254                 :            :         }
     255                 :            :         memset(state, 0, sizeof(*state));
     256                 :          0 :         state->cpp = cpp;
     257                 :          0 :         state->res = res;
     258                 :            : 
     259                 :          0 :         err = nfp_nsp_check(state);
     260         [ #  # ]:          0 :         if (err != 0) {
     261                 :          0 :                 PMD_DRV_LOG(DEBUG, "NSP - check failed");
     262                 :          0 :                 nfp_nsp_close(state);
     263                 :          0 :                 return NULL;
     264                 :            :         }
     265                 :            : 
     266                 :            :         return state;
     267                 :            : }
     268                 :            : 
     269                 :            : /**
     270                 :            :  * Clean up and unlock the NSP resource.
     271                 :            :  *
     272                 :            :  * @param state
     273                 :            :  *   NFP SP state
     274                 :            :  */
     275                 :            : void
     276                 :          0 : nfp_nsp_close(struct nfp_nsp *state)
     277                 :            : {
     278                 :          0 :         nfp_resource_release(state->res);
     279                 :          0 :         free(state);
     280                 :          0 : }
     281                 :            : 
     282                 :            : uint16_t
     283                 :          0 : nfp_nsp_get_abi_ver_major(struct nfp_nsp *state)
     284                 :            : {
     285                 :          0 :         return state->ver.major;
     286                 :            : }
     287                 :            : 
     288                 :            : uint16_t
     289                 :          0 : nfp_nsp_get_abi_ver_minor(struct nfp_nsp *state)
     290                 :            : {
     291                 :          0 :         return state->ver.minor;
     292                 :            : }
     293                 :            : 
     294                 :            : static int
     295                 :          0 : nfp_nsp_wait_reg(struct nfp_cpp *cpp,
     296                 :            :                 uint64_t *reg,
     297                 :            :                 uint32_t nsp_cpp,
     298                 :            :                 uint64_t addr,
     299                 :            :                 uint64_t mask,
     300                 :            :                 uint64_t val)
     301                 :            : {
     302                 :            :         int err;
     303                 :            :         uint32_t count = 0;
     304                 :            :         struct timespec wait;
     305                 :            : 
     306                 :          0 :         wait.tv_sec = 0;
     307                 :          0 :         wait.tv_nsec = 25000000;     /* 25ms */
     308                 :            : 
     309                 :            :         for (;;) {
     310                 :          0 :                 err = nfp_cpp_readq(cpp, nsp_cpp, addr, reg);
     311         [ #  # ]:          0 :                 if (err < 0) {
     312                 :          0 :                         PMD_DRV_LOG(ERR, "NSP - CPP readq failed");
     313                 :          0 :                         return err;
     314                 :            :                 }
     315                 :            : 
     316         [ #  # ]:          0 :                 if ((*reg & mask) == val)
     317                 :            :                         return 0;
     318                 :            : 
     319                 :          0 :                 nanosleep(&wait, 0);
     320         [ #  # ]:          0 :                 if (count++ > 1000)     /* 25ms * 1000 = 25s */
     321                 :            :                         return -ETIMEDOUT;
     322                 :            :         }
     323                 :            : }
     324                 :            : 
     325                 :            : /**
     326                 :            :  * Execute a command on the NFP Service Processor
     327                 :            :  *
     328                 :            :  * @param state
     329                 :            :  *   NFP SP state
     330                 :            :  * @param arg
     331                 :            :  *   NFP command argument structure
     332                 :            :  *
     333                 :            :  * @return
     334                 :            :  *   - 0 for success with no result
     335                 :            :  *   - Positive value for NSP completion with a result code
     336                 :            :  *   - -EAGAIN if the NSP is not yet present
     337                 :            :  *   - -ENODEV if the NSP is not a supported model
     338                 :            :  *   - -EBUSY if the NSP is stuck
     339                 :            :  *   - -EINTR if interrupted while waiting for completion
     340                 :            :  *   - -ETIMEDOUT if the NSP took longer than @timeout_sec seconds to complete
     341                 :            :  */
     342                 :            : static int
     343                 :          0 : nfp_nsp_command_real(struct nfp_nsp *state,
     344                 :            :                 const struct nfp_nsp_command_arg *arg)
     345                 :            : {
     346                 :            :         int err;
     347                 :            :         uint64_t reg;
     348                 :            :         uint32_t nsp_cpp;
     349                 :            :         uint64_t ret_val;
     350                 :            :         uint64_t nsp_base;
     351                 :            :         uint64_t nsp_buffer;
     352                 :            :         uint64_t nsp_status;
     353                 :            :         uint64_t nsp_command;
     354                 :          0 :         struct nfp_cpp *cpp = state->cpp;
     355                 :            : 
     356                 :          0 :         nsp_cpp = nfp_resource_cpp_id(state->res);
     357                 :          0 :         nsp_base = nfp_resource_address(state->res);
     358                 :            :         nsp_status = nsp_base + NSP_STATUS;
     359                 :          0 :         nsp_command = nsp_base + NSP_COMMAND;
     360                 :          0 :         nsp_buffer = nsp_base + NSP_BUFFER;
     361                 :            : 
     362                 :          0 :         err = nfp_nsp_check(state);
     363         [ #  # ]:          0 :         if (err != 0) {
     364                 :          0 :                 PMD_DRV_LOG(ERR, "Check NSP command failed");
     365                 :          0 :                 return err;
     366                 :            :         }
     367                 :            : 
     368                 :          0 :         err = nfp_cpp_writeq(cpp, nsp_cpp, nsp_buffer, arg->buf);
     369         [ #  # ]:          0 :         if (err < 0)
     370                 :            :                 return err;
     371                 :            : 
     372                 :          0 :         err = nfp_cpp_writeq(cpp, nsp_cpp, nsp_command,
     373                 :          0 :                         FIELD_PREP(NSP_COMMAND_OPTION, arg->option) |
     374                 :          0 :                         FIELD_PREP(NSP_COMMAND_VER_MAJOR, state->ver.major) |
     375                 :          0 :                         FIELD_PREP(NSP_COMMAND_CODE, arg->code) |
     376                 :          0 :                         FIELD_PREP(NSP_COMMAND_DMA_BUF, arg->dma) |
     377                 :            :                         FIELD_PREP(NSP_COMMAND_START, 1));
     378         [ #  # ]:          0 :         if (err < 0)
     379                 :            :                 return err;
     380                 :            : 
     381                 :            :         /* Wait for NSP_COMMAND_START to go to 0 */
     382                 :          0 :         err = nfp_nsp_wait_reg(cpp, &reg, nsp_cpp, nsp_command,
     383                 :            :                         NSP_COMMAND_START, 0);
     384         [ #  # ]:          0 :         if (err != 0) {
     385                 :          0 :                 PMD_DRV_LOG(ERR, "Error %d waiting for code %#04x to start",
     386                 :            :                                 err, arg->code);
     387                 :          0 :                 return err;
     388                 :            :         }
     389                 :            : 
     390                 :            :         /* Wait for NSP_STATUS_BUSY to go to 0 */
     391                 :          0 :         err = nfp_nsp_wait_reg(cpp, &reg, nsp_cpp, nsp_status,
     392                 :            :                         NSP_STATUS_BUSY, 0);
     393         [ #  # ]:          0 :         if (err != 0) {
     394                 :          0 :                 PMD_DRV_LOG(ERR, "Error %d waiting for code %#04x to complete",
     395                 :            :                                 err, arg->code);
     396                 :          0 :                 return err;
     397                 :            :         }
     398                 :            : 
     399                 :          0 :         err = nfp_cpp_readq(cpp, nsp_cpp, nsp_command, &ret_val);
     400         [ #  # ]:          0 :         if (err < 0)
     401                 :            :                 return err;
     402                 :            : 
     403                 :          0 :         ret_val = FIELD_GET(NSP_COMMAND_OPTION, ret_val);
     404                 :            : 
     405                 :          0 :         err = FIELD_GET(NSP_STATUS_RESULT, reg);
     406         [ #  # ]:          0 :         if (err != 0) {
     407         [ #  # ]:          0 :                 if (!arg->error_quiet)
     408                 :          0 :                         PMD_DRV_LOG(WARNING, "Result (error) code set: %d (%d) command: %d",
     409                 :            :                                         -err, (int)ret_val, arg->code);
     410                 :            : 
     411         [ #  # ]:          0 :                 if (arg->error_cb != 0)
     412                 :          0 :                         arg->error_cb(state, ret_val);
     413                 :            :                 else
     414                 :          0 :                         nfp_nsp_print_extended_error(ret_val);
     415                 :            : 
     416                 :          0 :                 return -err;
     417                 :            :         }
     418                 :            : 
     419                 :          0 :         return ret_val;
     420                 :            : }
     421                 :            : 
     422                 :            : static int
     423                 :            : nfp_nsp_command(struct nfp_nsp *state,
     424                 :            :                 uint16_t code)
     425                 :            : {
     426                 :          0 :         const struct nfp_nsp_command_arg arg = {
     427                 :            :                 .code = code,
     428                 :            :         };
     429                 :            : 
     430                 :          0 :         return nfp_nsp_command_real(state, &arg);
     431                 :            : }
     432                 :            : 
     433                 :            : static int
     434                 :          0 : nfp_nsp_command_buf_def(struct nfp_nsp *nsp,
     435                 :            :                 struct nfp_nsp_command_buf_arg *arg)
     436                 :            : {
     437                 :            :         int err;
     438                 :            :         int ret;
     439                 :            :         uint64_t reg;
     440                 :            :         uint32_t cpp_id;
     441                 :            :         uint64_t cpp_buf;
     442                 :          0 :         struct nfp_cpp *cpp = nsp->cpp;
     443                 :            : 
     444                 :          0 :         err = nfp_cpp_readq(cpp, nfp_resource_cpp_id(nsp->res),
     445                 :          0 :                         nfp_resource_address(nsp->res) + NSP_DFLT_BUFFER,
     446                 :            :                         &reg);
     447         [ #  # ]:          0 :         if (err < 0)
     448                 :            :                 return err;
     449                 :            : 
     450                 :          0 :         cpp_id = FIELD_GET(NSP_DFLT_BUFFER_CPP, reg) << 8;
     451                 :          0 :         cpp_buf = FIELD_GET(NSP_DFLT_BUFFER_ADDRESS, reg);
     452                 :            : 
     453   [ #  #  #  # ]:          0 :         if (arg->in_buf != NULL && arg->in_size > 0) {
     454                 :          0 :                 err = nfp_cpp_write(cpp, cpp_id, cpp_buf,
     455                 :            :                                 arg->in_buf, arg->in_size);
     456         [ #  # ]:          0 :                 if (err < 0)
     457                 :            :                         return err;
     458                 :            :         }
     459                 :            : 
     460                 :            :         /* Zero out remaining part of the buffer */
     461   [ #  #  #  # ]:          0 :         if (arg->out_buf != NULL && arg->out_size > arg->in_size) {
     462                 :          0 :                 err = nfp_cpp_write(cpp, cpp_id, cpp_buf + arg->in_size,
     463                 :          0 :                                 arg->out_buf, arg->out_size - arg->in_size);
     464         [ #  # ]:          0 :                 if (err < 0)
     465                 :            :                         return err;
     466                 :            :         }
     467                 :            : 
     468                 :          0 :         if (!FIELD_FIT(NSP_BUFFER_CPP, cpp_id >> 8) ||
     469                 :            :                         !FIELD_FIT(NSP_BUFFER_ADDRESS, cpp_buf)) {
     470                 :            :                 PMD_DRV_LOG(ERR, "Buffer out of reach %#08x %#016lx",
     471                 :            :                                 cpp_id, cpp_buf);
     472                 :            :                 return -EINVAL;
     473                 :            :         }
     474                 :            : 
     475                 :          0 :         arg->arg.buf = FIELD_PREP(NSP_BUFFER_CPP, cpp_id >> 8) |
     476                 :            :                         FIELD_PREP(NSP_BUFFER_ADDRESS, cpp_buf);
     477                 :          0 :         ret = nfp_nsp_command_real(nsp, &arg->arg);
     478         [ #  # ]:          0 :         if (ret < 0) {
     479                 :          0 :                 PMD_DRV_LOG(ERR, "NSP command failed");
     480                 :          0 :                 return ret;
     481                 :            :         }
     482                 :            : 
     483   [ #  #  #  # ]:          0 :         if (arg->out_buf != NULL && arg->out_size > 0) {
     484                 :          0 :                 err = nfp_cpp_read(cpp, cpp_id, cpp_buf,
     485                 :            :                                 arg->out_buf, arg->out_size);
     486         [ #  # ]:          0 :                 if (err < 0)
     487                 :          0 :                         return err;
     488                 :            :         }
     489                 :            : 
     490                 :            :         return ret;
     491                 :            : }
     492                 :            : 
     493                 :            : #define SZ_1M 0x00100000
     494                 :            : #define SZ_4K 0x00001000
     495                 :            : 
     496                 :            : static int
     497                 :          0 : nfp_nsp_command_buf(struct nfp_nsp *nsp,
     498                 :            :                 struct nfp_nsp_command_buf_arg *arg)
     499                 :            : {
     500                 :            :         int err;
     501                 :            :         size_t size;
     502                 :            :         uint64_t reg;
     503                 :            :         size_t max_size;
     504                 :          0 :         struct nfp_cpp *cpp = nsp->cpp;
     505                 :            : 
     506         [ #  # ]:          0 :         if (nsp->ver.minor < 13) {
     507                 :          0 :                 PMD_DRV_LOG(ERR, "NSP: Code %#04x with buffer not supported ABI %hu.%hu)",
     508                 :            :                                 arg->arg.code, nsp->ver.major, nsp->ver.minor);
     509                 :          0 :                 return -EOPNOTSUPP;
     510                 :            :         }
     511                 :            : 
     512                 :          0 :         err = nfp_cpp_readq(cpp, nfp_resource_cpp_id(nsp->res),
     513                 :          0 :                         nfp_resource_address(nsp->res) + NSP_DFLT_BUFFER_CONFIG,
     514                 :            :                         &reg);
     515         [ #  # ]:          0 :         if (err < 0)
     516                 :            :                 return err;
     517                 :            : 
     518                 :          0 :         max_size = RTE_MAX(arg->in_size, arg->out_size);
     519                 :          0 :         size = FIELD_GET(NSP_DFLT_BUFFER_SIZE_MB, reg) * SZ_1M +
     520                 :          0 :                         FIELD_GET(NSP_DFLT_BUFFER_SIZE_4KB, reg) * SZ_4K;
     521         [ #  # ]:          0 :         if (size < max_size) {
     522                 :          0 :                 PMD_DRV_LOG(ERR, "NSP: default buffer too small for command %#04x (%zu < %zu)",
     523                 :            :                                 arg->arg.code, size, max_size);
     524                 :          0 :                 return -EINVAL;
     525                 :            :         }
     526                 :            : 
     527                 :          0 :         return nfp_nsp_command_buf_def(nsp, arg);
     528                 :            : }
     529                 :            : 
     530                 :            : int
     531                 :          0 : nfp_nsp_wait(struct nfp_nsp *state)
     532                 :            : {
     533                 :            :         int err;
     534                 :            :         int count = 0;
     535                 :            :         struct timespec wait;
     536                 :            : 
     537                 :          0 :         wait.tv_sec = 0;
     538                 :          0 :         wait.tv_nsec = 25000000;    /* 25ms */
     539                 :            : 
     540                 :            :         for (;;) {
     541                 :            :                 err = nfp_nsp_command(state, SPCODE_NOOP);
     542         [ #  # ]:          0 :                 if (err != -EAGAIN)
     543                 :            :                         break;
     544                 :            : 
     545                 :          0 :                 nanosleep(&wait, 0);
     546                 :            : 
     547         [ #  # ]:          0 :                 if (count++ > 1000) {    /* 25ms * 1000 = 25s */
     548                 :            :                         err = -ETIMEDOUT;
     549                 :            :                         break;
     550                 :            :                 }
     551                 :            :         }
     552                 :            : 
     553         [ #  # ]:          0 :         if (err != 0)
     554                 :          0 :                 PMD_DRV_LOG(ERR, "NSP failed to respond %d", err);
     555                 :            : 
     556                 :          0 :         return err;
     557                 :            : }
     558                 :            : 
     559                 :            : int
     560                 :          0 : nfp_nsp_device_soft_reset(struct nfp_nsp *state)
     561                 :            : {
     562                 :          0 :         return nfp_nsp_command(state, SPCODE_SOFT_RESET);
     563                 :            : }
     564                 :            : 
     565                 :            : int
     566                 :          0 : nfp_nsp_mac_reinit(struct nfp_nsp *state)
     567                 :            : {
     568                 :          0 :         return nfp_nsp_command(state, SPCODE_MAC_INIT);
     569                 :            : }
     570                 :            : 
     571                 :            : static void
     572                 :          0 : nfp_nsp_load_fw_extended_msg(struct nfp_nsp *state,
     573                 :            :                 uint32_t ret_val)
     574                 :            : {
     575                 :            :         uint32_t minor;
     576                 :            :         uint32_t major;
     577                 :            :         static const char * const major_msg[] = {
     578                 :            :                 /* 0 */ "Firmware from driver loaded",
     579                 :            :                 /* 1 */ "Firmware from flash loaded",
     580                 :            :                 /* 2 */ "Firmware loading failure",
     581                 :            :         };
     582                 :            :         static const char * const minor_msg[] = {
     583                 :            :                 /*  0 */ "",
     584                 :            :                 /*  1 */ "no named partition on flash",
     585                 :            :                 /*  2 */ "error reading from flash",
     586                 :            :                 /*  3 */ "can not deflate",
     587                 :            :                 /*  4 */ "not a trusted file",
     588                 :            :                 /*  5 */ "can not parse FW file",
     589                 :            :                 /*  6 */ "MIP not found in FW file",
     590                 :            :                 /*  7 */ "null firmware name in MIP",
     591                 :            :                 /*  8 */ "FW version none",
     592                 :            :                 /*  9 */ "FW build number none",
     593                 :            :                 /* 10 */ "no FW selection policy HWInfo key found",
     594                 :            :                 /* 11 */ "static FW selection policy",
     595                 :            :                 /* 12 */ "FW version has precedence",
     596                 :            :                 /* 13 */ "different FW application load requested",
     597                 :            :                 /* 14 */ "development build",
     598                 :            :         };
     599                 :            : 
     600                 :          0 :         major = FIELD_GET(NFP_FW_LOAD_RET_MAJOR, ret_val);
     601                 :          0 :         minor = FIELD_GET(NFP_FW_LOAD_RET_MINOR, ret_val);
     602                 :            : 
     603         [ #  # ]:          0 :         if (!nfp_nsp_has_stored_fw_load(state))
     604                 :            :                 return;
     605                 :            : 
     606         [ #  # ]:          0 :         if (major >= RTE_DIM(major_msg))
     607                 :          0 :                 PMD_DRV_LOG(INFO, "FW loading status: %x", ret_val);
     608         [ #  # ]:          0 :         else if (minor >= RTE_DIM(minor_msg))
     609                 :          0 :                 PMD_DRV_LOG(INFO, "%s, reason code: %d", major_msg[major], minor);
     610                 :            :         else
     611         [ #  # ]:          0 :                 PMD_DRV_LOG(INFO, "%s%c %s", major_msg[major],
     612                 :            :                                 minor != 0 ? ',' : '.', minor_msg[minor]);
     613                 :            : }
     614                 :            : 
     615                 :            : int
     616                 :          0 : nfp_nsp_load_fw(struct nfp_nsp *state,
     617                 :            :                 void *buf,
     618                 :            :                 size_t size)
     619                 :            : {
     620                 :            :         int ret;
     621                 :          0 :         struct nfp_nsp_command_buf_arg load_fw = {
     622                 :            :                 {
     623                 :            :                         .code     = SPCODE_FW_LOAD,
     624                 :            :                         .option   = size,
     625                 :            :                         .error_cb = nfp_nsp_load_fw_extended_msg,
     626                 :            :                 },
     627                 :            :                 .in_buf  = buf,
     628                 :            :                 .in_size = size,
     629                 :            :         };
     630                 :            : 
     631                 :          0 :         ret = nfp_nsp_command_buf(state, &load_fw);
     632         [ #  # ]:          0 :         if (ret < 0)
     633                 :            :                 return ret;
     634                 :            : 
     635                 :          0 :         nfp_nsp_load_fw_extended_msg(state, ret);
     636                 :            : 
     637                 :          0 :         return 0;
     638                 :            : }
     639                 :            : 
     640                 :            : bool
     641                 :          0 : nfp_nsp_fw_loaded(struct nfp_nsp *state)
     642                 :            : {
     643                 :          0 :         return nfp_nsp_command(state, SPCODE_FW_LOADED) > 0;
     644                 :            : }
     645                 :            : 
     646                 :            : int
     647                 :          0 : nfp_nsp_read_eth_table(struct nfp_nsp *state,
     648                 :            :                 void *buf,
     649                 :            :                 size_t size)
     650                 :            : {
     651                 :          0 :         struct nfp_nsp_command_buf_arg eth_rescan = {
     652                 :            :                 {
     653                 :            :                         .code   = SPCODE_ETH_RESCAN,
     654                 :            :                         .option = size,
     655                 :            :                 },
     656                 :            :                 .out_buf  = buf,
     657                 :            :                 .out_size = size,
     658                 :            :         };
     659                 :            : 
     660                 :          0 :         return nfp_nsp_command_buf(state, &eth_rescan);
     661                 :            : }
     662                 :            : 
     663                 :            : int
     664                 :          0 : nfp_nsp_write_eth_table(struct nfp_nsp *state,
     665                 :            :                 const void *buf,
     666                 :            :                 size_t size)
     667                 :            : {
     668                 :          0 :         struct nfp_nsp_command_buf_arg eth_ctrl = {
     669                 :            :                 {
     670                 :            :                         .code   = SPCODE_ETH_CONTROL,
     671                 :            :                         .option = size,
     672                 :            :                 },
     673                 :            :                 .in_buf  = buf,
     674                 :            :                 .in_size = size,
     675                 :            :         };
     676                 :            : 
     677                 :          0 :         return nfp_nsp_command_buf(state, &eth_ctrl);
     678                 :            : }
     679                 :            : 
     680                 :            : int
     681                 :          0 : nfp_nsp_read_identify(struct nfp_nsp *state,
     682                 :            :                 void *buf,
     683                 :            :                 size_t size)
     684                 :            : {
     685                 :          0 :         struct nfp_nsp_command_buf_arg identify = {
     686                 :            :                 {
     687                 :            :                         .code   = SPCODE_NSP_IDENTIFY,
     688                 :            :                         .option = size,
     689                 :            :                 },
     690                 :            :                 .out_buf  = buf,
     691                 :            :                 .out_size = size,
     692                 :            :         };
     693                 :            : 
     694                 :          0 :         return nfp_nsp_command_buf(state, &identify);
     695                 :            : }
     696                 :            : 
     697                 :            : int
     698                 :          0 : nfp_nsp_read_sensors(struct nfp_nsp *state,
     699                 :            :                 uint32_t sensor_mask,
     700                 :            :                 void *buf,
     701                 :            :                 size_t size)
     702                 :            : {
     703                 :          0 :         struct nfp_nsp_command_buf_arg sensors = {
     704                 :            :                 {
     705                 :            :                         .code   = SPCODE_NSP_SENSORS,
     706                 :            :                         .option = sensor_mask,
     707                 :            :                 },
     708                 :            :                 .out_buf  = buf,
     709                 :            :                 .out_size = size,
     710                 :            :         };
     711                 :            : 
     712                 :          0 :         return nfp_nsp_command_buf(state, &sensors);
     713                 :            : }
     714                 :            : 
     715                 :            : int
     716                 :          0 : nfp_nsp_hwinfo_set(struct nfp_nsp *state,
     717                 :            :                 const void *buf,
     718                 :            :                 size_t size)
     719                 :            : {
     720                 :          0 :         struct nfp_nsp_command_buf_arg hwinfo_set = {
     721                 :            :                 {
     722                 :            :                         .code   = SPCODE_HWINFO_SET,
     723                 :            :                         .option = size,
     724                 :            :                 },
     725                 :            :                 .in_buf  = buf,
     726                 :            :                 .in_size = size,
     727                 :            :         };
     728                 :            : 
     729                 :          0 :         return nfp_nsp_command_buf(state, &hwinfo_set);
     730                 :            : }
     731                 :            : 
     732                 :            : int
     733                 :          0 : nfp_nsp_read_media(struct nfp_nsp *state,
     734                 :            :                 void *buf,
     735                 :            :                 size_t size)
     736                 :            : {
     737                 :          0 :         struct nfp_nsp_command_buf_arg media = {
     738                 :            :                 {
     739                 :            :                         .code   = SPCODE_READ_MEDIA,
     740                 :            :                         .option = size,
     741                 :            :                 },
     742                 :            :                 .out_buf  = buf,
     743                 :            :                 .out_size = size,
     744                 :            :         };
     745                 :            : 
     746                 :          0 :         return nfp_nsp_command_buf(state, &media);
     747                 :            : }

Generated by: LCOV version 1.14