net/bnxt: add helper functions for blob/regfile ops
1. blob routines for managing key/mask/result data 2. regfile routines for managing temporal data during flow construction Signed-off-by: Mike Baucom <michael.baucom@broadcom.com> Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com> Signed-off-by: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com> Reviewed-by: Lance Richardson <lance.richardson@broadcom.com> Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
This commit is contained in:
parent
70e64b27af
commit
88badb3aef
@ -61,6 +61,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_ulp/bnxt_ulp.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_ulp/ulp_mark_mgr.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_ulp/ulp_flow_db.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_ulp/ulp_template_db.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_ulp/ulp_utils.c
|
||||
|
||||
#
|
||||
# Export include files
|
||||
#
|
||||
|
@ -27,6 +27,18 @@ enum bnxt_ulp_device_id {
|
||||
BNXT_ULP_DEVICE_ID_LAST
|
||||
};
|
||||
|
||||
enum bnxt_ulp_fmf_mask {
|
||||
BNXT_ULP_FMF_MASK_IGNORE,
|
||||
BNXT_ULP_FMF_MASK_ANY,
|
||||
BNXT_ULP_FMF_MASK_EXACT,
|
||||
BNXT_ULP_FMF_MASK_WILDCARD,
|
||||
BNXT_ULP_FMF_MASK_LAST
|
||||
};
|
||||
|
||||
enum bnxt_ulp_regfile_index {
|
||||
BNXT_ULP_REGFILE_INDEX_LAST
|
||||
};
|
||||
|
||||
enum bnxt_ulp_sym {
|
||||
BNXT_ULP_SYM_LITTLE_ENDIAN = 1,
|
||||
BNXT_ULP_SYM_YES = 1
|
||||
|
521
drivers/net/bnxt/tf_ulp/ulp_utils.c
Normal file
521
drivers/net/bnxt/tf_ulp/ulp_utils.c
Normal file
@ -0,0 +1,521 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright(c) 2014-2019 Broadcom
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include "ulp_utils.h"
|
||||
#include "bnxt_tf_common.h"
|
||||
|
||||
/*
|
||||
* Initialize the regfile structure for writing
|
||||
*
|
||||
* regfile [in] Ptr to a regfile instance
|
||||
*
|
||||
* returns 0 on error or 1 on success
|
||||
*/
|
||||
uint32_t
|
||||
ulp_regfile_init(struct ulp_regfile *regfile)
|
||||
{
|
||||
/* validate the arguments */
|
||||
if (!regfile) {
|
||||
BNXT_TF_DBG(ERR, "invalid argument\n");
|
||||
return 0; /* failure */
|
||||
}
|
||||
memset(regfile, 0, sizeof(struct ulp_regfile));
|
||||
return 1; /* Success */
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a value from the regfile
|
||||
*
|
||||
* regfile [in] The regfile instance. Must be initialized prior to being used
|
||||
*
|
||||
* field [in] The field to be read within the regfile.
|
||||
*
|
||||
* data [in/out]
|
||||
*
|
||||
* returns size, zero on failure
|
||||
*/
|
||||
uint32_t
|
||||
ulp_regfile_read(struct ulp_regfile *regfile,
|
||||
enum bnxt_ulp_regfile_index field,
|
||||
uint64_t *data)
|
||||
{
|
||||
/* validate the arguments */
|
||||
if (!regfile || field >= BNXT_ULP_REGFILE_INDEX_LAST) {
|
||||
BNXT_TF_DBG(ERR, "invalid argument\n");
|
||||
return 0; /* failure */
|
||||
}
|
||||
|
||||
*data = regfile->entry[field].data;
|
||||
return sizeof(*data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a value to the regfile
|
||||
*
|
||||
* regfile [in] The regfile instance. Must be initialized prior to being used
|
||||
*
|
||||
* field [in] The field to be written within the regfile.
|
||||
*
|
||||
* data [in] The value is written into this variable. It is going to be in the
|
||||
* same byte order as it was written.
|
||||
*
|
||||
* size [in] The size in bytes of the value beingritten into this
|
||||
* variable.
|
||||
*
|
||||
* returns 0 on fail
|
||||
*/
|
||||
uint32_t
|
||||
ulp_regfile_write(struct ulp_regfile *regfile,
|
||||
enum bnxt_ulp_regfile_index field,
|
||||
uint64_t data)
|
||||
{
|
||||
/* validate the arguments */
|
||||
if (!regfile || field >= BNXT_ULP_REGFILE_INDEX_LAST) {
|
||||
BNXT_TF_DBG(ERR, "invalid argument\n");
|
||||
return 0; /* failure */
|
||||
}
|
||||
|
||||
regfile->entry[field].data = data;
|
||||
return sizeof(data); /* Success */
|
||||
}
|
||||
|
||||
static void
|
||||
ulp_bs_put_msb(uint8_t *bs, uint16_t bitpos, uint8_t bitlen, uint8_t val)
|
||||
{
|
||||
uint8_t bitoffs = bitpos % 8;
|
||||
uint16_t index = bitpos / 8;
|
||||
uint8_t mask;
|
||||
uint8_t tmp;
|
||||
int8_t shift;
|
||||
|
||||
tmp = bs[index];
|
||||
mask = ((uint8_t)-1 >> (8 - bitlen));
|
||||
shift = 8 - bitoffs - bitlen;
|
||||
val &= mask;
|
||||
|
||||
if (shift >= 0) {
|
||||
tmp &= ~(mask << shift);
|
||||
tmp |= val << shift;
|
||||
bs[index] = tmp;
|
||||
} else {
|
||||
tmp &= ~((uint8_t)-1 >> bitoffs);
|
||||
tmp |= val >> -shift;
|
||||
bs[index++] = tmp;
|
||||
|
||||
tmp = bs[index];
|
||||
tmp &= ((uint8_t)-1 >> (bitlen - (8 - bitoffs)));
|
||||
tmp |= val << (8 + shift);
|
||||
bs[index] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ulp_bs_put_lsb(uint8_t *bs, uint16_t bitpos, uint8_t bitlen, uint8_t val)
|
||||
{
|
||||
uint8_t bitoffs = bitpos % 8;
|
||||
uint16_t index = bitpos / 8;
|
||||
uint8_t mask;
|
||||
uint8_t tmp;
|
||||
uint8_t shift;
|
||||
uint8_t partial;
|
||||
|
||||
tmp = bs[index];
|
||||
shift = bitoffs;
|
||||
|
||||
if (bitoffs + bitlen <= 8) {
|
||||
mask = ((1 << bitlen) - 1) << shift;
|
||||
tmp &= ~mask;
|
||||
tmp |= ((val << shift) & mask);
|
||||
bs[index] = tmp;
|
||||
} else {
|
||||
partial = 8 - bitoffs;
|
||||
mask = ((1 << partial) - 1) << shift;
|
||||
tmp &= ~mask;
|
||||
tmp |= ((val << shift) & mask);
|
||||
bs[index++] = tmp;
|
||||
|
||||
val >>= partial;
|
||||
partial = bitlen - partial;
|
||||
mask = ((1 << partial) - 1);
|
||||
tmp = bs[index];
|
||||
tmp &= ~mask;
|
||||
tmp |= (val & mask);
|
||||
bs[index] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Assuming that val is in Big-Endian Format */
|
||||
static uint32_t
|
||||
ulp_bs_push_lsb(uint8_t *bs, uint16_t pos, uint8_t len, uint8_t *val)
|
||||
{
|
||||
int i;
|
||||
int cnt = (len) / 8;
|
||||
int tlen = len;
|
||||
|
||||
if (cnt > 0 && !(len % 8))
|
||||
cnt -= 1;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
ulp_bs_put_lsb(bs, pos, 8, val[cnt - i]);
|
||||
pos += 8;
|
||||
tlen -= 8;
|
||||
}
|
||||
|
||||
/* Handle the remainder bits */
|
||||
if (tlen)
|
||||
ulp_bs_put_lsb(bs, pos, tlen, val[0]);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Assuming that val is in Big-Endian Format */
|
||||
static uint32_t
|
||||
ulp_bs_push_msb(uint8_t *bs, uint16_t pos, uint8_t len, uint8_t *val)
|
||||
{
|
||||
int i;
|
||||
int cnt = (len + 7) / 8;
|
||||
int tlen = len;
|
||||
|
||||
/* Handle any remainder bits */
|
||||
int tmp = len % 8;
|
||||
|
||||
if (!tmp)
|
||||
tmp = 8;
|
||||
|
||||
ulp_bs_put_msb(bs, pos, tmp, val[0]);
|
||||
|
||||
pos += tmp;
|
||||
tlen -= tmp;
|
||||
|
||||
for (i = 1; i < cnt; i++) {
|
||||
ulp_bs_put_msb(bs, pos, 8, val[i]);
|
||||
pos += 8;
|
||||
tlen -= 8;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes the blob structure for creating binary blob
|
||||
*
|
||||
* blob [in] The blob to be initialized
|
||||
*
|
||||
* bitlen [in] The bit length of the blob
|
||||
*
|
||||
* order [in] The byte order for the blob. Currently only supporting
|
||||
* big endian. All fields are packed with this order.
|
||||
*
|
||||
* returns 0 on error or 1 on success
|
||||
*/
|
||||
uint32_t
|
||||
ulp_blob_init(struct ulp_blob *blob,
|
||||
uint16_t bitlen,
|
||||
enum bnxt_ulp_byte_order order)
|
||||
{
|
||||
/* validate the arguments */
|
||||
if (!blob || bitlen > (8 * sizeof(blob->data))) {
|
||||
BNXT_TF_DBG(ERR, "invalid argument\n");
|
||||
return 0; /* failure */
|
||||
}
|
||||
blob->bitlen = bitlen;
|
||||
blob->byte_order = order;
|
||||
blob->write_idx = 0;
|
||||
memset(blob->data, 0, sizeof(blob->data));
|
||||
return 1; /* Success */
|
||||
}
|
||||
|
||||
/*
|
||||
* Add data to the binary blob at the current offset.
|
||||
*
|
||||
* blob [in] The blob that data is added to. The blob must
|
||||
* be initialized prior to pushing data.
|
||||
*
|
||||
* data [in] A pointer to bytes to be added to the blob.
|
||||
*
|
||||
* datalen [in] The number of bits to be added to the blob.
|
||||
*
|
||||
* The offset of the data is updated after each push of data.
|
||||
* NULL returned on error.
|
||||
*/
|
||||
#define ULP_BLOB_BYTE 8
|
||||
#define ULP_BLOB_BYTE_HEX 0xFF
|
||||
#define BLOB_MASK_CAL(x) ((0xFF << (x)) & 0xFF)
|
||||
uint32_t
|
||||
ulp_blob_push(struct ulp_blob *blob,
|
||||
uint8_t *data,
|
||||
uint32_t datalen)
|
||||
{
|
||||
uint32_t rc;
|
||||
|
||||
/* validate the arguments */
|
||||
if (!blob || datalen > (uint32_t)(blob->bitlen - blob->write_idx)) {
|
||||
BNXT_TF_DBG(ERR, "invalid argument\n");
|
||||
return 0; /* failure */
|
||||
}
|
||||
|
||||
if (blob->byte_order == BNXT_ULP_BYTE_ORDER_BE)
|
||||
rc = ulp_bs_push_msb(blob->data,
|
||||
blob->write_idx,
|
||||
datalen,
|
||||
data);
|
||||
else
|
||||
rc = ulp_bs_push_lsb(blob->data,
|
||||
blob->write_idx,
|
||||
datalen,
|
||||
data);
|
||||
if (!rc) {
|
||||
BNXT_TF_DBG(ERR, "Failed ro write blob\n");
|
||||
return 0;
|
||||
}
|
||||
blob->write_idx += datalen;
|
||||
return datalen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add data to the binary blob at the current offset.
|
||||
*
|
||||
* blob [in] The blob that data is added to. The blob must
|
||||
* be initialized prior to pushing data.
|
||||
*
|
||||
* data [in] 64-bit value to be added to the blob.
|
||||
*
|
||||
* datalen [in] The number of bits to be added to the blob.
|
||||
*
|
||||
* The offset of the data is updated after each push of data.
|
||||
* NULL returned on error, pointer pushed value otherwise.
|
||||
*/
|
||||
uint8_t *
|
||||
ulp_blob_push_64(struct ulp_blob *blob,
|
||||
uint64_t *data,
|
||||
uint32_t datalen)
|
||||
{
|
||||
uint8_t *val = (uint8_t *)data;
|
||||
int rc;
|
||||
|
||||
int size = (datalen + 7) / 8;
|
||||
|
||||
if (!blob || !data ||
|
||||
datalen > (uint32_t)(blob->bitlen - blob->write_idx)) {
|
||||
BNXT_TF_DBG(ERR, "invalid argument\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = ulp_blob_push(blob, &val[8 - size], datalen);
|
||||
if (!rc)
|
||||
return 0;
|
||||
|
||||
return &val[8 - size];
|
||||
}
|
||||
|
||||
/*
|
||||
* Add encap data to the binary blob at the current offset.
|
||||
*
|
||||
* blob [in] The blob that data is added to. The blob must
|
||||
* be initialized prior to pushing data.
|
||||
*
|
||||
* data [in] value to be added to the blob.
|
||||
*
|
||||
* datalen [in] The number of bits to be added to the blob.
|
||||
*
|
||||
* The offset of the data is updated after each push of data.
|
||||
* NULL returned on error, pointer pushed value otherwise.
|
||||
*/
|
||||
uint32_t
|
||||
ulp_blob_push_encap(struct ulp_blob *blob,
|
||||
uint8_t *data,
|
||||
uint32_t datalen)
|
||||
{
|
||||
uint8_t *val = (uint8_t *)data;
|
||||
uint32_t initial_size, write_size = datalen;
|
||||
uint32_t size = 0;
|
||||
|
||||
if (!blob || !data ||
|
||||
datalen > (uint32_t)(blob->bitlen - blob->write_idx)) {
|
||||
BNXT_TF_DBG(ERR, "invalid argument\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
initial_size = ULP_BYTE_2_BITS(sizeof(uint64_t)) -
|
||||
(blob->write_idx % ULP_BYTE_2_BITS(sizeof(uint64_t)));
|
||||
while (write_size > 0) {
|
||||
if (initial_size && write_size > initial_size) {
|
||||
size = initial_size;
|
||||
initial_size = 0;
|
||||
} else if (initial_size && write_size <= initial_size) {
|
||||
size = write_size;
|
||||
initial_size = 0;
|
||||
} else if (write_size > ULP_BYTE_2_BITS(sizeof(uint64_t))) {
|
||||
size = ULP_BYTE_2_BITS(sizeof(uint64_t));
|
||||
} else {
|
||||
size = write_size;
|
||||
}
|
||||
if (!ulp_blob_push(blob, val, size)) {
|
||||
BNXT_TF_DBG(ERR, "push field failed\n");
|
||||
return 0;
|
||||
}
|
||||
val += ULP_BITS_2_BYTE(size);
|
||||
write_size -= size;
|
||||
}
|
||||
return datalen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds pad to an initialized blob at the current offset
|
||||
*
|
||||
* blob [in] The blob that data is added to. The blob must
|
||||
* be initialized prior to pushing data.
|
||||
*
|
||||
* datalen [in] The number of bits of pad to add
|
||||
*
|
||||
* returns the number of pad bits added, zero on failure
|
||||
*/
|
||||
uint32_t
|
||||
ulp_blob_pad_push(struct ulp_blob *blob,
|
||||
uint32_t datalen)
|
||||
{
|
||||
if (datalen > (uint32_t)(blob->bitlen - blob->write_idx)) {
|
||||
BNXT_TF_DBG(ERR, "Pad too large for blob\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
blob->write_idx += datalen;
|
||||
return datalen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the data portion of the binary blob.
|
||||
*
|
||||
* blob [in] The blob's data to be retrieved. The blob must be
|
||||
* initialized prior to pushing data.
|
||||
*
|
||||
* datalen [out] The number of bits to that are filled.
|
||||
*
|
||||
* returns a byte array of the blob data. Returns NULL on error.
|
||||
*/
|
||||
uint8_t *
|
||||
ulp_blob_data_get(struct ulp_blob *blob,
|
||||
uint16_t *datalen)
|
||||
{
|
||||
/* validate the arguments */
|
||||
if (!blob) {
|
||||
BNXT_TF_DBG(ERR, "invalid argument\n");
|
||||
return NULL; /* failure */
|
||||
}
|
||||
*datalen = blob->write_idx;
|
||||
return blob->data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the encap swap start index of the binary blob.
|
||||
*
|
||||
* blob [in] The blob's data to be retrieved. The blob must be
|
||||
* initialized prior to pushing data.
|
||||
*
|
||||
* returns void.
|
||||
*/
|
||||
void
|
||||
ulp_blob_encap_swap_idx_set(struct ulp_blob *blob)
|
||||
{
|
||||
/* validate the arguments */
|
||||
if (!blob) {
|
||||
BNXT_TF_DBG(ERR, "invalid argument\n");
|
||||
return; /* failure */
|
||||
}
|
||||
blob->encap_swap_idx = blob->write_idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the encap buffer swap to 64 bit reversal.
|
||||
*
|
||||
* blob [in] The blob's data to be used for swap.
|
||||
*
|
||||
* returns void.
|
||||
*/
|
||||
void
|
||||
ulp_blob_perform_encap_swap(struct ulp_blob *blob)
|
||||
{
|
||||
uint32_t i, idx = 0, end_idx = 0;
|
||||
uint8_t temp_val_1, temp_val_2;
|
||||
|
||||
/* validate the arguments */
|
||||
if (!blob) {
|
||||
BNXT_TF_DBG(ERR, "invalid argument\n");
|
||||
return; /* failure */
|
||||
}
|
||||
idx = ULP_BITS_2_BYTE_NR(blob->encap_swap_idx + 1);
|
||||
end_idx = ULP_BITS_2_BYTE(blob->write_idx);
|
||||
|
||||
while (idx <= end_idx) {
|
||||
for (i = 0; i < 4; i = i + 2) {
|
||||
temp_val_1 = blob->data[idx + i];
|
||||
temp_val_2 = blob->data[idx + i + 1];
|
||||
blob->data[idx + i] = blob->data[idx + 6 - i];
|
||||
blob->data[idx + i + 1] = blob->data[idx + 7 - i];
|
||||
blob->data[idx + 7 - i] = temp_val_2;
|
||||
blob->data[idx + 6 - i] = temp_val_1;
|
||||
}
|
||||
idx += 8;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read data from the operand
|
||||
*
|
||||
* operand [in] A pointer to a 16 Byte operand
|
||||
*
|
||||
* val [in/out] The variable to copy the operand to
|
||||
*
|
||||
* bytes [in] The number of bytes to read into val
|
||||
*
|
||||
* returns number of bits read, zero on error
|
||||
*/
|
||||
uint16_t
|
||||
ulp_operand_read(uint8_t *operand,
|
||||
uint8_t *val,
|
||||
uint16_t bytes)
|
||||
{
|
||||
/* validate the arguments */
|
||||
if (!operand || !val) {
|
||||
BNXT_TF_DBG(ERR, "invalid argument\n");
|
||||
return 0; /* failure */
|
||||
}
|
||||
memcpy(val, operand, bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy the buffer in the encap format which is 2 bytes.
|
||||
* The MSB of the src is placed at the LSB of dst.
|
||||
*
|
||||
* dst [out] The destination buffer
|
||||
* src [in] The source buffer dst
|
||||
* size[in] size of the buffer.
|
||||
*/
|
||||
void
|
||||
ulp_encap_buffer_copy(uint8_t *dst,
|
||||
const uint8_t *src,
|
||||
uint16_t size)
|
||||
{
|
||||
uint16_t idx = 0;
|
||||
|
||||
/* copy 2 bytes at a time. Write MSB to LSB */
|
||||
while ((idx + sizeof(uint16_t)) <= size) {
|
||||
memcpy(&dst[idx], &src[size - idx - sizeof(uint16_t)],
|
||||
sizeof(uint16_t));
|
||||
idx += sizeof(uint16_t);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the buffer is empty
|
||||
*
|
||||
* buf [in] The buffer
|
||||
* size [in] The size of the buffer
|
||||
*
|
||||
*/
|
||||
int32_t ulp_buffer_is_empty(const uint8_t *buf, uint32_t size)
|
||||
{
|
||||
return buf[0] == 0 && !memcmp(buf, buf + 1, size - 1);
|
||||
}
|
279
drivers/net/bnxt/tf_ulp/ulp_utils.h
Normal file
279
drivers/net/bnxt/tf_ulp/ulp_utils.h
Normal file
@ -0,0 +1,279 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright(c) 2014-2019 Broadcom
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _ULP_UTILS_H_
|
||||
#define _ULP_UTILS_H_
|
||||
|
||||
#include "bnxt.h"
|
||||
#include "ulp_template_db.h"
|
||||
|
||||
/*
|
||||
* Macros for bitmap sets and gets
|
||||
* These macros can be used if the val are power of 2.
|
||||
*/
|
||||
#define ULP_BITMAP_SET(bitmap, val) ((bitmap) |= (val))
|
||||
#define ULP_BITMAP_RESET(bitmap, val) ((bitmap) &= ~(val))
|
||||
#define ULP_BITMAP_ISSET(bitmap, val) ((bitmap) & (val))
|
||||
#define ULP_BITSET_CMP(b1, b2) memcmp(&(b1)->bits, \
|
||||
&(b2)->bits, sizeof((b1)->bits))
|
||||
/*
|
||||
* Macros for bitmap sets and gets
|
||||
* These macros can be used if the val are not power of 2 and
|
||||
* are simple index values.
|
||||
*/
|
||||
#define ULP_INDEX_BITMAP_SIZE (sizeof(uint64_t) * 8)
|
||||
#define ULP_INDEX_BITMAP_CSET(i) (1UL << \
|
||||
((ULP_INDEX_BITMAP_SIZE - 1) - \
|
||||
((i) % ULP_INDEX_BITMAP_SIZE)))
|
||||
|
||||
#define ULP_INDEX_BITMAP_SET(b, i) ((b) |= \
|
||||
(1UL << ((ULP_INDEX_BITMAP_SIZE - 1) - \
|
||||
((i) % ULP_INDEX_BITMAP_SIZE))))
|
||||
|
||||
#define ULP_INDEX_BITMAP_RESET(b, i) ((b) &= \
|
||||
(~(1UL << ((ULP_INDEX_BITMAP_SIZE - 1) - \
|
||||
((i) % ULP_INDEX_BITMAP_SIZE)))))
|
||||
|
||||
#define ULP_INDEX_BITMAP_GET(b, i) (((b) >> \
|
||||
((ULP_INDEX_BITMAP_SIZE - 1) - \
|
||||
((i) % ULP_INDEX_BITMAP_SIZE))) & 1)
|
||||
|
||||
#define ULP_DEVICE_PARAMS_INDEX(tid, dev_id) \
|
||||
(((tid) << BNXT_ULP_LOG2_MAX_NUM_DEV) | (dev_id))
|
||||
|
||||
/* Macro to convert bytes to bits */
|
||||
#define ULP_BYTE_2_BITS(byte_x) ((byte_x) * 8)
|
||||
/* Macro to convert bits to bytes */
|
||||
#define ULP_BITS_2_BYTE(bits_x) (((bits_x) + 7) / 8)
|
||||
/* Macro to convert bits to bytes with no round off*/
|
||||
#define ULP_BITS_2_BYTE_NR(bits_x) ((bits_x) / 8)
|
||||
|
||||
/*
|
||||
* Making the blob statically sized to 128 bytes for now.
|
||||
* The blob must be initialized with ulp_blob_init prior to using.
|
||||
*/
|
||||
#define BNXT_ULP_FLMP_BLOB_SIZE (128)
|
||||
#define BNXT_ULP_FLMP_BLOB_SIZE_IN_BITS ULP_BYTE_2_BITS(BNXT_ULP_FLMP_BLOB_SIZE)
|
||||
struct ulp_blob {
|
||||
enum bnxt_ulp_byte_order byte_order;
|
||||
uint16_t write_idx;
|
||||
uint16_t bitlen;
|
||||
uint8_t data[BNXT_ULP_FLMP_BLOB_SIZE];
|
||||
uint16_t encap_swap_idx;
|
||||
};
|
||||
|
||||
/*
|
||||
* The data can likely be only 32 bits for now. Just size check
|
||||
* the data when being written.
|
||||
*/
|
||||
#define ULP_REGFILE_ENTRY_SIZE (sizeof(uint32_t))
|
||||
struct ulp_regfile_entry {
|
||||
uint64_t data;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
struct ulp_regfile {
|
||||
struct ulp_regfile_entry entry[BNXT_ULP_REGFILE_INDEX_LAST];
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize the regfile structure for writing
|
||||
*
|
||||
* regfile [in] Ptr to a regfile instance
|
||||
*
|
||||
* returns 0 on error or 1 on success
|
||||
*/
|
||||
uint32_t
|
||||
ulp_regfile_init(struct ulp_regfile *regfile);
|
||||
|
||||
/*
|
||||
* Read a value from the regfile
|
||||
*
|
||||
* regfile [in] The regfile instance. Must be initialized prior to being used
|
||||
*
|
||||
* field [in] The field to be read within the regfile.
|
||||
*
|
||||
* returns the byte array
|
||||
*/
|
||||
uint32_t
|
||||
ulp_regfile_read(struct ulp_regfile *regfile,
|
||||
enum bnxt_ulp_regfile_index field,
|
||||
uint64_t *data);
|
||||
|
||||
/*
|
||||
* Write a value to the regfile
|
||||
*
|
||||
* regfile [in] The regfile instance. Must be initialized prior to being used
|
||||
*
|
||||
* field [in] The field to be written within the regfile.
|
||||
*
|
||||
* data [in] The value is written into this variable. It is going to be in the
|
||||
* same byte order as it was written.
|
||||
*
|
||||
* returns zero on error
|
||||
*/
|
||||
uint32_t
|
||||
ulp_regfile_write(struct ulp_regfile *regfile,
|
||||
enum bnxt_ulp_regfile_index field,
|
||||
uint64_t data);
|
||||
|
||||
/*
|
||||
* Initializes the blob structure for creating binary blob
|
||||
*
|
||||
* blob [in] The blob to be initialized
|
||||
*
|
||||
* bitlen [in] The bit length of the blob
|
||||
*
|
||||
* order [in] The byte order for the blob. Currently only supporting
|
||||
* big endian. All fields are packed with this order.
|
||||
*
|
||||
* returns 0 on error or 1 on success
|
||||
*/
|
||||
uint32_t
|
||||
ulp_blob_init(struct ulp_blob *blob,
|
||||
uint16_t bitlen,
|
||||
enum bnxt_ulp_byte_order order);
|
||||
|
||||
/*
|
||||
* Add data to the binary blob at the current offset.
|
||||
*
|
||||
* blob [in] The blob that data is added to. The blob must
|
||||
* be initialized prior to pushing data.
|
||||
*
|
||||
* data [in] A pointer to bytes to be added to the blob.
|
||||
*
|
||||
* datalen [in] The number of bits to be added to the blob.
|
||||
*
|
||||
* The offset of the data is updated after each push of data.
|
||||
* NULL returned on error.
|
||||
*/
|
||||
uint32_t
|
||||
ulp_blob_push(struct ulp_blob *blob,
|
||||
uint8_t *data,
|
||||
uint32_t datalen);
|
||||
|
||||
/*
|
||||
* Add data to the binary blob at the current offset.
|
||||
*
|
||||
* blob [in] The blob that data is added to. The blob must
|
||||
* be initialized prior to pushing data.
|
||||
*
|
||||
* data [in] 64-bit value to be added to the blob.
|
||||
*
|
||||
* datalen [in] The number of bits to be added to the blob.
|
||||
*
|
||||
* The offset of the data is updated after each push of data.
|
||||
* NULL returned on error, ptr to pushed data otherwise
|
||||
*/
|
||||
uint8_t *
|
||||
ulp_blob_push_64(struct ulp_blob *blob,
|
||||
uint64_t *data,
|
||||
uint32_t datalen);
|
||||
|
||||
/*
|
||||
* Add encap data to the binary blob at the current offset.
|
||||
*
|
||||
* blob [in] The blob that data is added to. The blob must
|
||||
* be initialized prior to pushing data.
|
||||
*
|
||||
* data [in] value to be added to the blob.
|
||||
*
|
||||
* datalen [in] The number of bits to be added to the blob.
|
||||
*
|
||||
* The offset of the data is updated after each push of data.
|
||||
* NULL returned on error, pointer pushed value otherwise.
|
||||
*/
|
||||
uint32_t
|
||||
ulp_blob_push_encap(struct ulp_blob *blob,
|
||||
uint8_t *data,
|
||||
uint32_t datalen);
|
||||
|
||||
/*
|
||||
* Get the data portion of the binary blob.
|
||||
*
|
||||
* blob [in] The blob's data to be retrieved. The blob must be
|
||||
* initialized prior to pushing data.
|
||||
*
|
||||
* datalen [out] The number of bits to that are filled.
|
||||
*
|
||||
* returns a byte array of the blob data. Returns NULL on error.
|
||||
*/
|
||||
uint8_t *
|
||||
ulp_blob_data_get(struct ulp_blob *blob,
|
||||
uint16_t *datalen);
|
||||
|
||||
/*
|
||||
* Adds pad to an initialized blob at the current offset
|
||||
*
|
||||
* blob [in] The blob that data is added to. The blob must
|
||||
* be initialized prior to pushing data.
|
||||
*
|
||||
* datalen [in] The number of bits of pad to add
|
||||
*
|
||||
* returns the number of pad bits added, zero on failure
|
||||
*/
|
||||
uint32_t
|
||||
ulp_blob_pad_push(struct ulp_blob *blob,
|
||||
uint32_t datalen);
|
||||
|
||||
/*
|
||||
* Set the 64 bit swap start index of the binary blob.
|
||||
*
|
||||
* blob [in] The blob's data to be retrieved. The blob must be
|
||||
* initialized prior to pushing data.
|
||||
*
|
||||
* returns void.
|
||||
*/
|
||||
void
|
||||
ulp_blob_encap_swap_idx_set(struct ulp_blob *blob);
|
||||
|
||||
/*
|
||||
* Perform the encap buffer swap to 64 bit reversal.
|
||||
*
|
||||
* blob [in] The blob's data to be used for swap.
|
||||
*
|
||||
* returns void.
|
||||
*/
|
||||
void
|
||||
ulp_blob_perform_encap_swap(struct ulp_blob *blob);
|
||||
|
||||
/*
|
||||
* Read data from the operand
|
||||
*
|
||||
* operand [in] A pointer to a 16 Byte operand
|
||||
*
|
||||
* val [in/out] The variable to copy the operand to
|
||||
*
|
||||
* bitlen [in] The number of bits to read into val
|
||||
*
|
||||
* returns number of bits read, zero on error
|
||||
*/
|
||||
uint16_t
|
||||
ulp_operand_read(uint8_t *operand,
|
||||
uint8_t *val,
|
||||
uint16_t bitlen);
|
||||
|
||||
/*
|
||||
* copy the buffer in the encap format which is 2 bytes.
|
||||
* The MSB of the src is placed at the LSB of dst.
|
||||
*
|
||||
* dst [out] The destination buffer
|
||||
* src [in] The source buffer dst
|
||||
* size[in] size of the buffer.
|
||||
*/
|
||||
void
|
||||
ulp_encap_buffer_copy(uint8_t *dst,
|
||||
const uint8_t *src,
|
||||
uint16_t size);
|
||||
|
||||
/*
|
||||
* Check the buffer is empty
|
||||
*
|
||||
* buf [in] The buffer
|
||||
* size [in] The size of the buffer
|
||||
*/
|
||||
int32_t ulp_buffer_is_empty(const uint8_t *buf, uint32_t size);
|
||||
|
||||
#endif /* _ULP_UTILS_H_ */
|
Loading…
Reference in New Issue
Block a user