LCOV - code coverage report
Current view: top level - drivers/net/bnxt/tf_ulp - ulp_utils.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 376 0.0 %
Date: 2024-01-22 15:55:54 Functions: 0 37 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 182 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2014-2023 Broadcom
       3                 :            :  * All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include <rte_common.h>
       7                 :            : #include "ulp_utils.h"
       8                 :            : #include "bnxt_tf_common.h"
       9                 :            : 
      10                 :            : /*
      11                 :            :  * Initialize the regfile structure for writing
      12                 :            :  *
      13                 :            :  * regfile [in] Ptr to a regfile instance
      14                 :            :  *
      15                 :            :  * returns 0 on error or 1 on success
      16                 :            :  */
      17                 :            : uint32_t
      18                 :          0 : ulp_regfile_init(struct ulp_regfile *regfile)
      19                 :            : {
      20                 :            :         /* validate the arguments */
      21         [ #  # ]:          0 :         if (!regfile) {
      22                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
      23                 :          0 :                 return 0; /* failure */
      24                 :            :         }
      25                 :            :         memset(regfile, 0, sizeof(struct ulp_regfile));
      26                 :          0 :         return 1; /* Success */
      27                 :            : }
      28                 :            : 
      29                 :            : /*
      30                 :            :  * Read a value from the regfile
      31                 :            :  *
      32                 :            :  * regfile [in] The regfile instance. Must be initialized prior to being used
      33                 :            :  *
      34                 :            :  * field [in] The field to be read within the regfile.
      35                 :            :  *
      36                 :            :  * data [in/out]
      37                 :            :  *
      38                 :            :  * returns size, zero on failure
      39                 :            :  */
      40                 :            : uint32_t
      41                 :          0 : ulp_regfile_read(struct ulp_regfile *regfile,
      42                 :            :                  enum bnxt_ulp_rf_idx field,
      43                 :            :                  uint64_t *data)
      44                 :            : {
      45                 :            :         /* validate the arguments */
      46         [ #  # ]:          0 :         if (!regfile || field >= BNXT_ULP_RF_IDX_LAST) {
      47                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
      48                 :          0 :                 return 0; /* failure */
      49                 :            :         }
      50                 :            : 
      51                 :          0 :         *data = regfile->entry[field].data;
      52                 :          0 :         return sizeof(*data);
      53                 :            : }
      54                 :            : 
      55                 :            : /*
      56                 :            :  * Write a value to the regfile
      57                 :            :  *
      58                 :            :  * regfile [in] The regfile instance.  Must be initialized prior to being used
      59                 :            :  *
      60                 :            :  * field [in] The field to be written within the regfile.
      61                 :            :  *
      62                 :            :  * data [in] The value is written into this variable.  It is going to be in the
      63                 :            :  * same byte order as it was written.
      64                 :            :  *
      65                 :            :  * size [in] The size in bytes of the value being written into this
      66                 :            :  * variable.
      67                 :            :  *
      68                 :            :  * returns 0 on success
      69                 :            :  */
      70                 :            : int32_t
      71                 :          0 : ulp_regfile_write(struct ulp_regfile *regfile,
      72                 :            :                   enum bnxt_ulp_rf_idx field,
      73                 :            :                   uint64_t data)
      74                 :            : {
      75                 :            :         /* validate the arguments */
      76         [ #  # ]:          0 :         if (!regfile || field >= BNXT_ULP_RF_IDX_LAST) {
      77                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
      78                 :          0 :                 return -EINVAL; /* failure */
      79                 :            :         }
      80                 :            : 
      81                 :          0 :         regfile->entry[field].data = data;
      82                 :          0 :         return 0; /* Success */
      83                 :            : }
      84                 :            : 
      85                 :            : static void
      86                 :          0 : ulp_bs_put_msb(uint8_t *bs, uint16_t bitpos, uint8_t bitlen, uint8_t val)
      87                 :            : {
      88                 :          0 :         uint8_t bitoffs = bitpos % 8;
      89                 :          0 :         uint16_t index  = bitpos / 8;
      90                 :            :         uint8_t mask;
      91                 :            :         uint8_t tmp;
      92                 :            :         int8_t shift;
      93                 :            : 
      94                 :          0 :         tmp = bs[index];
      95                 :          0 :         mask = ((uint8_t)-1 >> (8 - bitlen));
      96                 :          0 :         shift = 8 - bitoffs - bitlen;
      97                 :          0 :         val &= mask;
      98                 :            : 
      99         [ #  # ]:          0 :         if (shift >= 0) {
     100                 :          0 :                 tmp &= ~(mask << shift);
     101                 :          0 :                 tmp |= val << shift;
     102                 :          0 :                 bs[index] = tmp;
     103                 :            :         } else {
     104                 :          0 :                 tmp &= ~((uint8_t)-1 >> bitoffs);
     105                 :          0 :                 tmp |= val >> -shift;
     106                 :          0 :                 bs[index++] = tmp;
     107                 :            : 
     108                 :          0 :                 tmp = bs[index];
     109                 :          0 :                 tmp &= ((uint8_t)-1 >> (bitlen - (8 - bitoffs)));
     110                 :          0 :                 tmp |= val << (8 + shift);
     111                 :          0 :                 bs[index] = tmp;
     112                 :            :         }
     113                 :          0 : }
     114                 :            : 
     115                 :            : static void
     116                 :          0 : ulp_bs_put_lsb(uint8_t *bs, uint16_t bitpos, uint8_t bitlen, uint8_t val)
     117                 :            : {
     118                 :          0 :         uint8_t bitoffs = bitpos % 8;
     119                 :          0 :         uint16_t index  = bitpos / 8;
     120                 :            :         uint8_t mask;
     121                 :            :         uint8_t tmp;
     122                 :            :         uint8_t shift;
     123                 :            :         uint8_t partial;
     124                 :            : 
     125                 :          0 :         tmp = bs[index];
     126                 :            :         shift = bitoffs;
     127                 :            : 
     128         [ #  # ]:          0 :         if (bitoffs + bitlen <= 8) {
     129                 :          0 :                 mask = ((1 << bitlen) - 1) << shift;
     130                 :          0 :                 tmp &= ~mask;
     131                 :          0 :                 tmp |= ((val << shift) & mask);
     132                 :          0 :                 bs[index] = tmp;
     133                 :            :         } else {
     134                 :          0 :                 partial = 8 - bitoffs;
     135                 :          0 :                 mask = ((1 << partial) - 1) << shift;
     136                 :          0 :                 tmp &= ~mask;
     137                 :          0 :                 tmp |= ((val << shift) & mask);
     138                 :          0 :                 bs[index++] = tmp;
     139                 :            : 
     140                 :          0 :                 val >>= partial;
     141                 :          0 :                 partial = bitlen - partial;
     142                 :          0 :                 mask = ((1 << partial) - 1);
     143                 :          0 :                 tmp = bs[index];
     144                 :            :                 tmp &= ~mask;
     145                 :          0 :                 tmp |= (val & mask);
     146                 :          0 :                 bs[index] = tmp;
     147                 :            :         }
     148                 :          0 : }
     149                 :            : 
     150                 :            : /*
     151                 :            :  * Add data to the byte array in Little endian format.
     152                 :            :  *
     153                 :            :  * bs [in] The byte array where data is pushed
     154                 :            :  *
     155                 :            :  * pos [in] The offset where data is pushed
     156                 :            :  *
     157                 :            :  * len [in] The number of bits to be added to the data array.
     158                 :            :  *
     159                 :            :  * val [in] The data to be added to the data array.
     160                 :            :  *
     161                 :            :  * returns the number of bits pushed.
     162                 :            :  */
     163                 :            : uint32_t
     164                 :          0 : ulp_bs_push_lsb(uint8_t *bs, uint16_t pos, uint8_t len, uint8_t *val)
     165                 :            : {
     166                 :            :         int i;
     167                 :          0 :         int cnt = (len) / 8;
     168                 :          0 :         int tlen = len;
     169                 :            : 
     170   [ #  #  #  # ]:          0 :         if (cnt > 0 && !(len % 8))
     171                 :          0 :                 cnt -= 1;
     172                 :            : 
     173         [ #  # ]:          0 :         for (i = 0; i < cnt; i++) {
     174                 :          0 :                 ulp_bs_put_lsb(bs, pos, 8, val[cnt - i]);
     175                 :          0 :                 pos += 8;
     176                 :          0 :                 tlen -= 8;
     177                 :            :         }
     178                 :            : 
     179                 :            :         /* Handle the remainder bits */
     180         [ #  # ]:          0 :         if (tlen)
     181                 :          0 :                 ulp_bs_put_lsb(bs, pos, tlen, val[0]);
     182                 :          0 :         return len;
     183                 :            : }
     184                 :            : 
     185                 :            : /*
     186                 :            :  * Add data to the byte array in Big endian format.
     187                 :            :  *
     188                 :            :  * bs [in] The byte array where data is pushed
     189                 :            :  *
     190                 :            :  * pos [in] The offset where data is pushed
     191                 :            :  *
     192                 :            :  * len [in] The number of bits to be added to the data array.
     193                 :            :  *
     194                 :            :  * val [in] The data to be added to the data array.
     195                 :            :  *
     196                 :            :  * returns the number of bits pushed.
     197                 :            :  */
     198                 :            : uint32_t
     199                 :          0 : ulp_bs_push_msb(uint8_t *bs, uint16_t pos, uint8_t len, uint8_t *val)
     200                 :            : {
     201                 :            :         int i;
     202                 :          0 :         int cnt = (len + 7) / 8;
     203                 :            : 
     204                 :            :         /* Handle any remainder bits */
     205                 :          0 :         int tmp = len % 8;
     206                 :            : 
     207         [ #  # ]:          0 :         if (!tmp)
     208                 :            :                 tmp = 8;
     209                 :            : 
     210                 :          0 :         ulp_bs_put_msb(bs, pos, tmp, val[0]);
     211                 :            : 
     212                 :          0 :         pos += tmp;
     213                 :            : 
     214         [ #  # ]:          0 :         for (i = 1; i < cnt; i++) {
     215                 :          0 :                 ulp_bs_put_msb(bs, pos, 8, val[i]);
     216                 :          0 :                 pos += 8;
     217                 :            :         }
     218                 :            : 
     219                 :          0 :         return len;
     220                 :            : }
     221                 :            : 
     222                 :            : /*
     223                 :            :  * Initializes the blob structure for creating binary blob
     224                 :            :  *
     225                 :            :  * blob [in] The blob to be initialized
     226                 :            :  *
     227                 :            :  * bitlen [in] The bit length of the blob
     228                 :            :  *
     229                 :            :  * order [in] The byte order for the blob.  Currently only supporting
     230                 :            :  * big endian.  All fields are packed with this order.
     231                 :            :  *
     232                 :            :  * returns 0 on error or 1 on success
     233                 :            :  * Notes - If bitlen is zero then set it to max.
     234                 :            :  */
     235                 :            : uint32_t
     236                 :          0 : ulp_blob_init(struct ulp_blob *blob,
     237                 :            :               uint16_t bitlen,
     238                 :            :               enum bnxt_ulp_byte_order order)
     239                 :            : {
     240                 :            :         /* validate the arguments */
     241         [ #  # ]:          0 :         if (!blob || bitlen > (8 * sizeof(blob->data))) {
     242                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
     243                 :          0 :                 return 0; /* failure */
     244                 :            :         }
     245         [ #  # ]:          0 :         if (bitlen)
     246                 :          0 :                 blob->bitlen = bitlen;
     247                 :            :         else
     248                 :          0 :                 blob->bitlen = BNXT_ULP_FLMP_BLOB_SIZE_IN_BITS;
     249                 :          0 :         blob->byte_order = order;
     250                 :          0 :         blob->write_idx = 0;
     251                 :          0 :         memset(blob->data, 0, sizeof(blob->data));
     252                 :          0 :         return 1; /* Success */
     253                 :            : }
     254                 :            : 
     255                 :            : /*
     256                 :            :  * Add data to the binary blob at the current offset.
     257                 :            :  *
     258                 :            :  * blob [in] The blob that data is added to.  The blob must
     259                 :            :  * be initialized prior to pushing data.
     260                 :            :  *
     261                 :            :  * data [in] A pointer to bytes to be added to the blob.
     262                 :            :  *
     263                 :            :  * datalen [in] The number of bits to be added to the blob.
     264                 :            :  *
     265                 :            :  * The offset of the data is updated after each push of data.
     266                 :            :  * NULL returned on error.
     267                 :            :  */
     268                 :            : #define ULP_BLOB_BYTE           8
     269                 :            : #define ULP_BLOB_BYTE_HEX       0xFF
     270                 :            : #define BLOB_MASK_CAL(x)        ((0xFF << (x)) & 0xFF)
     271                 :            : uint32_t
     272                 :          0 : ulp_blob_push(struct ulp_blob *blob,
     273                 :            :               uint8_t *data,
     274                 :            :               uint32_t datalen)
     275                 :            : {
     276                 :            :         uint32_t rc;
     277                 :            : 
     278                 :            :         /* validate the arguments */
     279   [ #  #  #  # ]:          0 :         if (!blob || datalen > (uint32_t)(blob->bitlen - blob->write_idx)) {
     280                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
     281                 :          0 :                 return 0; /* failure */
     282                 :            :         }
     283                 :            : 
     284         [ #  # ]:          0 :         if (blob->byte_order == BNXT_ULP_BYTE_ORDER_BE)
     285                 :          0 :                 rc = ulp_bs_push_msb(blob->data,
     286                 :            :                                      blob->write_idx,
     287                 :            :                                      datalen,
     288                 :            :                                      data);
     289                 :            :         else
     290                 :          0 :                 rc = ulp_bs_push_lsb(blob->data,
     291                 :            :                                      blob->write_idx,
     292                 :            :                                      datalen,
     293                 :            :                                      data);
     294         [ #  # ]:          0 :         if (!rc) {
     295                 :          0 :                 BNXT_TF_DBG(ERR, "Failed to write blob\n");
     296                 :          0 :                 return 0;
     297                 :            :         }
     298                 :          0 :         blob->write_idx += datalen;
     299                 :          0 :         return datalen;
     300                 :            : }
     301                 :            : 
     302                 :            : /*
     303                 :            :  * Insert data into the binary blob at the given offset.
     304                 :            :  *
     305                 :            :  * blob [in] The blob that data is added to.  The blob must
     306                 :            :  * be initialized prior to pushing data.
     307                 :            :  *
     308                 :            :  * offset [in] The offset where the data needs to be inserted.
     309                 :            :  *
     310                 :            :  * data [in/out] A pointer to bytes to be added to the blob.
     311                 :            :  *
     312                 :            :  * datalen [in] The number of bits to be added to the blob.
     313                 :            :  *
     314                 :            :  * The offset of the data is updated after each push of data.
     315                 :            :  * NULL returned on error.
     316                 :            :  */
     317                 :            : uint32_t
     318                 :          0 : ulp_blob_insert(struct ulp_blob *blob, uint32_t offset,
     319                 :            :                 uint8_t *data, uint32_t datalen)
     320                 :            : {
     321                 :            :         uint32_t rc;
     322                 :            :         uint8_t local_data[BNXT_ULP_FLMP_BLOB_SIZE];
     323                 :            :         uint16_t mov_len;
     324                 :            : 
     325                 :            :         /* validate the arguments */
     326   [ #  #  #  # ]:          0 :         if (!blob || datalen > (uint32_t)(blob->bitlen - blob->write_idx) ||
     327         [ #  # ]:          0 :             offset > blob->write_idx) {
     328                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
     329                 :          0 :                 return 0; /* failure */
     330                 :            :         }
     331                 :            : 
     332                 :          0 :         mov_len = blob->write_idx - offset;
     333                 :            :         /* If offset and data len are not 8 bit aligned then return error */
     334         [ #  # ]:          0 :         if (ULP_BITS_IS_BYTE_NOT_ALIGNED(offset) ||
     335         [ #  # ]:          0 :             ULP_BITS_IS_BYTE_NOT_ALIGNED(datalen)) {
     336                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument, not aligned\n");
     337                 :          0 :                 return 0; /* failure */
     338                 :            :         }
     339                 :            : 
     340                 :            :         /* copy the data so we can move the data */
     341                 :          0 :         memcpy(local_data, &blob->data[ULP_BITS_2_BYTE_NR(offset)],
     342         [ #  # ]:          0 :                ULP_BITS_2_BYTE(mov_len));
     343                 :          0 :         blob->write_idx = offset;
     344         [ #  # ]:          0 :         if (blob->byte_order == BNXT_ULP_BYTE_ORDER_BE)
     345                 :          0 :                 rc = ulp_bs_push_msb(blob->data,
     346                 :            :                                      blob->write_idx,
     347                 :            :                                      datalen,
     348                 :            :                                      data);
     349                 :            :         else
     350                 :          0 :                 rc = ulp_bs_push_lsb(blob->data,
     351                 :            :                                      blob->write_idx,
     352                 :            :                                      datalen,
     353                 :            :                                      data);
     354         [ #  # ]:          0 :         if (!rc) {
     355                 :          0 :                 BNXT_TF_DBG(ERR, "Failed to write blob\n");
     356                 :          0 :                 return 0;
     357                 :            :         }
     358                 :            :         /* copy the previously stored data */
     359                 :          0 :         memcpy(&blob->data[ULP_BITS_2_BYTE_NR(offset + datalen)], local_data,
     360                 :            :                ULP_BITS_2_BYTE(mov_len));
     361                 :          0 :         blob->write_idx += (mov_len + datalen);
     362                 :          0 :         return datalen;
     363                 :            : }
     364                 :            : 
     365                 :            : /*
     366                 :            :  * Add data to the binary blob at the current offset.
     367                 :            :  *
     368                 :            :  * blob [in] The blob that data is added to.  The blob must
     369                 :            :  * be initialized prior to pushing data.
     370                 :            :  *
     371                 :            :  * data [in] 64-bit value to be added to the blob.
     372                 :            :  *
     373                 :            :  * datalen [in] The number of bits to be added to the blob.
     374                 :            :  *
     375                 :            :  * The offset of the data is updated after each push of data.
     376                 :            :  * NULL returned on error, pointer pushed value otherwise.
     377                 :            :  */
     378                 :            : uint8_t *
     379                 :          0 : ulp_blob_push_64(struct ulp_blob *blob,
     380                 :            :                  uint64_t *data,
     381                 :            :                  uint32_t datalen)
     382                 :            : {
     383                 :            :         uint8_t *val = (uint8_t *)data;
     384                 :            :         int rc;
     385                 :            : 
     386                 :          0 :         int size = (datalen + 7) / 8;
     387                 :            : 
     388         [ #  # ]:          0 :         if (!blob || !data ||
     389         [ #  # ]:          0 :             datalen > (uint32_t)(blob->bitlen - blob->write_idx)) {
     390                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
     391                 :          0 :                 return 0;
     392                 :            :         }
     393                 :            : 
     394                 :          0 :         rc = ulp_blob_push(blob, &val[8 - size], datalen);
     395         [ #  # ]:          0 :         if (!rc)
     396                 :          0 :                 return 0;
     397                 :            : 
     398                 :            :         return &val[8 - size];
     399                 :            : }
     400                 :            : 
     401                 :            : /*
     402                 :            :  * Add data to the binary blob at the current offset.
     403                 :            :  *
     404                 :            :  * blob [in] The blob that data is added to.  The blob must
     405                 :            :  * be initialized prior to pushing data.
     406                 :            :  *
     407                 :            :  * data [in] 32-bit value to be added to the blob.
     408                 :            :  *
     409                 :            :  * datalen [in] The number of bits to be added to the blob.
     410                 :            :  *
     411                 :            :  * The offset of the data is updated after each push of data.
     412                 :            :  * NULL returned on error, pointer pushed value otherwise.
     413                 :            :  */
     414                 :            : uint8_t *
     415                 :          0 : ulp_blob_push_32(struct ulp_blob *blob,
     416                 :            :                  uint32_t *data,
     417                 :            :                  uint32_t datalen)
     418                 :            : {
     419                 :            :         uint8_t *val = (uint8_t *)data;
     420                 :            :         uint32_t rc;
     421                 :          0 :         uint32_t size = ULP_BITS_2_BYTE(datalen);
     422                 :            : 
     423         [ #  # ]:          0 :         if (!data || size > sizeof(uint32_t)) {
     424                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
     425                 :          0 :                 return 0;
     426                 :            :         }
     427                 :            : 
     428                 :          0 :         rc = ulp_blob_push(blob, &val[sizeof(uint32_t) - size], datalen);
     429         [ #  # ]:          0 :         if (!rc)
     430                 :          0 :                 return 0;
     431                 :            : 
     432                 :            :         return &val[sizeof(uint32_t) - size];
     433                 :            : }
     434                 :            : 
     435                 :            : /*
     436                 :            :  * Add encap data to the binary blob at the current offset.
     437                 :            :  *
     438                 :            :  * blob [in] The blob that data is added to.  The blob must
     439                 :            :  * be initialized prior to pushing data.
     440                 :            :  *
     441                 :            :  * data [in] value to be added to the blob.
     442                 :            :  *
     443                 :            :  * datalen [in] The number of bits to be added to the blob.
     444                 :            :  *
     445                 :            :  * The offset of the data is updated after each push of data.
     446                 :            :  * NULL returned on error, pointer pushed value otherwise.
     447                 :            :  */
     448                 :            : int32_t
     449                 :          0 : ulp_blob_push_encap(struct ulp_blob *blob,
     450                 :            :                     uint8_t *data,
     451                 :            :                     uint32_t datalen)
     452                 :            : {
     453                 :            :         uint8_t         *val = (uint8_t *)data;
     454                 :            :         uint32_t        initial_size, write_size = datalen;
     455                 :            :         uint32_t        size = 0;
     456                 :            : 
     457         [ #  # ]:          0 :         if (!blob || !data ||
     458         [ #  # ]:          0 :             datalen > (uint32_t)(blob->bitlen - blob->write_idx)) {
     459                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
     460                 :          0 :                 return -1;
     461                 :            :         }
     462                 :            : 
     463                 :          0 :         initial_size = ULP_BYTE_2_BITS(sizeof(uint64_t)) -
     464                 :          0 :             (blob->write_idx % ULP_BYTE_2_BITS(sizeof(uint64_t)));
     465         [ #  # ]:          0 :         while (write_size > 0) {
     466         [ #  # ]:          0 :                 if (initial_size && write_size > initial_size) {
     467                 :            :                         size = initial_size;
     468                 :            :                         initial_size = 0;
     469         [ #  # ]:          0 :                 } else if (initial_size && write_size <= initial_size) {
     470                 :            :                         size = write_size;
     471                 :            :                         initial_size = 0;
     472                 :            :                 } else if (write_size > ULP_BYTE_2_BITS(sizeof(uint64_t))) {
     473                 :            :                         size = ULP_BYTE_2_BITS(sizeof(uint64_t));
     474                 :            :                 } else {
     475                 :            :                         size = write_size;
     476                 :            :                 }
     477         [ #  # ]:          0 :                 if (!ulp_blob_push(blob, val, size)) {
     478                 :          0 :                         BNXT_TF_DBG(ERR, "push field failed\n");
     479                 :          0 :                         return -1;
     480                 :            :                 }
     481                 :          0 :                 val += ULP_BITS_2_BYTE(size);
     482                 :          0 :                 write_size -= size;
     483                 :            :         }
     484                 :          0 :         return datalen;
     485                 :            : }
     486                 :            : 
     487                 :            : /*
     488                 :            :  * Adds pad to an initialized blob at the current offset
     489                 :            :  *
     490                 :            :  * blob [in] The blob that data is added to.  The blob must
     491                 :            :  * be initialized prior to pushing data.
     492                 :            :  *
     493                 :            :  * datalen [in] The number of bits of pad to add
     494                 :            :  *
     495                 :            :  * returns the number of pad bits added, -1 on failure
     496                 :            :  */
     497                 :            : int32_t
     498                 :          0 : ulp_blob_pad_push(struct ulp_blob *blob,
     499                 :            :                   uint32_t datalen)
     500                 :            : {
     501         [ #  # ]:          0 :         if (datalen > (uint32_t)(blob->bitlen - blob->write_idx)) {
     502                 :          0 :                 BNXT_TF_DBG(ERR, "Pad too large for blob\n");
     503                 :          0 :                 return -1;
     504                 :            :         }
     505                 :            : 
     506                 :          0 :         blob->write_idx += datalen;
     507                 :          0 :         return datalen;
     508                 :            : }
     509                 :            : 
     510                 :            : /*
     511                 :            :  * Adds pad to an initialized blob at the current offset based on
     512                 :            :  * the alignment.
     513                 :            :  *
     514                 :            :  * blob [in] The blob that needs to be aligned
     515                 :            :  *
     516                 :            :  * align [in] Alignment in bits.
     517                 :            :  *
     518                 :            :  * returns the number of pad bits added, -1 on failure
     519                 :            :  */
     520                 :            : int32_t
     521                 :          0 : ulp_blob_pad_align(struct ulp_blob *blob,
     522                 :            :                    uint32_t align)
     523                 :            : {
     524                 :            :         int32_t pad = 0;
     525                 :            : 
     526                 :          0 :         pad = RTE_ALIGN(blob->write_idx, align) - blob->write_idx;
     527         [ #  # ]:          0 :         if (pad > (int32_t)(blob->bitlen - blob->write_idx)) {
     528                 :          0 :                 BNXT_TF_DBG(ERR, "Pad too large for blob\n");
     529                 :          0 :                 return -1;
     530                 :            :         }
     531                 :          0 :         blob->write_idx += pad;
     532                 :          0 :         return pad;
     533                 :            : }
     534                 :            : 
     535                 :            : /* Get data from src and put into dst using little-endian format */
     536                 :            : static void
     537                 :          0 : ulp_bs_get_lsb(uint8_t *src, uint16_t bitpos, uint8_t bitlen, uint8_t *dst)
     538                 :            : {
     539                 :          0 :         uint8_t bitoffs = bitpos % ULP_BLOB_BYTE;
     540                 :          0 :         uint16_t index  = ULP_BITS_2_BYTE_NR(bitpos);
     541                 :            :         uint8_t mask, partial, shift;
     542                 :            : 
     543                 :            :         shift = bitoffs;
     544                 :          0 :         partial = ULP_BLOB_BYTE - bitoffs;
     545         [ #  # ]:          0 :         if (bitoffs + bitlen <= ULP_BLOB_BYTE) {
     546                 :          0 :                 mask = ((1 << bitlen) - 1) << shift;
     547                 :          0 :                 *dst = (src[index] & mask) >> shift;
     548                 :            :         } else {
     549                 :          0 :                 mask = ((1 << partial) - 1) << shift;
     550                 :          0 :                 *dst = (src[index] & mask) >> shift;
     551                 :          0 :                 index++;
     552                 :          0 :                 partial = bitlen - partial;
     553                 :          0 :                 mask = ((1 << partial) - 1);
     554                 :          0 :                 *dst |= (src[index] & mask) << (ULP_BLOB_BYTE - bitoffs);
     555                 :            :         }
     556                 :          0 : }
     557                 :            : 
     558                 :            : /*
     559                 :            :  * Get data from the byte array in Little endian format.
     560                 :            :  *
     561                 :            :  * src [in] The byte array where data is extracted from
     562                 :            :  *
     563                 :            :  * dst [out] The byte array where data is pulled into
     564                 :            :  *
     565                 :            :  * size [in] The size of dst array in bytes
     566                 :            :  *
     567                 :            :  * offset [in] The offset where data is pulled
     568                 :            :  *
     569                 :            :  * len [in] The number of bits to be extracted from the data array
     570                 :            :  *
     571                 :            :  * returns None.
     572                 :            :  */
     573                 :            : void
     574                 :          0 : ulp_bs_pull_lsb(uint8_t *src, uint8_t *dst, uint32_t size,
     575                 :            :                 uint32_t offset, uint32_t len)
     576                 :            : {
     577                 :            :         uint32_t idx;
     578                 :          0 :         uint32_t cnt = ULP_BITS_2_BYTE_NR(len);
     579                 :            : 
     580                 :            :         /* iterate bytewise to get data */
     581         [ #  # ]:          0 :         for (idx = 0; idx < cnt; idx++) {
     582                 :          0 :                 ulp_bs_get_lsb(src, offset, ULP_BLOB_BYTE,
     583                 :          0 :                                &dst[size - 1 - idx]);
     584                 :          0 :                 offset += ULP_BLOB_BYTE;
     585                 :          0 :                 len -= ULP_BLOB_BYTE;
     586                 :            :         }
     587                 :            : 
     588                 :            :         /* Extract the last reminder data that is not 8 byte boundary */
     589         [ #  # ]:          0 :         if (len)
     590                 :          0 :                 ulp_bs_get_lsb(src, offset, len, &dst[size - 1 - idx]);
     591                 :          0 : }
     592                 :            : 
     593                 :            : /* Get data from src and put into dst using big-endian format */
     594                 :            : static void
     595                 :          0 : ulp_bs_get_msb(uint8_t *src, uint16_t bitpos, uint8_t bitlen, uint8_t *dst)
     596                 :            : {
     597                 :          0 :         uint8_t bitoffs = bitpos % ULP_BLOB_BYTE;
     598                 :          0 :         uint16_t index  = ULP_BITS_2_BYTE_NR(bitpos);
     599                 :            :         uint8_t mask;
     600                 :            :         int32_t shift;
     601                 :            : 
     602                 :          0 :         shift = ULP_BLOB_BYTE - bitoffs - bitlen;
     603         [ #  # ]:          0 :         if (shift >= 0) {
     604                 :            :                 mask = 0xFF >> -bitlen;
     605                 :          0 :                 *dst = (src[index] >> shift) & mask;
     606                 :            :         } else {
     607                 :          0 :                 *dst = (src[index] & (0xFF >> bitoffs)) << -shift;
     608                 :          0 :                 *dst |= src[index + 1] >> -shift;
     609                 :            :         }
     610                 :          0 : }
     611                 :            : 
     612                 :            : /*
     613                 :            :  * Get data from the byte array in Big endian format.
     614                 :            :  *
     615                 :            :  * src [in] The byte array where data is extracted from
     616                 :            :  *
     617                 :            :  * dst [out] The byte array where data is pulled into
     618                 :            :  *
     619                 :            :  * offset [in] The offset where data is pulled
     620                 :            :  *
     621                 :            :  * len [in] The number of bits to be extracted from the data array
     622                 :            :  *
     623                 :            :  * returns None.
     624                 :            :  */
     625                 :            : void
     626                 :          0 : ulp_bs_pull_msb(uint8_t *src, uint8_t *dst,
     627                 :            :                 uint32_t offset, uint32_t len)
     628                 :            : {
     629                 :            :         uint32_t idx;
     630                 :          0 :         uint32_t cnt = ULP_BITS_2_BYTE_NR(len);
     631                 :            : 
     632                 :            :         /* iterate bytewise to get data */
     633         [ #  # ]:          0 :         for (idx = 0; idx < cnt; idx++) {
     634                 :          0 :                 ulp_bs_get_msb(src, offset, ULP_BLOB_BYTE, &dst[idx]);
     635                 :          0 :                 offset += ULP_BLOB_BYTE;
     636                 :          0 :                 len -= ULP_BLOB_BYTE;
     637                 :            :         }
     638                 :            : 
     639                 :            :         /* Extract the last reminder data that is not 8 byte boundary */
     640         [ #  # ]:          0 :         if (len)
     641                 :          0 :                 ulp_bs_get_msb(src, offset, len, &dst[idx]);
     642                 :          0 : }
     643                 :            : 
     644                 :            : /*
     645                 :            :  * Extract data from the binary blob using given offset.
     646                 :            :  *
     647                 :            :  * blob [in] The blob that data is extracted from. The blob must
     648                 :            :  * be initialized prior to pulling data.
     649                 :            :  *
     650                 :            :  * data [in] A pointer to put the data.
     651                 :            :  * data_size [in] size of the data buffer in bytes.
     652                 :            :  *offset [in] - Offset in the blob to extract the data in bits format.
     653                 :            :  * len [in] The number of bits to be pulled from the blob.
     654                 :            :  *
     655                 :            :  * Output: zero on success, -1 on failure
     656                 :            :  */
     657                 :            : int32_t
     658                 :          0 : ulp_blob_pull(struct ulp_blob *blob, uint8_t *data, uint32_t data_size,
     659                 :            :               uint16_t offset, uint16_t len)
     660                 :            : {
     661                 :            :         /* validate the arguments */
     662   [ #  #  #  # ]:          0 :         if (!blob || (offset + len) > blob->bitlen ||
     663         [ #  # ]:          0 :             ULP_BYTE_2_BITS(data_size) < len) {
     664                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
     665                 :          0 :                 return -1; /* failure */
     666                 :            :         }
     667                 :            : 
     668         [ #  # ]:          0 :         if (blob->byte_order == BNXT_ULP_BYTE_ORDER_BE)
     669                 :          0 :                 ulp_bs_pull_msb(blob->data, data, offset, len);
     670                 :            :         else
     671                 :          0 :                 ulp_bs_pull_lsb(blob->data, data, data_size, offset, len);
     672                 :            :         return 0;
     673                 :            : }
     674                 :            : 
     675                 :            : /*
     676                 :            :  * Get the data portion of the binary blob.
     677                 :            :  *
     678                 :            :  * blob [in] The blob's data to be retrieved. The blob must be
     679                 :            :  * initialized prior to pushing data.
     680                 :            :  *
     681                 :            :  * datalen [out] The number of bits to that are filled.
     682                 :            :  *
     683                 :            :  * returns a byte array of the blob data.  Returns NULL on error.
     684                 :            :  */
     685                 :            : uint8_t *
     686                 :          0 : ulp_blob_data_get(struct ulp_blob *blob,
     687                 :            :                   uint16_t *datalen)
     688                 :            : {
     689                 :            :         /* validate the arguments */
     690         [ #  # ]:          0 :         if (!blob) {
     691                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
     692                 :          0 :                 return NULL; /* failure */
     693                 :            :         }
     694                 :          0 :         *datalen = blob->write_idx;
     695                 :          0 :         return blob->data;
     696                 :            : }
     697                 :            : 
     698                 :            : /*
     699                 :            :  * Get the data length of the binary blob.
     700                 :            :  *
     701                 :            :  * blob [in] The blob's data len to be retrieved.
     702                 :            :  *
     703                 :            :  * returns length of the binary blob
     704                 :            :  */
     705                 :            : uint16_t
     706                 :          0 : ulp_blob_data_len_get(struct ulp_blob *blob)
     707                 :            : {
     708                 :            :         /* validate the arguments */
     709         [ #  # ]:          0 :         if (!blob) {
     710                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
     711                 :          0 :                 return 0; /* failure */
     712                 :            :         }
     713                 :          0 :         return blob->write_idx;
     714                 :            : }
     715                 :            : 
     716                 :            : /*
     717                 :            :  * Set the encap swap start index of the binary blob.
     718                 :            :  *
     719                 :            :  * blob [in] The blob's data to be retrieved. The blob must be
     720                 :            :  * initialized prior to pushing data.
     721                 :            :  *
     722                 :            :  * returns void.
     723                 :            :  */
     724                 :            : void
     725                 :          0 : ulp_blob_encap_swap_idx_set(struct ulp_blob *blob)
     726                 :            : {
     727                 :            :         /* validate the arguments */
     728         [ #  # ]:          0 :         if (!blob) {
     729                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
     730                 :          0 :                 return; /* failure */
     731                 :            :         }
     732                 :          0 :         blob->encap_swap_idx = blob->write_idx;
     733                 :            : }
     734                 :            : 
     735                 :            : /*
     736                 :            :  * Perform the encap buffer swap to 64 bit reversal.
     737                 :            :  *
     738                 :            :  * blob [in] The blob's data to be used for swap.
     739                 :            :  *
     740                 :            :  * returns void.
     741                 :            :  */
     742                 :            : void
     743                 :          0 : ulp_blob_perform_encap_swap(struct ulp_blob *blob)
     744                 :            : {
     745                 :            :         uint32_t i, idx = 0, end_idx = 0, roundoff;
     746                 :            :         uint8_t temp_val_1, temp_val_2;
     747                 :            : 
     748                 :            :         /* validate the arguments */
     749         [ #  # ]:          0 :         if (!blob) {
     750                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
     751                 :          0 :                 return; /* failure */
     752                 :            :         }
     753                 :          0 :         idx = ULP_BITS_2_BYTE_NR(blob->encap_swap_idx);
     754                 :          0 :         end_idx = ULP_BITS_2_BYTE(blob->write_idx);
     755                 :          0 :         roundoff = ULP_BYTE_2_BITS(ULP_BITS_2_BYTE(end_idx));
     756         [ #  # ]:          0 :         if (roundoff > end_idx) {
     757                 :          0 :                 blob->write_idx += ULP_BYTE_2_BITS(roundoff - end_idx);
     758                 :            :                 end_idx = roundoff;
     759                 :            :         }
     760         [ #  # ]:          0 :         while (idx <= end_idx) {
     761         [ #  # ]:          0 :                 for (i = 0; i < 4; i = i + 2) {
     762                 :          0 :                         temp_val_1 = blob->data[idx + i];
     763                 :          0 :                         temp_val_2 = blob->data[idx + i + 1];
     764                 :          0 :                         blob->data[idx + i] = blob->data[idx + 6 - i];
     765                 :          0 :                         blob->data[idx + i + 1] = blob->data[idx + 7 - i];
     766                 :          0 :                         blob->data[idx + 7 - i] = temp_val_2;
     767                 :          0 :                         blob->data[idx + 6 - i] = temp_val_1;
     768                 :            :                 }
     769                 :          0 :                 idx += 8;
     770                 :            :         }
     771                 :            : }
     772                 :            : 
     773                 :            : /*
     774                 :            :  * Perform the blob buffer reversal byte wise.
     775                 :            :  * This api makes the first byte the last and
     776                 :            :  * vice-versa.
     777                 :            :  *
     778                 :            :  * blob [in] The blob's data to be used for swap.
     779                 :            :  * chunk_size[in] the swap is done within the chunk in bytes
     780                 :            :  *
     781                 :            :  * returns void.
     782                 :            :  */
     783                 :            : void
     784                 :          0 : ulp_blob_perform_byte_reverse(struct ulp_blob *blob,
     785                 :            :                               uint32_t chunk_size)
     786                 :            : {
     787                 :            :         uint32_t idx = 0, jdx = 0, num = 0;
     788                 :            :         uint8_t xchar;
     789                 :            :         uint8_t *buff;
     790                 :            : 
     791                 :            :         /* validate the arguments */
     792         [ #  # ]:          0 :         if (!blob) {
     793                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
     794                 :          0 :                 return; /* failure */
     795                 :            :         }
     796                 :            : 
     797                 :          0 :         buff = blob->data;
     798                 :          0 :         num = ULP_BITS_2_BYTE(blob->write_idx) / chunk_size;
     799         [ #  # ]:          0 :         for (idx = 0; idx < num; idx++) {
     800         [ #  # ]:          0 :                 for (jdx = 0; jdx < chunk_size / 2; jdx++) {
     801                 :          0 :                         xchar = buff[jdx];
     802                 :          0 :                         buff[jdx] = buff[(chunk_size - 1) - jdx];
     803                 :          0 :                         buff[(chunk_size - 1) - jdx] = xchar;
     804                 :            :                 }
     805                 :          0 :                 buff += chunk_size;
     806                 :            :         }
     807                 :            : }
     808                 :            : 
     809                 :            : /*
     810                 :            :  * Perform the blob buffer 64 bit word swap.
     811                 :            :  * This api makes the first 4 bytes the last in
     812                 :            :  * a given 64 bit value and vice-versa.
     813                 :            :  *
     814                 :            :  * blob [in] The blob's data to be used for swap.
     815                 :            :  *
     816                 :            :  * returns void.
     817                 :            :  */
     818                 :            : void
     819                 :          0 : ulp_blob_perform_64B_word_swap(struct ulp_blob *blob)
     820                 :            : {
     821                 :            :         uint32_t i, j, num;
     822                 :            :         uint8_t xchar;
     823                 :            :         uint32_t word_size = ULP_64B_IN_BYTES / 2;
     824                 :            : 
     825                 :            :         /* validate the arguments */
     826         [ #  # ]:          0 :         if (!blob) {
     827                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
     828                 :          0 :                 return; /* failure */
     829                 :            :         }
     830                 :          0 :         num = ULP_BITS_2_BYTE(blob->write_idx);
     831         [ #  # ]:          0 :         for (i = 0; i < num; i = i + ULP_64B_IN_BYTES) {
     832         [ #  # ]:          0 :                 for (j = 0; j < word_size; j++) {
     833                 :          0 :                         xchar = blob->data[i + j];
     834                 :          0 :                         blob->data[i + j] = blob->data[i + j + word_size];
     835                 :          0 :                         blob->data[i + j + word_size] = xchar;
     836                 :            :                 }
     837                 :            :         }
     838                 :            : }
     839                 :            : 
     840                 :            : /*
     841                 :            :  * Perform the blob buffer 64 bit byte swap.
     842                 :            :  * This api makes the first byte the last in
     843                 :            :  * a given 64 bit value and vice-versa.
     844                 :            :  *
     845                 :            :  * blob [in] The blob's data to be used for swap.
     846                 :            :  *
     847                 :            :  * returns void.
     848                 :            :  */
     849                 :            : void
     850                 :          0 : ulp_blob_perform_64B_byte_swap(struct ulp_blob *blob)
     851                 :            : {
     852                 :            :         uint32_t i, j, num;
     853                 :            :         uint8_t xchar;
     854                 :            :         uint32_t offset = ULP_64B_IN_BYTES - 1;
     855                 :            : 
     856                 :            :         /* validate the arguments */
     857         [ #  # ]:          0 :         if (!blob) {
     858                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
     859                 :          0 :                 return; /* failure */
     860                 :            :         }
     861                 :          0 :         num = ULP_BITS_2_BYTE(blob->write_idx);
     862         [ #  # ]:          0 :         for (i = 0; i < num; i = i + ULP_64B_IN_BYTES) {
     863         [ #  # ]:          0 :                 for (j = 0; j < (ULP_64B_IN_BYTES / 2); j++) {
     864                 :          0 :                         xchar = blob->data[i + j];
     865                 :          0 :                         blob->data[i + j] = blob->data[i + offset - j];
     866                 :          0 :                         blob->data[i + offset - j] = xchar;
     867                 :            :                 }
     868                 :            :         }
     869                 :            : }
     870                 :            : 
     871                 :            : static int32_t
     872                 :          0 : ulp_blob_msb_block_merge(struct ulp_blob *dst, struct ulp_blob *src,
     873                 :            :                          uint32_t block_size, uint32_t pad)
     874                 :            : {
     875                 :            :         uint32_t i, k, write_bytes, remaining;
     876                 :            :         uint16_t num;
     877                 :          0 :         uint8_t *src_buf = ulp_blob_data_get(src, &num);
     878                 :            :         uint8_t bluff;
     879                 :            : 
     880         [ #  # ]:          0 :         for (i = 0; i < num;) {
     881         [ #  # ]:          0 :                 if (((dst->write_idx % block_size)  + (num - i)) > block_size)
     882                 :          0 :                         write_bytes = block_size -
     883                 :            :                                 (dst->write_idx % block_size);
     884                 :            :                 else
     885                 :            :                         write_bytes = num - i;
     886         [ #  # ]:          0 :                 for (k = 0; k < ULP_BITS_2_BYTE_NR(write_bytes); k++) {
     887                 :          0 :                         ulp_bs_put_msb(dst->data, dst->write_idx, ULP_BLOB_BYTE,
     888                 :          0 :                                        *src_buf);
     889                 :          0 :                         dst->write_idx += ULP_BLOB_BYTE;
     890                 :          0 :                         src_buf++;
     891                 :            :                 }
     892                 :          0 :                 remaining = write_bytes % ULP_BLOB_BYTE;
     893         [ #  # ]:          0 :                 if (remaining) {
     894                 :          0 :                         bluff = (*src_buf) & ((uint8_t)-1 <<
     895                 :          0 :                                               (ULP_BLOB_BYTE - remaining));
     896                 :          0 :                         ulp_bs_put_msb(dst->data, dst->write_idx,
     897                 :            :                                        ULP_BLOB_BYTE, bluff);
     898                 :          0 :                         dst->write_idx += remaining;
     899                 :            :                 }
     900         [ #  # ]:          0 :                 if (write_bytes != (num - i)) {
     901                 :            :                         /* add the padding */
     902                 :          0 :                         ulp_blob_pad_push(dst, pad);
     903         [ #  # ]:          0 :                         if (remaining) {
     904                 :          0 :                                 ulp_bs_put_msb(dst->data, dst->write_idx,
     905                 :          0 :                                                ULP_BLOB_BYTE - remaining,
     906                 :          0 :                                                *src_buf);
     907                 :          0 :                                 dst->write_idx += ULP_BLOB_BYTE - remaining;
     908                 :          0 :                                 src_buf++;
     909                 :            :                         }
     910                 :            :                 }
     911                 :          0 :                 i += write_bytes;
     912                 :            :         }
     913                 :          0 :         return 0;
     914                 :            : }
     915                 :            : 
     916                 :            : /*
     917                 :            :  * Perform the blob buffer merge.
     918                 :            :  * This api makes the src blob merged to the dst blob.
     919                 :            :  * The block size and pad size help in padding the dst blob
     920                 :            :  *
     921                 :            :  * dst [in] The destination blob, the blob to be merged.
     922                 :            :  * src [in] The src blob.
     923                 :            :  * block_size [in] The size of the block after which padding gets applied.
     924                 :            :  * pad [in] The size of the pad to be applied.
     925                 :            :  *
     926                 :            :  * returns 0 on success.
     927                 :            :  */
     928                 :            : int32_t
     929                 :          0 : ulp_blob_block_merge(struct ulp_blob *dst, struct ulp_blob *src,
     930                 :            :                      uint32_t block_size, uint32_t pad)
     931                 :            : {
     932         [ #  # ]:          0 :         if (dst->byte_order == BNXT_ULP_BYTE_ORDER_BE &&
     933         [ #  # ]:          0 :             src->byte_order == BNXT_ULP_BYTE_ORDER_BE)
     934                 :          0 :                 return ulp_blob_msb_block_merge(dst, src, block_size, pad);
     935                 :            : 
     936                 :          0 :         BNXT_TF_DBG(ERR, "block merge not implemented yet\n");
     937                 :          0 :         return -EINVAL;
     938                 :            : }
     939                 :            : 
     940                 :            : int32_t
     941                 :          0 : ulp_blob_append(struct ulp_blob *dst, struct ulp_blob *src,
     942                 :            :                 uint16_t src_offset, uint16_t src_len)
     943                 :            : {
     944                 :            :         uint32_t k, remaining;
     945                 :            :         uint16_t num;
     946                 :            :         uint8_t bluff;
     947                 :          0 :         uint8_t *src_buf = ulp_blob_data_get(src, &num);
     948                 :            : 
     949         [ #  # ]:          0 :         if ((src_offset + src_len) > num)
     950                 :            :                 return -EINVAL;
     951                 :            : 
     952                 :            :         /* Only supporting BE for now */
     953         [ #  # ]:          0 :         if (src->byte_order != BNXT_ULP_BYTE_ORDER_BE ||
     954         [ #  # ]:          0 :             dst->byte_order != BNXT_ULP_BYTE_ORDER_BE)
     955                 :            :                 return -EINVAL;
     956                 :            : 
     957                 :            :         /* Handle if the source offset is not on a byte boundary */
     958                 :          0 :         remaining = src_offset % ULP_BLOB_BYTE;
     959         [ #  # ]:          0 :         if (remaining) {
     960                 :          0 :                 bluff = src_buf[src_offset / ULP_BLOB_BYTE] & ((uint8_t)-1 >>
     961                 :          0 :                                       (ULP_BLOB_BYTE - remaining));
     962                 :          0 :                 ulp_bs_put_msb(dst->data, dst->write_idx,
     963                 :            :                                ULP_BLOB_BYTE, bluff);
     964                 :          0 :                 dst->write_idx += remaining;
     965                 :          0 :                 src_offset += remaining;
     966                 :            :         }
     967                 :            : 
     968                 :          0 :         src_buf += ULP_BITS_2_BYTE_NR(src_offset);
     969                 :            : 
     970                 :            :         /* Push the byte aligned pieces */
     971         [ #  # ]:          0 :         for (k = 0; k < ULP_BITS_2_BYTE_NR(src_len); k++) {
     972                 :          0 :                 ulp_bs_put_msb(dst->data, dst->write_idx, ULP_BLOB_BYTE,
     973                 :          0 :                                *src_buf);
     974                 :          0 :                 dst->write_idx += ULP_BLOB_BYTE;
     975                 :          0 :                 src_buf++;
     976                 :            :         }
     977                 :            : 
     978                 :            :         /* Handle the remaining if length is not a byte boundary */
     979                 :          0 :         remaining = src_len % ULP_BLOB_BYTE;
     980         [ #  # ]:          0 :         if (remaining) {
     981                 :          0 :                 bluff = (*src_buf) & ((uint8_t)-1 <<
     982                 :          0 :                                       (ULP_BLOB_BYTE - remaining));
     983                 :          0 :                 ulp_bs_put_msb(dst->data, dst->write_idx,
     984                 :            :                                ULP_BLOB_BYTE, bluff);
     985                 :          0 :                 dst->write_idx += remaining;
     986                 :            :         }
     987                 :            : 
     988                 :            :         return 0;
     989                 :            : }
     990                 :            : 
     991                 :            : /*
     992                 :            :  * Perform the blob buffer copy.
     993                 :            :  * This api makes the src blob merged to the dst blob.
     994                 :            :  *
     995                 :            :  * dst [in] The destination blob, the blob to be merged.
     996                 :            :  * src [in] The src blob.
     997                 :            :  *
     998                 :            :  * returns 0 on success.
     999                 :            :  */
    1000                 :            : int32_t
    1001                 :          0 : ulp_blob_buffer_copy(struct ulp_blob *dst, struct ulp_blob *src)
    1002                 :            : {
    1003         [ #  # ]:          0 :         if ((dst->write_idx + src->write_idx) > dst->bitlen) {
    1004                 :          0 :                 BNXT_TF_DBG(ERR, "source buffer too large\n");
    1005                 :          0 :                 return -EINVAL;
    1006                 :            :         }
    1007   [ #  #  #  # ]:          0 :         if (ULP_BITS_IS_BYTE_NOT_ALIGNED(dst->write_idx) ||
    1008                 :            :             ULP_BITS_IS_BYTE_NOT_ALIGNED(src->write_idx)) {
    1009                 :          0 :                 BNXT_TF_DBG(ERR, "source buffer is not aligned\n");
    1010                 :          0 :                 return -EINVAL;
    1011                 :            :         }
    1012                 :          0 :         memcpy(&dst->data[ULP_BITS_2_BYTE_NR(dst->write_idx)],
    1013                 :          0 :                src->data, ULP_BITS_2_BYTE_NR(src->write_idx));
    1014                 :          0 :         dst->write_idx += src->write_idx;
    1015                 :          0 :         return 0;
    1016                 :            : }
    1017                 :            : 
    1018                 :            : /*
    1019                 :            :  * Read data from the operand
    1020                 :            :  *
    1021                 :            :  * operand [in] A pointer to a 16 Byte operand
    1022                 :            :  *
    1023                 :            :  * val [in/out] The variable to copy the operand to
    1024                 :            :  *
    1025                 :            :  * bytes [in] The number of bytes to read into val
    1026                 :            :  *
    1027                 :            :  * returns number of bits read, zero on error
    1028                 :            :  */
    1029                 :            : uint16_t
    1030                 :          0 : ulp_operand_read(uint8_t *operand,
    1031                 :            :                  uint8_t *val,
    1032                 :            :                  uint16_t bytes)
    1033                 :            : {
    1034                 :            :         /* validate the arguments */
    1035         [ #  # ]:          0 :         if (!operand || !val) {
    1036                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
    1037                 :          0 :                 return 0; /* failure */
    1038                 :            :         }
    1039                 :          0 :         memcpy(val, operand, bytes);
    1040                 :          0 :         return bytes;
    1041                 :            : }
    1042                 :            : 
    1043                 :            : /*
    1044                 :            :  * Check the buffer is empty
    1045                 :            :  *
    1046                 :            :  * buf [in] The buffer
    1047                 :            :  * size [in] The size of the buffer
    1048                 :            :  *
    1049                 :            :  */
    1050                 :          0 : int32_t ulp_buffer_is_empty(const uint8_t *buf, uint32_t size)
    1051                 :            : {
    1052   [ #  #  #  # ]:          0 :         return buf[0] == 0 && !memcmp(buf, buf + 1, size - 1);
    1053                 :            : }
    1054                 :            : 
    1055                 :            : /* Function to check if bitmap is zero.Return 1 on success */
    1056                 :          0 : uint32_t ulp_bitmap_is_zero(uint8_t *bitmap, int32_t size)
    1057                 :            : {
    1058         [ #  # ]:          0 :         while (size-- > 0) {
    1059         [ #  # ]:          0 :                 if (*bitmap != 0)
    1060                 :            :                         return 0;
    1061                 :          0 :                 bitmap++;
    1062                 :            :         }
    1063                 :            :         return 1;
    1064                 :            : }
    1065                 :            : 
    1066                 :            : /* Function to check if bitmap is ones. Return 1 on success */
    1067                 :          0 : uint32_t ulp_bitmap_is_ones(uint8_t *bitmap, int32_t size)
    1068                 :            : {
    1069         [ #  # ]:          0 :         while (size-- > 0) {
    1070         [ #  # ]:          0 :                 if (*bitmap != 0xFF)
    1071                 :            :                         return 0;
    1072                 :          0 :                 bitmap++;
    1073                 :            :         }
    1074                 :            :         return 1;
    1075                 :            : }
    1076                 :            : 
    1077                 :            : /* Function to check if bitmap is not zero. Return 1 on success */
    1078                 :          0 : uint32_t ulp_bitmap_notzero(const uint8_t *bitmap, int32_t size)
    1079                 :            : {
    1080         [ #  # ]:          0 :         while (size-- > 0) {
    1081         [ #  # ]:          0 :                 if (*bitmap != 0)
    1082                 :            :                         return 1;
    1083                 :          0 :                 bitmap++;
    1084                 :            :         }
    1085                 :            :         return 0;
    1086                 :            : }
    1087                 :            : 
    1088                 :            : /* returns 0 if input is power of 2 */
    1089                 :          0 : int32_t ulp_util_is_power_of_2(uint64_t x)
    1090                 :            : {
    1091         [ #  # ]:          0 :         if (((x - 1) & x))
    1092                 :          0 :                 return -1;
    1093                 :            :         return 0;
    1094                 :            : }

Generated by: LCOV version 1.14