188badb3aSMike Baucom /* SPDX-License-Identifier: BSD-3-Clause 288badb3aSMike Baucom * Copyright(c) 2014-2019 Broadcom 388badb3aSMike Baucom * All rights reserved. 488badb3aSMike Baucom */ 588badb3aSMike Baucom 688badb3aSMike Baucom #include "ulp_utils.h" 788badb3aSMike Baucom #include "bnxt_tf_common.h" 888badb3aSMike Baucom 988badb3aSMike Baucom /* 1088badb3aSMike Baucom * Initialize the regfile structure for writing 1188badb3aSMike Baucom * 1288badb3aSMike Baucom * regfile [in] Ptr to a regfile instance 1388badb3aSMike Baucom * 1488badb3aSMike Baucom * returns 0 on error or 1 on success 1588badb3aSMike Baucom */ 1688badb3aSMike Baucom uint32_t 1788badb3aSMike Baucom ulp_regfile_init(struct ulp_regfile *regfile) 1888badb3aSMike Baucom { 1988badb3aSMike Baucom /* validate the arguments */ 2088badb3aSMike Baucom if (!regfile) { 2188badb3aSMike Baucom BNXT_TF_DBG(ERR, "invalid argument\n"); 2288badb3aSMike Baucom return 0; /* failure */ 2388badb3aSMike Baucom } 2488badb3aSMike Baucom memset(regfile, 0, sizeof(struct ulp_regfile)); 2588badb3aSMike Baucom return 1; /* Success */ 2688badb3aSMike Baucom } 2788badb3aSMike Baucom 2888badb3aSMike Baucom /* 2988badb3aSMike Baucom * Read a value from the regfile 3088badb3aSMike Baucom * 3188badb3aSMike Baucom * regfile [in] The regfile instance. Must be initialized prior to being used 3288badb3aSMike Baucom * 3388badb3aSMike Baucom * field [in] The field to be read within the regfile. 3488badb3aSMike Baucom * 3588badb3aSMike Baucom * data [in/out] 3688badb3aSMike Baucom * 3788badb3aSMike Baucom * returns size, zero on failure 3888badb3aSMike Baucom */ 3988badb3aSMike Baucom uint32_t 4088badb3aSMike Baucom ulp_regfile_read(struct ulp_regfile *regfile, 4188badb3aSMike Baucom enum bnxt_ulp_regfile_index field, 4288badb3aSMike Baucom uint64_t *data) 4388badb3aSMike Baucom { 4488badb3aSMike Baucom /* validate the arguments */ 4588badb3aSMike Baucom if (!regfile || field >= BNXT_ULP_REGFILE_INDEX_LAST) { 4688badb3aSMike Baucom BNXT_TF_DBG(ERR, "invalid argument\n"); 4788badb3aSMike Baucom return 0; /* failure */ 4888badb3aSMike Baucom } 4988badb3aSMike Baucom 5088badb3aSMike Baucom *data = regfile->entry[field].data; 5188badb3aSMike Baucom return sizeof(*data); 5288badb3aSMike Baucom } 5388badb3aSMike Baucom 5488badb3aSMike Baucom /* 5588badb3aSMike Baucom * Write a value to the regfile 5688badb3aSMike Baucom * 5788badb3aSMike Baucom * regfile [in] The regfile instance. Must be initialized prior to being used 5888badb3aSMike Baucom * 5988badb3aSMike Baucom * field [in] The field to be written within the regfile. 6088badb3aSMike Baucom * 6188badb3aSMike Baucom * data [in] The value is written into this variable. It is going to be in the 6288badb3aSMike Baucom * same byte order as it was written. 6388badb3aSMike Baucom * 6488badb3aSMike Baucom * size [in] The size in bytes of the value beingritten into this 6588badb3aSMike Baucom * variable. 6688badb3aSMike Baucom * 6788badb3aSMike Baucom * returns 0 on fail 6888badb3aSMike Baucom */ 6988badb3aSMike Baucom uint32_t 7088badb3aSMike Baucom ulp_regfile_write(struct ulp_regfile *regfile, 7188badb3aSMike Baucom enum bnxt_ulp_regfile_index field, 7288badb3aSMike Baucom uint64_t data) 7388badb3aSMike Baucom { 7488badb3aSMike Baucom /* validate the arguments */ 7588badb3aSMike Baucom if (!regfile || field >= BNXT_ULP_REGFILE_INDEX_LAST) { 7688badb3aSMike Baucom BNXT_TF_DBG(ERR, "invalid argument\n"); 7788badb3aSMike Baucom return 0; /* failure */ 7888badb3aSMike Baucom } 7988badb3aSMike Baucom 8088badb3aSMike Baucom regfile->entry[field].data = data; 8188badb3aSMike Baucom return sizeof(data); /* Success */ 8288badb3aSMike Baucom } 8388badb3aSMike Baucom 8488badb3aSMike Baucom static void 8588badb3aSMike Baucom ulp_bs_put_msb(uint8_t *bs, uint16_t bitpos, uint8_t bitlen, uint8_t val) 8688badb3aSMike Baucom { 8788badb3aSMike Baucom uint8_t bitoffs = bitpos % 8; 8888badb3aSMike Baucom uint16_t index = bitpos / 8; 8988badb3aSMike Baucom uint8_t mask; 9088badb3aSMike Baucom uint8_t tmp; 9188badb3aSMike Baucom int8_t shift; 9288badb3aSMike Baucom 9388badb3aSMike Baucom tmp = bs[index]; 9488badb3aSMike Baucom mask = ((uint8_t)-1 >> (8 - bitlen)); 9588badb3aSMike Baucom shift = 8 - bitoffs - bitlen; 9688badb3aSMike Baucom val &= mask; 9788badb3aSMike Baucom 9888badb3aSMike Baucom if (shift >= 0) { 9988badb3aSMike Baucom tmp &= ~(mask << shift); 10088badb3aSMike Baucom tmp |= val << shift; 10188badb3aSMike Baucom bs[index] = tmp; 10288badb3aSMike Baucom } else { 10388badb3aSMike Baucom tmp &= ~((uint8_t)-1 >> bitoffs); 10488badb3aSMike Baucom tmp |= val >> -shift; 10588badb3aSMike Baucom bs[index++] = tmp; 10688badb3aSMike Baucom 10788badb3aSMike Baucom tmp = bs[index]; 10888badb3aSMike Baucom tmp &= ((uint8_t)-1 >> (bitlen - (8 - bitoffs))); 10988badb3aSMike Baucom tmp |= val << (8 + shift); 11088badb3aSMike Baucom bs[index] = tmp; 11188badb3aSMike Baucom } 11288badb3aSMike Baucom } 11388badb3aSMike Baucom 11488badb3aSMike Baucom static void 11588badb3aSMike Baucom ulp_bs_put_lsb(uint8_t *bs, uint16_t bitpos, uint8_t bitlen, uint8_t val) 11688badb3aSMike Baucom { 11788badb3aSMike Baucom uint8_t bitoffs = bitpos % 8; 11888badb3aSMike Baucom uint16_t index = bitpos / 8; 11988badb3aSMike Baucom uint8_t mask; 12088badb3aSMike Baucom uint8_t tmp; 12188badb3aSMike Baucom uint8_t shift; 12288badb3aSMike Baucom uint8_t partial; 12388badb3aSMike Baucom 12488badb3aSMike Baucom tmp = bs[index]; 12588badb3aSMike Baucom shift = bitoffs; 12688badb3aSMike Baucom 12788badb3aSMike Baucom if (bitoffs + bitlen <= 8) { 12888badb3aSMike Baucom mask = ((1 << bitlen) - 1) << shift; 12988badb3aSMike Baucom tmp &= ~mask; 13088badb3aSMike Baucom tmp |= ((val << shift) & mask); 13188badb3aSMike Baucom bs[index] = tmp; 13288badb3aSMike Baucom } else { 13388badb3aSMike Baucom partial = 8 - bitoffs; 13488badb3aSMike Baucom mask = ((1 << partial) - 1) << shift; 13588badb3aSMike Baucom tmp &= ~mask; 13688badb3aSMike Baucom tmp |= ((val << shift) & mask); 13788badb3aSMike Baucom bs[index++] = tmp; 13888badb3aSMike Baucom 13988badb3aSMike Baucom val >>= partial; 14088badb3aSMike Baucom partial = bitlen - partial; 14188badb3aSMike Baucom mask = ((1 << partial) - 1); 14288badb3aSMike Baucom tmp = bs[index]; 14388badb3aSMike Baucom tmp &= ~mask; 14488badb3aSMike Baucom tmp |= (val & mask); 14588badb3aSMike Baucom bs[index] = tmp; 14688badb3aSMike Baucom } 14788badb3aSMike Baucom } 14888badb3aSMike Baucom 14988badb3aSMike Baucom /* Assuming that val is in Big-Endian Format */ 15088badb3aSMike Baucom static uint32_t 15188badb3aSMike Baucom ulp_bs_push_lsb(uint8_t *bs, uint16_t pos, uint8_t len, uint8_t *val) 15288badb3aSMike Baucom { 15388badb3aSMike Baucom int i; 15488badb3aSMike Baucom int cnt = (len) / 8; 15588badb3aSMike Baucom int tlen = len; 15688badb3aSMike Baucom 15788badb3aSMike Baucom if (cnt > 0 && !(len % 8)) 15888badb3aSMike Baucom cnt -= 1; 15988badb3aSMike Baucom 16088badb3aSMike Baucom for (i = 0; i < cnt; i++) { 16188badb3aSMike Baucom ulp_bs_put_lsb(bs, pos, 8, val[cnt - i]); 16288badb3aSMike Baucom pos += 8; 16388badb3aSMike Baucom tlen -= 8; 16488badb3aSMike Baucom } 16588badb3aSMike Baucom 16688badb3aSMike Baucom /* Handle the remainder bits */ 16788badb3aSMike Baucom if (tlen) 16888badb3aSMike Baucom ulp_bs_put_lsb(bs, pos, tlen, val[0]); 16988badb3aSMike Baucom return len; 17088badb3aSMike Baucom } 17188badb3aSMike Baucom 17288badb3aSMike Baucom /* Assuming that val is in Big-Endian Format */ 17388badb3aSMike Baucom static uint32_t 17488badb3aSMike Baucom ulp_bs_push_msb(uint8_t *bs, uint16_t pos, uint8_t len, uint8_t *val) 17588badb3aSMike Baucom { 17688badb3aSMike Baucom int i; 17788badb3aSMike Baucom int cnt = (len + 7) / 8; 17888badb3aSMike Baucom int tlen = len; 17988badb3aSMike Baucom 18088badb3aSMike Baucom /* Handle any remainder bits */ 18188badb3aSMike Baucom int tmp = len % 8; 18288badb3aSMike Baucom 18388badb3aSMike Baucom if (!tmp) 18488badb3aSMike Baucom tmp = 8; 18588badb3aSMike Baucom 18688badb3aSMike Baucom ulp_bs_put_msb(bs, pos, tmp, val[0]); 18788badb3aSMike Baucom 18888badb3aSMike Baucom pos += tmp; 18988badb3aSMike Baucom tlen -= tmp; 19088badb3aSMike Baucom 19188badb3aSMike Baucom for (i = 1; i < cnt; i++) { 19288badb3aSMike Baucom ulp_bs_put_msb(bs, pos, 8, val[i]); 19388badb3aSMike Baucom pos += 8; 19488badb3aSMike Baucom tlen -= 8; 19588badb3aSMike Baucom } 19688badb3aSMike Baucom 19788badb3aSMike Baucom return len; 19888badb3aSMike Baucom } 19988badb3aSMike Baucom 20088badb3aSMike Baucom /* 20188badb3aSMike Baucom * Initializes the blob structure for creating binary blob 20288badb3aSMike Baucom * 20388badb3aSMike Baucom * blob [in] The blob to be initialized 20488badb3aSMike Baucom * 20588badb3aSMike Baucom * bitlen [in] The bit length of the blob 20688badb3aSMike Baucom * 20788badb3aSMike Baucom * order [in] The byte order for the blob. Currently only supporting 20888badb3aSMike Baucom * big endian. All fields are packed with this order. 20988badb3aSMike Baucom * 21088badb3aSMike Baucom * returns 0 on error or 1 on success 21188badb3aSMike Baucom */ 21288badb3aSMike Baucom uint32_t 21388badb3aSMike Baucom ulp_blob_init(struct ulp_blob *blob, 21488badb3aSMike Baucom uint16_t bitlen, 21588badb3aSMike Baucom enum bnxt_ulp_byte_order order) 21688badb3aSMike Baucom { 21788badb3aSMike Baucom /* validate the arguments */ 21888badb3aSMike Baucom if (!blob || bitlen > (8 * sizeof(blob->data))) { 21988badb3aSMike Baucom BNXT_TF_DBG(ERR, "invalid argument\n"); 22088badb3aSMike Baucom return 0; /* failure */ 22188badb3aSMike Baucom } 22288badb3aSMike Baucom blob->bitlen = bitlen; 22388badb3aSMike Baucom blob->byte_order = order; 22488badb3aSMike Baucom blob->write_idx = 0; 22588badb3aSMike Baucom memset(blob->data, 0, sizeof(blob->data)); 22688badb3aSMike Baucom return 1; /* Success */ 22788badb3aSMike Baucom } 22888badb3aSMike Baucom 22988badb3aSMike Baucom /* 23088badb3aSMike Baucom * Add data to the binary blob at the current offset. 23188badb3aSMike Baucom * 23288badb3aSMike Baucom * blob [in] The blob that data is added to. The blob must 23388badb3aSMike Baucom * be initialized prior to pushing data. 23488badb3aSMike Baucom * 23588badb3aSMike Baucom * data [in] A pointer to bytes to be added to the blob. 23688badb3aSMike Baucom * 23788badb3aSMike Baucom * datalen [in] The number of bits to be added to the blob. 23888badb3aSMike Baucom * 23988badb3aSMike Baucom * The offset of the data is updated after each push of data. 24088badb3aSMike Baucom * NULL returned on error. 24188badb3aSMike Baucom */ 24288badb3aSMike Baucom #define ULP_BLOB_BYTE 8 24388badb3aSMike Baucom #define ULP_BLOB_BYTE_HEX 0xFF 24488badb3aSMike Baucom #define BLOB_MASK_CAL(x) ((0xFF << (x)) & 0xFF) 24588badb3aSMike Baucom uint32_t 24688badb3aSMike Baucom ulp_blob_push(struct ulp_blob *blob, 24788badb3aSMike Baucom uint8_t *data, 24888badb3aSMike Baucom uint32_t datalen) 24988badb3aSMike Baucom { 25088badb3aSMike Baucom uint32_t rc; 25188badb3aSMike Baucom 25288badb3aSMike Baucom /* validate the arguments */ 25388badb3aSMike Baucom if (!blob || datalen > (uint32_t)(blob->bitlen - blob->write_idx)) { 25488badb3aSMike Baucom BNXT_TF_DBG(ERR, "invalid argument\n"); 25588badb3aSMike Baucom return 0; /* failure */ 25688badb3aSMike Baucom } 25788badb3aSMike Baucom 25888badb3aSMike Baucom if (blob->byte_order == BNXT_ULP_BYTE_ORDER_BE) 25988badb3aSMike Baucom rc = ulp_bs_push_msb(blob->data, 26088badb3aSMike Baucom blob->write_idx, 26188badb3aSMike Baucom datalen, 26288badb3aSMike Baucom data); 26388badb3aSMike Baucom else 26488badb3aSMike Baucom rc = ulp_bs_push_lsb(blob->data, 26588badb3aSMike Baucom blob->write_idx, 26688badb3aSMike Baucom datalen, 26788badb3aSMike Baucom data); 26888badb3aSMike Baucom if (!rc) { 26988badb3aSMike Baucom BNXT_TF_DBG(ERR, "Failed ro write blob\n"); 27088badb3aSMike Baucom return 0; 27188badb3aSMike Baucom } 27288badb3aSMike Baucom blob->write_idx += datalen; 27388badb3aSMike Baucom return datalen; 27488badb3aSMike Baucom } 27588badb3aSMike Baucom 27688badb3aSMike Baucom /* 27788badb3aSMike Baucom * Add data to the binary blob at the current offset. 27888badb3aSMike Baucom * 27988badb3aSMike Baucom * blob [in] The blob that data is added to. The blob must 28088badb3aSMike Baucom * be initialized prior to pushing data. 28188badb3aSMike Baucom * 28288badb3aSMike Baucom * data [in] 64-bit value to be added to the blob. 28388badb3aSMike Baucom * 28488badb3aSMike Baucom * datalen [in] The number of bits to be added to the blob. 28588badb3aSMike Baucom * 28688badb3aSMike Baucom * The offset of the data is updated after each push of data. 28788badb3aSMike Baucom * NULL returned on error, pointer pushed value otherwise. 28888badb3aSMike Baucom */ 28988badb3aSMike Baucom uint8_t * 29088badb3aSMike Baucom ulp_blob_push_64(struct ulp_blob *blob, 29188badb3aSMike Baucom uint64_t *data, 29288badb3aSMike Baucom uint32_t datalen) 29388badb3aSMike Baucom { 29488badb3aSMike Baucom uint8_t *val = (uint8_t *)data; 29588badb3aSMike Baucom int rc; 29688badb3aSMike Baucom 29788badb3aSMike Baucom int size = (datalen + 7) / 8; 29888badb3aSMike Baucom 29988badb3aSMike Baucom if (!blob || !data || 30088badb3aSMike Baucom datalen > (uint32_t)(blob->bitlen - blob->write_idx)) { 30188badb3aSMike Baucom BNXT_TF_DBG(ERR, "invalid argument\n"); 30288badb3aSMike Baucom return 0; 30388badb3aSMike Baucom } 30488badb3aSMike Baucom 30588badb3aSMike Baucom rc = ulp_blob_push(blob, &val[8 - size], datalen); 30688badb3aSMike Baucom if (!rc) 30788badb3aSMike Baucom return 0; 30888badb3aSMike Baucom 30988badb3aSMike Baucom return &val[8 - size]; 31088badb3aSMike Baucom } 31188badb3aSMike Baucom 31288badb3aSMike Baucom /* 313*a2be13e1SKishore Padmanabha * Add data to the binary blob at the current offset. 314*a2be13e1SKishore Padmanabha * 315*a2be13e1SKishore Padmanabha * blob [in] The blob that data is added to. The blob must 316*a2be13e1SKishore Padmanabha * be initialized prior to pushing data. 317*a2be13e1SKishore Padmanabha * 318*a2be13e1SKishore Padmanabha * data [in] 32-bit value to be added to the blob. 319*a2be13e1SKishore Padmanabha * 320*a2be13e1SKishore Padmanabha * datalen [in] The number of bits to be added ot the blob. 321*a2be13e1SKishore Padmanabha * 322*a2be13e1SKishore Padmanabha * The offset of the data is updated after each push of data. 323*a2be13e1SKishore Padmanabha * NULL returned on error, pointer pushed value otherwise. 324*a2be13e1SKishore Padmanabha */ 325*a2be13e1SKishore Padmanabha uint8_t * 326*a2be13e1SKishore Padmanabha ulp_blob_push_32(struct ulp_blob *blob, 327*a2be13e1SKishore Padmanabha uint32_t *data, 328*a2be13e1SKishore Padmanabha uint32_t datalen) 329*a2be13e1SKishore Padmanabha { 330*a2be13e1SKishore Padmanabha uint8_t *val = (uint8_t *)data; 331*a2be13e1SKishore Padmanabha uint32_t rc; 332*a2be13e1SKishore Padmanabha uint32_t size = ULP_BITS_2_BYTE(datalen); 333*a2be13e1SKishore Padmanabha 334*a2be13e1SKishore Padmanabha if (!data || size > sizeof(uint32_t)) { 335*a2be13e1SKishore Padmanabha BNXT_TF_DBG(ERR, "invalid argument\n"); 336*a2be13e1SKishore Padmanabha return 0; 337*a2be13e1SKishore Padmanabha } 338*a2be13e1SKishore Padmanabha 339*a2be13e1SKishore Padmanabha rc = ulp_blob_push(blob, &val[sizeof(uint32_t) - size], datalen); 340*a2be13e1SKishore Padmanabha if (!rc) 341*a2be13e1SKishore Padmanabha return 0; 342*a2be13e1SKishore Padmanabha 343*a2be13e1SKishore Padmanabha return &val[sizeof(uint32_t) - size]; 344*a2be13e1SKishore Padmanabha } 345*a2be13e1SKishore Padmanabha 346*a2be13e1SKishore Padmanabha /* 34788badb3aSMike Baucom * Add encap data to the binary blob at the current offset. 34888badb3aSMike Baucom * 34988badb3aSMike Baucom * blob [in] The blob that data is added to. The blob must 35088badb3aSMike Baucom * be initialized prior to pushing data. 35188badb3aSMike Baucom * 35288badb3aSMike Baucom * data [in] value to be added to the blob. 35388badb3aSMike Baucom * 35488badb3aSMike Baucom * datalen [in] The number of bits to be added to the blob. 35588badb3aSMike Baucom * 35688badb3aSMike Baucom * The offset of the data is updated after each push of data. 35788badb3aSMike Baucom * NULL returned on error, pointer pushed value otherwise. 35888badb3aSMike Baucom */ 35988badb3aSMike Baucom uint32_t 36088badb3aSMike Baucom ulp_blob_push_encap(struct ulp_blob *blob, 36188badb3aSMike Baucom uint8_t *data, 36288badb3aSMike Baucom uint32_t datalen) 36388badb3aSMike Baucom { 36488badb3aSMike Baucom uint8_t *val = (uint8_t *)data; 36588badb3aSMike Baucom uint32_t initial_size, write_size = datalen; 36688badb3aSMike Baucom uint32_t size = 0; 36788badb3aSMike Baucom 36888badb3aSMike Baucom if (!blob || !data || 36988badb3aSMike Baucom datalen > (uint32_t)(blob->bitlen - blob->write_idx)) { 37088badb3aSMike Baucom BNXT_TF_DBG(ERR, "invalid argument\n"); 37188badb3aSMike Baucom return 0; 37288badb3aSMike Baucom } 37388badb3aSMike Baucom 37488badb3aSMike Baucom initial_size = ULP_BYTE_2_BITS(sizeof(uint64_t)) - 37588badb3aSMike Baucom (blob->write_idx % ULP_BYTE_2_BITS(sizeof(uint64_t))); 37688badb3aSMike Baucom while (write_size > 0) { 37788badb3aSMike Baucom if (initial_size && write_size > initial_size) { 37888badb3aSMike Baucom size = initial_size; 37988badb3aSMike Baucom initial_size = 0; 38088badb3aSMike Baucom } else if (initial_size && write_size <= initial_size) { 38188badb3aSMike Baucom size = write_size; 38288badb3aSMike Baucom initial_size = 0; 38388badb3aSMike Baucom } else if (write_size > ULP_BYTE_2_BITS(sizeof(uint64_t))) { 38488badb3aSMike Baucom size = ULP_BYTE_2_BITS(sizeof(uint64_t)); 38588badb3aSMike Baucom } else { 38688badb3aSMike Baucom size = write_size; 38788badb3aSMike Baucom } 38888badb3aSMike Baucom if (!ulp_blob_push(blob, val, size)) { 38988badb3aSMike Baucom BNXT_TF_DBG(ERR, "push field failed\n"); 39088badb3aSMike Baucom return 0; 39188badb3aSMike Baucom } 39288badb3aSMike Baucom val += ULP_BITS_2_BYTE(size); 39388badb3aSMike Baucom write_size -= size; 39488badb3aSMike Baucom } 39588badb3aSMike Baucom return datalen; 39688badb3aSMike Baucom } 39788badb3aSMike Baucom 39888badb3aSMike Baucom /* 39988badb3aSMike Baucom * Adds pad to an initialized blob at the current offset 40088badb3aSMike Baucom * 40188badb3aSMike Baucom * blob [in] The blob that data is added to. The blob must 40288badb3aSMike Baucom * be initialized prior to pushing data. 40388badb3aSMike Baucom * 40488badb3aSMike Baucom * datalen [in] The number of bits of pad to add 40588badb3aSMike Baucom * 40688badb3aSMike Baucom * returns the number of pad bits added, zero on failure 40788badb3aSMike Baucom */ 40888badb3aSMike Baucom uint32_t 40988badb3aSMike Baucom ulp_blob_pad_push(struct ulp_blob *blob, 41088badb3aSMike Baucom uint32_t datalen) 41188badb3aSMike Baucom { 41288badb3aSMike Baucom if (datalen > (uint32_t)(blob->bitlen - blob->write_idx)) { 41388badb3aSMike Baucom BNXT_TF_DBG(ERR, "Pad too large for blob\n"); 41488badb3aSMike Baucom return 0; 41588badb3aSMike Baucom } 41688badb3aSMike Baucom 41788badb3aSMike Baucom blob->write_idx += datalen; 41888badb3aSMike Baucom return datalen; 41988badb3aSMike Baucom } 42088badb3aSMike Baucom 42188badb3aSMike Baucom /* 42288badb3aSMike Baucom * Get the data portion of the binary blob. 42388badb3aSMike Baucom * 42488badb3aSMike Baucom * blob [in] The blob's data to be retrieved. The blob must be 42588badb3aSMike Baucom * initialized prior to pushing data. 42688badb3aSMike Baucom * 42788badb3aSMike Baucom * datalen [out] The number of bits to that are filled. 42888badb3aSMike Baucom * 42988badb3aSMike Baucom * returns a byte array of the blob data. Returns NULL on error. 43088badb3aSMike Baucom */ 43188badb3aSMike Baucom uint8_t * 43288badb3aSMike Baucom ulp_blob_data_get(struct ulp_blob *blob, 43388badb3aSMike Baucom uint16_t *datalen) 43488badb3aSMike Baucom { 43588badb3aSMike Baucom /* validate the arguments */ 43688badb3aSMike Baucom if (!blob) { 43788badb3aSMike Baucom BNXT_TF_DBG(ERR, "invalid argument\n"); 43888badb3aSMike Baucom return NULL; /* failure */ 43988badb3aSMike Baucom } 44088badb3aSMike Baucom *datalen = blob->write_idx; 44188badb3aSMike Baucom return blob->data; 44288badb3aSMike Baucom } 44388badb3aSMike Baucom 44488badb3aSMike Baucom /* 44588badb3aSMike Baucom * Set the encap swap start index of the binary blob. 44688badb3aSMike Baucom * 44788badb3aSMike Baucom * blob [in] The blob's data to be retrieved. The blob must be 44888badb3aSMike Baucom * initialized prior to pushing data. 44988badb3aSMike Baucom * 45088badb3aSMike Baucom * returns void. 45188badb3aSMike Baucom */ 45288badb3aSMike Baucom void 45388badb3aSMike Baucom ulp_blob_encap_swap_idx_set(struct ulp_blob *blob) 45488badb3aSMike Baucom { 45588badb3aSMike Baucom /* validate the arguments */ 45688badb3aSMike Baucom if (!blob) { 45788badb3aSMike Baucom BNXT_TF_DBG(ERR, "invalid argument\n"); 45888badb3aSMike Baucom return; /* failure */ 45988badb3aSMike Baucom } 46088badb3aSMike Baucom blob->encap_swap_idx = blob->write_idx; 46188badb3aSMike Baucom } 46288badb3aSMike Baucom 46388badb3aSMike Baucom /* 46488badb3aSMike Baucom * Perform the encap buffer swap to 64 bit reversal. 46588badb3aSMike Baucom * 46688badb3aSMike Baucom * blob [in] The blob's data to be used for swap. 46788badb3aSMike Baucom * 46888badb3aSMike Baucom * returns void. 46988badb3aSMike Baucom */ 47088badb3aSMike Baucom void 47188badb3aSMike Baucom ulp_blob_perform_encap_swap(struct ulp_blob *blob) 47288badb3aSMike Baucom { 47388badb3aSMike Baucom uint32_t i, idx = 0, end_idx = 0; 47488badb3aSMike Baucom uint8_t temp_val_1, temp_val_2; 47588badb3aSMike Baucom 47688badb3aSMike Baucom /* validate the arguments */ 47788badb3aSMike Baucom if (!blob) { 47888badb3aSMike Baucom BNXT_TF_DBG(ERR, "invalid argument\n"); 47988badb3aSMike Baucom return; /* failure */ 48088badb3aSMike Baucom } 48188badb3aSMike Baucom idx = ULP_BITS_2_BYTE_NR(blob->encap_swap_idx + 1); 48288badb3aSMike Baucom end_idx = ULP_BITS_2_BYTE(blob->write_idx); 48388badb3aSMike Baucom 48488badb3aSMike Baucom while (idx <= end_idx) { 48588badb3aSMike Baucom for (i = 0; i < 4; i = i + 2) { 48688badb3aSMike Baucom temp_val_1 = blob->data[idx + i]; 48788badb3aSMike Baucom temp_val_2 = blob->data[idx + i + 1]; 48888badb3aSMike Baucom blob->data[idx + i] = blob->data[idx + 6 - i]; 48988badb3aSMike Baucom blob->data[idx + i + 1] = blob->data[idx + 7 - i]; 49088badb3aSMike Baucom blob->data[idx + 7 - i] = temp_val_2; 49188badb3aSMike Baucom blob->data[idx + 6 - i] = temp_val_1; 49288badb3aSMike Baucom } 49388badb3aSMike Baucom idx += 8; 49488badb3aSMike Baucom } 49588badb3aSMike Baucom } 49688badb3aSMike Baucom 49788badb3aSMike Baucom /* 49888badb3aSMike Baucom * Read data from the operand 49988badb3aSMike Baucom * 50088badb3aSMike Baucom * operand [in] A pointer to a 16 Byte operand 50188badb3aSMike Baucom * 50288badb3aSMike Baucom * val [in/out] The variable to copy the operand to 50388badb3aSMike Baucom * 50488badb3aSMike Baucom * bytes [in] The number of bytes to read into val 50588badb3aSMike Baucom * 50688badb3aSMike Baucom * returns number of bits read, zero on error 50788badb3aSMike Baucom */ 50888badb3aSMike Baucom uint16_t 50988badb3aSMike Baucom ulp_operand_read(uint8_t *operand, 51088badb3aSMike Baucom uint8_t *val, 51188badb3aSMike Baucom uint16_t bytes) 51288badb3aSMike Baucom { 51388badb3aSMike Baucom /* validate the arguments */ 51488badb3aSMike Baucom if (!operand || !val) { 51588badb3aSMike Baucom BNXT_TF_DBG(ERR, "invalid argument\n"); 51688badb3aSMike Baucom return 0; /* failure */ 51788badb3aSMike Baucom } 51888badb3aSMike Baucom memcpy(val, operand, bytes); 51988badb3aSMike Baucom return bytes; 52088badb3aSMike Baucom } 52188badb3aSMike Baucom 52288badb3aSMike Baucom /* 52388badb3aSMike Baucom * copy the buffer in the encap format which is 2 bytes. 52488badb3aSMike Baucom * The MSB of the src is placed at the LSB of dst. 52588badb3aSMike Baucom * 52688badb3aSMike Baucom * dst [out] The destination buffer 52788badb3aSMike Baucom * src [in] The source buffer dst 52888badb3aSMike Baucom * size[in] size of the buffer. 52988badb3aSMike Baucom */ 53088badb3aSMike Baucom void 53188badb3aSMike Baucom ulp_encap_buffer_copy(uint8_t *dst, 53288badb3aSMike Baucom const uint8_t *src, 53388badb3aSMike Baucom uint16_t size) 53488badb3aSMike Baucom { 53588badb3aSMike Baucom uint16_t idx = 0; 53688badb3aSMike Baucom 53788badb3aSMike Baucom /* copy 2 bytes at a time. Write MSB to LSB */ 53888badb3aSMike Baucom while ((idx + sizeof(uint16_t)) <= size) { 53988badb3aSMike Baucom memcpy(&dst[idx], &src[size - idx - sizeof(uint16_t)], 54088badb3aSMike Baucom sizeof(uint16_t)); 54188badb3aSMike Baucom idx += sizeof(uint16_t); 54288badb3aSMike Baucom } 54388badb3aSMike Baucom } 54488badb3aSMike Baucom 54588badb3aSMike Baucom /* 54688badb3aSMike Baucom * Check the buffer is empty 54788badb3aSMike Baucom * 54888badb3aSMike Baucom * buf [in] The buffer 54988badb3aSMike Baucom * size [in] The size of the buffer 55088badb3aSMike Baucom * 55188badb3aSMike Baucom */ 55288badb3aSMike Baucom int32_t ulp_buffer_is_empty(const uint8_t *buf, uint32_t size) 55388badb3aSMike Baucom { 55488badb3aSMike Baucom return buf[0] == 0 && !memcmp(buf, buf + 1, size - 1); 55588badb3aSMike Baucom } 5562bbcdee8SKishore Padmanabha 5572bbcdee8SKishore Padmanabha /* Function to check if bitmap is zero.Return 1 on success */ 5582bbcdee8SKishore Padmanabha uint32_t ulp_bitmap_is_zero(uint8_t *bitmap, int32_t size) 5592bbcdee8SKishore Padmanabha { 5602bbcdee8SKishore Padmanabha while (size-- > 0) { 5612bbcdee8SKishore Padmanabha if (*bitmap != 0) 5622bbcdee8SKishore Padmanabha return 0; 5632bbcdee8SKishore Padmanabha bitmap++; 5642bbcdee8SKishore Padmanabha } 5652bbcdee8SKishore Padmanabha return 1; 5662bbcdee8SKishore Padmanabha } 5672bbcdee8SKishore Padmanabha 5682bbcdee8SKishore Padmanabha /* Function to check if bitmap is ones. Return 1 on success */ 5692bbcdee8SKishore Padmanabha uint32_t ulp_bitmap_is_ones(uint8_t *bitmap, int32_t size) 5702bbcdee8SKishore Padmanabha { 5712bbcdee8SKishore Padmanabha while (size-- > 0) { 5722bbcdee8SKishore Padmanabha if (*bitmap != 0xFF) 5732bbcdee8SKishore Padmanabha return 0; 5742bbcdee8SKishore Padmanabha bitmap++; 5752bbcdee8SKishore Padmanabha } 5762bbcdee8SKishore Padmanabha return 1; 5772bbcdee8SKishore Padmanabha } 5782bbcdee8SKishore Padmanabha 5792bbcdee8SKishore Padmanabha /* Function to check if bitmap is not zero. Return 1 on success */ 5802bbcdee8SKishore Padmanabha uint32_t ulp_bitmap_notzero(uint8_t *bitmap, int32_t size) 5812bbcdee8SKishore Padmanabha { 5822bbcdee8SKishore Padmanabha while (size-- > 0) { 5832bbcdee8SKishore Padmanabha if (*bitmap != 0) 5842bbcdee8SKishore Padmanabha return 1; 5852bbcdee8SKishore Padmanabha bitmap++; 5862bbcdee8SKishore Padmanabha } 5872bbcdee8SKishore Padmanabha return 0; 5882bbcdee8SKishore Padmanabha } 589