Shad Ansari | 2f7f9be | 2017-06-07 13:34:53 -0700 | [diff] [blame] | 1 | /* |
| 2 | <:copyright-BRCM:2016:DUAL/GPL:standard |
| 3 | |
| 4 | Broadcom Proprietary and Confidential.(c) 2016 Broadcom |
| 5 | All Rights Reserved |
| 6 | |
| 7 | Unless you and Broadcom execute a separate written software license |
| 8 | agreement governing use of this software, this software is licensed |
| 9 | to you under the terms of the GNU General Public License version 2 |
| 10 | (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, |
| 11 | with the following added to such license: |
| 12 | |
| 13 | As a special exception, the copyright holders of this software give |
| 14 | you permission to link this software with independent modules, and |
| 15 | to copy and distribute the resulting executable under terms of your |
| 16 | choice, provided that you also meet, for each linked independent |
| 17 | module, the terms and conditions of the license of that module. |
| 18 | An independent module is a module which is not derived from this |
| 19 | software. The special exception does not apply to any modifications |
| 20 | of the software. |
| 21 | |
| 22 | Not withstanding the above, under no circumstances may you combine |
| 23 | this software in any way with any other Broadcom software provided |
| 24 | under a license other than the GPL, without Broadcom's express prior |
| 25 | written consent. |
| 26 | |
| 27 | :> |
| 28 | */ |
| 29 | |
| 30 | /** |
| 31 | * bcmolt_bit_utils.h |
| 32 | * Created on: 03/10/2014 |
| 33 | * Author: cpark1 |
| 34 | * |
| 35 | * This bit vector implementation is used for the EPON encryption. |
| 36 | * There is a certain hardware restriction that the global encryption mode |
| 37 | * can not be changed when a link encryption is configured for a different |
| 38 | * encryption mode. |
| 39 | * Likewise, the link encryption mode can not be changed if the global |
| 40 | * encryption mode is set to other mode. |
| 41 | * Therefore, when the host tries to change any of them, the OLT needs to |
| 42 | * check either the global encryption mode or the link encryption mode |
| 43 | * before applying the change. |
| 44 | * In the old implementation (like Pioneer), the firmware iterates through |
| 45 | * every link records of each PON port and check the encryption mode of each. |
| 46 | * This is very inefficient and time consuming. |
| 47 | * The host may want to know how many links are enabled for the encryption, |
| 48 | * or which link is enabled, etc. |
| 49 | * I thought that a bit vector implementation is best satisfies. |
| 50 | * Also, this implementation exactly reflects the IC implementation, so we |
| 51 | * can use it to mirror the hardware status. |
| 52 | * |
| 53 | */ |
| 54 | |
| 55 | #ifndef BCMOLT_BIT_UTILS_H |
| 56 | #define BCMOLT_BIT_UTILS_H |
| 57 | |
| 58 | |
| 59 | #include "bcmos_system.h" |
| 60 | |
| 61 | |
| 62 | /* the current (draft) design of the ASIC uses 32-bit bitmap data port */ |
| 63 | typedef uint32_t bv_bits; |
| 64 | |
| 65 | typedef struct |
| 66 | { |
| 67 | uint32_t nbits; |
| 68 | bv_bits *vector; |
| 69 | } bit_vector; |
| 70 | |
| 71 | |
| 72 | #define BITS_SZ (sizeof(bv_bits) * CHAR_BIT) |
| 73 | |
| 74 | #define BITS_SET(val, mask) (((val) & (mask)) == (mask)) |
| 75 | |
| 76 | /** Test if all given bits are set in the given data word |
| 77 | * \param[in] word Given data word to test |
| 78 | * \param[in] mask Test mask |
| 79 | * \return TRUE if all the bits in the bitMask are set |
| 80 | */ |
| 81 | static inline bcmos_bool test_bits_set(uint32_t word, uint32_t mask) |
| 82 | { |
| 83 | return ((word & mask) == mask); |
| 84 | } |
| 85 | |
| 86 | /** Test if all given bits are clear in the given data word |
| 87 | * \param word Given word to test |
| 88 | * \param mask Test mask |
| 89 | * \return TRUE if all the bits given by bitMask are clear |
| 90 | */ |
| 91 | static inline bcmos_bool test_bits_clear(uint32_t word, uint32_t mask) |
| 92 | { |
| 93 | return (word & mask) == 0; |
| 94 | } |
| 95 | |
| 96 | /** Test whether any of the given bits are set in a value |
| 97 | * \param[in] val The value to test |
| 98 | * \param[in] bits The bits to test for |
| 99 | * \return TRUE if any of the bits are set in the value, FALSE otherwise |
| 100 | */ |
| 101 | static inline bcmos_bool test_bits_any(uint32_t val, uint32_t bits) |
| 102 | { |
| 103 | return (val & bits) != 0; |
| 104 | } |
| 105 | |
| 106 | |
| 107 | /** return true if only one bit is set for a given integer. |
| 108 | */ |
| 109 | static inline bcmos_bool is_one_bit_set(uint32_t number) |
| 110 | { |
| 111 | return (number & (number - 1)) == 0; |
| 112 | } |
| 113 | |
| 114 | |
| 115 | |
| 116 | /** dynamically allocate space for an array of `nbits' bits and initalize |
| 117 | * the bits to all be zero. |
| 118 | * |
| 119 | * \param[out] bv pointer to a bit_vector struct. |
| 120 | * \param[in] nbits number of bits to allocate. |
| 121 | * \return FALSE if space was not available, otherwise TRUE. |
| 122 | */ |
| 123 | bcmos_bool bcmolt_bv_new(bit_vector *bv, const uint32_t nbits); |
| 124 | |
| 125 | |
| 126 | /** return the value of the `offset'th bit element of the bit vector. |
| 127 | * |
| 128 | * \param[in] bv pointer to a bit_vector struct. |
| 129 | * \param[in] offset offset of bit to test. |
| 130 | * \return FALSE if the bit offset is out of range, otherwise TRUE. |
| 131 | */ |
| 132 | bcmos_bool bcmolt_bv_get(const bit_vector *bv, const uint32_t offset); |
| 133 | |
| 134 | |
| 135 | /** set or clear the bit in position `offset' of the bit vector. |
| 136 | * bv->vector[bit_pos] is to be set (assigned to 1) if value is TRUE, |
| 137 | * otherwise it is to be cleared (assigned to 0). |
| 138 | * |
| 139 | * \param[in] bv pointer to a bit_vector struct. |
| 140 | * \param[in] offset offset of bit to set or clear. |
| 141 | * \param[in] value boolean value. TRUE for set, FALSE for clear. |
| 142 | * \return FALSE if the bit offset is out of range, otherwise TRUE. |
| 143 | */ |
| 144 | void bcmolt_bv_assign(bit_vector *bv, const uint32_t offset, const bcmos_bool value); |
| 145 | |
| 146 | |
| 147 | /** set or clear 'nbits' bits of given bit vector. |
| 148 | * |
| 149 | * \param[in] bv pointer to a bit_vector struct. |
| 150 | * \param[in] nbits number of bits to set or clear. |
| 151 | * \param[in] value boolean value. TRUE for set, FALSE for clear. |
| 152 | * \return FALSE if the bit offset is out of range, otherwise TRUE. |
| 153 | */ |
| 154 | void bv_assign_nbits(bit_vector *bv, const uint32_t nbits, |
| 155 | const bcmos_bool value); |
| 156 | |
| 157 | |
| 158 | /** toggle the bit in position `offset' of the bit vector. |
| 159 | * i.e. if it was 1 it is 0; if it was 0 it is 1. |
| 160 | * |
| 161 | * \param[in] bv pointer to a bit_vector struct. |
| 162 | * \param[in] offset offset of bit to toggle. |
| 163 | * \return FALSE if the bit offset is out of range, otherwise TRUE. |
| 164 | */ |
| 165 | void bcmolt_bv_toggle(bit_vector *bv, const uint32_t offset); |
| 166 | |
| 167 | |
| 168 | /** copy bit vector from 'src' to 'dst'. |
| 169 | * |
| 170 | * \param[out] dst pointer to a bit_vector struct to copy to. |
| 171 | * \param[in] src pointer to a bit_vector struct to copy from. |
| 172 | * \param[in] nbits number of bits to copy. |
| 173 | * \return none. |
| 174 | */ |
| 175 | void bcmolt_bv_copy(bit_vector *dst, const bit_vector *src, const uint32_t nbits); |
| 176 | |
| 177 | |
| 178 | /** Print bit pattern of word FORMATTED to string. |
| 179 | * |
| 180 | * \param[in] value value to transform to bit string. |
| 181 | * \param[in] bitcnt count of bits to be shown. |
| 182 | * \param[out] outstr pointer to a output buffer to store the string. |
| 183 | * \return none |
| 184 | * \warning this fn doesn't check the size of 'outstr'. |
| 185 | * the caller should ensure 'outstr' has enough room for the |
| 186 | * bit string, space characters and null terminator. |
| 187 | */ |
| 188 | void bcmolt_bit_string(const bv_bits value, const uint32_t bitcnt, char *outstr); |
| 189 | |
| 190 | |
| 191 | /** Print all bits in the bit vector. |
| 192 | * |
| 193 | * \param[in] bv pointer to a bit_vector struct. |
| 194 | * \return none. |
| 195 | */ |
| 196 | void bcmolt_bv_dump(const bit_vector *bv); |
| 197 | |
| 198 | |
| 199 | /** Count the number of bits set in a long integer. |
| 200 | * |
| 201 | * \param[in] num integer value. |
| 202 | * \return number of bits set. |
| 203 | */ |
| 204 | uint32_t bcmolt_bit_count(uint32_t num); |
| 205 | |
| 206 | |
| 207 | /** Count the number of bits set in the whole bit vector. |
| 208 | * |
| 209 | * \param[in] bv pointer to the bit vector struct. |
| 210 | * \return number of bits set. |
| 211 | */ |
| 212 | uint32_t bcmolt_bv_bit_count(const bit_vector *bv); |
| 213 | |
| 214 | |
| 215 | /** Copy bit range from a 32-bit word array to an arbitrary bit position of |
| 216 | * the destination 32-bit word array. |
| 217 | * |
| 218 | * \param[in] dst destination buffer |
| 219 | * \param[in] dst_bytes destination buffer size in bytes |
| 220 | * \param[in] dst_bit_pos least bit position to dest |
| 221 | * \param[in] src source buffer |
| 222 | * \param[in] src_bits many bits to copy from source |
| 223 | * \note src is in little endian and dst is in big endian. |
| 224 | */ |
| 225 | void bcmos_bit_range_set(uint32_t *dst, uint32_t dst_bytes, uint16_t dst_bit_pos, |
| 226 | uint32_t *src, uint16_t n_bits); |
| 227 | |
| 228 | /** Get bit range at an arbitrary bit position of a 32-bit word array |
| 229 | * |
| 230 | * \param[in] src source buffer (e.g. dataport) |
| 231 | * \param[in] src_bytes source buffer size in bytes |
| 232 | * \param[in] src_bit_pos least bit position of the source |
| 233 | * \param[in] dst destination buffer to store the bit value |
| 234 | * \param[in] n_bits how many bits to copy from srouce |
| 235 | * \note src is in big endian and dst is in little endian. |
| 236 | */ |
| 237 | void bcmos_bit_range_get(const uint32_t *src, uint32_t src_bytes, |
| 238 | uint16_t src_bit_pos, uint32_t *dst, uint16_t n_bits); |
| 239 | |
| 240 | |
| 241 | #endif /* BCMOLT_BIT_UTILS_H */ |
| 242 | |