2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/cnm_mem.c#2 $
6 \brief This file contain the management function of packet buffers and
7 generic memory alloc/free functioin for mailbox message.
9 A data packet has a fixed size of buffer, but a management
10 packet can be equipped with a variable size of buffer.
13 /*******************************************************************************
14 * Copyright (c) 2009 MediaTek Inc.
16 * All rights reserved. Copying, compilation, modification, distribution
17 * or any other use whatsoever of this material is strictly prohibited
18 * except in accordance with a Software License Agreement with
20 ********************************************************************************
23 /*******************************************************************************
26 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
27 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
28 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
29 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
30 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
31 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
32 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
33 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
34 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
35 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
36 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
37 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
38 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
40 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
41 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
42 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
43 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
44 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
46 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
47 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
48 * OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
49 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
50 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
52 ********************************************************************************
59 * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting
60 * Adding the related code which support beacon can reflect the security setting open or WPA2-PSK, WPA-PSK not yet
61 * Adn support the indicate the assoc request ie at New STA CMD, needed kernel patch.
63 * 11 17 2011 tsaiyuan.hsu
64 * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3.
65 * initialize fgNeedResp.
67 * 11 17 2011 tsaiyuan.hsu
68 * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3.
69 * avoid deactivating staRec when changing state from 3 to 3.
72 * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver
73 * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk
76 * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode
80 * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
81 * Allocate system RAM if fixed message or mgmt buffer is not available
84 * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
87 * 01 25 2011 yuche.tsai
88 * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
89 * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role.
92 * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver
93 * create branch for Wi-Fi driver v1.1
96 * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
97 * 1. BSSINFO include RLM parameter
98 * 2. free all sta records when network is disconnected
100 * 11 29 2010 cm.chang
101 * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for initial TX rate selection of auto-rate algorithm
102 * Sync RCPI of STA_REC to FW as reference of initial TX rate
104 * 11 25 2010 yuche.tsai
106 * Update SLT Function for QoS Support and not be affected by fixed rate function.
109 * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS associated
110 * 1. remove redundant variables in STA_REC structure
111 * 2. add STA-REC uninitialization routine for clearing pending events
113 * 10 13 2010 cm.chang
114 * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash.
115 * Add exception handle when cmd buffer is not available
118 * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
119 * add HT (802.11n) fixed rate support.
122 * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
123 * adding fixed rate support for distance test. (from registry setting)
127 * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning.
130 * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS associated
131 * Do a complete reset with STA-REC null checking for RF test re-entry
133 * 09 16 2010 cm.chang
135 * Change conditional compiling options for BOW
137 * 09 10 2010 cm.chang
139 * Always update Beacon content if FW sync OBSS info
141 * 08 24 2010 cm.chang
143 * Support RLM initail channel of Ad-hoc, P2P and BOW
145 * 08 23 2010 chinghwa.yu
149 * 08 20 2010 cm.chang
151 * Migrate RLM code to host from FW
155 * adding the tx pkt call back handle for countermeasure.
159 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
161 * 07 08 2010 cm.chang
162 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
163 * Check draft RLM code for HT cap
165 * 07 07 2010 cm.chang
166 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
167 * Support state of STA record change from 1 to 1
169 * 07 05 2010 cm.chang
170 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
171 * Fix correct structure size in cnmStaSendDeactivateCmd()
174 * [WPD00003833][MT6620 and MT5931] Driver migration
175 * 1) ignore RSN checking when RSN is not turned on.
176 * 2) set STA-REC deactivation callback as NULL
177 * 3) add variable initialization API based on PHY configuration
180 * [WPD00003833][MT6620 and MT5931] Driver migration
181 * spin lock target revised
184 * [WPD00003833][MT6620 and MT5931] Driver migration
185 * change inner loop index from i to k.
187 * 07 01 2010 cm.chang
188 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
189 * Support sync command of STA_REC
191 * 06 23 2010 yarco.yang
192 * [WPD00003837][MT6620]Data Path Refine
193 * Merge g_arStaRec[] into adapter->arStaRec[]
195 * 06 18 2010 cm.chang
196 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
197 * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
199 * 05 31 2010 yarco.yang
200 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
201 * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling
203 * 05 28 2010 cm.chang
204 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
205 * Support checking of duplicated buffer free
208 * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing
209 * fixed the ad-hoc wpa-none send non-encrypted frame issue.
211 * 05 28 2010 kevin.huang
212 * [BORA00000794][WIFISYS][New Feature]Power Management Support
213 * Move define of STA_REC_NUM to config.h and rename to CFG_STA_REC_NUM
215 * 05 12 2010 kevin.huang
216 * [BORA00000794][WIFISYS][New Feature]Power Management Support
217 * Add Power Management - Legacy PS-POLL support.
219 * 04 28 2010 tehuang.liu
220 * [BORA00000605][WIFISYS] Phase3 Integration
221 * Modified some MQM-related data structures (SN counter, TX/RX BA table)
223 * 04 27 2010 tehuang.liu
224 * [BORA00000605][WIFISYS] Phase3 Integration
225 * Added new TX/RX BA tables in STA_REC
227 * 04 27 2010 tehuang.liu
228 * [BORA00000605][WIFISYS] Phase3 Integration
229 * Notify MQM, TXM, and RXM upon disconnection .
231 * 04 26 2010 tehuang.liu
232 * [BORA00000605][WIFISYS] Phase3 Integration
233 * Call mqm, txm, rxm functions upon disconnection
235 * 04 24 2010 cm.chang
236 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
237 * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
239 * 04 22 2010 cm.chang
240 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
241 * First draft code to support protection in AP mode
243 * 04 19 2010 kevin.huang
244 * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
245 * Add Beacon Timeout Support
246 * * * * * * * * * * and will send Null frame to diagnose connection
248 * 04 09 2010 tehuang.liu
249 * [BORA00000605][WIFISYS] Phase3 Integration
250 * [BORA00000644] WiFi phase 4 integration
251 * * Added per-TID SN cache in STA_REC
253 * 04 07 2010 cm.chang
254 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
255 * Different invoking order for WTBL entry of associated AP
258 * [BORA00000605][WIFISYS] Phase3 Integration
259 * move the wlan table alloc / free to change state function.
261 * 03 24 2010 cm.chang
262 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
263 * Support power control
265 * 03 03 2010 tehuang.liu
266 * [BORA00000569][WIFISYS] Phase 2 Integration Test
267 * Initialize StaRec->arStaWaitQueue
269 * 03 03 2010 cm.chang
270 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
271 * Add debug message when no available pkt buffer
273 * 03 01 2010 tehuang.liu
274 * [BORA00000569][WIFISYS] Phase 2 Integration Test
275 * Fixed STA_REC initialization bug: prStaRec->au2CachedSeqCtrl[k]
277 * 02 26 2010 tehuang.liu
278 * [BORA00000569][WIFISYS] Phase 2 Integration Test
279 * Added fgIsWmmSupported in STA_RECORD_T.
281 * 02 26 2010 tehuang.liu
282 * [BORA00000569][WIFISYS] Phase 2 Integration Test
283 * Added fgIsUapsdSupported in STA_RECORD_T
285 * 02 26 2010 kevin.huang
286 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
287 * add support of Driver STA_RECORD_T activation
289 * 02 13 2010 tehuang.liu
290 * [BORA00000569][WIFISYS] Phase 2 Integration Test
291 * Added arTspecTable in STA_REC for TSPEC management
293 * 02 12 2010 cm.chang
294 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
295 * Enable mgmt buffer debug by default
297 * 02 12 2010 tehuang.liu
298 * [BORA00000569][WIFISYS] Phase 2 Integration Test
299 * Added BUFFER_SOURCE_BCN
301 * 02 04 2010 kevin.huang
302 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
303 * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
305 * 01 11 2010 kevin.huang
306 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
307 * Add Deauth and Disassoc Handler
310 * [BORA00000368]Integrate HIF part into BORA
311 * 1) separate wifi_var_emu.c/.h from wifi_var.c/.h
312 * * * * * * * * * 2) eliminate HIF_EMULATION code sections appeared in wifi_var/cnm_mem
313 * * * * * * * * * 3) use cnmMemAlloc() instead to allocate SRAM buffer
315 * 12 25 2009 tehuang.liu
316 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
317 * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM)
318 * * * * * * * MQM: BA handling
319 * * * * * * * TXM: Macros updates
320 * * * * * * * RXM: Macros/Duplicate Removal updates
322 * 12 24 2009 yarco.yang
323 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
326 * 12 21 2009 cm.chang
327 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
328 * Support several data buffer banks.
330 * 12 18 2009 cm.chang
331 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
332 * .For new FPGA memory size
334 * Dec 9 2009 MTK02468
335 * [BORA00000337] To check in codes for FPGA emulation
338 * Dec 9 2009 mtk02752
339 * [BORA00000368] Integrate HIF part into BORA
340 * add cnmDataPktFree() for emulation loopback purpose
342 * Dec 3 2009 mtk01461
343 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
344 * Fix warning of null pointer
346 * Dec 3 2009 mtk01461
347 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
348 * Add cnmGetStaRecByAddress() and add fgIsInUse flag in STA_RECORD_T
350 * Nov 23 2009 mtk01104
351 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
352 * Assign ucBufferSource in function cnmMgtPktAlloc()
354 * Nov 23 2009 mtk02468
355 * [BORA00000337] To check in codes for FPGA emulation
356 * Added packet redispatch function calls
358 * Nov 13 2009 mtk01084
359 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
360 * enable packet re-usable in current emulation driver
362 * Nov 12 2009 mtk01104
363 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
364 * 1. Add new function cnmGetStaRecByIndex()
365 * 2. Rename STA_REC_T to STA_RECORD_T
367 * Nov 9 2009 mtk01104
368 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
369 * Call cnmDataPktDispatch() in cnmPktFree()
371 * Nov 2 2009 mtk01104
372 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
373 * Remove definition of pragma section code
375 * Oct 28 2009 mtk01104
376 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
379 * Oct 23 2009 mtk01461
380 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
383 * Oct 23 2009 mtk01461
384 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
387 * Oct 12 2009 mtk01104
388 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
391 * Oct 8 2009 mtk01104
392 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
397 /*******************************************************************************
398 * C O M P I L E R F L A G S
399 ********************************************************************************
402 /*******************************************************************************
403 * E X T E R N A L R E F E R E N C E S
404 ********************************************************************************
408 /*******************************************************************************
410 ********************************************************************************
413 /*******************************************************************************
415 ********************************************************************************
418 /*******************************************************************************
419 * P U B L I C D A T A
420 ********************************************************************************
423 /*******************************************************************************
424 * P R I V A T E D A T A
425 ********************************************************************************
428 /*******************************************************************************
430 ********************************************************************************
433 /*******************************************************************************
434 * F U N C T I O N D E C L A R A T I O N S
435 ********************************************************************************
438 cnmStaRecHandleEventPkt (
439 P_ADAPTER_T prAdapter,
440 P_CMD_INFO_T prCmdInfo,
445 cnmStaSendUpdateCmd (
446 P_ADAPTER_T prAdapter,
447 P_STA_RECORD_T prStaRec,
452 cnmStaSendRemoveCmd (
453 P_ADAPTER_T prAdapter,
454 P_STA_RECORD_T prStaRec
457 /*******************************************************************************
459 ********************************************************************************
462 /*----------------------------------------------------------------------------*/
470 /*----------------------------------------------------------------------------*/
473 P_ADAPTER_T prAdapter,
477 P_MSDU_INFO_T prMsduInfo;
479 KAL_SPIN_LOCK_DECLARATION();
482 prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList;
484 /* Get a free MSDU_INFO_T */
485 KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
486 QUEUE_REMOVE_HEAD(prQueList, prMsduInfo, P_MSDU_INFO_T);
487 KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
490 prMsduInfo->prPacket = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4Length);
491 prMsduInfo->eSrc = TX_PACKET_MGMT;
493 if (prMsduInfo->prPacket == NULL) {
494 KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
495 QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry);
496 KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
502 if (prMsduInfo == NULL) {
503 DBGLOG(MEM, WARN, ("\n"));
504 DBGLOG(MEM, WARN, ("MgtDesc#=%ld\n", prQueList->u4NumElem));
507 DBGLOG(MEM, WARN, ("rMgtBufInfo: alloc#=%ld, free#=%ld, null#=%ld\n",
508 prAdapter->rMgtBufInfo.u4AllocCount,
509 prAdapter->rMgtBufInfo.u4FreeCount,
510 prAdapter->rMgtBufInfo.u4AllocNullCount));
513 DBGLOG(MEM, WARN, ("\n"));
520 /*----------------------------------------------------------------------------*/
528 /*----------------------------------------------------------------------------*/
531 P_ADAPTER_T prAdapter,
532 P_MSDU_INFO_T prMsduInfo
536 KAL_SPIN_LOCK_DECLARATION();
541 prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList;
543 ASSERT(prMsduInfo->prPacket);
544 if (prMsduInfo->prPacket) {
545 cnmMemFree(prAdapter, prMsduInfo->prPacket);
546 prMsduInfo->prPacket = NULL;
549 KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
550 QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry)
551 KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
554 /*----------------------------------------------------------------------------*/
556 * \brief This function is used to initial the MGMT/MSG memory pool.
562 /*----------------------------------------------------------------------------*/
565 P_ADAPTER_T prAdapter
568 P_BUF_INFO_T prBufInfo;
570 /* Initialize Management buffer pool */
571 prBufInfo = &prAdapter->rMgtBufInfo;
572 kalMemZero(prBufInfo, sizeof(prAdapter->rMgtBufInfo));
573 prBufInfo->pucBuf = prAdapter->pucMgtBufCached;
575 /* Setup available memory blocks. 1 indicates FREE */
576 prBufInfo->rFreeBlocksBitmap =
577 (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1);
580 /* Initialize Message buffer pool */
581 prBufInfo = &prAdapter->rMsgBufInfo;
582 kalMemZero(prBufInfo, sizeof(prAdapter->rMsgBufInfo));
583 prBufInfo->pucBuf = &prAdapter->aucMsgBuf[0];
585 /* Setup available memory blocks. 1 indicates FREE */
586 prBufInfo->rFreeBlocksBitmap =
587 (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1);
591 } /* end of cnmMemInit() */
594 /*----------------------------------------------------------------------------*/
596 * \brief Allocate MGMT/MSG memory pool.
598 * \param[in] eRamType Target RAM type.
599 * TCM blk_sz= 16bytes, BUF blk_sz= 256bytes
600 * \param[in] u4Length Length of the buffer to allocate.
602 * \retval !NULL Pointer to the start address of allocated memory.
603 * \retval NULL Fail to allocat memory
605 /*----------------------------------------------------------------------------*/
608 IN P_ADAPTER_T prAdapter,
609 IN ENUM_RAM_TYPE_T eRamType,
613 P_BUF_INFO_T prBufInfo;
614 BUF_BITMAP rRequiredBitmap;
616 UINT_32 i, u4BlkSzInPower;
618 KAL_SPIN_LOCK_DECLARATION();
623 if (eRamType == RAM_TYPE_MSG && u4Length <= 256) {
624 prBufInfo = &prAdapter->rMsgBufInfo;
625 u4BlkSzInPower = MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2;
627 u4Length += (MSG_BUF_BLOCK_SIZE - 1);
628 u4BlockNum = u4Length >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2;
630 ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS);
633 eRamType = RAM_TYPE_BUF;
635 prBufInfo = &prAdapter->rMgtBufInfo;
636 u4BlkSzInPower = MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2;
638 u4Length += (MGT_BUF_BLOCK_SIZE - 1);
639 u4BlockNum = u4Length >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2;
641 ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS);
645 prBufInfo->u4AllocCount++;
648 KAL_ACQUIRE_SPIN_LOCK(prAdapter,
649 eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
651 if ((u4BlockNum > 0) && (u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS)) {
653 /* Convert number of block into bit cluster */
654 rRequiredBitmap = BITS(0, u4BlockNum-1);
656 for (i = 0; i <= (MAX_NUM_OF_BUF_BLOCKS - u4BlockNum); i++) {
658 /* Have available memory blocks */
659 if ((prBufInfo->rFreeBlocksBitmap & rRequiredBitmap)
660 == rRequiredBitmap) {
662 /* Clear corresponding bits of allocated memory blocks */
663 prBufInfo->rFreeBlocksBitmap &= ~rRequiredBitmap;
665 /* Store how many blocks be allocated */
666 prBufInfo->aucAllocatedBlockNum[i] = (UINT_8) u4BlockNum;
668 KAL_RELEASE_SPIN_LOCK(prAdapter,
669 eRamType == RAM_TYPE_MSG ?
670 SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
672 /* Return the start address of allocated memory */
673 return (PVOID)(prBufInfo->pucBuf + (i << u4BlkSzInPower));
677 rRequiredBitmap <<= 1;
682 pvMemory = (PVOID)kalMemAlloc(u4Length, VIR_MEM_TYPE);
684 pvMemory = (PVOID)NULL;
688 prBufInfo->u4AllocNullCount++;
691 prAdapter->u4MemAllocDynamicCount++;
695 KAL_RELEASE_SPIN_LOCK(prAdapter,
696 eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
700 } /* end of cnmMemAlloc() */
703 /*----------------------------------------------------------------------------*/
705 * \brief Release memory to MGT/MSG memory pool.
707 * \param pucMemory Start address of previous allocated memory
711 /*----------------------------------------------------------------------------*/
714 IN P_ADAPTER_T prAdapter,
718 P_BUF_INFO_T prBufInfo;
719 UINT_32 u4BlockIndex;
720 BUF_BITMAP rAllocatedBlocksBitmap;
721 ENUM_RAM_TYPE_T eRamType;
722 KAL_SPIN_LOCK_DECLARATION();
731 /* Judge it belongs to which RAM type */
732 if ( ((UINT_32)pvMemory >= (UINT_32)&prAdapter->aucMsgBuf[0]) &&
733 ((UINT_32)pvMemory <= (UINT_32)&prAdapter->aucMsgBuf[MSG_BUFFER_SIZE-1])) {
735 prBufInfo = &prAdapter->rMsgBufInfo;
736 u4BlockIndex = ((UINT_32)pvMemory - (UINT_32)prBufInfo->pucBuf)
737 >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2;
738 ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS);
739 eRamType = RAM_TYPE_MSG;
741 else if ( ((UINT_32)pvMemory >= (UINT_32)prAdapter->pucMgtBufCached) &&
742 ((UINT_32)pvMemory <= ((UINT_32)prAdapter->pucMgtBufCached + MGT_BUFFER_SIZE -1))) {
743 prBufInfo = &prAdapter->rMgtBufInfo;
744 u4BlockIndex = ((UINT_32)pvMemory - (UINT_32)prBufInfo->pucBuf)
745 >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2;
746 ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS);
747 eRamType = RAM_TYPE_BUF;
751 /* For Linux, it is supported because size is not needed */
752 kalMemFree(pvMemory, VIR_MEM_TYPE, 0);
754 /* For Windows, it is not supported because of no size argument */
759 prAdapter->u4MemFreeDynamicCount++;
764 KAL_ACQUIRE_SPIN_LOCK(prAdapter,
765 eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
768 prBufInfo->u4FreeCount++;
771 /* Convert number of block into bit cluster */
772 ASSERT(prBufInfo->aucAllocatedBlockNum[u4BlockIndex] > 0);
774 rAllocatedBlocksBitmap =
775 BITS(0, prBufInfo->aucAllocatedBlockNum[u4BlockIndex] - 1);
776 rAllocatedBlocksBitmap <<= u4BlockIndex;
778 /* Clear saved block count for this memory segment */
779 prBufInfo->aucAllocatedBlockNum[u4BlockIndex] = 0;
781 /* Set corresponding bit of released memory block */
782 prBufInfo->rFreeBlocksBitmap |= rAllocatedBlocksBitmap;
784 KAL_RELEASE_SPIN_LOCK(prAdapter,
785 eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
789 } /* end of cnmMemFree() */
792 /*----------------------------------------------------------------------------*/
800 /*----------------------------------------------------------------------------*/
803 P_ADAPTER_T prAdapter
806 P_STA_RECORD_T prStaRec;
809 for (i = 0; i < CFG_STA_REC_NUM; i++) {
810 prStaRec = &prAdapter->arStaRec[i];
812 prStaRec->ucIndex = (UINT_8) i;
813 prStaRec->fgIsInUse = FALSE;
818 /*----------------------------------------------------------------------------*/
826 /*----------------------------------------------------------------------------*/
829 IN P_ADAPTER_T prAdapter
832 P_STA_RECORD_T prStaRec;
835 for (i = 0; i < CFG_STA_REC_NUM; i++) {
836 prStaRec = &prAdapter->arStaRec[i];
838 if (prStaRec->fgIsInUse) {
839 cnmStaRecFree(prAdapter, prStaRec, FALSE);
845 /*----------------------------------------------------------------------------*/
853 /*----------------------------------------------------------------------------*/
856 P_ADAPTER_T prAdapter,
857 UINT_8 ucNetTypeIndex
860 P_STA_RECORD_T prStaRec;
865 for (i = 0; i < CFG_STA_REC_NUM; i++) {
866 prStaRec = &prAdapter->arStaRec[i];
868 if (!prStaRec->fgIsInUse) {
869 /*---- Initialize STA_REC_T here ----*/
870 kalMemZero(prStaRec, sizeof(STA_RECORD_T));
871 prStaRec->ucIndex = (UINT_8) i;
872 prStaRec->ucNetTypeIndex = ucNetTypeIndex;
873 prStaRec->fgIsInUse = TRUE;
875 if (prStaRec->pucAssocReqIe) {
876 kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen);
877 prStaRec->pucAssocReqIe = NULL;
878 prStaRec->u2AssocReqIeLen = 0;
881 /* Initialize the SN caches for duplicate detection */
882 for (k = 0; k < TID_NUM + 1; k++) {
883 prStaRec->au2CachedSeqCtrl[k] = 0xFFFF;
886 /* Initialize SW TX queues in STA_REC */
887 for (k = 0; k < STA_WAIT_QUEUE_NUM; k++) {
888 LINK_INITIALIZE(&prStaRec->arStaWaitQueue[k]);
891 /* Default enable TX/RX AMPDU */
892 prStaRec->fgTxAmpduEn = TRUE;
893 prStaRec->fgRxAmpduEn = TRUE;
895 for (k = 0; k < NUM_OF_PER_STA_TX_QUEUES; k++) {
896 QUEUE_INITIALIZE(&prStaRec->arTxQueue[k]);
903 return (i < CFG_STA_REC_NUM) ? prStaRec : NULL;
907 /*----------------------------------------------------------------------------*/
915 /*----------------------------------------------------------------------------*/
918 P_ADAPTER_T prAdapter,
919 P_STA_RECORD_T prStaRec,
926 /* To do: free related resources, e.g. timers, buffers, etc */
927 cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
928 prStaRec->fgTransmitKeyExist = FALSE;
929 prStaRec->fgSetPwrMgtBit = FALSE;
931 if (prStaRec->pucAssocReqIe) {
932 kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen);
933 prStaRec->pucAssocReqIe = NULL;
934 prStaRec->u2AssocReqIeLen = 0;
937 qmDeactivateStaRec(prAdapter, prStaRec->ucIndex);
940 cnmStaSendRemoveCmd(prAdapter, prStaRec);
943 prStaRec->fgIsInUse = FALSE;
948 /*----------------------------------------------------------------------------*/
956 /*----------------------------------------------------------------------------*/
958 cnmStaFreeAllStaByNetType (
959 P_ADAPTER_T prAdapter,
960 ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
964 P_STA_RECORD_T prStaRec;
967 for (i = 0; i < CFG_STA_REC_NUM; i++) {
968 prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i];
970 if (prStaRec->fgIsInUse &&
971 prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex) {
973 cnmStaRecFree(prAdapter, prStaRec, fgSyncToChip);
975 } /* end of for loop */
978 /*----------------------------------------------------------------------------*/
986 /*----------------------------------------------------------------------------*/
988 cnmGetStaRecByIndex (
989 P_ADAPTER_T prAdapter,
993 P_STA_RECORD_T prStaRec;
997 prStaRec = (ucIndex < CFG_STA_REC_NUM) ?
998 &prAdapter->arStaRec[ucIndex] : NULL;
1000 if (prStaRec && prStaRec->fgIsInUse == FALSE) {
1007 /*----------------------------------------------------------------------------*/
1009 * @brief Get STA_RECORD_T by Peer MAC Address(Usually TA).
1011 * @param[in] pucPeerMacAddr Given Peer MAC Address.
1013 * @retval Pointer to STA_RECORD_T, if found. NULL, if not found
1015 /*----------------------------------------------------------------------------*/
1017 cnmGetStaRecByAddress (
1018 P_ADAPTER_T prAdapter,
1019 UINT_8 ucNetTypeIndex,
1020 PUINT_8 pucPeerMacAddr
1023 P_STA_RECORD_T prStaRec;
1027 ASSERT(pucPeerMacAddr);
1029 for (i = 0; i < CFG_STA_REC_NUM; i++) {
1030 prStaRec = &prAdapter->arStaRec[i];
1032 if (prStaRec->fgIsInUse &&
1033 prStaRec->ucNetTypeIndex == ucNetTypeIndex &&
1034 EQUAL_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMacAddr)) {
1039 return (i < CFG_STA_REC_NUM) ? prStaRec : NULL;
1042 /*----------------------------------------------------------------------------*/
1044 * @brief Reset the Status and Reason Code Field to 0 of all Station Records for
1045 * the specified Network Type
1047 * @param[in] eNetType Specify Network Type
1051 /*----------------------------------------------------------------------------*/
1053 cnmStaRecResetStatus (
1054 P_ADAPTER_T prAdapter,
1055 ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex
1058 cnmStaFreeAllStaByNetType(prAdapter, eNetTypeIndex, FALSE);
1061 P_STA_RECORD_T prStaRec;
1066 for (i = 0; i < CFG_STA_REC_NUM; i++) {
1067 prStaRec = &prAdapter->arStaRec[i];
1069 if (prStaRec->fgIsInUse) {
1070 if ((NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) &&
1071 IS_STA_IN_AIS(prStaRec->eStaType)) {
1073 prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL;
1074 prStaRec->u2ReasonCode = REASON_CODE_RESERVED;
1075 prStaRec->ucJoinFailureCount = 0;
1076 prStaRec->fgTransmitKeyExist = FALSE;
1078 prStaRec->fgSetPwrMgtBit = FALSE;
1081 /* TODO(Kevin): For P2P and BOW */
1089 /*----------------------------------------------------------------------------*/
1091 * @brief This function will change the ucStaState of STA_RECORD_T and also do
1092 * event indication to HOST to sync the STA_RECORD_T in driver.
1094 * @param[in] prStaRec Pointer to the STA_RECORD_T
1095 * @param[in] u4NewState New STATE to change.
1099 /*----------------------------------------------------------------------------*/
1101 cnmStaRecChangeState (
1102 P_ADAPTER_T prAdapter,
1103 P_STA_RECORD_T prStaRec,
1111 ASSERT(prStaRec->fgIsInUse);
1113 /* Do nothing when following state transitions happen,
1114 * other 6 conditions should be sync to FW, including 1-->1, 3-->3
1116 if ((ucNewState == STA_STATE_2 && prStaRec->ucStaState != STA_STATE_3) ||
1117 (ucNewState == STA_STATE_1 && prStaRec->ucStaState == STA_STATE_2)) {
1118 prStaRec->ucStaState = ucNewState;
1123 if (ucNewState == STA_STATE_3) {
1124 secFsmEventStart(prAdapter, prStaRec);
1125 if (ucNewState != prStaRec->ucStaState) {
1130 if (ucNewState != prStaRec->ucStaState &&
1131 prStaRec->ucStaState == STA_STATE_3) {
1132 qmDeactivateStaRec(prAdapter, prStaRec->ucIndex);
1136 prStaRec->ucStaState = ucNewState;
1138 cnmStaSendUpdateCmd(prAdapter, prStaRec, fgNeedResp);
1140 #if CFG_ENABLE_WIFI_DIRECT
1141 /* To do: Confirm if it is invoked here or other location, but it should
1142 * be invoked after state sync of STA_REC
1143 * Update system operation parameters for AP mode
1145 if (prAdapter->fgIsP2PRegistered && (IS_STA_IN_P2P(prStaRec))) {
1146 P_BSS_INFO_T prBssInfo;
1148 prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
1150 if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
1151 if(prAdapter->rP2pFuncLkr.prRlmUpdateParamsForAp) {
1152 prAdapter->rP2pFuncLkr.prRlmUpdateParamsForAp(prAdapter, prBssInfo, FALSE);
1162 /*----------------------------------------------------------------------------*/
1170 /*----------------------------------------------------------------------------*/
1172 cnmStaRecHandleEventPkt (
1173 P_ADAPTER_T prAdapter,
1174 P_CMD_INFO_T prCmdInfo,
1178 P_EVENT_ACTIVATE_STA_REC_T prEventContent;
1179 P_STA_RECORD_T prStaRec;
1181 prEventContent = (P_EVENT_ACTIVATE_STA_REC_T) pucEventBuf;
1182 prStaRec = cnmGetStaRecByIndex(prAdapter, prEventContent->ucStaRecIdx);
1184 if (prStaRec && prStaRec->ucStaState == STA_STATE_3 &&
1185 !kalMemCmp(&prStaRec->aucMacAddr[0], &prEventContent->aucMacAddr[0],
1188 qmActivateStaRec(prAdapter, prStaRec);
1193 /*----------------------------------------------------------------------------*/
1201 /*----------------------------------------------------------------------------*/
1203 cnmStaSendUpdateCmd (
1204 P_ADAPTER_T prAdapter,
1205 P_STA_RECORD_T prStaRec,
1209 P_CMD_UPDATE_STA_RECORD_T prCmdContent;
1210 WLAN_STATUS rStatus;
1214 ASSERT(prStaRec->fgIsInUse);
1216 /* To do: come out a mechanism to limit one STA_REC sync once for AP mode
1217 * to avoid buffer empty case when many STAs are associated
1221 /* To do: how to avoid 2 times of allocated memory. Use Stack?
1222 * One is here, the other is in wlanSendQueryCmd()
1224 prCmdContent = cnmMemAlloc(prAdapter,
1225 RAM_TYPE_BUF, sizeof(CMD_UPDATE_STA_RECORD_T));
1226 ASSERT(prCmdContent);
1228 /* To do: exception handle */
1229 if (!prCmdContent) {
1233 prCmdContent->ucIndex = prStaRec->ucIndex;
1234 prCmdContent->ucStaType = (UINT_8) prStaRec->eStaType;
1235 kalMemCopy(&prCmdContent->aucMacAddr[0], &prStaRec->aucMacAddr[0],
1237 prCmdContent->u2AssocId = prStaRec->u2AssocId;
1238 prCmdContent->u2ListenInterval = prStaRec->u2ListenInterval;
1239 prCmdContent->ucNetTypeIndex = prStaRec->ucNetTypeIndex;
1241 prCmdContent->ucDesiredPhyTypeSet = prStaRec->ucDesiredPhyTypeSet;
1242 prCmdContent->u2DesiredNonHTRateSet = prStaRec->u2DesiredNonHTRateSet;
1243 prCmdContent->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet;
1244 prCmdContent->ucMcsSet = prStaRec->ucMcsSet;
1245 prCmdContent->ucSupMcs32 = (UINT_8) prStaRec->fgSupMcs32;
1246 prCmdContent->u2HtCapInfo = prStaRec->u2HtCapInfo;
1247 prCmdContent->ucNeedResp = (UINT_8) fgNeedResp;
1249 #if !CFG_SLT_SUPPORT
1250 if(prAdapter->rWifiVar.eRateSetting != FIXED_RATE_NONE) {
1251 /* override rate configuration */
1252 nicUpdateRateParams(prAdapter,
1253 prAdapter->rWifiVar.eRateSetting,
1254 &(prCmdContent->ucDesiredPhyTypeSet),
1255 &(prCmdContent->u2DesiredNonHTRateSet),
1256 &(prCmdContent->u2BSSBasicRateSet),
1257 &(prCmdContent->ucMcsSet),
1258 &(prCmdContent->ucSupMcs32),
1259 &(prCmdContent->u2HtCapInfo));
1263 prCmdContent->ucIsQoS = prStaRec->fgIsQoS;
1264 prCmdContent->ucIsUapsdSupported = prStaRec->fgIsUapsdSupported;
1265 prCmdContent->ucStaState = prStaRec->ucStaState;
1267 prCmdContent->ucAmpduParam = prStaRec->ucAmpduParam;
1268 prCmdContent->u2HtExtendedCap = prStaRec->u2HtExtendedCap;
1269 prCmdContent->u4TxBeamformingCap = prStaRec->u4TxBeamformingCap;
1270 prCmdContent->ucAselCap = prStaRec->ucAselCap;
1271 prCmdContent->ucRCPI = prStaRec->ucRCPI;
1273 prCmdContent->ucUapsdAc = prStaRec->ucBmpTriggerAC | (prStaRec->ucBmpDeliveryAC << 4);
1274 prCmdContent->ucUapsdSp = prStaRec->ucUapsdSp;
1276 DBGLOG(REQ, TRACE, ("STA "MACSTR" type=%d state = %d\n", MAC2STR(prStaRec->aucMacAddr), prStaRec->eStaType, prStaRec->ucStaState));
1278 rStatus = wlanSendSetQueryCmd (
1279 prAdapter, /* prAdapter */
1280 CMD_ID_UPDATE_STA_RECORD, /* ucCID */
1281 TRUE, /* fgSetQuery */
1282 fgNeedResp, /* fgNeedResp */
1283 FALSE, /* fgIsOid */
1284 fgNeedResp? cnmStaRecHandleEventPkt : NULL,
1285 NULL, /* pfCmdTimeoutHandler */
1286 sizeof(CMD_UPDATE_STA_RECORD_T), /* u4SetQueryInfoLen */
1287 (PUINT_8) prCmdContent, /* pucInfoBuffer */
1288 NULL, /* pvSetQueryBuffer */
1289 0 /* u4SetQueryBufferLen */
1292 ASSERT(rStatus == WLAN_STATUS_PENDING);
1294 cnmMemFree(prAdapter, prCmdContent);
1297 /*----------------------------------------------------------------------------*/
1305 /*----------------------------------------------------------------------------*/
1307 cnmStaSendRemoveCmd (
1308 P_ADAPTER_T prAdapter,
1309 P_STA_RECORD_T prStaRec
1312 CMD_REMOVE_STA_RECORD_T rCmdContent;
1313 WLAN_STATUS rStatus;
1318 rCmdContent.ucIndex = prStaRec->ucIndex;
1319 kalMemCopy(&rCmdContent.aucMacAddr[0], &prStaRec->aucMacAddr[0],
1322 rStatus = wlanSendSetQueryCmd (
1323 prAdapter, /* prAdapter */
1324 CMD_ID_REMOVE_STA_RECORD, /* ucCID */
1325 TRUE, /* fgSetQuery */
1326 FALSE, /* fgNeedResp */
1327 FALSE, /* fgIsOid */
1328 NULL, /* pfCmdDoneHandler */
1329 NULL, /* pfCmdTimeoutHandler */
1330 sizeof(CMD_REMOVE_STA_RECORD_T), /* u4SetQueryInfoLen */
1331 (PUINT_8) &rCmdContent, /* pucInfoBuffer */
1332 NULL, /* pvSetQueryBuffer */
1333 0 /* u4SetQueryBufferLen */
1336 ASSERT(rStatus == WLAN_STATUS_PENDING);