2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/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.
18 * 07 17 2012 yuche.tsai
20 * Compile no error before trial run.
23 * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting
26 * 11 17 2011 tsaiyuan.hsu
27 * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3.
28 * initialize fgNeedResp.
30 * 11 17 2011 tsaiyuan.hsu
31 * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3.
32 * avoid deactivating staRec when changing state from 3 to 3.
35 * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode
39 * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
40 * Allocate system RAM if fixed message or mgmt buffer is not available
43 * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
46 * 01 25 2011 yuche.tsai
47 * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
48 * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role.
51 * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver
52 * create branch for Wi-Fi driver v1.1
55 * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
56 * 1. BSSINFO include RLM parameter
57 * 2. free all sta records when network is disconnected
60 * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for initial TX rate selection of auto-rate algorithm
61 * Sync RCPI of STA_REC to FW as reference of initial TX rate
63 * 11 25 2010 yuche.tsai
65 * Update SLT Function for QoS Support and not be affected by fixed rate function.
68 * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS associated
69 * 1. remove redundant variables in STA_REC structure
70 * 2. add STA-REC uninitialization routine for clearing pending events
73 * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash.
74 * Add exception handle when cmd buffer is not available
77 * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
78 * add HT (802.11n) fixed rate support.
81 * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
82 * adding fixed rate support for distance test. (from registry setting)
86 * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning.
89 * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS associated
90 * Do a complete reset with STA-REC null checking for RF test re-entry
94 * Change conditional compiling options for BOW
98 * Always update Beacon content if FW sync OBSS info
100 * 08 24 2010 cm.chang
102 * Support RLM initail channel of Ad-hoc, P2P and BOW
104 * 08 23 2010 chinghwa.yu
108 * 08 20 2010 cm.chang
110 * Migrate RLM code to host from FW
114 * adding the tx pkt call back handle for countermeasure.
118 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
120 * 07 08 2010 cm.chang
121 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
122 * Check draft RLM code for HT cap
124 * 07 07 2010 cm.chang
125 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
126 * Support state of STA record change from 1 to 1
128 * 07 05 2010 cm.chang
129 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
130 * Fix correct structure size in cnmStaSendDeactivateCmd()
133 * [WPD00003833][MT6620 and MT5931] Driver migration
134 * 1) ignore RSN checking when RSN is not turned on.
135 * 2) set STA-REC deactivation callback as NULL
136 * 3) add variable initialization API based on PHY configuration
139 * [WPD00003833][MT6620 and MT5931] Driver migration
140 * spin lock target revised
143 * [WPD00003833][MT6620 and MT5931] Driver migration
144 * change inner loop index from i to k.
146 * 07 01 2010 cm.chang
147 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
148 * Support sync command of STA_REC
150 * 06 23 2010 yarco.yang
151 * [WPD00003837][MT6620]Data Path Refine
152 * Merge g_arStaRec[] into adapter->arStaRec[]
154 * 06 18 2010 cm.chang
155 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
156 * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
158 * 05 31 2010 yarco.yang
159 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
160 * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling
162 * 05 28 2010 cm.chang
163 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
164 * Support checking of duplicated buffer free
167 * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing
168 * fixed the ad-hoc wpa-none send non-encrypted frame issue.
170 * 05 28 2010 kevin.huang
171 * [BORA00000794][WIFISYS][New Feature]Power Management Support
172 * Move define of STA_REC_NUM to config.h and rename to CFG_STA_REC_NUM
174 * 05 12 2010 kevin.huang
175 * [BORA00000794][WIFISYS][New Feature]Power Management Support
176 * Add Power Management - Legacy PS-POLL support.
178 * 04 28 2010 tehuang.liu
179 * [BORA00000605][WIFISYS] Phase3 Integration
180 * Modified some MQM-related data structures (SN counter, TX/RX BA table)
182 * 04 27 2010 tehuang.liu
183 * [BORA00000605][WIFISYS] Phase3 Integration
184 * Added new TX/RX BA tables in STA_REC
186 * 04 27 2010 tehuang.liu
187 * [BORA00000605][WIFISYS] Phase3 Integration
188 * Notify MQM, TXM, and RXM upon disconnection .
190 * 04 26 2010 tehuang.liu
191 * [BORA00000605][WIFISYS] Phase3 Integration
192 * Call mqm, txm, rxm functions upon disconnection
194 * 04 24 2010 cm.chang
195 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
196 * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
198 * 04 22 2010 cm.chang
199 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
200 * First draft code to support protection in AP mode
202 * 04 19 2010 kevin.huang
203 * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
204 * Add Beacon Timeout Support
205 * * * * * * * * * * and will send Null frame to diagnose connection
207 * 04 09 2010 tehuang.liu
208 * [BORA00000605][WIFISYS] Phase3 Integration
209 * [BORA00000644] WiFi phase 4 integration
210 * * Added per-TID SN cache in STA_REC
212 * 04 07 2010 cm.chang
213 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
214 * Different invoking order for WTBL entry of associated AP
217 * [BORA00000605][WIFISYS] Phase3 Integration
218 * move the wlan table alloc / free to change state function.
220 * 03 24 2010 cm.chang
221 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
222 * Support power control
224 * 03 03 2010 tehuang.liu
225 * [BORA00000569][WIFISYS] Phase 2 Integration Test
226 * Initialize StaRec->arStaWaitQueue
228 * 03 03 2010 cm.chang
229 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
230 * Add debug message when no available pkt buffer
232 * 03 01 2010 tehuang.liu
233 * [BORA00000569][WIFISYS] Phase 2 Integration Test
234 * Fixed STA_REC initialization bug: prStaRec->au2CachedSeqCtrl[k]
236 * 02 26 2010 tehuang.liu
237 * [BORA00000569][WIFISYS] Phase 2 Integration Test
238 * Added fgIsWmmSupported in STA_RECORD_T.
240 * 02 26 2010 tehuang.liu
241 * [BORA00000569][WIFISYS] Phase 2 Integration Test
242 * Added fgIsUapsdSupported in STA_RECORD_T
244 * 02 26 2010 kevin.huang
245 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
246 * add support of Driver STA_RECORD_T activation
248 * 02 13 2010 tehuang.liu
249 * [BORA00000569][WIFISYS] Phase 2 Integration Test
250 * Added arTspecTable in STA_REC for TSPEC management
252 * 02 12 2010 cm.chang
253 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
254 * Enable mgmt buffer debug by default
256 * 02 12 2010 tehuang.liu
257 * [BORA00000569][WIFISYS] Phase 2 Integration Test
258 * Added BUFFER_SOURCE_BCN
260 * 02 04 2010 kevin.huang
261 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
262 * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
264 * 01 11 2010 kevin.huang
265 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
266 * Add Deauth and Disassoc Handler
269 * [BORA00000368]Integrate HIF part into BORA
270 * 1) separate wifi_var_emu.c/.h from wifi_var.c/.h
271 * * * * * * * * * 2) eliminate HIF_EMULATION code sections appeared in wifi_var/cnm_mem
272 * * * * * * * * * 3) use cnmMemAlloc() instead to allocate SRAM buffer
274 * 12 25 2009 tehuang.liu
275 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
276 * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM)
277 * * * * * * * MQM: BA handling
278 * * * * * * * TXM: Macros updates
279 * * * * * * * RXM: Macros/Duplicate Removal updates
281 * 12 24 2009 yarco.yang
282 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
285 * 12 21 2009 cm.chang
286 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
287 * Support several data buffer banks.
289 * 12 18 2009 cm.chang
290 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
291 * .For new FPGA memory size
293 * Dec 9 2009 MTK02468
294 * [BORA00000337] To check in codes for FPGA emulation
297 * Dec 9 2009 mtk02752
298 * [BORA00000368] Integrate HIF part into BORA
299 * add cnmDataPktFree() for emulation loopback purpose
301 * Dec 3 2009 mtk01461
302 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
303 * Fix warning of null pointer
305 * Dec 3 2009 mtk01461
306 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
307 * Add cnmGetStaRecByAddress() and add fgIsInUse flag in STA_RECORD_T
309 * Nov 23 2009 mtk01104
310 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
311 * Assign ucBufferSource in function cnmMgtPktAlloc()
313 * Nov 23 2009 mtk02468
314 * [BORA00000337] To check in codes for FPGA emulation
315 * Added packet redispatch function calls
317 * Nov 13 2009 mtk01084
318 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
319 * enable packet re-usable in current emulation driver
321 * Nov 12 2009 mtk01104
322 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
323 * 1. Add new function cnmGetStaRecByIndex()
324 * 2. Rename STA_REC_T to STA_RECORD_T
326 * Nov 9 2009 mtk01104
327 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
328 * Call cnmDataPktDispatch() in cnmPktFree()
330 * Nov 2 2009 mtk01104
331 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
332 * Remove definition of pragma section code
334 * Oct 28 2009 mtk01104
335 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
338 * Oct 23 2009 mtk01461
339 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
342 * Oct 23 2009 mtk01461
343 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
346 * Oct 12 2009 mtk01104
347 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
350 * Oct 8 2009 mtk01104
351 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
356 /*******************************************************************************
357 * C O M P I L E R F L A G S
358 ********************************************************************************
361 /*******************************************************************************
362 * E X T E R N A L R E F E R E N C E S
363 ********************************************************************************
367 /*******************************************************************************
369 ********************************************************************************
372 /*******************************************************************************
374 ********************************************************************************
377 /*******************************************************************************
378 * P U B L I C D A T A
379 ********************************************************************************
382 /*******************************************************************************
383 * P R I V A T E D A T A
384 ********************************************************************************
387 /*******************************************************************************
389 ********************************************************************************
392 /*******************************************************************************
393 * F U N C T I O N D E C L A R A T I O N S
394 ********************************************************************************
397 cnmStaRecHandleEventPkt (
398 P_ADAPTER_T prAdapter,
399 P_CMD_INFO_T prCmdInfo,
404 cnmStaSendUpdateCmd (
405 P_ADAPTER_T prAdapter,
406 P_STA_RECORD_T prStaRec,
411 cnmStaSendRemoveCmd (
412 P_ADAPTER_T prAdapter,
413 P_STA_RECORD_T prStaRec
416 /*******************************************************************************
418 ********************************************************************************
421 /*----------------------------------------------------------------------------*/
429 /*----------------------------------------------------------------------------*/
432 P_ADAPTER_T prAdapter,
436 P_MSDU_INFO_T prMsduInfo;
438 KAL_SPIN_LOCK_DECLARATION();
441 prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList;
443 /* Get a free MSDU_INFO_T */
444 KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
445 QUEUE_REMOVE_HEAD(prQueList, prMsduInfo, P_MSDU_INFO_T);
446 KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
449 prMsduInfo->prPacket = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4Length);
450 prMsduInfo->eSrc = TX_PACKET_MGMT;
452 if (prMsduInfo->prPacket == NULL) {
453 KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
454 QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry);
455 KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
461 if (prMsduInfo == NULL) {
462 DBGLOG(MEM, WARN, ("\n"));
463 DBGLOG(MEM, WARN, ("MgtDesc#=%ld\n", prQueList->u4NumElem));
466 DBGLOG(MEM, WARN, ("rMgtBufInfo: alloc#=%ld, free#=%ld, null#=%ld\n",
467 prAdapter->rMgtBufInfo.u4AllocCount,
468 prAdapter->rMgtBufInfo.u4FreeCount,
469 prAdapter->rMgtBufInfo.u4AllocNullCount));
472 DBGLOG(MEM, WARN, ("\n"));
479 /*----------------------------------------------------------------------------*/
487 /*----------------------------------------------------------------------------*/
490 P_ADAPTER_T prAdapter,
491 P_MSDU_INFO_T prMsduInfo
495 KAL_SPIN_LOCK_DECLARATION();
500 prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList;
502 ASSERT(prMsduInfo->prPacket);
503 if (prMsduInfo->prPacket) {
504 cnmMemFree(prAdapter, prMsduInfo->prPacket);
505 prMsduInfo->prPacket = NULL;
508 KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
509 QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry)
510 KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
513 /*----------------------------------------------------------------------------*/
515 * \brief This function is used to initial the MGMT/MSG memory pool.
521 /*----------------------------------------------------------------------------*/
524 P_ADAPTER_T prAdapter
527 P_BUF_INFO_T prBufInfo;
529 /* Initialize Management buffer pool */
530 prBufInfo = &prAdapter->rMgtBufInfo;
531 kalMemZero(prBufInfo, sizeof(prAdapter->rMgtBufInfo));
532 prBufInfo->pucBuf = prAdapter->pucMgtBufCached;
534 /* Setup available memory blocks. 1 indicates FREE */
535 prBufInfo->rFreeBlocksBitmap =
536 (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1);
539 /* Initialize Message buffer pool */
540 prBufInfo = &prAdapter->rMsgBufInfo;
541 kalMemZero(prBufInfo, sizeof(prAdapter->rMsgBufInfo));
542 prBufInfo->pucBuf = &prAdapter->aucMsgBuf[0];
544 /* Setup available memory blocks. 1 indicates FREE */
545 prBufInfo->rFreeBlocksBitmap =
546 (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1);
550 } /* end of cnmMemInit() */
553 /*----------------------------------------------------------------------------*/
555 * \brief Allocate MGMT/MSG memory pool.
557 * \param[in] eRamType Target RAM type.
558 * TCM blk_sz= 16bytes, BUF blk_sz= 256bytes
559 * \param[in] u4Length Length of the buffer to allocate.
561 * \retval !NULL Pointer to the start address of allocated memory.
562 * \retval NULL Fail to allocat memory
564 /*----------------------------------------------------------------------------*/
567 IN P_ADAPTER_T prAdapter,
568 IN ENUM_RAM_TYPE_T eRamType,
572 P_BUF_INFO_T prBufInfo;
573 BUF_BITMAP rRequiredBitmap;
575 UINT_32 i, u4BlkSzInPower;
577 KAL_SPIN_LOCK_DECLARATION();
582 if (eRamType == RAM_TYPE_MSG && u4Length <= 256) {
583 prBufInfo = &prAdapter->rMsgBufInfo;
584 u4BlkSzInPower = MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2;
586 u4Length += (MSG_BUF_BLOCK_SIZE - 1);
587 u4BlockNum = u4Length >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2;
589 ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS);
592 eRamType = RAM_TYPE_BUF;
594 prBufInfo = &prAdapter->rMgtBufInfo;
595 u4BlkSzInPower = MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2;
597 u4Length += (MGT_BUF_BLOCK_SIZE - 1);
598 u4BlockNum = u4Length >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2;
600 ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS);
604 prBufInfo->u4AllocCount++;
607 KAL_ACQUIRE_SPIN_LOCK(prAdapter,
608 eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
610 if ((u4BlockNum > 0) && (u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS)) {
612 /* Convert number of block into bit cluster */
613 rRequiredBitmap = BITS(0, u4BlockNum-1);
615 for (i = 0; i <= (MAX_NUM_OF_BUF_BLOCKS - u4BlockNum); i++) {
617 /* Have available memory blocks */
618 if ((prBufInfo->rFreeBlocksBitmap & rRequiredBitmap)
619 == rRequiredBitmap) {
621 /* Clear corresponding bits of allocated memory blocks */
622 prBufInfo->rFreeBlocksBitmap &= ~rRequiredBitmap;
624 /* Store how many blocks be allocated */
625 prBufInfo->aucAllocatedBlockNum[i] = (UINT_8) u4BlockNum;
627 KAL_RELEASE_SPIN_LOCK(prAdapter,
628 eRamType == RAM_TYPE_MSG ?
629 SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
631 /* Return the start address of allocated memory */
632 return (PVOID)(prBufInfo->pucBuf + (i << u4BlkSzInPower));
636 rRequiredBitmap <<= 1;
641 pvMemory = (PVOID)kalMemAlloc(u4Length, VIR_MEM_TYPE);
643 pvMemory = (PVOID)NULL;
647 prBufInfo->u4AllocNullCount++;
650 prAdapter->u4MemAllocDynamicCount++;
654 KAL_RELEASE_SPIN_LOCK(prAdapter,
655 eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
659 } /* end of cnmMemAlloc() */
662 /*----------------------------------------------------------------------------*/
664 * \brief Release memory to MGT/MSG memory pool.
666 * \param pucMemory Start address of previous allocated memory
670 /*----------------------------------------------------------------------------*/
673 IN P_ADAPTER_T prAdapter,
677 P_BUF_INFO_T prBufInfo;
678 UINT_32 u4BlockIndex;
679 BUF_BITMAP rAllocatedBlocksBitmap;
680 ENUM_RAM_TYPE_T eRamType;
681 KAL_SPIN_LOCK_DECLARATION();
690 /* Judge it belongs to which RAM type */
691 if ( ((UINT_32)pvMemory >= (UINT_32)&prAdapter->aucMsgBuf[0]) &&
692 ((UINT_32)pvMemory <= (UINT_32)&prAdapter->aucMsgBuf[MSG_BUFFER_SIZE-1])) {
694 prBufInfo = &prAdapter->rMsgBufInfo;
695 u4BlockIndex = ((UINT_32)pvMemory - (UINT_32)prBufInfo->pucBuf)
696 >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2;
697 ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS);
698 eRamType = RAM_TYPE_MSG;
700 else if ( ((UINT_32)pvMemory >= (UINT_32)prAdapter->pucMgtBufCached) &&
701 ((UINT_32)pvMemory <= ((UINT_32)prAdapter->pucMgtBufCached + MGT_BUFFER_SIZE -1))) {
702 prBufInfo = &prAdapter->rMgtBufInfo;
703 u4BlockIndex = ((UINT_32)pvMemory - (UINT_32)prBufInfo->pucBuf)
704 >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2;
705 ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS);
706 eRamType = RAM_TYPE_BUF;
710 /* For Linux, it is supported because size is not needed */
711 kalMemFree(pvMemory, VIR_MEM_TYPE, 0);
713 /* For Windows, it is not supported because of no size argument */
718 prAdapter->u4MemFreeDynamicCount++;
723 KAL_ACQUIRE_SPIN_LOCK(prAdapter,
724 eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
727 prBufInfo->u4FreeCount++;
730 /* Convert number of block into bit cluster */
731 ASSERT(prBufInfo->aucAllocatedBlockNum[u4BlockIndex] > 0);
733 rAllocatedBlocksBitmap =
734 BITS(0, prBufInfo->aucAllocatedBlockNum[u4BlockIndex] - 1);
735 rAllocatedBlocksBitmap <<= u4BlockIndex;
737 /* Clear saved block count for this memory segment */
738 prBufInfo->aucAllocatedBlockNum[u4BlockIndex] = 0;
740 /* Set corresponding bit of released memory block */
741 prBufInfo->rFreeBlocksBitmap |= rAllocatedBlocksBitmap;
743 KAL_RELEASE_SPIN_LOCK(prAdapter,
744 eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
748 } /* end of cnmMemFree() */
751 /*----------------------------------------------------------------------------*/
759 /*----------------------------------------------------------------------------*/
762 P_ADAPTER_T prAdapter
765 P_STA_RECORD_T prStaRec;
768 for (i = 0; i < CFG_STA_REC_NUM; i++) {
769 prStaRec = &prAdapter->arStaRec[i];
771 prStaRec->ucIndex = (UINT_8) i;
772 prStaRec->fgIsInUse = FALSE;
777 /*----------------------------------------------------------------------------*/
785 /*----------------------------------------------------------------------------*/
788 IN P_ADAPTER_T prAdapter
791 P_STA_RECORD_T prStaRec;
794 for (i = 0; i < CFG_STA_REC_NUM; i++) {
795 prStaRec = &prAdapter->arStaRec[i];
797 if (prStaRec->fgIsInUse) {
798 cnmStaRecFree(prAdapter, prStaRec, FALSE);
804 /*----------------------------------------------------------------------------*/
812 /*----------------------------------------------------------------------------*/
815 P_ADAPTER_T prAdapter,
816 UINT_8 ucNetTypeIndex
819 P_STA_RECORD_T prStaRec;
824 for (i = 0; i < CFG_STA_REC_NUM; i++) {
825 prStaRec = &prAdapter->arStaRec[i];
827 if (!prStaRec->fgIsInUse) {
828 /*---- Initialize STA_REC_T here ----*/
829 kalMemZero(prStaRec, sizeof(STA_RECORD_T));
830 prStaRec->ucIndex = (UINT_8) i;
831 prStaRec->ucNetTypeIndex = ucNetTypeIndex;
832 prStaRec->fgIsInUse = TRUE;
834 if (prStaRec->pucAssocReqIe) {
835 kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen);
836 prStaRec->pucAssocReqIe = NULL;
837 prStaRec->u2AssocReqIeLen = 0;
840 /* Initialize the SN caches for duplicate detection */
841 for (k = 0; k < TID_NUM + 1; k++) {
842 prStaRec->au2CachedSeqCtrl[k] = 0xFFFF;
845 /* Initialize SW TX queues in STA_REC */
846 for (k = 0; k < STA_WAIT_QUEUE_NUM; k++) {
847 LINK_INITIALIZE(&prStaRec->arStaWaitQueue[k]);
850 /* Default enable TX/RX AMPDU */
851 prStaRec->fgTxAmpduEn = TRUE;
852 prStaRec->fgRxAmpduEn = TRUE;
854 for (k = 0; k < NUM_OF_PER_STA_TX_QUEUES; k++) {
855 QUEUE_INITIALIZE(&prStaRec->arTxQueue[k]);
862 return (i < CFG_STA_REC_NUM) ? prStaRec : NULL;
866 /*----------------------------------------------------------------------------*/
874 /*----------------------------------------------------------------------------*/
877 P_ADAPTER_T prAdapter,
878 P_STA_RECORD_T prStaRec,
885 /* To do: free related resources, e.g. timers, buffers, etc */
886 cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
887 prStaRec->fgTransmitKeyExist = FALSE;
888 prStaRec->fgSetPwrMgtBit = FALSE;
890 if (prStaRec->pucAssocReqIe) {
891 kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen);
892 prStaRec->pucAssocReqIe = NULL;
893 prStaRec->u2AssocReqIeLen = 0;
896 qmDeactivateStaRec(prAdapter, prStaRec->ucIndex);
899 cnmStaSendRemoveCmd(prAdapter, prStaRec);
902 prStaRec->fgIsInUse = FALSE;
907 /*----------------------------------------------------------------------------*/
915 /*----------------------------------------------------------------------------*/
917 cnmStaFreeAllStaByNetType (
918 P_ADAPTER_T prAdapter,
919 ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
923 P_STA_RECORD_T prStaRec;
926 for (i = 0; i < CFG_STA_REC_NUM; i++) {
927 prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i];
929 if (prStaRec->fgIsInUse &&
930 prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex) {
932 cnmStaRecFree(prAdapter, prStaRec, fgSyncToChip);
934 } /* end of for loop */
937 /*----------------------------------------------------------------------------*/
945 /*----------------------------------------------------------------------------*/
947 cnmGetStaRecByIndex (
948 P_ADAPTER_T prAdapter,
952 P_STA_RECORD_T prStaRec;
956 prStaRec = (ucIndex < CFG_STA_REC_NUM) ?
957 &prAdapter->arStaRec[ucIndex] : NULL;
959 if (prStaRec && prStaRec->fgIsInUse == FALSE) {
966 /*----------------------------------------------------------------------------*/
968 * @brief Get STA_RECORD_T by Peer MAC Address(Usually TA).
970 * @param[in] pucPeerMacAddr Given Peer MAC Address.
972 * @retval Pointer to STA_RECORD_T, if found. NULL, if not found
974 /*----------------------------------------------------------------------------*/
976 cnmGetStaRecByAddress (
977 P_ADAPTER_T prAdapter,
978 UINT_8 ucNetTypeIndex,
979 PUINT_8 pucPeerMacAddr
982 P_STA_RECORD_T prStaRec;
986 ASSERT(pucPeerMacAddr);
988 for (i = 0; i < CFG_STA_REC_NUM; i++) {
989 prStaRec = &prAdapter->arStaRec[i];
991 if (prStaRec->fgIsInUse &&
992 prStaRec->ucNetTypeIndex == ucNetTypeIndex &&
993 EQUAL_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMacAddr)) {
998 return (i < CFG_STA_REC_NUM) ? prStaRec : NULL;
1001 /*----------------------------------------------------------------------------*/
1003 * @brief Reset the Status and Reason Code Field to 0 of all Station Records for
1004 * the specified Network Type
1006 * @param[in] eNetType Specify Network Type
1010 /*----------------------------------------------------------------------------*/
1012 cnmStaRecResetStatus (
1013 P_ADAPTER_T prAdapter,
1014 ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex
1017 cnmStaFreeAllStaByNetType(prAdapter, eNetTypeIndex, FALSE);
1020 P_STA_RECORD_T prStaRec;
1025 for (i = 0; i < CFG_STA_REC_NUM; i++) {
1026 prStaRec = &prAdapter->arStaRec[i];
1028 if (prStaRec->fgIsInUse) {
1029 if ((NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) &&
1030 IS_STA_IN_AIS(prStaRec->eStaType)) {
1032 prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL;
1033 prStaRec->u2ReasonCode = REASON_CODE_RESERVED;
1034 prStaRec->ucJoinFailureCount = 0;
1035 prStaRec->fgTransmitKeyExist = FALSE;
1037 prStaRec->fgSetPwrMgtBit = FALSE;
1040 /* TODO(Kevin): For P2P and BOW */
1048 /*----------------------------------------------------------------------------*/
1050 * @brief This function will change the ucStaState of STA_RECORD_T and also do
1051 * event indication to HOST to sync the STA_RECORD_T in driver.
1053 * @param[in] prStaRec Pointer to the STA_RECORD_T
1054 * @param[in] u4NewState New STATE to change.
1058 /*----------------------------------------------------------------------------*/
1060 cnmStaRecChangeState (
1061 P_ADAPTER_T prAdapter,
1062 P_STA_RECORD_T prStaRec,
1070 ASSERT(prStaRec->fgIsInUse);
1072 /* Do nothing when following state transitions happen,
1073 * other 6 conditions should be sync to FW, including 1-->1, 3-->3
1075 if ((ucNewState == STA_STATE_2 && prStaRec->ucStaState != STA_STATE_3) ||
1076 (ucNewState == STA_STATE_1 && prStaRec->ucStaState == STA_STATE_2)) {
1077 prStaRec->ucStaState = ucNewState;
1082 if (ucNewState == STA_STATE_3) {
1083 secFsmEventStart(prAdapter, prStaRec);
1084 if (ucNewState != prStaRec->ucStaState) {
1089 if (ucNewState != prStaRec->ucStaState &&
1090 prStaRec->ucStaState == STA_STATE_3) {
1091 qmDeactivateStaRec(prAdapter, prStaRec->ucIndex);
1095 prStaRec->ucStaState = ucNewState;
1097 cnmStaSendUpdateCmd(prAdapter, prStaRec, fgNeedResp);
1099 #if CFG_ENABLE_WIFI_DIRECT
1100 /* To do: Confirm if it is invoked here or other location, but it should
1101 * be invoked after state sync of STA_REC
1102 * Update system operation parameters for AP mode
1104 if (prAdapter->fgIsP2PRegistered && (IS_STA_IN_P2P(prStaRec))) {
1105 P_BSS_INFO_T prBssInfo;
1107 prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
1109 if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
1110 rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE);
1117 /*----------------------------------------------------------------------------*/
1125 /*----------------------------------------------------------------------------*/
1127 cnmStaRecHandleEventPkt (
1128 P_ADAPTER_T prAdapter,
1129 P_CMD_INFO_T prCmdInfo,
1133 P_EVENT_ACTIVATE_STA_REC_T prEventContent;
1134 P_STA_RECORD_T prStaRec;
1136 prEventContent = (P_EVENT_ACTIVATE_STA_REC_T) pucEventBuf;
1137 prStaRec = cnmGetStaRecByIndex(prAdapter, prEventContent->ucStaRecIdx);
1139 if (prStaRec && prStaRec->ucStaState == STA_STATE_3 &&
1140 !kalMemCmp(&prStaRec->aucMacAddr[0], &prEventContent->aucMacAddr[0],
1143 qmActivateStaRec(prAdapter, prStaRec);
1148 /*----------------------------------------------------------------------------*/
1156 /*----------------------------------------------------------------------------*/
1158 cnmStaSendUpdateCmd (
1159 P_ADAPTER_T prAdapter,
1160 P_STA_RECORD_T prStaRec,
1164 P_CMD_UPDATE_STA_RECORD_T prCmdContent;
1165 WLAN_STATUS rStatus;
1169 ASSERT(prStaRec->fgIsInUse);
1171 /* To do: come out a mechanism to limit one STA_REC sync once for AP mode
1172 * to avoid buffer empty case when many STAs are associated
1176 /* To do: how to avoid 2 times of allocated memory. Use Stack?
1177 * One is here, the other is in wlanSendQueryCmd()
1179 prCmdContent = cnmMemAlloc(prAdapter,
1180 RAM_TYPE_BUF, sizeof(CMD_UPDATE_STA_RECORD_T));
1181 ASSERT(prCmdContent);
1183 /* To do: exception handle */
1184 if (!prCmdContent) {
1188 prCmdContent->ucIndex = prStaRec->ucIndex;
1189 prCmdContent->ucStaType = (UINT_8) prStaRec->eStaType;
1190 kalMemCopy(&prCmdContent->aucMacAddr[0], &prStaRec->aucMacAddr[0],
1192 prCmdContent->u2AssocId = prStaRec->u2AssocId;
1193 prCmdContent->u2ListenInterval = prStaRec->u2ListenInterval;
1194 prCmdContent->ucNetTypeIndex = prStaRec->ucNetTypeIndex;
1196 prCmdContent->ucDesiredPhyTypeSet = prStaRec->ucDesiredPhyTypeSet;
1197 prCmdContent->u2DesiredNonHTRateSet = prStaRec->u2DesiredNonHTRateSet;
1198 prCmdContent->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet;
1199 prCmdContent->ucMcsSet = prStaRec->ucMcsSet;
1200 prCmdContent->ucSupMcs32 = (UINT_8) prStaRec->fgSupMcs32;
1201 prCmdContent->u2HtCapInfo = prStaRec->u2HtCapInfo;
1202 prCmdContent->ucNeedResp = (UINT_8) fgNeedResp;
1204 #if !CFG_SLT_SUPPORT
1205 if(prAdapter->rWifiVar.eRateSetting != FIXED_RATE_NONE) {
1206 /* override rate configuration */
1207 nicUpdateRateParams(prAdapter,
1208 prAdapter->rWifiVar.eRateSetting,
1209 &(prCmdContent->ucDesiredPhyTypeSet),
1210 &(prCmdContent->u2DesiredNonHTRateSet),
1211 &(prCmdContent->u2BSSBasicRateSet),
1212 &(prCmdContent->ucMcsSet),
1213 &(prCmdContent->ucSupMcs32),
1214 &(prCmdContent->u2HtCapInfo));
1218 prCmdContent->ucIsQoS = prStaRec->fgIsQoS;
1219 prCmdContent->ucIsUapsdSupported = prStaRec->fgIsUapsdSupported;
1220 prCmdContent->ucStaState = prStaRec->ucStaState;
1222 prCmdContent->ucAmpduParam = prStaRec->ucAmpduParam;
1223 prCmdContent->u2HtExtendedCap = prStaRec->u2HtExtendedCap;
1224 prCmdContent->u4TxBeamformingCap = prStaRec->u4TxBeamformingCap;
1225 prCmdContent->ucAselCap = prStaRec->ucAselCap;
1226 prCmdContent->ucRCPI = prStaRec->ucRCPI;
1228 prCmdContent->ucUapsdAc = prStaRec->ucBmpTriggerAC | (prStaRec->ucBmpDeliveryAC << 4);
1229 prCmdContent->ucUapsdSp = prStaRec->ucUapsdSp;
1231 rStatus = wlanSendSetQueryCmd (
1232 prAdapter, /* prAdapter */
1233 CMD_ID_UPDATE_STA_RECORD, /* ucCID */
1234 TRUE, /* fgSetQuery */
1235 fgNeedResp, /* fgNeedResp */
1236 FALSE, /* fgIsOid */
1237 fgNeedResp? cnmStaRecHandleEventPkt : NULL,
1238 NULL, /* pfCmdTimeoutHandler */
1239 sizeof(CMD_UPDATE_STA_RECORD_T), /* u4SetQueryInfoLen */
1240 (PUINT_8) prCmdContent, /* pucInfoBuffer */
1241 NULL, /* pvSetQueryBuffer */
1242 0 /* u4SetQueryBufferLen */
1245 ASSERT(rStatus == WLAN_STATUS_PENDING);
1247 cnmMemFree(prAdapter, prCmdContent);
1250 /*----------------------------------------------------------------------------*/
1258 /*----------------------------------------------------------------------------*/
1260 cnmStaSendRemoveCmd (
1261 P_ADAPTER_T prAdapter,
1262 P_STA_RECORD_T prStaRec
1265 CMD_REMOVE_STA_RECORD_T rCmdContent;
1266 WLAN_STATUS rStatus;
1271 rCmdContent.ucIndex = prStaRec->ucIndex;
1272 kalMemCopy(&rCmdContent.aucMacAddr[0], &prStaRec->aucMacAddr[0],
1275 rStatus = wlanSendSetQueryCmd (
1276 prAdapter, /* prAdapter */
1277 CMD_ID_REMOVE_STA_RECORD, /* ucCID */
1278 TRUE, /* fgSetQuery */
1279 FALSE, /* fgNeedResp */
1280 FALSE, /* fgIsOid */
1281 NULL, /* pfCmdDoneHandler */
1282 NULL, /* pfCmdTimeoutHandler */
1283 sizeof(CMD_REMOVE_STA_RECORD_T), /* u4SetQueryInfoLen */
1284 (PUINT_8) &rCmdContent, /* pucInfoBuffer */
1285 NULL, /* pvSetQueryBuffer */
1286 0 /* u4SetQueryBufferLen */
1289 ASSERT(rStatus == WLAN_STATUS_PENDING);