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 #if CFG_ENABLE_PER_STA_STATISTICS && CFG_ENABLE_PKT_LIFETIME_PROFILE
855 prStaRec->u4TotalTxPktsNumber = 0;
856 prStaRec->u4TotalTxPktsTime = 0;
857 prStaRec->u4MaxTxPktsTime = 0;
860 for (k = 0; k < NUM_OF_PER_STA_TX_QUEUES; k++) {
861 QUEUE_INITIALIZE(&prStaRec->arTxQueue[k]);
868 return (i < CFG_STA_REC_NUM) ? prStaRec : NULL;
872 /*----------------------------------------------------------------------------*/
880 /*----------------------------------------------------------------------------*/
883 P_ADAPTER_T prAdapter,
884 P_STA_RECORD_T prStaRec,
891 /* To do: free related resources, e.g. timers, buffers, etc */
892 cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
893 prStaRec->fgTransmitKeyExist = FALSE;
894 prStaRec->fgSetPwrMgtBit = FALSE;
896 if (prStaRec->pucAssocReqIe) {
897 kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen);
898 prStaRec->pucAssocReqIe = NULL;
899 prStaRec->u2AssocReqIeLen = 0;
902 qmDeactivateStaRec(prAdapter, prStaRec->ucIndex);
905 cnmStaSendRemoveCmd(prAdapter, prStaRec);
908 prStaRec->fgIsInUse = FALSE;
913 /*----------------------------------------------------------------------------*/
921 /*----------------------------------------------------------------------------*/
923 cnmStaFreeAllStaByNetType (
924 P_ADAPTER_T prAdapter,
925 ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
929 P_STA_RECORD_T prStaRec;
932 for (i = 0; i < CFG_STA_REC_NUM; i++) {
933 prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i];
935 if (prStaRec->fgIsInUse &&
936 prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex) {
938 cnmStaRecFree(prAdapter, prStaRec, fgSyncToChip);
940 } /* end of for loop */
943 /*----------------------------------------------------------------------------*/
951 /*----------------------------------------------------------------------------*/
953 cnmGetStaRecByIndex (
954 P_ADAPTER_T prAdapter,
958 P_STA_RECORD_T prStaRec;
962 prStaRec = (ucIndex < CFG_STA_REC_NUM) ?
963 &prAdapter->arStaRec[ucIndex] : NULL;
965 if (prStaRec && prStaRec->fgIsInUse == FALSE) {
972 /*----------------------------------------------------------------------------*/
974 * @brief Get STA_RECORD_T by Peer MAC Address(Usually TA).
976 * @param[in] pucPeerMacAddr Given Peer MAC Address.
978 * @retval Pointer to STA_RECORD_T, if found. NULL, if not found
980 /*----------------------------------------------------------------------------*/
982 cnmGetStaRecByAddress (
983 P_ADAPTER_T prAdapter,
984 UINT_8 ucNetTypeIndex,
985 PUINT_8 pucPeerMacAddr
988 P_STA_RECORD_T prStaRec;
992 ASSERT(pucPeerMacAddr);
994 for (i = 0; i < CFG_STA_REC_NUM; i++) {
995 prStaRec = &prAdapter->arStaRec[i];
997 if (prStaRec->fgIsInUse &&
998 prStaRec->ucNetTypeIndex == ucNetTypeIndex &&
999 EQUAL_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMacAddr)) {
1004 return (i < CFG_STA_REC_NUM) ? prStaRec : NULL;
1007 /*----------------------------------------------------------------------------*/
1009 * @brief Reset the Status and Reason Code Field to 0 of all Station Records for
1010 * the specified Network Type
1012 * @param[in] eNetType Specify Network Type
1016 /*----------------------------------------------------------------------------*/
1018 cnmStaRecResetStatus (
1019 P_ADAPTER_T prAdapter,
1020 ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex
1023 cnmStaFreeAllStaByNetType(prAdapter, eNetTypeIndex, FALSE);
1026 P_STA_RECORD_T prStaRec;
1031 for (i = 0; i < CFG_STA_REC_NUM; i++) {
1032 prStaRec = &prAdapter->arStaRec[i];
1034 if (prStaRec->fgIsInUse) {
1035 if ((NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) &&
1036 IS_STA_IN_AIS(prStaRec->eStaType)) {
1038 prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL;
1039 prStaRec->u2ReasonCode = REASON_CODE_RESERVED;
1040 prStaRec->ucJoinFailureCount = 0;
1041 prStaRec->fgTransmitKeyExist = FALSE;
1043 prStaRec->fgSetPwrMgtBit = FALSE;
1046 /* TODO(Kevin): For P2P and BOW */
1054 /*----------------------------------------------------------------------------*/
1056 * @brief This function will change the ucStaState of STA_RECORD_T and also do
1057 * event indication to HOST to sync the STA_RECORD_T in driver.
1059 * @param[in] prStaRec Pointer to the STA_RECORD_T
1060 * @param[in] u4NewState New STATE to change.
1064 /*----------------------------------------------------------------------------*/
1066 cnmStaRecChangeState (
1067 P_ADAPTER_T prAdapter,
1068 P_STA_RECORD_T prStaRec,
1076 ASSERT(prStaRec->fgIsInUse);
1078 /* Do nothing when following state transitions happen,
1079 * other 6 conditions should be sync to FW, including 1-->1, 3-->3
1081 if ((ucNewState == STA_STATE_2 && prStaRec->ucStaState != STA_STATE_3) ||
1082 (ucNewState == STA_STATE_1 && prStaRec->ucStaState == STA_STATE_2)) {
1083 prStaRec->ucStaState = ucNewState;
1088 if (ucNewState == STA_STATE_3) {
1089 secFsmEventStart(prAdapter, prStaRec);
1090 if (ucNewState != prStaRec->ucStaState) {
1095 if (ucNewState != prStaRec->ucStaState &&
1096 prStaRec->ucStaState == STA_STATE_3) {
1097 qmDeactivateStaRec(prAdapter, prStaRec->ucIndex);
1101 prStaRec->ucStaState = ucNewState;
1103 cnmStaSendUpdateCmd(prAdapter, prStaRec, fgNeedResp);
1105 #if CFG_ENABLE_WIFI_DIRECT
1106 /* To do: Confirm if it is invoked here or other location, but it should
1107 * be invoked after state sync of STA_REC
1108 * Update system operation parameters for AP mode
1110 if (prAdapter->fgIsP2PRegistered && (IS_STA_IN_P2P(prStaRec))) {
1111 P_BSS_INFO_T prBssInfo;
1113 prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
1115 if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
1116 rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE);
1123 /*----------------------------------------------------------------------------*/
1131 /*----------------------------------------------------------------------------*/
1133 cnmStaRecHandleEventPkt (
1134 P_ADAPTER_T prAdapter,
1135 P_CMD_INFO_T prCmdInfo,
1139 P_EVENT_ACTIVATE_STA_REC_T prEventContent;
1140 P_STA_RECORD_T prStaRec;
1142 prEventContent = (P_EVENT_ACTIVATE_STA_REC_T) pucEventBuf;
1143 prStaRec = cnmGetStaRecByIndex(prAdapter, prEventContent->ucStaRecIdx);
1145 if (prStaRec && prStaRec->ucStaState == STA_STATE_3 &&
1146 !kalMemCmp(&prStaRec->aucMacAddr[0], &prEventContent->aucMacAddr[0],
1149 qmActivateStaRec(prAdapter, prStaRec);
1154 /*----------------------------------------------------------------------------*/
1162 /*----------------------------------------------------------------------------*/
1164 cnmStaSendUpdateCmd (
1165 P_ADAPTER_T prAdapter,
1166 P_STA_RECORD_T prStaRec,
1170 P_CMD_UPDATE_STA_RECORD_T prCmdContent;
1171 WLAN_STATUS rStatus;
1175 ASSERT(prStaRec->fgIsInUse);
1177 /* To do: come out a mechanism to limit one STA_REC sync once for AP mode
1178 * to avoid buffer empty case when many STAs are associated
1182 /* To do: how to avoid 2 times of allocated memory. Use Stack?
1183 * One is here, the other is in wlanSendQueryCmd()
1185 prCmdContent = cnmMemAlloc(prAdapter,
1186 RAM_TYPE_BUF, sizeof(CMD_UPDATE_STA_RECORD_T));
1187 ASSERT(prCmdContent);
1189 /* To do: exception handle */
1190 if (!prCmdContent) {
1194 prCmdContent->ucIndex = prStaRec->ucIndex;
1195 prCmdContent->ucStaType = (UINT_8) prStaRec->eStaType;
1196 kalMemCopy(&prCmdContent->aucMacAddr[0], &prStaRec->aucMacAddr[0],
1198 prCmdContent->u2AssocId = prStaRec->u2AssocId;
1199 prCmdContent->u2ListenInterval = prStaRec->u2ListenInterval;
1200 prCmdContent->ucNetTypeIndex = prStaRec->ucNetTypeIndex;
1202 prCmdContent->ucDesiredPhyTypeSet = prStaRec->ucDesiredPhyTypeSet;
1203 prCmdContent->u2DesiredNonHTRateSet = prStaRec->u2DesiredNonHTRateSet;
1204 prCmdContent->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet;
1205 prCmdContent->ucMcsSet = prStaRec->ucMcsSet;
1206 prCmdContent->ucSupMcs32 = (UINT_8) prStaRec->fgSupMcs32;
1207 prCmdContent->u2HtCapInfo = prStaRec->u2HtCapInfo;
1208 prCmdContent->ucNeedResp = (UINT_8) fgNeedResp;
1210 #if !CFG_SLT_SUPPORT
1211 if(prAdapter->rWifiVar.eRateSetting != FIXED_RATE_NONE) {
1212 /* override rate configuration */
1213 nicUpdateRateParams(prAdapter,
1214 prAdapter->rWifiVar.eRateSetting,
1215 &(prCmdContent->ucDesiredPhyTypeSet),
1216 &(prCmdContent->u2DesiredNonHTRateSet),
1217 &(prCmdContent->u2BSSBasicRateSet),
1218 &(prCmdContent->ucMcsSet),
1219 &(prCmdContent->ucSupMcs32),
1220 &(prCmdContent->u2HtCapInfo));
1224 prCmdContent->ucIsQoS = prStaRec->fgIsQoS;
1225 prCmdContent->ucIsUapsdSupported = prStaRec->fgIsUapsdSupported;
1226 prCmdContent->ucStaState = prStaRec->ucStaState;
1228 prCmdContent->ucAmpduParam = prStaRec->ucAmpduParam;
1229 prCmdContent->u2HtExtendedCap = prStaRec->u2HtExtendedCap;
1230 prCmdContent->u4TxBeamformingCap = prStaRec->u4TxBeamformingCap;
1231 prCmdContent->ucAselCap = prStaRec->ucAselCap;
1232 prCmdContent->ucRCPI = prStaRec->ucRCPI;
1234 prCmdContent->ucUapsdAc = prStaRec->ucBmpTriggerAC | (prStaRec->ucBmpDeliveryAC << 4);
1235 prCmdContent->ucUapsdSp = prStaRec->ucUapsdSp;
1237 rStatus = wlanSendSetQueryCmd (
1238 prAdapter, /* prAdapter */
1239 CMD_ID_UPDATE_STA_RECORD, /* ucCID */
1240 TRUE, /* fgSetQuery */
1241 fgNeedResp, /* fgNeedResp */
1242 FALSE, /* fgIsOid */
1243 fgNeedResp? cnmStaRecHandleEventPkt : NULL,
1244 NULL, /* pfCmdTimeoutHandler */
1245 sizeof(CMD_UPDATE_STA_RECORD_T), /* u4SetQueryInfoLen */
1246 (PUINT_8) prCmdContent, /* pucInfoBuffer */
1247 NULL, /* pvSetQueryBuffer */
1248 0 /* u4SetQueryBufferLen */
1251 ASSERT(rStatus == WLAN_STATUS_PENDING);
1253 cnmMemFree(prAdapter, prCmdContent);
1256 /*----------------------------------------------------------------------------*/
1264 /*----------------------------------------------------------------------------*/
1266 cnmStaSendRemoveCmd (
1267 P_ADAPTER_T prAdapter,
1268 P_STA_RECORD_T prStaRec
1271 CMD_REMOVE_STA_RECORD_T rCmdContent;
1272 WLAN_STATUS rStatus;
1277 rCmdContent.ucIndex = prStaRec->ucIndex;
1278 kalMemCopy(&rCmdContent.aucMacAddr[0], &prStaRec->aucMacAddr[0],
1281 rStatus = wlanSendSetQueryCmd (
1282 prAdapter, /* prAdapter */
1283 CMD_ID_REMOVE_STA_RECORD, /* ucCID */
1284 TRUE, /* fgSetQuery */
1285 FALSE, /* fgNeedResp */
1286 FALSE, /* fgIsOid */
1287 NULL, /* pfCmdDoneHandler */
1288 NULL, /* pfCmdTimeoutHandler */
1289 sizeof(CMD_REMOVE_STA_RECORD_T), /* u4SetQueryInfoLen */
1290 (PUINT_8) &rCmdContent, /* pucInfoBuffer */
1291 NULL, /* pvSetQueryBuffer */
1292 0 /* u4SetQueryBufferLen */
1295 ASSERT(rStatus == WLAN_STATUS_PENDING);