1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2014-2021 Broadcom 3 * All rights reserved. 4 */ 5 6 #ifndef _ULP_UTILS_H_ 7 #define _ULP_UTILS_H_ 8 9 #include "bnxt.h" 10 #include "ulp_template_db_enum.h" 11 12 #define ULP_BUFFER_ALIGN_8_BITS 8 13 #define ULP_BUFFER_ALIGN_8_BYTE 8 14 #define ULP_BUFFER_ALIGN_16_BYTE 16 15 #define ULP_BUFFER_ALIGN_64_BYTE 64 16 #define ULP_64B_IN_BYTES 8 17 18 /* 19 * Macros for bitmap sets and gets 20 * These macros can be used if the val are power of 2. 21 */ 22 #define ULP_BITMAP_SET(bitmap, val) ((bitmap) |= (val)) 23 #define ULP_BITMAP_RESET(bitmap, val) ((bitmap) &= ~(val)) 24 #define ULP_BITMAP_ISSET(bitmap, val) ((bitmap) & (val)) 25 #define ULP_BITMAP_CMP(b1, b2) memcmp(&(b1)->bits, \ 26 &(b2)->bits, sizeof((b1)->bits)) 27 /* 28 * Macros for bitmap sets and gets 29 * These macros can be used if the val are not power of 2 and 30 * are simple index values. 31 */ 32 #define ULP_INDEX_BITMAP_SIZE (sizeof(uint64_t) * 8) 33 #define ULP_INDEX_BITMAP_CSET(i) (1UL << \ 34 ((ULP_INDEX_BITMAP_SIZE - 1) - \ 35 ((i) % ULP_INDEX_BITMAP_SIZE))) 36 37 #define ULP_INDEX_BITMAP_SET(b, i) ((b) |= \ 38 (1UL << ((ULP_INDEX_BITMAP_SIZE - 1) - \ 39 ((i) % ULP_INDEX_BITMAP_SIZE)))) 40 41 #define ULP_INDEX_BITMAP_RESET(b, i) ((b) &= \ 42 (~(1UL << ((ULP_INDEX_BITMAP_SIZE - 1) - \ 43 ((i) % ULP_INDEX_BITMAP_SIZE))))) 44 45 #define ULP_INDEX_BITMAP_GET(b, i) (((b) >> \ 46 ((ULP_INDEX_BITMAP_SIZE - 1) - \ 47 ((i) % ULP_INDEX_BITMAP_SIZE))) & 1) 48 49 #define ULP_DEVICE_PARAMS_INDEX(tid, dev_id) \ 50 (((tid) << BNXT_ULP_LOG2_MAX_NUM_DEV) | (dev_id)) 51 52 /* Macro to convert bytes to bits */ 53 #define ULP_BYTE_2_BITS(byte_x) ((byte_x) * 8) 54 /* Macro to convert bits to bytes */ 55 #define ULP_BITS_2_BYTE(bits_x) (((bits_x) + 7) / 8) 56 /* Macro to convert bits to bytes with no round off*/ 57 #define ULP_BITS_2_BYTE_NR(bits_x) ((bits_x) / 8) 58 59 /* Macro to round off to next multiple of 8*/ 60 #define ULP_BYTE_ROUND_OFF_8(x) (((x) + 7) & ~7) 61 62 /* Macro to check bits are byte aligned */ 63 #define ULP_BITS_IS_BYTE_NOT_ALIGNED(x) ((x) % 8) 64 65 /* Macros to read the computed fields */ 66 #define ULP_COMP_FLD_IDX_RD(params, idx) \ 67 rte_be_to_cpu_64((params)->comp_fld[(idx)]) 68 69 #define ULP_COMP_FLD_IDX_WR(params, idx, val) \ 70 ((params)->comp_fld[(idx)] = rte_cpu_to_be_64((uint64_t)(val))) 71 /* 72 * Making the blob statically sized to 128 bytes for now. 73 * The blob must be initialized with ulp_blob_init prior to using. 74 */ 75 #define BNXT_ULP_FLMP_BLOB_SIZE (128) 76 #define BNXT_ULP_FLMP_BLOB_SIZE_IN_BITS ULP_BYTE_2_BITS(BNXT_ULP_FLMP_BLOB_SIZE) 77 struct ulp_blob { 78 enum bnxt_ulp_byte_order byte_order; 79 uint16_t write_idx; 80 uint16_t bitlen; 81 uint8_t data[BNXT_ULP_FLMP_BLOB_SIZE]; 82 uint16_t encap_swap_idx; 83 }; 84 85 /* 86 * The data can likely be only 32 bits for now. Just size check 87 * the data when being written. 88 */ 89 #define ULP_REGFILE_ENTRY_SIZE (sizeof(uint32_t)) 90 struct ulp_regfile_entry { 91 uint64_t data; 92 uint32_t size; 93 }; 94 95 struct ulp_regfile { 96 struct ulp_regfile_entry entry[BNXT_ULP_RF_IDX_LAST]; 97 }; 98 99 /* 100 * Initialize the regfile structure for writing 101 * 102 * regfile [in] Ptr to a regfile instance 103 * 104 * returns 0 on error or 1 on success 105 */ 106 uint32_t 107 ulp_regfile_init(struct ulp_regfile *regfile); 108 109 /* 110 * Read a value from the regfile 111 * 112 * regfile [in] The regfile instance. Must be initialized prior to being used 113 * 114 * field [in] The field to be read within the regfile. 115 * 116 * returns the byte array 117 */ 118 uint32_t 119 ulp_regfile_read(struct ulp_regfile *regfile, 120 enum bnxt_ulp_rf_idx field, 121 uint64_t *data); 122 123 /* 124 * Write a value to the regfile 125 * 126 * regfile [in] The regfile instance. Must be initialized prior to being used 127 * 128 * field [in] The field to be written within the regfile. 129 * 130 * data [in] The value is written into this variable. It is going to be in the 131 * same byte order as it was written. 132 * 133 * returns zero on success 134 */ 135 int32_t 136 ulp_regfile_write(struct ulp_regfile *regfile, 137 enum bnxt_ulp_rf_idx field, 138 uint64_t data); 139 140 /* 141 * Add data to the byte array in Little endian format. 142 * 143 * bs [in] The byte array where data is pushed 144 * 145 * pos [in] The offset where data is pushed 146 * 147 * len [in] The number of bits to be added to the data array. 148 * 149 * val [in] The data to be added to the data array. 150 * 151 * returns the number of bits pushed. 152 */ 153 uint32_t 154 ulp_bs_push_lsb(uint8_t *bs, uint16_t pos, uint8_t len, uint8_t *val); 155 156 /* 157 * Add data to the byte array in Big endian format. 158 * 159 * bs [in] The byte array where data is pushed 160 * 161 * pos [in] The offset where data is pushed 162 * 163 * len [in] The number of bits to be added to the data array. 164 * 165 * val [in] The data to be added to the data array. 166 * 167 * returns the number of bits pushed. 168 */ 169 uint32_t 170 ulp_bs_push_msb(uint8_t *bs, uint16_t pos, uint8_t len, uint8_t *val); 171 172 /* 173 * Initializes the blob structure for creating binary blob 174 * 175 * blob [in] The blob to be initialized 176 * 177 * bitlen [in] The bit length of the blob 178 * 179 * order [in] The byte order for the blob. Currently only supporting 180 * big endian. All fields are packed with this order. 181 * 182 * returns 0 on error or 1 on success 183 */ 184 uint32_t 185 ulp_blob_init(struct ulp_blob *blob, 186 uint16_t bitlen, 187 enum bnxt_ulp_byte_order order); 188 189 /* 190 * Add data to the binary blob at the current offset. 191 * 192 * blob [in] The blob that data is added to. The blob must 193 * be initialized prior to pushing data. 194 * 195 * data [in] A pointer to bytes to be added to the blob. 196 * 197 * datalen [in] The number of bits to be added to the blob. 198 * 199 * The offset of the data is updated after each push of data. 200 * NULL returned on error. 201 */ 202 uint32_t 203 ulp_blob_push(struct ulp_blob *blob, 204 uint8_t *data, 205 uint32_t datalen); 206 207 /* 208 * Insert data into the binary blob at the given offset. 209 * 210 * blob [in] The blob that data is added to. The blob must 211 * be initialized prior to pushing data. 212 * 213 * offset [in] The offset where the data needs to be inserted. 214 * 215 * data [in/out] A pointer to bytes to be added to the blob. 216 * 217 * datalen [in] The number of bits to be added to the blob. 218 * 219 * The offset of the data is updated after each push of data. 220 * NULL returned on error. 221 */ 222 uint32_t 223 ulp_blob_insert(struct ulp_blob *blob, uint32_t offset, 224 uint8_t *data, uint32_t datalen); 225 226 /* 227 * Add data to the binary blob at the current offset. 228 * 229 * blob [in] The blob that data is added to. The blob must 230 * be initialized prior to pushing data. 231 * 232 * data [in] 64-bit value to be added to the blob. 233 * 234 * datalen [in] The number of bits to be added to the blob. 235 * 236 * The offset of the data is updated after each push of data. 237 * NULL returned on error, ptr to pushed data otherwise 238 */ 239 uint8_t * 240 ulp_blob_push_64(struct ulp_blob *blob, 241 uint64_t *data, 242 uint32_t datalen); 243 244 /* 245 * Add data to the binary blob at the current offset. 246 * 247 * blob [in] The blob that data is added to. The blob must 248 * be initialized prior to pushing data. 249 * 250 * data [in] 32-bit value to be added to the blob. 251 * 252 * datalen [in] The number of bits to be added ot the blob. 253 * 254 * The offset of the data is updated after each push of data. 255 * NULL returned on error, pointer pushed value otherwise. 256 */ 257 uint8_t * 258 ulp_blob_push_32(struct ulp_blob *blob, 259 uint32_t *data, 260 uint32_t datalen); 261 262 /* 263 * Add encap data to the binary blob at the current offset. 264 * 265 * blob [in] The blob that data is added to. The blob must 266 * be initialized prior to pushing data. 267 * 268 * data [in] value to be added to the blob. 269 * 270 * datalen [in] The number of bits to be added to the blob. 271 * 272 * The offset of the data is updated after each push of data. 273 * NULL returned on error, pointer pushed value otherwise. 274 */ 275 int32_t 276 ulp_blob_push_encap(struct ulp_blob *blob, 277 uint8_t *data, 278 uint32_t datalen); 279 280 /* 281 * Get the data portion of the binary blob. 282 * 283 * blob [in] The blob's data to be retrieved. The blob must be 284 * initialized prior to pushing data. 285 * 286 * datalen [out] The number of bits to that are filled. 287 * 288 * returns a byte array of the blob data. Returns NULL on error. 289 */ 290 uint8_t * 291 ulp_blob_data_get(struct ulp_blob *blob, 292 uint16_t *datalen); 293 294 /* 295 * Get the data length of the binary blob. 296 * 297 * blob [in] The blob's data len to be retrieved. 298 * 299 * returns length of the binary blob 300 */ 301 uint16_t 302 ulp_blob_data_len_get(struct ulp_blob *blob); 303 304 /* 305 * Get data from the byte array in Little endian format. 306 * 307 * src [in] The byte array where data is extracted from 308 * 309 * dst [out] The byte array where data is pulled into 310 * 311 * size [in] The size of dst array in bytes 312 * 313 * offset [in] The offset where data is pulled 314 * 315 * len [in] The number of bits to be extracted from the data array 316 * 317 * returns None. 318 */ 319 void 320 ulp_bs_pull_lsb(uint8_t *src, uint8_t *dst, uint32_t size, 321 uint32_t offset, uint32_t len); 322 323 /* 324 * Get data from the byte array in Big endian format. 325 * 326 * src [in] The byte array where data is extracted from 327 * 328 * dst [out] The byte array where data is pulled into 329 * 330 * offset [in] The offset where data is pulled 331 * 332 * len [in] The number of bits to be extracted from the data array 333 * 334 * returns None. 335 */ 336 void 337 ulp_bs_pull_msb(uint8_t *src, uint8_t *dst, 338 uint32_t offset, uint32_t len); 339 340 /* 341 * Extract data from the binary blob using given offset. 342 * 343 * blob [in] The blob that data is extracted from. The blob must 344 * be initialized prior to pulling data. 345 * 346 * data [in] A pointer to put the data. 347 * data_size [in] size of the data buffer in bytes. 348 *offset [in] - Offset in the blob to extract the data in bits format. 349 * len [in] The number of bits to be pulled from the blob. 350 * 351 * Output: zero on success, -1 on failure 352 */ 353 int32_t 354 ulp_blob_pull(struct ulp_blob *blob, uint8_t *data, uint32_t data_size, 355 uint16_t offset, uint16_t len); 356 357 /* 358 * Adds pad to an initialized blob at the current offset 359 * 360 * blob [in] The blob that data is added to. The blob must 361 * be initialized prior to pushing data. 362 * 363 * datalen [in] The number of bits of pad to add 364 * 365 * returns the number of pad bits added, -1 on failure 366 */ 367 int32_t 368 ulp_blob_pad_push(struct ulp_blob *blob, 369 uint32_t datalen); 370 371 /* 372 * Adds pad to an initialized blob at the current offset based on 373 * the alignment. 374 * 375 * blob [in] The blob that needs to be aligned 376 * 377 * align [in] Alignment in bits. 378 * 379 * returns the number of pad bits added, -1 on failure 380 */ 381 int32_t 382 ulp_blob_pad_align(struct ulp_blob *blob, 383 uint32_t align); 384 385 /* 386 * Set the 64 bit swap start index of the binary blob. 387 * 388 * blob [in] The blob's data to be retrieved. The blob must be 389 * initialized prior to pushing data. 390 * 391 * returns void. 392 */ 393 void 394 ulp_blob_encap_swap_idx_set(struct ulp_blob *blob); 395 396 /* 397 * Perform the encap buffer swap to 64 bit reversal. 398 * 399 * blob [in] The blob's data to be used for swap. 400 * 401 * returns void. 402 */ 403 void 404 ulp_blob_perform_encap_swap(struct ulp_blob *blob); 405 406 /* 407 * Perform the blob buffer reversal byte wise. 408 * This api makes the first byte the last and 409 * vice-versa. 410 * 411 * blob [in] The blob's data to be used for swap. 412 * chunk_size[in] the swap is done within the chunk in bytes 413 * 414 * returns void. 415 */ 416 void 417 ulp_blob_perform_byte_reverse(struct ulp_blob *blob, 418 uint32_t chunk_size); 419 420 /* 421 * Perform the blob buffer 64 bit word swap. 422 * This api makes the first 4 bytes the last in 423 * a given 64 bit value and vice-versa. 424 * 425 * blob [in] The blob's data to be used for swap. 426 * 427 * returns void. 428 */ 429 void 430 ulp_blob_perform_64B_word_swap(struct ulp_blob *blob); 431 432 /* 433 * Perform the blob buffer 64 bit byte swap. 434 * This api makes the first byte the last in 435 * a given 64 bit value and vice-versa. 436 * 437 * blob [in] The blob's data to be used for swap. 438 * 439 * returns void. 440 */ 441 void 442 ulp_blob_perform_64B_byte_swap(struct ulp_blob *blob); 443 444 /* 445 * Perform the blob buffer merge. 446 * This api makes the src blob merged to the dst blob. 447 * The block size and pad size help in padding the dst blob 448 * 449 * dst [in] The destination blob, the blob to be merged. 450 * src [in] The src blob. 451 * block_size [in] The size of the block after which padding gets applied. 452 * pad [in] The size of the pad to be applied. 453 * 454 * returns 0 on success. 455 */ 456 int32_t 457 ulp_blob_block_merge(struct ulp_blob *dst, struct ulp_blob *src, 458 uint32_t block_size, uint32_t pad); 459 460 /* 461 * Append bits from src blob to dst blob. 462 * Only works on BE blobs 463 * 464 * dst [in/out] The destination blob to append to 465 * 466 * src [in] The src blob to append from 467 * 468 * src_offset [in] The bit offset from src to start at 469 * 470 * src_len [in] The number of bits to append to dst 471 * 472 * returns 0 on success, non-zero on error 473 */ 474 int32_t 475 ulp_blob_append(struct ulp_blob *dst, struct ulp_blob *src, 476 uint16_t src_offset, uint16_t src_len); 477 478 /* 479 * Perform the blob buffer copy. 480 * This api makes the src blob merged to the dst blob. 481 * 482 * dst [in] The destination blob, the blob to be merged. 483 * src [in] The src blob. 484 * 485 * returns 0 on success. 486 */ 487 int32_t 488 ulp_blob_buffer_copy(struct ulp_blob *dst, struct ulp_blob *src); 489 490 /* 491 * Read data from the operand 492 * 493 * operand [in] A pointer to a 16 Byte operand 494 * 495 * val [in/out] The variable to copy the operand to 496 * 497 * bitlen [in] The number of bits to read into val 498 * 499 * returns number of bits read, zero on error 500 */ 501 uint16_t 502 ulp_operand_read(uint8_t *operand, 503 uint8_t *val, 504 uint16_t bitlen); 505 506 /* 507 * Check the buffer is empty 508 * 509 * buf [in] The buffer 510 * size [in] The size of the buffer 511 */ 512 int32_t ulp_buffer_is_empty(const uint8_t *buf, uint32_t size); 513 514 /* Function to check if bitmap is zero.Return 1 on success */ 515 uint32_t ulp_bitmap_is_zero(uint8_t *bitmap, int32_t size); 516 517 /* Function to check if bitmap is ones. Return 1 on success */ 518 uint32_t ulp_bitmap_is_ones(uint8_t *bitmap, int32_t size); 519 520 /* Function to check if bitmap is not zero. Return 1 on success */ 521 uint32_t ulp_bitmap_notzero(const uint8_t *bitmap, int32_t size); 522 523 /* returns 0 if input is power of 2 */ 524 int32_t ulp_util_is_power_of_2(uint64_t x); 525 526 #endif /* _ULP_UTILS_H_ */ 527