12302ed9f221469204dee4d8859afb76dc400f2c
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / mt5931_kk / drv_wlan / mgmt / cnm_mem.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT662X_593X_WIFI_DRIVER_V2_3/mgmt/cnm_mem.c#1 $
3 */
4
5 /*! \file   "cnm_mem.c"
6     \brief  This file contain the management function of packet buffers and
7             generic memory alloc/free functioin for mailbox message.
8
9             A data packet has a fixed size of buffer, but a management
10             packet can be equipped with a variable size of buffer.
11 */
12
13 /*******************************************************************************
14 * Copyright (c) 2009 MediaTek Inc.
15 *
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
19 * MediaTek Inc.
20 ********************************************************************************
21 */
22
23 /*******************************************************************************
24 * LEGAL DISCLAIMER
25 *
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.
39 *
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.
45 *
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
51 * (ICC).
52 ********************************************************************************
53 */
54
55 /*
56 ** $Log: cnm_mem.c $
57  *
58  * 07 17 2012 yuche.tsai
59  * NULL
60  * Compile no error before trial run.
61  *
62  * 03 14 2012 wh.su
63  * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting
64  * Add code from 2.2
65  *
66  * 11 17 2011 tsaiyuan.hsu
67  * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3.
68  * initialize fgNeedResp.
69  *
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.
73  *
74  * 02 01 2011 cm.chang
75  * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode
76  * .
77  *
78  * 01 26 2011 cm.chang
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
81  *
82  * 01 26 2011 cm.chang
83  * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
84  * .
85  *
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.
89  *
90  * 12 13 2010 cp.wu
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
93  *
94  * 12 07 2010 cm.chang
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
98  *
99  * 11 29 2010 cm.chang
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
102  *
103  * 11 25 2010 yuche.tsai
104  * NULL
105  * Update SLT Function for QoS Support and not be affected by fixed rate function.
106  *
107  * 10 18 2010 cp.wu
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
111  *
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
115  *
116  * 10 12 2010 cp.wu
117  * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
118  * add HT (802.11n) fixed rate support.
119  *
120  * 10 08 2010 cp.wu
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)
123  *
124  * 09 24 2010 wh.su
125  * NULL
126  * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning.
127  *
128  * 09 21 2010 cp.wu
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
131  *
132  * 09 16 2010 cm.chang
133  * NULL
134  * Change conditional compiling options for BOW
135  *
136  * 09 10 2010 cm.chang
137  * NULL
138  * Always update Beacon content if FW sync OBSS info
139  *
140  * 08 24 2010 cm.chang
141  * NULL
142  * Support RLM initail channel of Ad-hoc, P2P and BOW
143  *
144  * 08 23 2010 chinghwa.yu
145  * NULL
146  * Update for BOW.
147  *
148  * 08 20 2010 cm.chang
149  * NULL
150  * Migrate RLM code to host from FW
151  *
152  * 08 19 2010 wh.su
153  * NULL
154  * adding the tx pkt call back handle for countermeasure.
155  *
156  * 07 08 2010 cp.wu
157  *
158  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
159  *
160  * 07 08 2010 cm.chang
161  * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
162  * Check draft RLM code for HT cap
163  *
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
167  *
168  * 07 05 2010 cm.chang
169  * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
170  * Fix correct structure size in cnmStaSendDeactivateCmd()
171  *
172  * 07 05 2010 cp.wu
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
177  *
178  * 07 02 2010 cp.wu
179  * [WPD00003833][MT6620 and MT5931] Driver migration
180  * spin lock target revised
181  *
182  * 07 02 2010 cp.wu
183  * [WPD00003833][MT6620 and MT5931] Driver migration
184  * change inner loop index from i to k.
185  *
186  * 07 01 2010 cm.chang
187  * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
188  * Support sync command of STA_REC
189  *
190  * 06 23 2010 yarco.yang
191  * [WPD00003837][MT6620]Data Path Refine
192  * Merge g_arStaRec[] into adapter->arStaRec[]
193  *
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
197  *
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
201  *
202  * 05 28 2010 cm.chang
203  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
204  * Support checking  of duplicated buffer free
205  *
206  * 05 28 2010 wh.su
207  * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing
208  * fixed the ad-hoc wpa-none send non-encrypted frame issue.
209  *
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
213  *
214  * 05 12 2010 kevin.huang
215  * [BORA00000794][WIFISYS][New Feature]Power Management Support
216  * Add Power Management - Legacy PS-POLL support.
217  *
218  * 04 28 2010 tehuang.liu
219  * [BORA00000605][WIFISYS] Phase3 Integration
220  * Modified some MQM-related data structures (SN counter, TX/RX BA table)
221  *
222  * 04 27 2010 tehuang.liu
223  * [BORA00000605][WIFISYS] Phase3 Integration
224  * Added new TX/RX BA tables in STA_REC
225  *
226  * 04 27 2010 tehuang.liu
227  * [BORA00000605][WIFISYS] Phase3 Integration
228  * Notify MQM, TXM, and RXM upon disconnection .
229  *
230  * 04 26 2010 tehuang.liu
231  * [BORA00000605][WIFISYS] Phase3 Integration
232  * Call mqm, txm, rxm functions upon disconnection
233  *
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
237  *
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
241  *
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
246  *
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
251  *
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
255  *
256  * 03 29 2010 wh.su
257  * [BORA00000605][WIFISYS] Phase3 Integration
258  * move the wlan table alloc / free to change state function.
259  *
260  * 03 24 2010 cm.chang
261  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
262  * Support power control
263  *
264  * 03 03 2010 tehuang.liu
265  * [BORA00000569][WIFISYS] Phase 2 Integration Test
266  * Initialize StaRec->arStaWaitQueue
267  *
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
271  *
272  * 03 01 2010 tehuang.liu
273  * [BORA00000569][WIFISYS] Phase 2 Integration Test
274  * Fixed STA_REC initialization bug: prStaRec->au2CachedSeqCtrl[k]
275  *
276  * 02 26 2010 tehuang.liu
277  * [BORA00000569][WIFISYS] Phase 2 Integration Test
278  * Added fgIsWmmSupported in STA_RECORD_T.
279  *
280  * 02 26 2010 tehuang.liu
281  * [BORA00000569][WIFISYS] Phase 2 Integration Test
282  * Added fgIsUapsdSupported in STA_RECORD_T
283  *
284  * 02 26 2010 kevin.huang
285  * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
286  * add support of Driver STA_RECORD_T activation
287  *
288  * 02 13 2010 tehuang.liu
289  * [BORA00000569][WIFISYS] Phase 2 Integration Test
290  * Added arTspecTable in STA_REC for TSPEC management
291  *
292  * 02 12 2010 cm.chang
293  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
294  * Enable mgmt buffer debug by default
295  *
296  * 02 12 2010 tehuang.liu
297  * [BORA00000569][WIFISYS] Phase 2 Integration Test
298  * Added BUFFER_SOURCE_BCN
299  *
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
303  *
304  * 01 11 2010 kevin.huang
305  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
306  * Add Deauth and Disassoc Handler
307  *
308  * 01 08 2010 cp.wu
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
313  *
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
320  *
321  * 12 24 2009 yarco.yang
322  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
323  * .
324  *
325  * 12 21 2009 cm.chang
326  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
327  * Support several data buffer banks.
328  *
329  * 12 18 2009 cm.chang
330  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
331  * .For new FPGA memory size
332  *
333  * Dec 9 2009 MTK02468
334  * [BORA00000337] To check in codes for FPGA emulation
335  * Removed DBGPRINT
336  *
337  * Dec 9 2009 mtk02752
338  * [BORA00000368] Integrate HIF part into BORA
339  * add cnmDataPktFree() for emulation loopback purpose
340  *
341  * Dec 3 2009 mtk01461
342  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
343  * Fix warning of null pointer
344  *
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
348  *
349  * Nov 23 2009 mtk01104
350  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
351  * Assign ucBufferSource in function cnmMgtPktAlloc()
352  *
353  * Nov 23 2009 mtk02468
354  * [BORA00000337] To check in codes for FPGA emulation
355  * Added packet redispatch function calls
356  *
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
360  *
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
365  *
366  * Nov 9 2009 mtk01104
367  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
368  * Call cnmDataPktDispatch() in cnmPktFree()
369  *
370  * Nov 2 2009 mtk01104
371  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
372  * Remove definition of pragma section code
373  *
374  * Oct 28 2009 mtk01104
375  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
376  *
377  *
378  * Oct 23 2009 mtk01461
379  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
380  * Fix lint warning
381  *
382  * Oct 23 2009 mtk01461
383  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
384  * Fix typo
385  *
386  * Oct 12 2009 mtk01104
387  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
388  *
389  *
390  * Oct 8 2009 mtk01104
391  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
392  *
393 **
394 */
395
396 /*******************************************************************************
397 *                         C O M P I L E R   F L A G S
398 ********************************************************************************
399 */
400
401 /*******************************************************************************
402 *                    E X T E R N A L   R E F E R E N C E S
403 ********************************************************************************
404 */
405 #include "precomp.h"
406
407 /*******************************************************************************
408 *                              C O N S T A N T S
409 ********************************************************************************
410 */
411
412 /*******************************************************************************
413 *                             D A T A   T Y P E S
414 ********************************************************************************
415 */
416
417 /*******************************************************************************
418 *                            P U B L I C   D A T A
419 ********************************************************************************
420 */
421
422 /*******************************************************************************
423 *                           P R I V A T E   D A T A
424 ********************************************************************************
425 */
426
427 /*******************************************************************************
428 *                                 M A C R O S
429 ********************************************************************************
430 */
431
432 /*******************************************************************************
433 *                   F U N C T I O N   D E C L A R A T I O N S
434 ********************************************************************************
435 */
436 static VOID
437 cnmStaRecHandleEventPkt (
438     P_ADAPTER_T     prAdapter,
439     P_CMD_INFO_T    prCmdInfo,
440     PUINT_8         pucEventBuf
441     );
442
443 static VOID
444 cnmStaSendUpdateCmd (
445     P_ADAPTER_T     prAdapter,
446     P_STA_RECORD_T  prStaRec,
447     BOOLEAN         fgNeedResp
448     );
449
450 static VOID
451 cnmStaSendRemoveCmd (
452     P_ADAPTER_T     prAdapter,
453     P_STA_RECORD_T  prStaRec
454     );
455
456 /*******************************************************************************
457 *                              F U N C T I O N S
458 ********************************************************************************
459 */
460
461 /*----------------------------------------------------------------------------*/
462 /*!
463 * \brief
464 *
465 * \param[in]
466 *
467 * \return none
468 */
469 /*----------------------------------------------------------------------------*/
470 P_MSDU_INFO_T
471 cnmMgtPktAlloc (
472     P_ADAPTER_T     prAdapter,
473     UINT_32         u4Length
474     )
475 {
476     P_MSDU_INFO_T   prMsduInfo;
477     P_QUE_T         prQueList;
478     KAL_SPIN_LOCK_DECLARATION();
479
480     ASSERT(prAdapter);
481     prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList;
482
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);
487
488     if (prMsduInfo) {
489         prMsduInfo->prPacket = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4Length);
490         prMsduInfo->eSrc = TX_PACKET_MGMT;
491
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);
496             prMsduInfo = NULL;
497         }
498     }
499
500 #if DBG
501     if (prMsduInfo == NULL) {
502         DBGLOG(MEM, WARN, ("\n"));
503         DBGLOG(MEM, WARN, ("MgtDesc#=%ld\n", prQueList->u4NumElem));
504
505 #if CFG_DBG_MGT_BUF
506         DBGLOG(MEM, WARN, ("rMgtBufInfo: alloc#=%ld, free#=%ld, null#=%ld\n",
507             prAdapter->rMgtBufInfo.u4AllocCount,
508             prAdapter->rMgtBufInfo.u4FreeCount,
509             prAdapter->rMgtBufInfo.u4AllocNullCount));
510 #endif
511
512         DBGLOG(MEM, WARN, ("\n"));
513     }
514 #endif
515
516     return prMsduInfo;
517 }
518
519 /*----------------------------------------------------------------------------*/
520 /*!
521 * \brief
522 *
523 * \param[in]
524 *
525 * \return none
526 */
527 /*----------------------------------------------------------------------------*/
528 VOID
529 cnmMgtPktFree (
530     P_ADAPTER_T     prAdapter,
531     P_MSDU_INFO_T   prMsduInfo
532     )
533 {
534     P_QUE_T         prQueList;
535     KAL_SPIN_LOCK_DECLARATION();
536
537     ASSERT(prAdapter);
538     ASSERT(prMsduInfo);
539
540     prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList;
541
542     ASSERT(prMsduInfo->prPacket);
543     if (prMsduInfo->prPacket) {
544         cnmMemFree(prAdapter, prMsduInfo->prPacket);
545         prMsduInfo->prPacket = NULL;
546     }
547
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);
551 }
552
553 /*----------------------------------------------------------------------------*/
554 /*!
555 * \brief This function is used to initial the MGMT/MSG memory pool.
556 *
557 * \param (none)
558 *
559 * \return (none)
560 */
561 /*----------------------------------------------------------------------------*/
562 VOID
563 cnmMemInit (
564     P_ADAPTER_T     prAdapter
565     )
566 {
567     P_BUF_INFO_T    prBufInfo;
568
569     /* Initialize Management buffer pool */
570     prBufInfo = &prAdapter->rMgtBufInfo;
571     kalMemZero(prBufInfo, sizeof(prAdapter->rMgtBufInfo));
572     prBufInfo->pucBuf = prAdapter->pucMgtBufCached;
573
574     /* Setup available memory blocks. 1 indicates FREE */
575     prBufInfo->rFreeBlocksBitmap =
576         (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1);
577
578
579     /* Initialize Message buffer pool */
580     prBufInfo = &prAdapter->rMsgBufInfo;
581     kalMemZero(prBufInfo, sizeof(prAdapter->rMsgBufInfo));
582     prBufInfo->pucBuf = &prAdapter->aucMsgBuf[0];
583
584     /* Setup available memory blocks. 1 indicates FREE */
585     prBufInfo->rFreeBlocksBitmap =
586         (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1);
587
588     return;
589
590 } /* end of cnmMemInit() */
591
592
593 /*----------------------------------------------------------------------------*/
594 /*!
595 * \brief Allocate MGMT/MSG memory pool.
596 *
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.
600 *
601 * \retval !NULL    Pointer to the start address of allocated memory.
602 * \retval NULL     Fail to allocat memory
603 */
604 /*----------------------------------------------------------------------------*/
605 PVOID
606 cnmMemAlloc (
607     IN P_ADAPTER_T      prAdapter,
608     IN ENUM_RAM_TYPE_T  eRamType,
609     IN UINT_32          u4Length
610     )
611 {
612     P_BUF_INFO_T        prBufInfo;
613     BUF_BITMAP          rRequiredBitmap;
614     UINT_32             u4BlockNum;
615     UINT_32             i, u4BlkSzInPower;
616     PVOID               pvMemory;
617     KAL_SPIN_LOCK_DECLARATION();
618
619     ASSERT(prAdapter);
620     ASSERT(u4Length);
621
622     if (eRamType == RAM_TYPE_MSG && u4Length <= 256) {
623         prBufInfo = &prAdapter->rMsgBufInfo;
624         u4BlkSzInPower = MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2;
625
626         u4Length += (MSG_BUF_BLOCK_SIZE - 1);
627         u4BlockNum = u4Length >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2;
628
629         ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS);
630     }
631     else {
632         eRamType = RAM_TYPE_BUF;
633
634         prBufInfo = &prAdapter->rMgtBufInfo;
635         u4BlkSzInPower = MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2;
636
637         u4Length += (MGT_BUF_BLOCK_SIZE - 1);
638         u4BlockNum = u4Length >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2;
639
640         ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS);
641     }
642
643 #if CFG_DBG_MGT_BUF
644     prBufInfo->u4AllocCount++;
645 #endif
646
647     KAL_ACQUIRE_SPIN_LOCK(prAdapter,
648         eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
649
650     if ((u4BlockNum > 0) && (u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS)) {
651
652         /* Convert number of block into bit cluster */
653         rRequiredBitmap = BITS(0, u4BlockNum-1);
654
655         for (i = 0; i <= (MAX_NUM_OF_BUF_BLOCKS - u4BlockNum); i++) {
656
657             /* Have available memory blocks */
658             if ((prBufInfo->rFreeBlocksBitmap & rRequiredBitmap)
659                 == rRequiredBitmap) {
660
661                 /* Clear corresponding bits of allocated memory blocks */
662                 prBufInfo->rFreeBlocksBitmap &= ~rRequiredBitmap;
663
664                 /* Store how many blocks be allocated */
665                 prBufInfo->aucAllocatedBlockNum[i] = (UINT_8) u4BlockNum;
666
667                 KAL_RELEASE_SPIN_LOCK(prAdapter,
668                         eRamType == RAM_TYPE_MSG ?
669                         SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
670
671                 /* Return the start address of allocated memory */
672                 return (PVOID)(prBufInfo->pucBuf + (i << u4BlkSzInPower));
673
674             }
675
676             rRequiredBitmap <<= 1;
677         }
678     }
679
680         KAL_RELEASE_SPIN_LOCK(prAdapter,
681         eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
682
683 #ifdef LINUX
684     pvMemory = (PVOID)kalMemAlloc(u4Length, VIR_MEM_TYPE);
685 #else
686     pvMemory = (PVOID)NULL;
687 #endif
688
689 KAL_ACQUIRE_SPIN_LOCK(prAdapter,
690         eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
691
692 #if CFG_DBG_MGT_BUF
693     prBufInfo->u4AllocNullCount++;
694
695     if (pvMemory) {
696         prAdapter->u4MemAllocDynamicCount++;
697     }
698 #endif
699     KAL_RELEASE_SPIN_LOCK(prAdapter,
700         eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
701
702     return pvMemory;
703
704 } /* end of cnmMemAlloc() */
705
706
707 /*----------------------------------------------------------------------------*/
708 /*!
709 * \brief Release memory to MGT/MSG memory pool.
710 *
711 * \param pucMemory  Start address of previous allocated memory
712 *
713 * \return (none)
714 */
715 /*----------------------------------------------------------------------------*/
716 VOID
717 cnmMemFree (
718     IN P_ADAPTER_T      prAdapter,
719     IN PVOID            pvMemory
720     )
721 {
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();
727
728
729     ASSERT(prAdapter);
730     ASSERT(pvMemory);
731     if (!pvMemory) {
732         return;
733     }
734
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])) {
738
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;
744     }
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;
752     }
753     else {
754     #ifdef LINUX
755         /* For Linux, it is supported because size is not needed */
756         kalMemFree(pvMemory, VIR_MEM_TYPE, 0);
757     #else
758         /* For Windows, it is not supported because of no size argument */
759         ASSERT(0);
760     #endif
761
762     #if CFG_DBG_MGT_BUF
763         prAdapter->u4MemFreeDynamicCount++;
764     #endif
765         return;
766     }
767
768     KAL_ACQUIRE_SPIN_LOCK(prAdapter,
769         eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
770
771 #if CFG_DBG_MGT_BUF
772     prBufInfo->u4FreeCount++;
773 #endif
774
775     /* Convert number of block into bit cluster */
776     ASSERT(prBufInfo->aucAllocatedBlockNum[u4BlockIndex] > 0);
777
778     rAllocatedBlocksBitmap =
779         BITS(0, prBufInfo->aucAllocatedBlockNum[u4BlockIndex] - 1);
780     rAllocatedBlocksBitmap <<= u4BlockIndex;
781
782     /* Clear saved block count for this memory segment */
783     prBufInfo->aucAllocatedBlockNum[u4BlockIndex] = 0;
784
785     /* Set corresponding bit of released memory block */
786     prBufInfo->rFreeBlocksBitmap |= rAllocatedBlocksBitmap;
787
788     KAL_RELEASE_SPIN_LOCK(prAdapter,
789         eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
790
791     return;
792
793 } /* end of cnmMemFree() */
794
795
796 /*----------------------------------------------------------------------------*/
797 /*!
798 * \brief
799 *
800 * \param[in]
801 *
802 * \return none
803 */
804 /*----------------------------------------------------------------------------*/
805 VOID
806 cnmStaRecInit (
807     P_ADAPTER_T     prAdapter
808     )
809 {
810     P_STA_RECORD_T  prStaRec;
811     UINT_16         i;
812
813     for (i = 0; i < CFG_STA_REC_NUM; i++) {
814         prStaRec = &prAdapter->arStaRec[i];
815
816         prStaRec->ucIndex = (UINT_8) i;
817         prStaRec->fgIsInUse = FALSE;
818     }
819 }
820
821
822 /*----------------------------------------------------------------------------*/
823 /*!
824 * \brief
825 *
826 * \param[in]
827 *
828 * \return none
829 */
830 /*----------------------------------------------------------------------------*/
831 VOID
832 cnmStaRecUninit (
833     IN P_ADAPTER_T  prAdapter
834     )
835 {
836     P_STA_RECORD_T  prStaRec;
837     UINT_16         i;
838
839     for (i = 0; i < CFG_STA_REC_NUM; i++) {
840         prStaRec = &prAdapter->arStaRec[i];
841
842         if (prStaRec->fgIsInUse) {
843             cnmStaRecFree(prAdapter, prStaRec, FALSE);
844         }
845     }
846 }
847
848
849 /*----------------------------------------------------------------------------*/
850 /*!
851 * \brief
852 *
853 * \param[in]
854 *
855 * \return none
856 */
857 /*----------------------------------------------------------------------------*/
858 P_STA_RECORD_T
859 cnmStaRecAlloc (
860     P_ADAPTER_T     prAdapter,
861     UINT_8          ucNetTypeIndex
862     )
863 {
864     P_STA_RECORD_T  prStaRec;
865     UINT_16         i, k;
866
867     ASSERT(prAdapter);
868
869     for (i = 0; i < CFG_STA_REC_NUM; i++) {
870         prStaRec = &prAdapter->arStaRec[i];
871
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;
878
879             if (prStaRec->pucAssocReqIe) {
880                 kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen);
881                 prStaRec->pucAssocReqIe = NULL;
882                 prStaRec->u2AssocReqIeLen = 0;
883             }
884
885             /* Initialize the SN caches for duplicate detection */
886             for (k = 0; k < TID_NUM + 1; k++) {
887                 prStaRec->au2CachedSeqCtrl[k] = 0xFFFF;
888             }
889
890             /* Initialize SW TX queues in STA_REC */
891             for (k = 0; k < STA_WAIT_QUEUE_NUM; k++) {
892                 LINK_INITIALIZE(&prStaRec->arStaWaitQueue[k]);
893             }
894
895             /* Default enable TX/RX AMPDU */
896             prStaRec->fgTxAmpduEn = TRUE;
897             prStaRec->fgRxAmpduEn = TRUE;
898
899             for (k = 0; k < NUM_OF_PER_STA_TX_QUEUES; k++) {
900                 QUEUE_INITIALIZE(&prStaRec->arTxQueue[k]);
901             }
902
903             break;
904         }
905     }
906
907     return (i < CFG_STA_REC_NUM) ? prStaRec : NULL;
908 }
909
910
911 /*----------------------------------------------------------------------------*/
912 /*!
913 * \brief
914 *
915 * \param[in]
916 *
917 * \return none
918 */
919 /*----------------------------------------------------------------------------*/
920 VOID
921 cnmStaRecFree (
922     P_ADAPTER_T     prAdapter,
923     P_STA_RECORD_T  prStaRec,
924     BOOLEAN         fgSyncToChip
925     )
926 {
927     ASSERT(prAdapter);
928     ASSERT(prStaRec);
929
930     /* To do: free related resources, e.g. timers, buffers, etc */
931     cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
932     prStaRec->fgTransmitKeyExist = FALSE;
933     prStaRec->fgSetPwrMgtBit = FALSE;
934
935     if (prStaRec->pucAssocReqIe) {
936         kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen);
937         prStaRec->pucAssocReqIe = NULL;
938         prStaRec->u2AssocReqIeLen = 0;
939     }
940
941     qmDeactivateStaRec(prAdapter, prStaRec->ucIndex);
942
943     if (fgSyncToChip) {
944         cnmStaSendRemoveCmd(prAdapter, prStaRec);
945     }
946
947     prStaRec->fgIsInUse = FALSE;
948
949     return;
950 }
951
952 /*----------------------------------------------------------------------------*/
953 /*!
954 * \brief
955 *
956 * \param[in]
957 *
958 * \return none
959 */
960 /*----------------------------------------------------------------------------*/
961 VOID
962 cnmStaFreeAllStaByNetType (
963     P_ADAPTER_T                 prAdapter,
964     ENUM_NETWORK_TYPE_INDEX_T   eNetTypeIndex,
965     BOOLEAN                     fgSyncToChip
966     )
967 {
968     P_STA_RECORD_T  prStaRec;
969     UINT_16         i;
970
971     for (i = 0; i < CFG_STA_REC_NUM; i++) {
972         prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i];
973
974         if (prStaRec->fgIsInUse &&
975             prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex) {
976
977             cnmStaRecFree(prAdapter, prStaRec, fgSyncToChip);
978         }
979     } /* end of for loop */
980 }
981
982 /*----------------------------------------------------------------------------*/
983 /*!
984 * \brief
985 *
986 * \param[in]
987 *
988 * \return none
989 */
990 /*----------------------------------------------------------------------------*/
991 P_STA_RECORD_T
992 cnmGetStaRecByIndex (
993     P_ADAPTER_T     prAdapter,
994     UINT_8          ucIndex
995     )
996 {
997     P_STA_RECORD_T  prStaRec;
998
999     ASSERT(prAdapter);
1000
1001     prStaRec = (ucIndex < CFG_STA_REC_NUM) ?
1002                &prAdapter->arStaRec[ucIndex] : NULL;
1003
1004     if (prStaRec && prStaRec->fgIsInUse == FALSE) {
1005         prStaRec = NULL;
1006     }
1007
1008     return prStaRec;
1009 }
1010
1011 /*----------------------------------------------------------------------------*/
1012 /*!
1013 * @brief Get STA_RECORD_T by Peer MAC Address(Usually TA).
1014 *
1015 * @param[in] pucPeerMacAddr      Given Peer MAC Address.
1016 *
1017 * @retval   Pointer to STA_RECORD_T, if found. NULL, if not found
1018 */
1019 /*----------------------------------------------------------------------------*/
1020 P_STA_RECORD_T
1021 cnmGetStaRecByAddress (
1022     P_ADAPTER_T     prAdapter,
1023     UINT_8          ucNetTypeIndex,
1024     PUINT_8         pucPeerMacAddr
1025     )
1026 {
1027     P_STA_RECORD_T  prStaRec;
1028     UINT_16         i;
1029
1030     ASSERT(prAdapter);
1031     ASSERT(pucPeerMacAddr);
1032
1033     for (i = 0; i < CFG_STA_REC_NUM; i++) {
1034         prStaRec = &prAdapter->arStaRec[i];
1035
1036         if (prStaRec->fgIsInUse &&
1037             prStaRec->ucNetTypeIndex == ucNetTypeIndex &&
1038             EQUAL_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMacAddr)) {
1039             break;
1040         }
1041     }
1042
1043     return (i < CFG_STA_REC_NUM) ? prStaRec : NULL;
1044 }
1045
1046 /*----------------------------------------------------------------------------*/
1047 /*!
1048 * @brief Reset the Status and Reason Code Field to 0 of all Station Records for
1049 *        the specified Network Type
1050 *
1051 * @param[in] eNetType       Specify Network Type
1052 *
1053 * @return   (none)
1054 */
1055 /*----------------------------------------------------------------------------*/
1056 VOID
1057 cnmStaRecResetStatus (
1058     P_ADAPTER_T                 prAdapter,
1059     ENUM_NETWORK_TYPE_INDEX_T   eNetTypeIndex
1060     )
1061 {
1062     cnmStaFreeAllStaByNetType(prAdapter, eNetTypeIndex, FALSE);
1063
1064 #if 0
1065     P_STA_RECORD_T  prStaRec;
1066     UINT_16         i;
1067
1068     ASSERT(prAdapter);
1069
1070     for (i = 0; i < CFG_STA_REC_NUM; i++) {
1071         prStaRec = &prAdapter->arStaRec[i];
1072
1073         if (prStaRec->fgIsInUse) {
1074             if ((NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) &&
1075                 IS_STA_IN_AIS(prStaRec->eStaType)) {
1076
1077                 prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL;
1078                 prStaRec->u2ReasonCode = REASON_CODE_RESERVED;
1079                 prStaRec->ucJoinFailureCount = 0;
1080                 prStaRec->fgTransmitKeyExist = FALSE;
1081
1082                 prStaRec->fgSetPwrMgtBit = FALSE;
1083             }
1084
1085             /* TODO(Kevin): For P2P and BOW */
1086         }
1087     }
1088
1089     return;
1090 #endif
1091 }
1092
1093 /*----------------------------------------------------------------------------*/
1094 /*!
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.
1097 *
1098 * @param[in] prStaRec       Pointer to the STA_RECORD_T
1099 * @param[in] u4NewState     New STATE to change.
1100 *
1101 * @return (none)
1102 */
1103 /*----------------------------------------------------------------------------*/
1104 VOID
1105 cnmStaRecChangeState (
1106     P_ADAPTER_T     prAdapter,
1107     P_STA_RECORD_T  prStaRec,
1108     UINT_8          ucNewState
1109     )
1110 {
1111     BOOLEAN         fgNeedResp;
1112
1113     ASSERT(prAdapter);
1114     ASSERT(prStaRec);
1115     ASSERT(prStaRec->fgIsInUse);
1116
1117     /* Do nothing when following state transitions happen,
1118      * other 6 conditions should be sync to FW, including 1-->1, 3-->3
1119      */
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;
1123         return;
1124     }
1125
1126     fgNeedResp = FALSE;
1127     if (ucNewState == STA_STATE_3) {
1128         secFsmEventStart(prAdapter, prStaRec);
1129         if (ucNewState != prStaRec->ucStaState) {
1130             fgNeedResp = TRUE;
1131         }
1132     }
1133     else {
1134         if (ucNewState != prStaRec->ucStaState &&
1135             prStaRec->ucStaState == STA_STATE_3) {
1136             qmDeactivateStaRec(prAdapter, prStaRec->ucIndex);
1137         }
1138         fgNeedResp = FALSE;
1139     }
1140     prStaRec->ucStaState = ucNewState;
1141
1142     cnmStaSendUpdateCmd(prAdapter, prStaRec, fgNeedResp);
1143
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
1148      */
1149     if (prAdapter->fgIsP2PRegistered && (IS_STA_IN_P2P(prStaRec))) {
1150         P_BSS_INFO_T    prBssInfo;
1151
1152         prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
1153
1154         if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
1155             rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE);
1156         }
1157     }
1158 #endif
1159     return;
1160 }
1161
1162 /*----------------------------------------------------------------------------*/
1163 /*!
1164 * @brief
1165 *
1166 * @param[in]
1167 *
1168 * @return (none)
1169 */
1170 /*----------------------------------------------------------------------------*/
1171 static VOID
1172 cnmStaRecHandleEventPkt (
1173     P_ADAPTER_T     prAdapter,
1174     P_CMD_INFO_T    prCmdInfo,
1175     PUINT_8         pucEventBuf
1176     )
1177 {
1178     P_EVENT_ACTIVATE_STA_REC_T  prEventContent;
1179     P_STA_RECORD_T              prStaRec;
1180
1181     prEventContent = (P_EVENT_ACTIVATE_STA_REC_T) pucEventBuf;
1182     prStaRec = cnmGetStaRecByIndex(prAdapter, prEventContent->ucStaRecIdx);
1183
1184     if (prStaRec && prStaRec->ucStaState == STA_STATE_3 &&
1185         !kalMemCmp(&prStaRec->aucMacAddr[0], &prEventContent->aucMacAddr[0],
1186                     MAC_ADDR_LEN)) {
1187
1188         qmActivateStaRec(prAdapter, prStaRec);
1189     }
1190
1191 }
1192
1193 /*----------------------------------------------------------------------------*/
1194 /*!
1195 * @brief
1196 *
1197 * @param[in]
1198 *
1199 * @return (none)
1200 */
1201 /*----------------------------------------------------------------------------*/
1202 static VOID
1203 cnmStaSendUpdateCmd (
1204     P_ADAPTER_T     prAdapter,
1205     P_STA_RECORD_T  prStaRec,
1206     BOOLEAN         fgNeedResp
1207     )
1208 {
1209     P_CMD_UPDATE_STA_RECORD_T   prCmdContent;
1210     WLAN_STATUS                 rStatus;
1211
1212     ASSERT(prAdapter);
1213     ASSERT(prStaRec);
1214     ASSERT(prStaRec->fgIsInUse);
1215
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
1218      *        simultaneously.
1219      */
1220
1221     /* To do: how to avoid 2 times of allocated memory. Use Stack?
1222      *        One is here, the other is in wlanSendQueryCmd()
1223      */
1224     prCmdContent = cnmMemAlloc(prAdapter,
1225                         RAM_TYPE_BUF, sizeof(CMD_UPDATE_STA_RECORD_T));
1226     ASSERT(prCmdContent);
1227
1228     /* To do: exception handle */
1229     if (!prCmdContent) {
1230         return;
1231     }
1232
1233     prCmdContent->ucIndex = prStaRec->ucIndex;
1234     prCmdContent->ucStaType = (UINT_8) prStaRec->eStaType;
1235     kalMemCopy(&prCmdContent->aucMacAddr[0], &prStaRec->aucMacAddr[0],
1236                MAC_ADDR_LEN);
1237     prCmdContent->u2AssocId = prStaRec->u2AssocId;
1238     prCmdContent->u2ListenInterval = prStaRec->u2ListenInterval;
1239     prCmdContent->ucNetTypeIndex = prStaRec->ucNetTypeIndex;
1240
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;
1248
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));
1260     }
1261 #endif
1262
1263     prCmdContent->ucIsQoS = prStaRec->fgIsQoS;
1264     prCmdContent->ucIsUapsdSupported = prStaRec->fgIsUapsdSupported;
1265     prCmdContent->ucStaState = prStaRec->ucStaState;
1266
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;
1272
1273     prCmdContent->ucUapsdAc = prStaRec->ucBmpTriggerAC | (prStaRec->ucBmpDeliveryAC << 4);
1274     prCmdContent->ucUapsdSp = prStaRec->ucUapsdSp;
1275
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 */
1288                 );
1289
1290     ASSERT(rStatus == WLAN_STATUS_PENDING);
1291
1292     cnmMemFree(prAdapter, prCmdContent);
1293 }
1294
1295 /*----------------------------------------------------------------------------*/
1296 /*!
1297 * @brief
1298 *
1299 * @param[in]
1300 *
1301 * @return (none)
1302 */
1303 /*----------------------------------------------------------------------------*/
1304 static VOID
1305 cnmStaSendRemoveCmd (
1306     P_ADAPTER_T     prAdapter,
1307     P_STA_RECORD_T  prStaRec
1308     )
1309 {
1310     CMD_REMOVE_STA_RECORD_T     rCmdContent;
1311     WLAN_STATUS                 rStatus;
1312
1313     ASSERT(prAdapter);
1314     ASSERT(prStaRec);
1315
1316     rCmdContent.ucIndex = prStaRec->ucIndex;
1317     kalMemCopy(&rCmdContent.aucMacAddr[0], &prStaRec->aucMacAddr[0],
1318                MAC_ADDR_LEN);
1319
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 */
1332                 );
1333
1334     ASSERT(rStatus == WLAN_STATUS_PENDING);
1335 }
1336
1337