| /* |
| * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. |
| * |
| * Previously licensed under the ISC license by Qualcomm Atheros, Inc. |
| * |
| * |
| * Permission to use, copy, modify, and/or distribute this software for |
| * any purpose with or without fee is hereby granted, provided that the |
| * above copyright notice and this permission notice appear in all |
| * copies. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
| * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
| * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
| * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| * PERFORMANCE OF THIS SOFTWARE. |
| */ |
| |
| /* |
| * This file was originally distributed by Qualcomm Atheros, Inc. |
| * under proprietary terms before Copyright ownership was assigned |
| * to the Linux Foundation. |
| */ |
| |
| /* |
| * |
| * This file lim_aid_mgmt.c contains the functions related to |
| * AID pool management like initialization, assignment etc. |
| * Author: Chandra Modumudi |
| * Date: 03/20/02 |
| * History:- |
| * Date Modified by Modification Information |
| * -------------------------------------------------------------------- |
| */ |
| |
| #include "cds_api.h" |
| #include "wni_cfg.h" |
| #include "ani_global.h" |
| #include "cfg_api.h" |
| #include "sir_params.h" |
| #include "lim_utils.h" |
| #include "lim_timer_utils.h" |
| #include "lim_ft_defs.h" |
| #include "lim_session.h" |
| #include "lim_session_utils.h" |
| |
| #define LIM_START_PEER_IDX 1 |
| |
| /** |
| * lim_init_peer_idxpool() -- initializes peer index pool |
| * @pMac: mac context |
| * @pSessionEntry: session entry |
| * |
| * This function is called while starting a BSS at AP |
| * to initialize AID pool. This may also be called while |
| * starting/joining an IBSS if 'Association' is allowed |
| * in IBSS. |
| * |
| * Return: None |
| */ |
| |
| void lim_init_peer_idxpool(tpAniSirGlobal pMac, tpPESession pSessionEntry) |
| { |
| uint8_t i; |
| uint8_t maxAssocSta = pMac->lim.maxStation; |
| |
| pSessionEntry->gpLimPeerIdxpool[0] = 0; |
| |
| #ifdef FEATURE_WLAN_TDLS |
| /* |
| * In station role, DPH_STA_HASH_INDEX_PEER (index 1) is reserved |
| * for peer station index corresponding to AP. Avoid choosing that index |
| * and get index starting from (DPH_STA_HASH_INDEX_PEER + 1) |
| * (index 2) for TDLS stations; |
| */ |
| if (LIM_IS_STA_ROLE(pSessionEntry)) { |
| pSessionEntry->freePeerIdxHead = DPH_STA_HASH_INDEX_PEER + 1; |
| } else |
| #endif |
| #ifdef QCA_IBSS_SUPPORT |
| if (LIM_IS_IBSS_ROLE(pSessionEntry)) { |
| pSessionEntry->freePeerIdxHead = LIM_START_PEER_IDX; |
| } else |
| #endif |
| { |
| pSessionEntry->freePeerIdxHead = LIM_START_PEER_IDX; |
| } |
| |
| for (i = pSessionEntry->freePeerIdxHead; i < maxAssocSta; i++) { |
| pSessionEntry->gpLimPeerIdxpool[i] = i + 1; |
| } |
| pSessionEntry->gpLimPeerIdxpool[i] = 0; |
| |
| pSessionEntry->freePeerIdxTail = i; |
| |
| } |
| |
| /** |
| * lim_assign_peer_idx() |
| * |
| ***FUNCTION: |
| * This function is called to get a peer station index. This index is |
| * used during Association/Reassociation |
| * frame handling to assign association ID (aid) to a STA. |
| * In case of TDLS, this is used to assign a index into the Dph hash entry. |
| * |
| ***LOGIC: |
| * |
| ***ASSUMPTIONS: |
| * NA |
| * |
| ***NOTE: |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @return peerIdx - assigned peer Station IDx for STA |
| */ |
| |
| uint16_t lim_assign_peer_idx(tpAniSirGlobal pMac, tpPESession pSessionEntry) |
| { |
| uint16_t peerId; |
| |
| /* make sure we haven't exceeded the configurable limit on associations */ |
| /* This count is global to ensure that it doesnt exceed the hardware limits. */ |
| if (pe_get_current_stas_count(pMac) >= pMac->lim.gLimAssocStaLimit) { |
| /* too many associations already active */ |
| return 0; |
| } |
| |
| /* return head of free list */ |
| |
| if (pSessionEntry->freePeerIdxHead) { |
| peerId = pSessionEntry->freePeerIdxHead; |
| pSessionEntry->freePeerIdxHead = |
| pSessionEntry->gpLimPeerIdxpool[pSessionEntry-> |
| freePeerIdxHead]; |
| if (pSessionEntry->freePeerIdxHead == 0) |
| pSessionEntry->freePeerIdxTail = 0; |
| pSessionEntry->gLimNumOfCurrentSTAs++; |
| return peerId; |
| } |
| |
| return 0; /* no more free peer index */ |
| } |
| |
| /** |
| * lim_release_peer_idx() |
| * |
| ***FUNCTION: |
| * This function is called when a STA context is removed |
| * at AP (or at a STA in IBSS mode or TDLS) to return peer Index |
| * to free pool. |
| * |
| ***LOGIC: |
| * |
| ***ASSUMPTIONS: |
| * NA |
| * |
| ***NOTE: |
| * |
| * @param pMac - Pointer to Global MAC structure |
| * @param peerIdx - peer station index that need to return to free pool |
| * |
| * @return None |
| */ |
| |
| void |
| lim_release_peer_idx(tpAniSirGlobal pMac, uint16_t peerIdx, |
| tpPESession pSessionEntry) |
| { |
| pSessionEntry->gLimNumOfCurrentSTAs--; |
| |
| /* insert at tail of free list */ |
| if (pSessionEntry->freePeerIdxTail) { |
| pSessionEntry->gpLimPeerIdxpool[pSessionEntry-> |
| freePeerIdxTail] = |
| (uint8_t) peerIdx; |
| pSessionEntry->freePeerIdxTail = (uint8_t) peerIdx; |
| } else { |
| pSessionEntry->freePeerIdxTail = |
| pSessionEntry->freePeerIdxHead = (uint8_t) peerIdx; |
| } |
| pSessionEntry->gpLimPeerIdxpool[(uint8_t) peerIdx] = 0; |
| } |