| /* |
| <:copyright-BRCM:2016:DUAL/GPL:standard |
| |
| Broadcom Proprietary and Confidential.(c) 2016 Broadcom |
| All Rights Reserved |
| |
| Unless you and Broadcom execute a separate written software license |
| agreement governing use of this software, this software is licensed |
| to you under the terms of the GNU General Public License version 2 |
| (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, |
| with the following added to such license: |
| |
| As a special exception, the copyright holders of this software give |
| you permission to link this software with independent modules, and |
| to copy and distribute the resulting executable under terms of your |
| choice, provided that you also meet, for each linked independent |
| module, the terms and conditions of the license of that module. |
| An independent module is a module which is not derived from this |
| software. The special exception does not apply to any modifications |
| of the software. |
| |
| Not withstanding the above, under no circumstances may you combine |
| this software in any way with any other Broadcom software provided |
| under a license other than the GPL, without Broadcom's express prior |
| written consent. |
| |
| :> |
| */ |
| |
| /** |
| * bcmolt_bit_utils.h |
| * Created on: 03/10/2014 |
| * Author: cpark1 |
| * |
| * This bit vector implementation is used for the EPON encryption. |
| * There is a certain hardware restriction that the global encryption mode |
| * can not be changed when a link encryption is configured for a different |
| * encryption mode. |
| * Likewise, the link encryption mode can not be changed if the global |
| * encryption mode is set to other mode. |
| * Therefore, when the host tries to change any of them, the OLT needs to |
| * check either the global encryption mode or the link encryption mode |
| * before applying the change. |
| * In the old implementation (like Pioneer), the firmware iterates through |
| * every link records of each PON port and check the encryption mode of each. |
| * This is very inefficient and time consuming. |
| * The host may want to know how many links are enabled for the encryption, |
| * or which link is enabled, etc. |
| * I thought that a bit vector implementation is best satisfies. |
| * Also, this implementation exactly reflects the IC implementation, so we |
| * can use it to mirror the hardware status. |
| * |
| */ |
| |
| #ifndef BCMOLT_BIT_UTILS_H |
| #define BCMOLT_BIT_UTILS_H |
| |
| |
| #include "bcmos_system.h" |
| |
| |
| /* the current (draft) design of the ASIC uses 32-bit bitmap data port */ |
| typedef uint32_t bv_bits; |
| |
| typedef struct |
| { |
| uint32_t nbits; |
| bv_bits *vector; |
| } bit_vector; |
| |
| |
| #define BITS_SZ (sizeof(bv_bits) * CHAR_BIT) |
| |
| #define BITS_SET(val, mask) (((val) & (mask)) == (mask)) |
| |
| /** Test if all given bits are set in the given data word |
| * \param[in] word Given data word to test |
| * \param[in] mask Test mask |
| * \return TRUE if all the bits in the bitMask are set |
| */ |
| static inline bcmos_bool test_bits_set(uint32_t word, uint32_t mask) |
| { |
| return ((word & mask) == mask); |
| } |
| |
| /** Test if all given bits are clear in the given data word |
| * \param word Given word to test |
| * \param mask Test mask |
| * \return TRUE if all the bits given by bitMask are clear |
| */ |
| static inline bcmos_bool test_bits_clear(uint32_t word, uint32_t mask) |
| { |
| return (word & mask) == 0; |
| } |
| |
| /** Test whether any of the given bits are set in a value |
| * \param[in] val The value to test |
| * \param[in] bits The bits to test for |
| * \return TRUE if any of the bits are set in the value, FALSE otherwise |
| */ |
| static inline bcmos_bool test_bits_any(uint32_t val, uint32_t bits) |
| { |
| return (val & bits) != 0; |
| } |
| |
| |
| /** return true if only one bit is set for a given integer. |
| */ |
| static inline bcmos_bool is_one_bit_set(uint32_t number) |
| { |
| return (number & (number - 1)) == 0; |
| } |
| |
| |
| |
| /** dynamically allocate space for an array of `nbits' bits and initalize |
| * the bits to all be zero. |
| * |
| * \param[out] bv pointer to a bit_vector struct. |
| * \param[in] nbits number of bits to allocate. |
| * \return FALSE if space was not available, otherwise TRUE. |
| */ |
| bcmos_bool bcmolt_bv_new(bit_vector *bv, const uint32_t nbits); |
| |
| |
| /** return the value of the `offset'th bit element of the bit vector. |
| * |
| * \param[in] bv pointer to a bit_vector struct. |
| * \param[in] offset offset of bit to test. |
| * \return FALSE if the bit offset is out of range, otherwise TRUE. |
| */ |
| bcmos_bool bcmolt_bv_get(const bit_vector *bv, const uint32_t offset); |
| |
| |
| /** set or clear the bit in position `offset' of the bit vector. |
| * bv->vector[bit_pos] is to be set (assigned to 1) if value is TRUE, |
| * otherwise it is to be cleared (assigned to 0). |
| * |
| * \param[in] bv pointer to a bit_vector struct. |
| * \param[in] offset offset of bit to set or clear. |
| * \param[in] value boolean value. TRUE for set, FALSE for clear. |
| * \return FALSE if the bit offset is out of range, otherwise TRUE. |
| */ |
| void bcmolt_bv_assign(bit_vector *bv, const uint32_t offset, const bcmos_bool value); |
| |
| |
| /** set or clear 'nbits' bits of given bit vector. |
| * |
| * \param[in] bv pointer to a bit_vector struct. |
| * \param[in] nbits number of bits to set or clear. |
| * \param[in] value boolean value. TRUE for set, FALSE for clear. |
| * \return FALSE if the bit offset is out of range, otherwise TRUE. |
| */ |
| void bv_assign_nbits(bit_vector *bv, const uint32_t nbits, |
| const bcmos_bool value); |
| |
| |
| /** toggle the bit in position `offset' of the bit vector. |
| * i.e. if it was 1 it is 0; if it was 0 it is 1. |
| * |
| * \param[in] bv pointer to a bit_vector struct. |
| * \param[in] offset offset of bit to toggle. |
| * \return FALSE if the bit offset is out of range, otherwise TRUE. |
| */ |
| void bcmolt_bv_toggle(bit_vector *bv, const uint32_t offset); |
| |
| |
| /** copy bit vector from 'src' to 'dst'. |
| * |
| * \param[out] dst pointer to a bit_vector struct to copy to. |
| * \param[in] src pointer to a bit_vector struct to copy from. |
| * \param[in] nbits number of bits to copy. |
| * \return none. |
| */ |
| void bcmolt_bv_copy(bit_vector *dst, const bit_vector *src, const uint32_t nbits); |
| |
| |
| /** Print bit pattern of word FORMATTED to string. |
| * |
| * \param[in] value value to transform to bit string. |
| * \param[in] bitcnt count of bits to be shown. |
| * \param[out] outstr pointer to a output buffer to store the string. |
| * \return none |
| * \warning this fn doesn't check the size of 'outstr'. |
| * the caller should ensure 'outstr' has enough room for the |
| * bit string, space characters and null terminator. |
| */ |
| void bcmolt_bit_string(const bv_bits value, const uint32_t bitcnt, char *outstr); |
| |
| |
| /** Print all bits in the bit vector. |
| * |
| * \param[in] bv pointer to a bit_vector struct. |
| * \return none. |
| */ |
| void bcmolt_bv_dump(const bit_vector *bv); |
| |
| |
| /** Count the number of bits set in a long integer. |
| * |
| * \param[in] num integer value. |
| * \return number of bits set. |
| */ |
| uint32_t bcmolt_bit_count(uint32_t num); |
| |
| |
| /** Count the number of bits set in the whole bit vector. |
| * |
| * \param[in] bv pointer to the bit vector struct. |
| * \return number of bits set. |
| */ |
| uint32_t bcmolt_bv_bit_count(const bit_vector *bv); |
| |
| |
| /** Copy bit range from a 32-bit word array to an arbitrary bit position of |
| * the destination 32-bit word array. |
| * |
| * \param[in] dst destination buffer |
| * \param[in] dst_bytes destination buffer size in bytes |
| * \param[in] dst_bit_pos least bit position to dest |
| * \param[in] src source buffer |
| * \param[in] src_bits many bits to copy from source |
| * \note src is in little endian and dst is in big endian. |
| */ |
| void bcmos_bit_range_set(uint32_t *dst, uint32_t dst_bytes, uint16_t dst_bit_pos, |
| uint32_t *src, uint16_t n_bits); |
| |
| /** Get bit range at an arbitrary bit position of a 32-bit word array |
| * |
| * \param[in] src source buffer (e.g. dataport) |
| * \param[in] src_bytes source buffer size in bytes |
| * \param[in] src_bit_pos least bit position of the source |
| * \param[in] dst destination buffer to store the bit value |
| * \param[in] n_bits how many bits to copy from srouce |
| * \note src is in big endian and dst is in little endian. |
| */ |
| void bcmos_bit_range_get(const uint32_t *src, uint32_t src_bytes, |
| uint16_t src_bit_pos, uint32_t *dst, uint16_t n_bits); |
| |
| |
| #endif /* BCMOLT_BIT_UTILS_H */ |
| |