xref: /dpdk/drivers/net/bnxt/tf_ulp/ulp_utils.h (revision 7917b0d38e92e8b9ec5a870415b791420e10f11a)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2014-2023 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 #endif /* _ULP_UTILS_H_ */
526