2 ** $Id: //Department/DaVinci/BRANCHES/MT662X_593X_WIFI_DRIVER_V2_3/mgmt/cnm_mem.c#1 $
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 ********************************************************************************
58 * 07 17 2012 yuche.tsai
60 * Compile no error before trial run.
63 * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting
66 * 11 17 2011 tsaiyuan.hsu
67 * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3.
68 * initialize fgNeedResp.
70 * 11 17 2011 tsaiyuan.hsu
71 * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3.
72 * avoid deactivating staRec when changing state from 3 to 3.
75 * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode
79 * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
80 * Allocate system RAM if fixed message or mgmt buffer is not available
83 * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
86 * 01 25 2011 yuche.tsai
87 * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
88 * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role.
91 * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver
92 * create branch for Wi-Fi driver v1.1
95 * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
96 * 1. BSSINFO include RLM parameter
97 * 2. free all sta records when network is disconnected
100 * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for initial TX rate selection of auto-rate algorithm
101 * Sync RCPI of STA_REC to FW as reference of initial TX rate
103 * 11 25 2010 yuche.tsai
105 * Update SLT Function for QoS Support and not be affected by fixed rate function.
108 * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS associated
109 * 1. remove redundant variables in STA_REC structure
110 * 2. add STA-REC uninitialization routine for clearing pending events
112 * 10 13 2010 cm.chang
113 * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash.
114 * Add exception handle when cmd buffer is not available
117 * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
118 * add HT (802.11n) fixed rate support.
121 * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
122 * adding fixed rate support for distance test. (from registry setting)
126 * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning.
129 * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS associated
130 * Do a complete reset with STA-REC null checking for RF test re-entry
132 * 09 16 2010 cm.chang
134 * Change conditional compiling options for BOW
136 * 09 10 2010 cm.chang
138 * Always update Beacon content if FW sync OBSS info
140 * 08 24 2010 cm.chang
142 * Support RLM initail channel of Ad-hoc, P2P and BOW
144 * 08 23 2010 chinghwa.yu
148 * 08 20 2010 cm.chang
150 * Migrate RLM code to host from FW
154 * adding the tx pkt call back handle for countermeasure.
158 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
160 * 07 08 2010 cm.chang
161 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
162 * Check draft RLM code for HT cap
164 * 07 07 2010 cm.chang
165 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
166 * Support state of STA record change from 1 to 1
168 * 07 05 2010 cm.chang
169 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
170 * Fix correct structure size in cnmStaSendDeactivateCmd()
173 * [WPD00003833][MT6620 and MT5931] Driver migration
174 * 1) ignore RSN checking when RSN is not turned on.
175 * 2) set STA-REC deactivation callback as NULL
176 * 3) add variable initialization API based on PHY configuration
179 * [WPD00003833][MT6620 and MT5931] Driver migration
180 * spin lock target revised
183 * [WPD00003833][MT6620 and MT5931] Driver migration
184 * change inner loop index from i to k.
186 * 07 01 2010 cm.chang
187 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
188 * Support sync command of STA_REC
190 * 06 23 2010 yarco.yang
191 * [WPD00003837][MT6620]Data Path Refine
192 * Merge g_arStaRec[] into adapter->arStaRec[]
194 * 06 18 2010 cm.chang
195 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
196 * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
198 * 05 31 2010 yarco.yang
199 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
200 * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling
202 * 05 28 2010 cm.chang
203 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
204 * Support checking of duplicated buffer free
207 * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing
208 * fixed the ad-hoc wpa-none send non-encrypted frame issue.
210 * 05 28 2010 kevin.huang
211 * [BORA00000794][WIFISYS][New Feature]Power Management Support
212 * Move define of STA_REC_NUM to config.h and rename to CFG_STA_REC_NUM
214 * 05 12 2010 kevin.huang
215 * [BORA00000794][WIFISYS][New Feature]Power Management Support
216 * Add Power Management - Legacy PS-POLL support.
218 * 04 28 2010 tehuang.liu
219 * [BORA00000605][WIFISYS] Phase3 Integration
220 * Modified some MQM-related data structures (SN counter, TX/RX BA table)
222 * 04 27 2010 tehuang.liu
223 * [BORA00000605][WIFISYS] Phase3 Integration
224 * Added new TX/RX BA tables in STA_REC
226 * 04 27 2010 tehuang.liu
227 * [BORA00000605][WIFISYS] Phase3 Integration
228 * Notify MQM, TXM, and RXM upon disconnection .
230 * 04 26 2010 tehuang.liu
231 * [BORA00000605][WIFISYS] Phase3 Integration
232 * Call mqm, txm, rxm functions upon disconnection
234 * 04 24 2010 cm.chang
235 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
236 * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
238 * 04 22 2010 cm.chang
239 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
240 * First draft code to support protection in AP mode
242 * 04 19 2010 kevin.huang
243 * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
244 * Add Beacon Timeout Support
245 * * * * * * * * * * and will send Null frame to diagnose connection
247 * 04 09 2010 tehuang.liu
248 * [BORA00000605][WIFISYS] Phase3 Integration
249 * [BORA00000644] WiFi phase 4 integration
250 * * Added per-TID SN cache in STA_REC
252 * 04 07 2010 cm.chang
253 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
254 * Different invoking order for WTBL entry of associated AP
257 * [BORA00000605][WIFISYS] Phase3 Integration
258 * move the wlan table alloc / free to change state function.
260 * 03 24 2010 cm.chang
261 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
262 * Support power control
264 * 03 03 2010 tehuang.liu
265 * [BORA00000569][WIFISYS] Phase 2 Integration Test
266 * Initialize StaRec->arStaWaitQueue
268 * 03 03 2010 cm.chang
269 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
270 * Add debug message when no available pkt buffer
272 * 03 01 2010 tehuang.liu
273 * [BORA00000569][WIFISYS] Phase 2 Integration Test
274 * Fixed STA_REC initialization bug: prStaRec->au2CachedSeqCtrl[k]
276 * 02 26 2010 tehuang.liu
277 * [BORA00000569][WIFISYS] Phase 2 Integration Test
278 * Added fgIsWmmSupported in STA_RECORD_T.
280 * 02 26 2010 tehuang.liu
281 * [BORA00000569][WIFISYS] Phase 2 Integration Test
282 * Added fgIsUapsdSupported in STA_RECORD_T
284 * 02 26 2010 kevin.huang
285 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
286 * add support of Driver STA_RECORD_T activation
288 * 02 13 2010 tehuang.liu
289 * [BORA00000569][WIFISYS] Phase 2 Integration Test
290 * Added arTspecTable in STA_REC for TSPEC management
292 * 02 12 2010 cm.chang
293 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
294 * Enable mgmt buffer debug by default
296 * 02 12 2010 tehuang.liu
297 * [BORA00000569][WIFISYS] Phase 2 Integration Test
298 * Added BUFFER_SOURCE_BCN
300 * 02 04 2010 kevin.huang
301 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
302 * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
304 * 01 11 2010 kevin.huang
305 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
306 * Add Deauth and Disassoc Handler
309 * [BORA00000368]Integrate HIF part into BORA
310 * 1) separate wifi_var_emu.c/.h from wifi_var.c/.h
311 * * * * * * * * * 2) eliminate HIF_EMULATION code sections appeared in wifi_var/cnm_mem
312 * * * * * * * * * 3) use cnmMemAlloc() instead to allocate SRAM buffer
314 * 12 25 2009 tehuang.liu
315 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
316 * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM)
317 * * * * * * * MQM: BA handling
318 * * * * * * * TXM: Macros updates
319 * * * * * * * RXM: Macros/Duplicate Removal updates
321 * 12 24 2009 yarco.yang
322 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
325 * 12 21 2009 cm.chang
326 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
327 * Support several data buffer banks.
329 * 12 18 2009 cm.chang
330 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
331 * .For new FPGA memory size
333 * Dec 9 2009 MTK02468
334 * [BORA00000337] To check in codes for FPGA emulation
337 * Dec 9 2009 mtk02752
338 * [BORA00000368] Integrate HIF part into BORA
339 * add cnmDataPktFree() for emulation loopback purpose
341 * Dec 3 2009 mtk01461
342 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
343 * Fix warning of null pointer
345 * Dec 3 2009 mtk01461
346 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
347 * Add cnmGetStaRecByAddress() and add fgIsInUse flag in STA_RECORD_T
349 * Nov 23 2009 mtk01104
350 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
351 * Assign ucBufferSource in function cnmMgtPktAlloc()
353 * Nov 23 2009 mtk02468
354 * [BORA00000337] To check in codes for FPGA emulation
355 * Added packet redispatch function calls
357 * Nov 13 2009 mtk01084
358 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
359 * enable packet re-usable in current emulation driver
361 * Nov 12 2009 mtk01104
362 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
363 * 1. Add new function cnmGetStaRecByIndex()
364 * 2. Rename STA_REC_T to STA_RECORD_T
366 * Nov 9 2009 mtk01104
367 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
368 * Call cnmDataPktDispatch() in cnmPktFree()
370 * Nov 2 2009 mtk01104
371 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
372 * Remove definition of pragma section code
374 * Oct 28 2009 mtk01104
375 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
378 * Oct 23 2009 mtk01461
379 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
382 * Oct 23 2009 mtk01461
383 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
386 * Oct 12 2009 mtk01104
387 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
390 * Oct 8 2009 mtk01104
391 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
396 /*******************************************************************************
397 * C O M P I L E R F L A G S
398 ********************************************************************************
401 /*******************************************************************************
402 * E X T E R N A L R E F E R E N C E S
403 ********************************************************************************
407 /*******************************************************************************
409 ********************************************************************************
412 /*******************************************************************************
414 ********************************************************************************
417 /*******************************************************************************
418 * P U B L I C D A T A
419 ********************************************************************************
422 /*******************************************************************************
423 * P R I V A T E D A T A
424 ********************************************************************************
427 /*******************************************************************************
429 ********************************************************************************
432 /*******************************************************************************
433 * F U N C T I O N D E C L A R A T I O N S
434 ********************************************************************************
437 cnmStaRecHandleEventPkt (
438 P_ADAPTER_T prAdapter,
439 P_CMD_INFO_T prCmdInfo,
444 cnmStaSendUpdateCmd (
445 P_ADAPTER_T prAdapter,
446 P_STA_RECORD_T prStaRec,
451 cnmStaSendRemoveCmd (
452 P_ADAPTER_T prAdapter,
453 P_STA_RECORD_T prStaRec
456 /*******************************************************************************
458 ********************************************************************************
461 /*----------------------------------------------------------------------------*/
469 /*----------------------------------------------------------------------------*/
472 P_ADAPTER_T prAdapter,
476 P_MSDU_INFO_T prMsduInfo;
478 KAL_SPIN_LOCK_DECLARATION();
481 prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList;
483 /* Get a free MSDU_INFO_T */
484 KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
485 QUEUE_REMOVE_HEAD(prQueList, prMsduInfo, P_MSDU_INFO_T);
486 KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
489 prMsduInfo->prPacket = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4Length);
490 prMsduInfo->eSrc = TX_PACKET_MGMT;
492 if (prMsduInfo->prPacket == NULL) {
493 KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
494 QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry);
495 KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
501 if (prMsduInfo == NULL) {
502 DBGLOG(MEM, WARN, ("\n"));
503 DBGLOG(MEM, WARN, ("MgtDesc#=%ld\n", prQueList->u4NumElem));
506 DBGLOG(MEM, WARN, ("rMgtBufInfo: alloc#=%ld, free#=%ld, null#=%ld\n",
507 prAdapter->rMgtBufInfo.u4AllocCount,
508 prAdapter->rMgtBufInfo.u4FreeCount,
509 prAdapter->rMgtBufInfo.u4AllocNullCount));
512 DBGLOG(MEM, WARN, ("\n"));
519 /*----------------------------------------------------------------------------*/
527 /*----------------------------------------------------------------------------*/
530 P_ADAPTER_T prAdapter,
531 P_MSDU_INFO_T prMsduInfo
535 KAL_SPIN_LOCK_DECLARATION();
540 prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList;
542 ASSERT(prMsduInfo->prPacket);
543 if (prMsduInfo->prPacket) {
544 cnmMemFree(prAdapter, prMsduInfo->prPacket);
545 prMsduInfo->prPacket = NULL;
548 KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
549 QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry)
550 KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
553 /*----------------------------------------------------------------------------*/
555 * \brief This function is used to initial the MGMT/MSG memory pool.
561 /*----------------------------------------------------------------------------*/
564 P_ADAPTER_T prAdapter
567 P_BUF_INFO_T prBufInfo;
569 /* Initialize Management buffer pool */
570 prBufInfo = &prAdapter->rMgtBufInfo;
571 kalMemZero(prBufInfo, sizeof(prAdapter->rMgtBufInfo));
572 prBufInfo->pucBuf = prAdapter->pucMgtBufCached;
574 /* Setup available memory blocks. 1 indicates FREE */
575 prBufInfo->rFreeBlocksBitmap =
576 (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1);
579 /* Initialize Message buffer pool */
580 prBufInfo = &prAdapter->rMsgBufInfo;
581 kalMemZero(prBufInfo, sizeof(prAdapter->rMsgBufInfo));
582 prBufInfo->pucBuf = &prAdapter->aucMsgBuf[0];
584 /* Setup available memory blocks. 1 indicates FREE */
585 prBufInfo->rFreeBlocksBitmap =
586 (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1);
590 } /* end of cnmMemInit() */
593 /*----------------------------------------------------------------------------*/
595 * \brief Allocate MGMT/MSG memory pool.
597 * \param[in] eRamType Target RAM type.
598 * TCM blk_sz= 16bytes, BUF blk_sz= 256bytes
599 * \param[in] u4Length Length of the buffer to allocate.
601 * \retval !NULL Pointer to the start address of allocated memory.
602 * \retval NULL Fail to allocat memory
604 /*----------------------------------------------------------------------------*/
607 IN P_ADAPTER_T prAdapter,
608 IN ENUM_RAM_TYPE_T eRamType,
612 P_BUF_INFO_T prBufInfo;
613 BUF_BITMAP rRequiredBitmap;
615 UINT_32 i, u4BlkSzInPower;
617 KAL_SPIN_LOCK_DECLARATION();
622 if (eRamType == RAM_TYPE_MSG && u4Length <= 256) {
623 prBufInfo = &prAdapter->rMsgBufInfo;
624 u4BlkSzInPower = MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2;
626 u4Length += (MSG_BUF_BLOCK_SIZE - 1);
627 u4BlockNum = u4Length >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2;
629 ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS);
632 eRamType = RAM_TYPE_BUF;
634 prBufInfo = &prAdapter->rMgtBufInfo;
635 u4BlkSzInPower = MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2;
637 u4Length += (MGT_BUF_BLOCK_SIZE - 1);
638 u4BlockNum = u4Length >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2;
640 ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS);
644 prBufInfo->u4AllocCount++;
647 KAL_ACQUIRE_SPIN_LOCK(prAdapter,
648 eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
650 if ((u4BlockNum > 0) && (u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS)) {
652 /* Convert number of block into bit cluster */
653 rRequiredBitmap = BITS(0, u4BlockNum-1);
655 for (i = 0; i <= (MAX_NUM_OF_BUF_BLOCKS - u4BlockNum); i++) {
657 /* Have available memory blocks */
658 if ((prBufInfo->rFreeBlocksBitmap & rRequiredBitmap)
659 == rRequiredBitmap) {
661 /* Clear corresponding bits of allocated memory blocks */
662 prBufInfo->rFreeBlocksBitmap &= ~rRequiredBitmap;
664 /* Store how many blocks be allocated */
665 prBufInfo->aucAllocatedBlockNum[i] = (UINT_8) u4BlockNum;
667 KAL_RELEASE_SPIN_LOCK(prAdapter,
668 eRamType == RAM_TYPE_MSG ?
669 SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
671 /* Return the start address of allocated memory */
672 return (PVOID)(prBufInfo->pucBuf + (i << u4BlkSzInPower));
676 rRequiredBitmap <<= 1;
680 KAL_RELEASE_SPIN_LOCK(prAdapter,
681 eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
684 pvMemory = (PVOID)kalMemAlloc(u4Length, VIR_MEM_TYPE);
686 pvMemory = (PVOID)NULL;
689 KAL_ACQUIRE_SPIN_LOCK(prAdapter,
690 eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
693 prBufInfo->u4AllocNullCount++;
696 prAdapter->u4MemAllocDynamicCount++;
699 KAL_RELEASE_SPIN_LOCK(prAdapter,
700 eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
704 } /* end of cnmMemAlloc() */
707 /*----------------------------------------------------------------------------*/
709 * \brief Release memory to MGT/MSG memory pool.
711 * \param pucMemory Start address of previous allocated memory
715 /*----------------------------------------------------------------------------*/
718 IN P_ADAPTER_T prAdapter,
722 P_BUF_INFO_T prBufInfo;
723 UINT_32 u4BlockIndex;
724 BUF_BITMAP rAllocatedBlocksBitmap;
725 ENUM_RAM_TYPE_T eRamType;
726 KAL_SPIN_LOCK_DECLARATION();
735 /* Judge it belongs to which RAM type */
736 if ( ((UINT_32)pvMemory >= (UINT_32)&prAdapter->aucMsgBuf[0]) &&
737 ((UINT_32)pvMemory <= (UINT_32)&prAdapter->aucMsgBuf[MSG_BUFFER_SIZE-1])) {
739 prBufInfo = &prAdapter->rMsgBufInfo;
740 u4BlockIndex = ((UINT_32)pvMemory - (UINT_32)prBufInfo->pucBuf)
741 >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2;
742 ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS);
743 eRamType = RAM_TYPE_MSG;
745 else if ( ((UINT_32)pvMemory >= (UINT_32)prAdapter->pucMgtBufCached) &&
746 ((UINT_32)pvMemory <= ((UINT_32)prAdapter->pucMgtBufCached + MGT_BUFFER_SIZE -1))) {
747 prBufInfo = &prAdapter->rMgtBufInfo;
748 u4BlockIndex = ((UINT_32)pvMemory - (UINT_32)prBufInfo->pucBuf)
749 >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2;
750 ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS);
751 eRamType = RAM_TYPE_BUF;
755 /* For Linux, it is supported because size is not needed */
756 kalMemFree(pvMemory, VIR_MEM_TYPE, 0);
758 /* For Windows, it is not supported because of no size argument */
763 prAdapter->u4MemFreeDynamicCount++;
768 KAL_ACQUIRE_SPIN_LOCK(prAdapter,
769 eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
772 prBufInfo->u4FreeCount++;
775 /* Convert number of block into bit cluster */
776 ASSERT(prBufInfo->aucAllocatedBlockNum[u4BlockIndex] > 0);
778 rAllocatedBlocksBitmap =
779 BITS(0, prBufInfo->aucAllocatedBlockNum[u4BlockIndex] - 1);
780 rAllocatedBlocksBitmap <<= u4BlockIndex;
782 /* Clear saved block count for this memory segment */
783 prBufInfo->aucAllocatedBlockNum[u4BlockIndex] = 0;
785 /* Set corresponding bit of released memory block */
786 prBufInfo->rFreeBlocksBitmap |= rAllocatedBlocksBitmap;
788 KAL_RELEASE_SPIN_LOCK(prAdapter,
789 eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
793 } /* end of cnmMemFree() */
796 /*----------------------------------------------------------------------------*/
804 /*----------------------------------------------------------------------------*/
807 P_ADAPTER_T prAdapter
810 P_STA_RECORD_T prStaRec;
813 for (i = 0; i < CFG_STA_REC_NUM; i++) {
814 prStaRec = &prAdapter->arStaRec[i];
816 prStaRec->ucIndex = (UINT_8) i;
817 prStaRec->fgIsInUse = FALSE;
822 /*----------------------------------------------------------------------------*/
830 /*----------------------------------------------------------------------------*/
833 IN P_ADAPTER_T prAdapter
836 P_STA_RECORD_T prStaRec;
839 for (i = 0; i < CFG_STA_REC_NUM; i++) {
840 prStaRec = &prAdapter->arStaRec[i];
842 if (prStaRec->fgIsInUse) {
843 cnmStaRecFree(prAdapter, prStaRec, FALSE);
849 /*----------------------------------------------------------------------------*/
857 /*----------------------------------------------------------------------------*/
860 P_ADAPTER_T prAdapter,
861 UINT_8 ucNetTypeIndex
864 P_STA_RECORD_T prStaRec;
869 for (i = 0; i < CFG_STA_REC_NUM; i++) {
870 prStaRec = &prAdapter->arStaRec[i];
872 if (!prStaRec->fgIsInUse) {
873 /*---- Initialize STA_REC_T here ----*/
874 kalMemZero(prStaRec, sizeof(STA_RECORD_T));
875 prStaRec->ucIndex = (UINT_8) i;
876 prStaRec->ucNetTypeIndex = ucNetTypeIndex;
877 prStaRec->fgIsInUse = TRUE;
879 if (prStaRec->pucAssocReqIe) {
880 kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen);
881 prStaRec->pucAssocReqIe = NULL;
882 prStaRec->u2AssocReqIeLen = 0;
885 /* Initialize the SN caches for duplicate detection */
886 for (k = 0; k < TID_NUM + 1; k++) {
887 prStaRec->au2CachedSeqCtrl[k] = 0xFFFF;
890 /* Initialize SW TX queues in STA_REC */
891 for (k = 0; k < STA_WAIT_QUEUE_NUM; k++) {
892 LINK_INITIALIZE(&prStaRec->arStaWaitQueue[k]);
895 /* Default enable TX/RX AMPDU */
896 prStaRec->fgTxAmpduEn = TRUE;
897 prStaRec->fgRxAmpduEn = TRUE;
899 for (k = 0; k < NUM_OF_PER_STA_TX_QUEUES; k++) {
900 QUEUE_INITIALIZE(&prStaRec->arTxQueue[k]);
907 return (i < CFG_STA_REC_NUM) ? prStaRec : NULL;
911 /*----------------------------------------------------------------------------*/
919 /*----------------------------------------------------------------------------*/
922 P_ADAPTER_T prAdapter,
923 P_STA_RECORD_T prStaRec,
930 /* To do: free related resources, e.g. timers, buffers, etc */
931 cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
932 prStaRec->fgTransmitKeyExist = FALSE;
933 prStaRec->fgSetPwrMgtBit = FALSE;
935 if (prStaRec->pucAssocReqIe) {
936 kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen);
937 prStaRec->pucAssocReqIe = NULL;
938 prStaRec->u2AssocReqIeLen = 0;
941 qmDeactivateStaRec(prAdapter, prStaRec->ucIndex);
944 cnmStaSendRemoveCmd(prAdapter, prStaRec);
947 prStaRec->fgIsInUse = FALSE;
952 /*----------------------------------------------------------------------------*/
960 /*----------------------------------------------------------------------------*/
962 cnmStaFreeAllStaByNetType (
963 P_ADAPTER_T prAdapter,
964 ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
968 P_STA_RECORD_T prStaRec;
971 for (i = 0; i < CFG_STA_REC_NUM; i++) {
972 prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i];
974 if (prStaRec->fgIsInUse &&
975 prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex) {
977 cnmStaRecFree(prAdapter, prStaRec, fgSyncToChip);
979 } /* end of for loop */
982 /*----------------------------------------------------------------------------*/
990 /*----------------------------------------------------------------------------*/
992 cnmGetStaRecByIndex (
993 P_ADAPTER_T prAdapter,
997 P_STA_RECORD_T prStaRec;
1001 prStaRec = (ucIndex < CFG_STA_REC_NUM) ?
1002 &prAdapter->arStaRec[ucIndex] : NULL;
1004 if (prStaRec && prStaRec->fgIsInUse == FALSE) {
1011 /*----------------------------------------------------------------------------*/
1013 * @brief Get STA_RECORD_T by Peer MAC Address(Usually TA).
1015 * @param[in] pucPeerMacAddr Given Peer MAC Address.
1017 * @retval Pointer to STA_RECORD_T, if found. NULL, if not found
1019 /*----------------------------------------------------------------------------*/
1021 cnmGetStaRecByAddress (
1022 P_ADAPTER_T prAdapter,
1023 UINT_8 ucNetTypeIndex,
1024 PUINT_8 pucPeerMacAddr
1027 P_STA_RECORD_T prStaRec;
1031 ASSERT(pucPeerMacAddr);
1033 for (i = 0; i < CFG_STA_REC_NUM; i++) {
1034 prStaRec = &prAdapter->arStaRec[i];
1036 if (prStaRec->fgIsInUse &&
1037 prStaRec->ucNetTypeIndex == ucNetTypeIndex &&
1038 EQUAL_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMacAddr)) {
1043 return (i < CFG_STA_REC_NUM) ? prStaRec : NULL;
1046 /*----------------------------------------------------------------------------*/
1048 * @brief Reset the Status and Reason Code Field to 0 of all Station Records for
1049 * the specified Network Type
1051 * @param[in] eNetType Specify Network Type
1055 /*----------------------------------------------------------------------------*/
1057 cnmStaRecResetStatus (
1058 P_ADAPTER_T prAdapter,
1059 ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex
1062 cnmStaFreeAllStaByNetType(prAdapter, eNetTypeIndex, FALSE);
1065 P_STA_RECORD_T prStaRec;
1070 for (i = 0; i < CFG_STA_REC_NUM; i++) {
1071 prStaRec = &prAdapter->arStaRec[i];
1073 if (prStaRec->fgIsInUse) {
1074 if ((NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) &&
1075 IS_STA_IN_AIS(prStaRec->eStaType)) {
1077 prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL;
1078 prStaRec->u2ReasonCode = REASON_CODE_RESERVED;
1079 prStaRec->ucJoinFailureCount = 0;
1080 prStaRec->fgTransmitKeyExist = FALSE;
1082 prStaRec->fgSetPwrMgtBit = FALSE;
1085 /* TODO(Kevin): For P2P and BOW */
1093 /*----------------------------------------------------------------------------*/
1095 * @brief This function will change the ucStaState of STA_RECORD_T and also do
1096 * event indication to HOST to sync the STA_RECORD_T in driver.
1098 * @param[in] prStaRec Pointer to the STA_RECORD_T
1099 * @param[in] u4NewState New STATE to change.
1103 /*----------------------------------------------------------------------------*/
1105 cnmStaRecChangeState (
1106 P_ADAPTER_T prAdapter,
1107 P_STA_RECORD_T prStaRec,
1115 ASSERT(prStaRec->fgIsInUse);
1117 /* Do nothing when following state transitions happen,
1118 * other 6 conditions should be sync to FW, including 1-->1, 3-->3
1120 if ((ucNewState == STA_STATE_2 && prStaRec->ucStaState != STA_STATE_3) ||
1121 (ucNewState == STA_STATE_1 && prStaRec->ucStaState == STA_STATE_2)) {
1122 prStaRec->ucStaState = ucNewState;
1127 if (ucNewState == STA_STATE_3) {
1128 secFsmEventStart(prAdapter, prStaRec);
1129 if (ucNewState != prStaRec->ucStaState) {
1134 if (ucNewState != prStaRec->ucStaState &&
1135 prStaRec->ucStaState == STA_STATE_3) {
1136 qmDeactivateStaRec(prAdapter, prStaRec->ucIndex);
1140 prStaRec->ucStaState = ucNewState;
1142 cnmStaSendUpdateCmd(prAdapter, prStaRec, fgNeedResp);
1144 #if CFG_ENABLE_WIFI_DIRECT
1145 /* To do: Confirm if it is invoked here or other location, but it should
1146 * be invoked after state sync of STA_REC
1147 * Update system operation parameters for AP mode
1149 if (prAdapter->fgIsP2PRegistered && (IS_STA_IN_P2P(prStaRec))) {
1150 P_BSS_INFO_T prBssInfo;
1152 prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
1154 if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
1155 rlmUpdateParamsForAP(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 rStatus = wlanSendSetQueryCmd (
1277 prAdapter, /* prAdapter */
1278 CMD_ID_UPDATE_STA_RECORD, /* ucCID */
1279 TRUE, /* fgSetQuery */
1280 fgNeedResp, /* fgNeedResp */
1281 FALSE, /* fgIsOid */
1282 fgNeedResp? cnmStaRecHandleEventPkt : NULL,
1283 NULL, /* pfCmdTimeoutHandler */
1284 sizeof(CMD_UPDATE_STA_RECORD_T), /* u4SetQueryInfoLen */
1285 (PUINT_8) prCmdContent, /* pucInfoBuffer */
1286 NULL, /* pvSetQueryBuffer */
1287 0 /* u4SetQueryBufferLen */
1290 ASSERT(rStatus == WLAN_STATUS_PENDING);
1292 cnmMemFree(prAdapter, prCmdContent);
1295 /*----------------------------------------------------------------------------*/
1303 /*----------------------------------------------------------------------------*/
1305 cnmStaSendRemoveCmd (
1306 P_ADAPTER_T prAdapter,
1307 P_STA_RECORD_T prStaRec
1310 CMD_REMOVE_STA_RECORD_T rCmdContent;
1311 WLAN_STATUS rStatus;
1316 rCmdContent.ucIndex = prStaRec->ucIndex;
1317 kalMemCopy(&rCmdContent.aucMacAddr[0], &prStaRec->aucMacAddr[0],
1320 rStatus = wlanSendSetQueryCmd (
1321 prAdapter, /* prAdapter */
1322 CMD_ID_REMOVE_STA_RECORD, /* ucCID */
1323 TRUE, /* fgSetQuery */
1324 FALSE, /* fgNeedResp */
1325 FALSE, /* fgIsOid */
1326 NULL, /* pfCmdDoneHandler */
1327 NULL, /* pfCmdTimeoutHandler */
1328 sizeof(CMD_REMOVE_STA_RECORD_T), /* u4SetQueryInfoLen */
1329 (PUINT_8) &rCmdContent, /* pucInfoBuffer */
1330 NULL, /* pvSetQueryBuffer */
1331 0 /* u4SetQueryBufferLen */
1334 ASSERT(rStatus == WLAN_STATUS_PENDING);