diff options
Diffstat (limited to 'drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_util.h')
-rw-r--r-- | drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_util.h | 492 |
1 files changed, 492 insertions, 0 deletions
diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_util.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_util.h new file mode 100644 index 000000000000..c86269e2b155 --- /dev/null +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_util.h @@ -0,0 +1,492 @@ +/** @file mlan_util.h + * + * @brief This file contains wrappers for linked-list, + * spinlock and timer defines. + * + * + * Copyright 2014-2020 NXP + * + * This software file (the File) is distributed by NXP + * under the terms of the GNU General Public License Version 2, June 1991 + * (the License). You may use, redistribute and/or modify the File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + * + */ + +/****************************************************** +Change log: + 10/28/2008: initial version +******************************************************/ + +#ifndef _MLAN_UTIL_H_ +#define _MLAN_UTIL_H_ + +/** Circular doubly linked list */ +typedef struct _mlan_linked_list { + /** Pointer to previous node */ + struct _mlan_linked_list *pprev; + /** Pointer to next node */ + struct _mlan_linked_list *pnext; +} mlan_linked_list, *pmlan_linked_list; + +/** List head */ +typedef struct _mlan_list_head { + /** Pointer to previous node */ + struct _mlan_linked_list *pprev; + /** Pointer to next node */ + struct _mlan_linked_list *pnext; + /** Pointer to lock */ + t_void *plock; +} mlan_list_head, *pmlan_list_head; + +/** + * @brief This function initializes a list without locking + * + * @param phead List head + * + * @return N/A + */ +static INLINE t_void util_init_list(pmlan_linked_list phead) +{ + /* Both next and prev point to self */ + phead->pprev = phead->pnext = (pmlan_linked_list)phead; +} + +/** + * @brief This function initializes a list + * + * @param phead List head + * @param lock_required A flag for spinlock requirement + * @param moal_init_lock A pointer to init lock handler + * + * @return N/A + */ +static INLINE t_void util_init_list_head( + t_void *pmoal_handle, pmlan_list_head phead, t_u8 lock_required, + mlan_status (*moal_init_lock)(t_void *handle, t_void **pplock)) +{ + /* Both next and prev point to self */ + util_init_list((pmlan_linked_list)phead); + if (lock_required) + moal_init_lock(pmoal_handle, &phead->plock); + else + phead->plock = 0; +} + +/** + * @brief This function frees a list + * + * @param phead List head + * @param moal_free_lock A pointer to free lock handler + * + * @return N/A + */ +static INLINE t_void util_free_list_head( + t_void *pmoal_handle, pmlan_list_head phead, + mlan_status (*moal_free_lock)(t_void *handle, t_void *plock)) +{ + phead->pprev = phead->pnext = 0; + if (phead->plock) + moal_free_lock(pmoal_handle, phead->plock); +} + +/** + * @brief This function peeks into a list + * + * @param phead List head + * @param moal_spin_lock A pointer to spin lock handler + * @param moal_spin_unlock A pointer to spin unlock handler + * + * @return List node + */ +static INLINE pmlan_linked_list +util_peek_list(t_void *pmoal_handle, pmlan_list_head phead, + mlan_status (*moal_spin_lock)(t_void *handle, t_void *plock), + mlan_status (*moal_spin_unlock)(t_void *handle, t_void *plock)) +{ + pmlan_linked_list pnode = 0; + + if (moal_spin_lock) + moal_spin_lock(pmoal_handle, phead->plock); + if (phead->pnext != (pmlan_linked_list)phead) + pnode = phead->pnext; + if (moal_spin_unlock) + moal_spin_unlock(pmoal_handle, phead->plock); + return pnode; +} + +/** + * @brief This function queues a node at the list tail + * + * @param phead List head + * @param pnode List node to queue + * @param moal_spin_lock A pointer to spin lock handler + * @param moal_spin_unlock A pointer to spin unlock handler + * + * @return N/A + */ +static INLINE t_void util_enqueue_list_tail( + t_void *pmoal_handle, pmlan_list_head phead, pmlan_linked_list pnode, + mlan_status (*moal_spin_lock)(t_void *handle, t_void *plock), + mlan_status (*moal_spin_unlock)(t_void *handle, t_void *plock)) +{ + pmlan_linked_list pold_last; + + if (moal_spin_lock) + moal_spin_lock(pmoal_handle, phead->plock); + pold_last = phead->pprev; + pnode->pprev = pold_last; + pnode->pnext = (pmlan_linked_list)phead; + + phead->pprev = pold_last->pnext = pnode; + if (moal_spin_unlock) + moal_spin_unlock(pmoal_handle, phead->plock); +} + +/** + * @brief This function adds a node at the list head + * + * @param phead List head + * @param pnode List node to add + * @param moal_spin_lock A pointer to spin lock handler + * @param moal_spin_unlock A pointer to spin unlock handler + * + * @return N/A + */ +static INLINE t_void util_enqueue_list_head( + t_void *pmoal_handle, pmlan_list_head phead, pmlan_linked_list pnode, + mlan_status (*moal_spin_lock)(t_void *handle, t_void *plock), + mlan_status (*moal_spin_unlock)(t_void *handle, t_void *plock)) +{ + pmlan_linked_list pold_first; + + if (moal_spin_lock) + moal_spin_lock(pmoal_handle, phead->plock); + pold_first = phead->pnext; + pnode->pprev = (pmlan_linked_list)phead; + pnode->pnext = pold_first; + + phead->pnext = pold_first->pprev = pnode; + if (moal_spin_unlock) + moal_spin_unlock(pmoal_handle, phead->plock); +} + +/** + * @brief This function removes a node from the list + * + * @param phead List head + * @param pnode List node to remove + * @param moal_spin_lock A pointer to spin lock handler + * @param moal_spin_unlock A pointer to spin unlock handler + * + * @return N/A + */ +static INLINE t_void util_unlink_list( + t_void *pmoal_handle, pmlan_list_head phead, pmlan_linked_list pnode, + mlan_status (*moal_spin_lock)(t_void *handle, t_void *plock), + mlan_status (*moal_spin_unlock)(t_void *handle, t_void *plock)) +{ + pmlan_linked_list pmy_prev; + pmlan_linked_list pmy_next; + + if (moal_spin_lock) + moal_spin_lock(pmoal_handle, phead->plock); + pmy_prev = pnode->pprev; + pmy_next = pnode->pnext; + pmy_next->pprev = pmy_prev; + pmy_prev->pnext = pmy_next; + + pnode->pnext = pnode->pprev = 0; + if (moal_spin_unlock) + moal_spin_unlock(pmoal_handle, phead->plock); +} + +/** + * @brief This function dequeues a node from the list + * + * @param phead List head + * @param moal_spin_lock A pointer to spin lock handler + * @param moal_spin_unlock A pointer to spin unlock handler + * + * @return List node + */ +static INLINE pmlan_linked_list util_dequeue_list( + t_void *pmoal_handle, pmlan_list_head phead, + mlan_status (*moal_spin_lock)(t_void *handle, t_void *plock), + mlan_status (*moal_spin_unlock)(t_void *handle, t_void *plock)) +{ + pmlan_linked_list pnode; + + if (moal_spin_lock) + moal_spin_lock(pmoal_handle, phead->plock); + pnode = phead->pnext; + if (pnode && (pnode != (pmlan_linked_list)phead)) + util_unlink_list(pmoal_handle, phead, pnode, 0, 0); + else + pnode = 0; + if (moal_spin_unlock) + moal_spin_unlock(pmoal_handle, phead->plock); + return pnode; +} + +/** Access controlled scalar variable */ +typedef struct _mlan_scalar { + /** Value */ + t_s32 value; + /** Pointer to lock */ + t_void *plock; + /** Control flags */ + t_u32 flags; +} mlan_scalar, *pmlan_scalar; + +/** Flag to scalar lock acquired */ +#define MLAN_SCALAR_FLAG_UNIQUE_LOCK MBIT(16) + +/** scalar conditional value list */ +typedef enum _MLAN_SCALAR_CONDITIONAL { + MLAN_SCALAR_COND_EQUAL, + MLAN_SCALAR_COND_NOT_EQUAL, + MLAN_SCALAR_COND_GREATER_THAN, + MLAN_SCALAR_COND_GREATER_OR_EQUAL, + MLAN_SCALAR_COND_LESS_THAN, + MLAN_SCALAR_COND_LESS_OR_EQUAL +} MLAN_SCALAR_CONDITIONAL; + +/** + * @brief This function initializes a scalar + * + * @param pscalar Pointer to scalar + * @param val Initial scalar value + * @param plock_to_use A new lock is created if NULL, else lock to use + * @param moal_init_lock A pointer to init lock handler + * + * @return N/A + */ +static INLINE t_void +util_scalar_init(t_void *pmoal_handle, pmlan_scalar pscalar, t_s32 val, + t_void *plock_to_use, + mlan_status (*moal_init_lock)(t_void *handle, t_void **pplock)) +{ + pscalar->value = val; + pscalar->flags = 0; + if (plock_to_use) { + pscalar->flags &= ~MLAN_SCALAR_FLAG_UNIQUE_LOCK; + pscalar->plock = plock_to_use; + } else { + pscalar->flags |= MLAN_SCALAR_FLAG_UNIQUE_LOCK; + moal_init_lock(pmoal_handle, &pscalar->plock); + } +} + +/** + * @brief This function frees a scalar + * + * @param pscalar Pointer to scalar + * @param moal_free_lock A pointer to free lock handler + * + * @return N/A + */ +static INLINE t_void +util_scalar_free(t_void *pmoal_handle, pmlan_scalar pscalar, + mlan_status (*moal_free_lock)(t_void *handle, t_void *plock)) +{ + if (pscalar->flags & MLAN_SCALAR_FLAG_UNIQUE_LOCK) + moal_free_lock(pmoal_handle, pscalar->plock); +} + +/** + * @brief This function reads value from scalar + * + * @param pscalar Pointer to scalar + * @param moal_spin_lock A pointer to spin lock handler + * @param moal_spin_unlock A pointer to spin unlock handler + * + * @return Stored value + */ +static INLINE t_s32 +util_scalar_read(t_void *pmoal_handle, pmlan_scalar pscalar, + mlan_status (*moal_spin_lock)(t_void *handle, t_void *plock), + mlan_status (*moal_spin_unlock)(t_void *handle, t_void *plock)) +{ + t_s32 val; + + if (moal_spin_lock) + moal_spin_lock(pmoal_handle, pscalar->plock); + val = pscalar->value; + if (moal_spin_unlock) + moal_spin_unlock(pmoal_handle, pscalar->plock); + + return val; +} + +/** + * @brief This function writes value to scalar + * + * @param pscalar Pointer to scalar + * @param val Value to write + * @param moal_spin_lock A pointer to spin lock handler + * @param moal_spin_unlock A pointer to spin unlock handler + * + * @return N/A + */ +static INLINE t_void util_scalar_write( + t_void *pmoal_handle, pmlan_scalar pscalar, t_s32 val, + mlan_status (*moal_spin_lock)(t_void *handle, t_void *plock), + mlan_status (*moal_spin_unlock)(t_void *handle, t_void *plock)) +{ + if (moal_spin_lock) + moal_spin_lock(pmoal_handle, pscalar->plock); + pscalar->value = val; + if (moal_spin_unlock) + moal_spin_unlock(pmoal_handle, pscalar->plock); +} + +/** + * @brief This function increments the value in scalar + * + * @param pscalar Pointer to scalar + * @param moal_spin_lock A pointer to spin lock handler + * @param moal_spin_unlock A pointer to spin unlock handler + * + * @return N/A + */ +static INLINE t_void util_scalar_increment( + t_void *pmoal_handle, pmlan_scalar pscalar, + mlan_status (*moal_spin_lock)(t_void *handle, t_void *plock), + mlan_status (*moal_spin_unlock)(t_void *handle, t_void *plock)) +{ + if (moal_spin_lock) + moal_spin_lock(pmoal_handle, pscalar->plock); + pscalar->value++; + if (moal_spin_unlock) + moal_spin_unlock(pmoal_handle, pscalar->plock); +} + +/** + * @brief This function decrements the value in scalar + * + * @param pscalar Pointer to scalar + * @param moal_spin_lock A pointer to spin lock handler + * @param moal_spin_unlock A pointer to spin unlock handler + * + * @return N/A + */ +static INLINE t_void util_scalar_decrement( + t_void *pmoal_handle, pmlan_scalar pscalar, + mlan_status (*moal_spin_lock)(t_void *handle, t_void *plock), + mlan_status (*moal_spin_unlock)(t_void *handle, t_void *plock)) +{ + if (moal_spin_lock) + moal_spin_lock(pmoal_handle, pscalar->plock); + pscalar->value--; + if (moal_spin_unlock) + moal_spin_unlock(pmoal_handle, pscalar->plock); +} + +/** + * @brief This function adds an offset to the value in scalar, + * and returns the new value + * + * @param pscalar Pointer to scalar + * @param offset Offset value (can be negative) + * @param moal_spin_lock A pointer to spin lock handler + * @param moal_spin_unlock A pointer to spin unlock handler + * + * @return Value after offset + */ +static INLINE t_s32 util_scalar_offset( + t_void *pmoal_handle, pmlan_scalar pscalar, t_s32 offset, + mlan_status (*moal_spin_lock)(t_void *handle, t_void *plock), + mlan_status (*moal_spin_unlock)(t_void *handle, t_void *plock)) +{ + t_s32 newval; + + if (moal_spin_lock) + moal_spin_lock(pmoal_handle, pscalar->plock); + newval = (pscalar->value += offset); + if (moal_spin_unlock) + moal_spin_unlock(pmoal_handle, pscalar->plock); + + return newval; +} + +/** + * @brief This function writes the value to the scalar + * if existing value compared with other value is true. + * + * @param pscalar Pointer to scalar + * @param condition Condition to check + * @param val_compare Value to compare against current value + * ((A X B), where B = val_compare) + * @param val_to_set Value to set if comparison is true + * @param moal_spin_lock A pointer to spin lock handler + * @param moal_spin_unlock A pointer to spin unlock handler + * + * @return Comparison result (MTRUE or MFALSE) + */ +static INLINE t_u8 util_scalar_conditional_write( + t_void *pmoal_handle, pmlan_scalar pscalar, + MLAN_SCALAR_CONDITIONAL condition, t_s32 val_compare, t_s32 val_to_set, + mlan_status (*moal_spin_lock)(t_void *handle, t_void *plock), + mlan_status (*moal_spin_unlock)(t_void *handle, t_void *plock)) +{ + t_u8 update; + if (moal_spin_lock) + moal_spin_lock(pmoal_handle, pscalar->plock); + + switch (condition) { + case MLAN_SCALAR_COND_EQUAL: + update = (pscalar->value == val_compare); + break; + case MLAN_SCALAR_COND_NOT_EQUAL: + update = (pscalar->value != val_compare); + break; + case MLAN_SCALAR_COND_GREATER_THAN: + update = (pscalar->value > val_compare); + break; + case MLAN_SCALAR_COND_GREATER_OR_EQUAL: + update = (pscalar->value >= val_compare); + break; + case MLAN_SCALAR_COND_LESS_THAN: + update = (pscalar->value < val_compare); + break; + case MLAN_SCALAR_COND_LESS_OR_EQUAL: + update = (pscalar->value <= val_compare); + break; + default: + update = MFALSE; + break; + } + if (update) + pscalar->value = val_to_set; + + if (moal_spin_unlock) + moal_spin_unlock(pmoal_handle, pscalar->plock); + return (update) ? MTRUE : MFALSE; +} + +/** + * @brief This function counts the bits of unsigned int number + * + * @param num number + * @return number of bits + */ +static INLINE t_u32 bitcount(t_u32 num) +{ + t_u32 count = 0; + static t_u32 nibblebits[] = {0, 1, 1, 2, 1, 2, 2, 3, + 1, 2, 2, 3, 2, 3, 3, 4}; + for (; num != 0; num >>= 4) + count += nibblebits[num & 0x0f]; + return count; +} + +#endif /* !_MLAN_UTIL_H_ */ |