fifo.h (5667B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * Generic FIFO allocation and maintenance 8 */ 9 10 #ifndef _SHR_FIFO_H 11 #define _SHR_FIFO_H 12 13 typedef struct shr_fifo_s { 14 uint32 fifo_size; /* Maximum depth of FIFO */ 15 uint32 fifo_write; /* Next entry to which to write */ 16 uint32 fifo_read; /* Current entry from which to read */ 17 uint32 fifo_count; /* Current FIFO depth */ 18 uint32 fifo_entry_words; /* Number of uint32 for each FIFO element */ 19 uint32 fifo_flags; /* Special handling flags to tune behavior */ 20 uint32 *fifo_mem; /* Memory pointer to FIFO queue */ 21 } shr_fifo_t; 22 23 /* If this flag is set, then any pushed entry cannot be the same as the 24 * old entry data in that slot. (To handle HW which doesn't clear the 25 * old FIFO entry */ 26 #define SHR_FIFO_FLAG_DO_NOT_PUSH_DUPLICATE 0x00000001 27 28 #define _SHR_FIFO_ADD_INDICES(_fifo_, _index1_, _index2_) \ 29 (((_index1_) + (_index2_)) % ((_fifo_)->fifo_size)) 30 31 #define _SHR_FIFO_NEXT_INDEX(_fifo_, _index_) \ 32 _SHR_FIFO_ADD_INDICES((_fifo_), _index_, 1) 33 34 #define _SHR_FIFO_WRITE_INC(_fifo_) \ 35 (_fifo_)->fifo_write = \ 36 _SHR_FIFO_NEXT_INDEX((_fifo_), (_fifo_)->fifo_write) 37 38 #define _SHR_FIFO_READ_INC(_fifo_) \ 39 (_fifo_)->fifo_read = \ 40 _SHR_FIFO_NEXT_INDEX((_fifo_), (_fifo_)->fifo_read) 41 42 #define _SHR_FIFO_ENTRY_INDEX_PTR(_fifo_, _index_) \ 43 (&((_fifo_)->fifo_mem[(_index_) * (_fifo_)->fifo_entry_words])) 44 45 #define _SHR_FIFO_ENTRY_BYTES(_fifo_) \ 46 ((_fifo_)->fifo_entry_words * sizeof(uint32)) 47 48 #define SHR_FIFO_ALLOC(_fifo_, _size_, _entry_bytes_, _flags_) \ 49 do { \ 50 (_fifo_)->fifo_entry_words = ((_entry_bytes_) + 3) / 4; \ 51 (_fifo_)->fifo_mem = \ 52 sal_alloc((_fifo_)->fifo_entry_words * 4 * (_size_), \ 53 "FIFO data memory"); \ 54 if ((_fifo_)->fifo_mem != NULL) { \ 55 sal_memset((_fifo_)->fifo_mem, 0, \ 56 (_fifo_)->fifo_entry_words * 4 * (_size_)); \ 57 (_fifo_)->fifo_size = (_size_); \ 58 (_fifo_)->fifo_write = 0; \ 59 (_fifo_)->fifo_read = 0; \ 60 (_fifo_)->fifo_count = 0; \ 61 (_fifo_)->fifo_flags = (_flags_); \ 62 } else { \ 63 (_fifo_)->fifo_size = 0; \ 64 } \ 65 } while (0) 66 67 #define SHR_FIFO_FREE(_fifo_) \ 68 if ((_fifo_)->fifo_mem != NULL) { \ 69 sal_free((_fifo_)->fifo_mem); \ 70 (_fifo_)->fifo_mem = NULL; \ 71 } 72 73 #define SHR_FIFO_PUSH(_fifo_, _entry_ptr_) \ 74 if (((_fifo_)->fifo_count < (_fifo_)->fifo_size) && \ 75 (!((_fifo_)->fifo_flags & SHR_FIFO_FLAG_DO_NOT_PUSH_DUPLICATE) \ 76 || sal_memcmp(_SHR_FIFO_ENTRY_INDEX_PTR((_fifo_), \ 77 (_fifo_)->fifo_write), \ 78 (_entry_ptr_), \ 79 _SHR_FIFO_ENTRY_BYTES(_fifo_)))) { \ 80 sal_memcpy(_SHR_FIFO_ENTRY_INDEX_PTR((_fifo_), \ 81 (_fifo_)->fifo_write), (_entry_ptr_), \ 82 _SHR_FIFO_ENTRY_BYTES(_fifo_)); \ 83 _SHR_FIFO_WRITE_INC(_fifo_); \ 84 (_fifo_)->fifo_count++; \ 85 } 86 87 #define SHR_FIFO_POP(_fifo_, _entry_ptr_) \ 88 if ((_fifo_)->fifo_count) { \ 89 sal_memcpy((_entry_ptr_), \ 90 _SHR_FIFO_ENTRY_INDEX_PTR((_fifo_), \ 91 (_fifo_)->fifo_read), \ 92 _SHR_FIFO_ENTRY_BYTES(_fifo_)); \ 93 _SHR_FIFO_READ_INC(_fifo_); \ 94 (_fifo_)->fifo_count--; \ 95 } else { \ 96 sal_memset((_entry_ptr_), 0, _SHR_FIFO_ENTRY_BYTES(_fifo_)); \ 97 } 98 99 #define SHR_FIFO_IS_FULL(_fifo_) \ 100 ((_fifo_)->fifo_count == (_fifo_)->fifo_size) 101 #define SHR_FIFO_IS_EMPTY(_fifo_) \ 102 ((_fifo_)->fifo_count == 0) 103 #define SHR_FIFO_DEPTH(_fifo_) \ 104 ((_fifo_)->fifo_count) 105 #define SHR_FIFO_SIZE(_fifo_) \ 106 ((_fifo_)->fifo_size) 107 108 #endif /* !_SHR_FIFO_H */