add MTK-combo-module,continue with commit 17f39ed917874e77e80411f33faba1b7ee8138c8
[firefly-linux-kernel-4.4.55.git] / drivers / mtk_wcn_combo / drv_wlan / wlan / mgmt / cnm_mem.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/cnm_mem.c#2 $
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  * 01 17 2012 wh.su
59  * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting
60  * Adding the related code which support beacon can reflect the security setting open or WPA2-PSK, WPA-PSK not yet
61  * Adn support the indicate the assoc request ie at New STA CMD, needed kernel patch.
62  *
63  * 11 17 2011 tsaiyuan.hsu
64  * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3.
65  * initialize fgNeedResp.
66  *
67  * 11 17 2011 tsaiyuan.hsu
68  * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3.
69  * avoid deactivating staRec when changing state from 3 to 3.
70  *
71  * 03 18 2011 cp.wu
72  * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver
73  * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk
74  *
75  * 02 01 2011 cm.chang
76  * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode
77  * .
78  *
79  * 01 26 2011 cm.chang
80  * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
81  * Allocate system RAM if fixed message or mgmt buffer is not available
82  *
83  * 01 26 2011 cm.chang
84  * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
85  * .
86  *
87  * 01 25 2011 yuche.tsai
88  * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
89  * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role.
90  *
91  * 12 13 2010 cp.wu
92  * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver
93  * create branch for Wi-Fi driver v1.1
94  *
95  * 12 07 2010 cm.chang
96  * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
97  * 1. BSSINFO include RLM parameter
98  * 2. free all sta records when network is disconnected
99  *
100  * 11 29 2010 cm.chang
101  * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for initial TX rate selection of auto-rate algorithm
102  * Sync RCPI of STA_REC to FW as reference of initial TX rate
103  *
104  * 11 25 2010 yuche.tsai
105  * NULL
106  * Update SLT Function for QoS Support and not be affected by fixed rate function.
107  *
108  * 10 18 2010 cp.wu
109  * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS associated
110  * 1. remove redundant variables in STA_REC structure
111  * 2. add STA-REC uninitialization routine for clearing pending events
112  *
113  * 10 13 2010 cm.chang
114  * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash.
115  * Add exception handle when cmd buffer is not available
116  *
117  * 10 12 2010 cp.wu
118  * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
119  * add HT (802.11n) fixed rate support.
120  *
121  * 10 08 2010 cp.wu
122  * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
123  * adding fixed rate support for distance test. (from registry setting)
124  *
125  * 09 24 2010 wh.su
126  * NULL
127  * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning.
128  *
129  * 09 21 2010 cp.wu
130  * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS associated
131  * Do a complete reset with STA-REC null checking for RF test re-entry
132  *
133  * 09 16 2010 cm.chang
134  * NULL
135  * Change conditional compiling options for BOW
136  *
137  * 09 10 2010 cm.chang
138  * NULL
139  * Always update Beacon content if FW sync OBSS info
140  *
141  * 08 24 2010 cm.chang
142  * NULL
143  * Support RLM initail channel of Ad-hoc, P2P and BOW
144  *
145  * 08 23 2010 chinghwa.yu
146  * NULL
147  * Update for BOW.
148  *
149  * 08 20 2010 cm.chang
150  * NULL
151  * Migrate RLM code to host from FW
152  *
153  * 08 19 2010 wh.su
154  * NULL
155  * adding the tx pkt call back handle for countermeasure.
156  *
157  * 07 08 2010 cp.wu
158  *
159  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
160  *
161  * 07 08 2010 cm.chang
162  * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
163  * Check draft RLM code for HT cap
164  *
165  * 07 07 2010 cm.chang
166  * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
167  * Support state of STA record change from 1 to 1
168  *
169  * 07 05 2010 cm.chang
170  * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
171  * Fix correct structure size in cnmStaSendDeactivateCmd()
172  *
173  * 07 05 2010 cp.wu
174  * [WPD00003833][MT6620 and MT5931] Driver migration
175  * 1) ignore RSN checking when RSN is not turned on.
176  * 2) set STA-REC deactivation callback as NULL
177  * 3) add variable initialization API based on PHY configuration
178  *
179  * 07 02 2010 cp.wu
180  * [WPD00003833][MT6620 and MT5931] Driver migration
181  * spin lock target revised
182  *
183  * 07 02 2010 cp.wu
184  * [WPD00003833][MT6620 and MT5931] Driver migration
185  * change inner loop index from i to k.
186  *
187  * 07 01 2010 cm.chang
188  * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
189  * Support sync command of STA_REC
190  *
191  * 06 23 2010 yarco.yang
192  * [WPD00003837][MT6620]Data Path Refine
193  * Merge g_arStaRec[] into adapter->arStaRec[]
194  *
195  * 06 18 2010 cm.chang
196  * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
197  * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
198  *
199  * 05 31 2010 yarco.yang
200  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
201  * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling
202  *
203  * 05 28 2010 cm.chang
204  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
205  * Support checking  of duplicated buffer free
206  *
207  * 05 28 2010 wh.su
208  * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing
209  * fixed the ad-hoc wpa-none send non-encrypted frame issue.
210  *
211  * 05 28 2010 kevin.huang
212  * [BORA00000794][WIFISYS][New Feature]Power Management Support
213  * Move define of STA_REC_NUM to config.h and rename to CFG_STA_REC_NUM
214  *
215  * 05 12 2010 kevin.huang
216  * [BORA00000794][WIFISYS][New Feature]Power Management Support
217  * Add Power Management - Legacy PS-POLL support.
218  *
219  * 04 28 2010 tehuang.liu
220  * [BORA00000605][WIFISYS] Phase3 Integration
221  * Modified some MQM-related data structures (SN counter, TX/RX BA table)
222  *
223  * 04 27 2010 tehuang.liu
224  * [BORA00000605][WIFISYS] Phase3 Integration
225  * Added new TX/RX BA tables in STA_REC
226  *
227  * 04 27 2010 tehuang.liu
228  * [BORA00000605][WIFISYS] Phase3 Integration
229  * Notify MQM, TXM, and RXM upon disconnection .
230  *
231  * 04 26 2010 tehuang.liu
232  * [BORA00000605][WIFISYS] Phase3 Integration
233  * Call mqm, txm, rxm functions upon disconnection
234  *
235  * 04 24 2010 cm.chang
236  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
237  * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
238  *
239  * 04 22 2010 cm.chang
240  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
241  * First draft code to support protection in AP mode
242  *
243  * 04 19 2010 kevin.huang
244  * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
245  * Add Beacon Timeout Support
246  *  *  *  *  *  *  *  *  *  *  and will send Null frame to diagnose connection
247  *
248  * 04 09 2010 tehuang.liu
249  * [BORA00000605][WIFISYS] Phase3 Integration
250  * [BORA00000644] WiFi phase 4 integration
251  *  * Added per-TID SN cache in STA_REC
252  *
253  * 04 07 2010 cm.chang
254  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
255  * Different invoking order for WTBL entry of associated AP
256  *
257  * 03 29 2010 wh.su
258  * [BORA00000605][WIFISYS] Phase3 Integration
259  * move the wlan table alloc / free to change state function.
260  *
261  * 03 24 2010 cm.chang
262  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
263  * Support power control
264  *
265  * 03 03 2010 tehuang.liu
266  * [BORA00000569][WIFISYS] Phase 2 Integration Test
267  * Initialize StaRec->arStaWaitQueue
268  *
269  * 03 03 2010 cm.chang
270  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
271  * Add debug message when no available pkt buffer
272  *
273  * 03 01 2010 tehuang.liu
274  * [BORA00000569][WIFISYS] Phase 2 Integration Test
275  * Fixed STA_REC initialization bug: prStaRec->au2CachedSeqCtrl[k]
276  *
277  * 02 26 2010 tehuang.liu
278  * [BORA00000569][WIFISYS] Phase 2 Integration Test
279  * Added fgIsWmmSupported in STA_RECORD_T.
280  *
281  * 02 26 2010 tehuang.liu
282  * [BORA00000569][WIFISYS] Phase 2 Integration Test
283  * Added fgIsUapsdSupported in STA_RECORD_T
284  *
285  * 02 26 2010 kevin.huang
286  * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
287  * add support of Driver STA_RECORD_T activation
288  *
289  * 02 13 2010 tehuang.liu
290  * [BORA00000569][WIFISYS] Phase 2 Integration Test
291  * Added arTspecTable in STA_REC for TSPEC management
292  *
293  * 02 12 2010 cm.chang
294  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
295  * Enable mgmt buffer debug by default
296  *
297  * 02 12 2010 tehuang.liu
298  * [BORA00000569][WIFISYS] Phase 2 Integration Test
299  * Added BUFFER_SOURCE_BCN
300  *
301  * 02 04 2010 kevin.huang
302  * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
303  * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
304  *
305  * 01 11 2010 kevin.huang
306  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
307  * Add Deauth and Disassoc Handler
308  *
309  * 01 08 2010 cp.wu
310  * [BORA00000368]Integrate HIF part into BORA
311  * 1) separate wifi_var_emu.c/.h from wifi_var.c/.h
312  *  *  *  *  *  *  *  *  * 2) eliminate HIF_EMULATION code sections appeared in wifi_var/cnm_mem
313  *  *  *  *  *  *  *  *  * 3) use cnmMemAlloc() instead to allocate SRAM buffer
314  *
315  * 12 25 2009 tehuang.liu
316  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
317  * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM)
318  *  *  *  *  *  *  * MQM: BA handling
319  *  *  *  *  *  *  * TXM: Macros updates
320  *  *  *  *  *  *  * RXM: Macros/Duplicate Removal updates
321  *
322  * 12 24 2009 yarco.yang
323  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
324  * .
325  *
326  * 12 21 2009 cm.chang
327  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
328  * Support several data buffer banks.
329  *
330  * 12 18 2009 cm.chang
331  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
332  * .For new FPGA memory size
333  *
334  * Dec 9 2009 MTK02468
335  * [BORA00000337] To check in codes for FPGA emulation
336  * Removed DBGPRINT
337  *
338  * Dec 9 2009 mtk02752
339  * [BORA00000368] Integrate HIF part into BORA
340  * add cnmDataPktFree() for emulation loopback purpose
341  *
342  * Dec 3 2009 mtk01461
343  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
344  * Fix warning of null pointer
345  *
346  * Dec 3 2009 mtk01461
347  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
348  * Add cnmGetStaRecByAddress() and add fgIsInUse flag in STA_RECORD_T
349  *
350  * Nov 23 2009 mtk01104
351  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
352  * Assign ucBufferSource in function cnmMgtPktAlloc()
353  *
354  * Nov 23 2009 mtk02468
355  * [BORA00000337] To check in codes for FPGA emulation
356  * Added packet redispatch function calls
357  *
358  * Nov 13 2009 mtk01084
359  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
360  * enable packet re-usable in current emulation driver
361  *
362  * Nov 12 2009 mtk01104
363  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
364  * 1. Add new function cnmGetStaRecByIndex()
365  * 2. Rename STA_REC_T to STA_RECORD_T
366  *
367  * Nov 9 2009 mtk01104
368  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
369  * Call cnmDataPktDispatch() in cnmPktFree()
370  *
371  * Nov 2 2009 mtk01104
372  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
373  * Remove definition of pragma section code
374  *
375  * Oct 28 2009 mtk01104
376  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
377  *
378  *
379  * Oct 23 2009 mtk01461
380  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
381  * Fix lint warning
382  *
383  * Oct 23 2009 mtk01461
384  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
385  * Fix typo
386  *
387  * Oct 12 2009 mtk01104
388  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
389  *
390  *
391  * Oct 8 2009 mtk01104
392  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
393  *
394 **
395 */
396
397 /*******************************************************************************
398 *                         C O M P I L E R   F L A G S
399 ********************************************************************************
400 */
401
402 /*******************************************************************************
403 *                    E X T E R N A L   R E F E R E N C E S
404 ********************************************************************************
405 */
406 #include "precomp.h"
407
408 /*******************************************************************************
409 *                              C O N S T A N T S
410 ********************************************************************************
411 */
412
413 /*******************************************************************************
414 *                             D A T A   T Y P E S
415 ********************************************************************************
416 */
417
418 /*******************************************************************************
419 *                            P U B L I C   D A T A
420 ********************************************************************************
421 */
422
423 /*******************************************************************************
424 *                           P R I V A T E   D A T A
425 ********************************************************************************
426 */
427
428 /*******************************************************************************
429 *                                 M A C R O S
430 ********************************************************************************
431 */
432
433 /*******************************************************************************
434 *                   F U N C T I O N   D E C L A R A T I O N S
435 ********************************************************************************
436 */
437 static VOID
438 cnmStaRecHandleEventPkt (
439     P_ADAPTER_T     prAdapter,
440     P_CMD_INFO_T    prCmdInfo,
441     PUINT_8         pucEventBuf
442     );
443
444 static VOID
445 cnmStaSendUpdateCmd (
446     P_ADAPTER_T     prAdapter,
447     P_STA_RECORD_T  prStaRec,
448     BOOLEAN         fgNeedResp
449     );
450
451 static VOID
452 cnmStaSendRemoveCmd (
453     P_ADAPTER_T     prAdapter,
454     P_STA_RECORD_T  prStaRec
455     );
456
457 /*******************************************************************************
458 *                              F U N C T I O N S
459 ********************************************************************************
460 */
461
462 /*----------------------------------------------------------------------------*/
463 /*!
464 * \brief
465 *
466 * \param[in]
467 *
468 * \return none
469 */
470 /*----------------------------------------------------------------------------*/
471 P_MSDU_INFO_T
472 cnmMgtPktAlloc (
473     P_ADAPTER_T     prAdapter,
474     UINT_32         u4Length
475     )
476 {
477     P_MSDU_INFO_T   prMsduInfo;
478     P_QUE_T         prQueList;
479     KAL_SPIN_LOCK_DECLARATION();
480
481     ASSERT(prAdapter);
482     prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList;
483
484     /* Get a free MSDU_INFO_T */
485     KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
486     QUEUE_REMOVE_HEAD(prQueList, prMsduInfo, P_MSDU_INFO_T);
487     KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
488
489     if (prMsduInfo) {
490         prMsduInfo->prPacket = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4Length);
491         prMsduInfo->eSrc = TX_PACKET_MGMT;
492
493         if (prMsduInfo->prPacket == NULL) {
494             KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
495             QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry);
496             KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
497             prMsduInfo = NULL;
498         }
499     }
500
501 #if DBG
502     if (prMsduInfo == NULL) {
503         DBGLOG(MEM, WARN, ("\n"));
504         DBGLOG(MEM, WARN, ("MgtDesc#=%ld\n", prQueList->u4NumElem));
505
506 #if CFG_DBG_MGT_BUF
507         DBGLOG(MEM, WARN, ("rMgtBufInfo: alloc#=%ld, free#=%ld, null#=%ld\n",
508             prAdapter->rMgtBufInfo.u4AllocCount,
509             prAdapter->rMgtBufInfo.u4FreeCount,
510             prAdapter->rMgtBufInfo.u4AllocNullCount));
511 #endif
512
513         DBGLOG(MEM, WARN, ("\n"));
514     }
515 #endif
516
517     return prMsduInfo;
518 }
519
520 /*----------------------------------------------------------------------------*/
521 /*!
522 * \brief
523 *
524 * \param[in]
525 *
526 * \return none
527 */
528 /*----------------------------------------------------------------------------*/
529 VOID
530 cnmMgtPktFree (
531     P_ADAPTER_T     prAdapter,
532     P_MSDU_INFO_T   prMsduInfo
533     )
534 {
535     P_QUE_T         prQueList;
536     KAL_SPIN_LOCK_DECLARATION();
537
538     ASSERT(prAdapter);
539     ASSERT(prMsduInfo);
540
541     prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList;
542
543     ASSERT(prMsduInfo->prPacket);
544     if (prMsduInfo->prPacket) {
545         cnmMemFree(prAdapter, prMsduInfo->prPacket);
546         prMsduInfo->prPacket = NULL;
547     }
548
549     KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
550     QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry)
551     KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
552 }
553
554 /*----------------------------------------------------------------------------*/
555 /*!
556 * \brief This function is used to initial the MGMT/MSG memory pool.
557 *
558 * \param (none)
559 *
560 * \return (none)
561 */
562 /*----------------------------------------------------------------------------*/
563 VOID
564 cnmMemInit (
565     P_ADAPTER_T     prAdapter
566     )
567 {
568     P_BUF_INFO_T    prBufInfo;
569
570     /* Initialize Management buffer pool */
571     prBufInfo = &prAdapter->rMgtBufInfo;
572     kalMemZero(prBufInfo, sizeof(prAdapter->rMgtBufInfo));
573     prBufInfo->pucBuf = prAdapter->pucMgtBufCached;
574
575     /* Setup available memory blocks. 1 indicates FREE */
576     prBufInfo->rFreeBlocksBitmap =
577         (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1);
578
579
580     /* Initialize Message buffer pool */
581     prBufInfo = &prAdapter->rMsgBufInfo;
582     kalMemZero(prBufInfo, sizeof(prAdapter->rMsgBufInfo));
583     prBufInfo->pucBuf = &prAdapter->aucMsgBuf[0];
584
585     /* Setup available memory blocks. 1 indicates FREE */
586     prBufInfo->rFreeBlocksBitmap =
587         (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1);
588
589     return;
590
591 } /* end of cnmMemInit() */
592
593
594 /*----------------------------------------------------------------------------*/
595 /*!
596 * \brief Allocate MGMT/MSG memory pool.
597 *
598 * \param[in] eRamType       Target RAM type.
599 *                           TCM blk_sz= 16bytes, BUF blk_sz= 256bytes
600 * \param[in] u4Length       Length of the buffer to allocate.
601 *
602 * \retval !NULL    Pointer to the start address of allocated memory.
603 * \retval NULL     Fail to allocat memory
604 */
605 /*----------------------------------------------------------------------------*/
606 PVOID
607 cnmMemAlloc (
608     IN P_ADAPTER_T      prAdapter,
609     IN ENUM_RAM_TYPE_T  eRamType,
610     IN UINT_32          u4Length
611     )
612 {
613     P_BUF_INFO_T        prBufInfo;
614     BUF_BITMAP          rRequiredBitmap;
615     UINT_32             u4BlockNum;
616     UINT_32             i, u4BlkSzInPower;
617     PVOID               pvMemory;
618     KAL_SPIN_LOCK_DECLARATION();
619
620     ASSERT(prAdapter);
621     ASSERT(u4Length);
622
623     if (eRamType == RAM_TYPE_MSG && u4Length <= 256) {
624         prBufInfo = &prAdapter->rMsgBufInfo;
625         u4BlkSzInPower = MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2;
626
627         u4Length += (MSG_BUF_BLOCK_SIZE - 1);
628         u4BlockNum = u4Length >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2;
629
630         ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS);
631     }
632     else {
633         eRamType = RAM_TYPE_BUF;
634
635         prBufInfo = &prAdapter->rMgtBufInfo;
636         u4BlkSzInPower = MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2;
637
638         u4Length += (MGT_BUF_BLOCK_SIZE - 1);
639         u4BlockNum = u4Length >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2;
640
641         ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS);
642     }
643
644 #if CFG_DBG_MGT_BUF
645     prBufInfo->u4AllocCount++;
646 #endif
647
648     KAL_ACQUIRE_SPIN_LOCK(prAdapter,
649         eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
650
651     if ((u4BlockNum > 0) && (u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS)) {
652
653         /* Convert number of block into bit cluster */
654         rRequiredBitmap = BITS(0, u4BlockNum-1);
655
656         for (i = 0; i <= (MAX_NUM_OF_BUF_BLOCKS - u4BlockNum); i++) {
657
658             /* Have available memory blocks */
659             if ((prBufInfo->rFreeBlocksBitmap & rRequiredBitmap)
660                 == rRequiredBitmap) {
661
662                 /* Clear corresponding bits of allocated memory blocks */
663                 prBufInfo->rFreeBlocksBitmap &= ~rRequiredBitmap;
664
665                 /* Store how many blocks be allocated */
666                 prBufInfo->aucAllocatedBlockNum[i] = (UINT_8) u4BlockNum;
667
668                 KAL_RELEASE_SPIN_LOCK(prAdapter,
669                         eRamType == RAM_TYPE_MSG ?
670                         SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
671
672                 /* Return the start address of allocated memory */
673                 return (PVOID)(prBufInfo->pucBuf + (i << u4BlkSzInPower));
674
675             }
676
677             rRequiredBitmap <<= 1;
678         }
679     }
680
681 #ifdef LINUX
682     pvMemory = (PVOID)kalMemAlloc(u4Length, VIR_MEM_TYPE);
683 #else
684     pvMemory = (PVOID)NULL;
685 #endif
686
687 #if CFG_DBG_MGT_BUF
688     prBufInfo->u4AllocNullCount++;
689
690     if (pvMemory) {
691         prAdapter->u4MemAllocDynamicCount++;
692     }
693 #endif
694
695     KAL_RELEASE_SPIN_LOCK(prAdapter,
696         eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
697
698     return pvMemory;
699
700 } /* end of cnmMemAlloc() */
701
702
703 /*----------------------------------------------------------------------------*/
704 /*!
705 * \brief Release memory to MGT/MSG memory pool.
706 *
707 * \param pucMemory  Start address of previous allocated memory
708 *
709 * \return (none)
710 */
711 /*----------------------------------------------------------------------------*/
712 VOID
713 cnmMemFree (
714     IN P_ADAPTER_T      prAdapter,
715     IN PVOID            pvMemory
716     )
717 {
718     P_BUF_INFO_T        prBufInfo;
719     UINT_32             u4BlockIndex;
720     BUF_BITMAP          rAllocatedBlocksBitmap;
721     ENUM_RAM_TYPE_T     eRamType;
722     KAL_SPIN_LOCK_DECLARATION();
723
724
725     ASSERT(prAdapter);
726     ASSERT(pvMemory);
727     if (!pvMemory) {
728         return;
729     }
730
731     /* Judge it belongs to which RAM type */
732     if ( ((UINT_32)pvMemory >= (UINT_32)&prAdapter->aucMsgBuf[0]) &&
733          ((UINT_32)pvMemory <= (UINT_32)&prAdapter->aucMsgBuf[MSG_BUFFER_SIZE-1])) {
734
735         prBufInfo = &prAdapter->rMsgBufInfo;
736         u4BlockIndex = ((UINT_32)pvMemory - (UINT_32)prBufInfo->pucBuf)
737                        >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2;
738         ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS);
739         eRamType = RAM_TYPE_MSG;
740     }
741     else if ( ((UINT_32)pvMemory >= (UINT_32)prAdapter->pucMgtBufCached) &&
742               ((UINT_32)pvMemory <= ((UINT_32)prAdapter->pucMgtBufCached + MGT_BUFFER_SIZE -1))) {
743         prBufInfo = &prAdapter->rMgtBufInfo;
744         u4BlockIndex = ((UINT_32)pvMemory - (UINT_32)prBufInfo->pucBuf)
745                        >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2;
746         ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS);
747         eRamType = RAM_TYPE_BUF;
748     }
749     else {
750     #ifdef LINUX
751         /* For Linux, it is supported because size is not needed */
752         kalMemFree(pvMemory, VIR_MEM_TYPE, 0);
753     #else
754         /* For Windows, it is not supported because of no size argument */
755         ASSERT(0);
756     #endif
757
758     #if CFG_DBG_MGT_BUF
759         prAdapter->u4MemFreeDynamicCount++;
760     #endif
761         return;
762     }
763
764     KAL_ACQUIRE_SPIN_LOCK(prAdapter,
765         eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
766
767 #if CFG_DBG_MGT_BUF
768     prBufInfo->u4FreeCount++;
769 #endif
770
771     /* Convert number of block into bit cluster */
772     ASSERT(prBufInfo->aucAllocatedBlockNum[u4BlockIndex] > 0);
773
774     rAllocatedBlocksBitmap =
775         BITS(0, prBufInfo->aucAllocatedBlockNum[u4BlockIndex] - 1);
776     rAllocatedBlocksBitmap <<= u4BlockIndex;
777
778     /* Clear saved block count for this memory segment */
779     prBufInfo->aucAllocatedBlockNum[u4BlockIndex] = 0;
780
781     /* Set corresponding bit of released memory block */
782     prBufInfo->rFreeBlocksBitmap |= rAllocatedBlocksBitmap;
783
784     KAL_RELEASE_SPIN_LOCK(prAdapter,
785         eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF);
786
787     return;
788
789 } /* end of cnmMemFree() */
790
791
792 /*----------------------------------------------------------------------------*/
793 /*!
794 * \brief
795 *
796 * \param[in]
797 *
798 * \return none
799 */
800 /*----------------------------------------------------------------------------*/
801 VOID
802 cnmStaRecInit (
803     P_ADAPTER_T     prAdapter
804     )
805 {
806     P_STA_RECORD_T  prStaRec;
807     UINT_16         i;
808
809     for (i = 0; i < CFG_STA_REC_NUM; i++) {
810         prStaRec = &prAdapter->arStaRec[i];
811
812         prStaRec->ucIndex = (UINT_8) i;
813         prStaRec->fgIsInUse = FALSE;
814     }
815 }
816
817
818 /*----------------------------------------------------------------------------*/
819 /*!
820 * \brief
821 *
822 * \param[in]
823 *
824 * \return none
825 */
826 /*----------------------------------------------------------------------------*/
827 VOID
828 cnmStaRecUninit (
829     IN P_ADAPTER_T  prAdapter
830     )
831 {
832     P_STA_RECORD_T  prStaRec;
833     UINT_16         i;
834
835     for (i = 0; i < CFG_STA_REC_NUM; i++) {
836         prStaRec = &prAdapter->arStaRec[i];
837
838         if (prStaRec->fgIsInUse) {
839             cnmStaRecFree(prAdapter, prStaRec, FALSE);
840         }
841     }
842 }
843
844
845 /*----------------------------------------------------------------------------*/
846 /*!
847 * \brief
848 *
849 * \param[in]
850 *
851 * \return none
852 */
853 /*----------------------------------------------------------------------------*/
854 P_STA_RECORD_T
855 cnmStaRecAlloc (
856     P_ADAPTER_T     prAdapter,
857     UINT_8          ucNetTypeIndex
858     )
859 {
860     P_STA_RECORD_T  prStaRec;
861     UINT_16         i, k;
862
863     ASSERT(prAdapter);
864
865     for (i = 0; i < CFG_STA_REC_NUM; i++) {
866         prStaRec = &prAdapter->arStaRec[i];
867
868         if (!prStaRec->fgIsInUse) {
869             /*---- Initialize STA_REC_T here ----*/
870             kalMemZero(prStaRec, sizeof(STA_RECORD_T));
871             prStaRec->ucIndex = (UINT_8) i;
872             prStaRec->ucNetTypeIndex = ucNetTypeIndex;
873             prStaRec->fgIsInUse = TRUE;
874
875             if (prStaRec->pucAssocReqIe) {
876                 kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen);
877                 prStaRec->pucAssocReqIe = NULL;
878                 prStaRec->u2AssocReqIeLen = 0;
879             }
880
881             /* Initialize the SN caches for duplicate detection */
882             for (k = 0; k < TID_NUM + 1; k++) {
883                 prStaRec->au2CachedSeqCtrl[k] = 0xFFFF;
884             }
885
886             /* Initialize SW TX queues in STA_REC */
887             for (k = 0; k < STA_WAIT_QUEUE_NUM; k++) {
888                 LINK_INITIALIZE(&prStaRec->arStaWaitQueue[k]);
889             }
890
891             /* Default enable TX/RX AMPDU */
892             prStaRec->fgTxAmpduEn = TRUE;
893             prStaRec->fgRxAmpduEn = TRUE;
894
895             for (k = 0; k < NUM_OF_PER_STA_TX_QUEUES; k++) {
896                 QUEUE_INITIALIZE(&prStaRec->arTxQueue[k]);
897             }
898
899             break;
900         }
901     }
902
903     return (i < CFG_STA_REC_NUM) ? prStaRec : NULL;
904 }
905
906
907 /*----------------------------------------------------------------------------*/
908 /*!
909 * \brief
910 *
911 * \param[in]
912 *
913 * \return none
914 */
915 /*----------------------------------------------------------------------------*/
916 VOID
917 cnmStaRecFree (
918     P_ADAPTER_T     prAdapter,
919     P_STA_RECORD_T  prStaRec,
920     BOOLEAN         fgSyncToChip
921     )
922 {
923     ASSERT(prAdapter);
924     ASSERT(prStaRec);
925
926     /* To do: free related resources, e.g. timers, buffers, etc */
927     cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
928     prStaRec->fgTransmitKeyExist = FALSE;
929     prStaRec->fgSetPwrMgtBit = FALSE;
930
931     if (prStaRec->pucAssocReqIe) {
932         kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen);
933         prStaRec->pucAssocReqIe = NULL;
934         prStaRec->u2AssocReqIeLen = 0;
935     }
936
937     qmDeactivateStaRec(prAdapter, prStaRec->ucIndex);
938
939     if (fgSyncToChip) {
940         cnmStaSendRemoveCmd(prAdapter, prStaRec);
941     }
942
943     prStaRec->fgIsInUse = FALSE;
944
945     return;
946 }
947
948 /*----------------------------------------------------------------------------*/
949 /*!
950 * \brief
951 *
952 * \param[in]
953 *
954 * \return none
955 */
956 /*----------------------------------------------------------------------------*/
957 VOID
958 cnmStaFreeAllStaByNetType (
959     P_ADAPTER_T                 prAdapter,
960     ENUM_NETWORK_TYPE_INDEX_T   eNetTypeIndex,
961     BOOLEAN                     fgSyncToChip
962     )
963 {
964     P_STA_RECORD_T  prStaRec;
965     UINT_16         i;
966
967     for (i = 0; i < CFG_STA_REC_NUM; i++) {
968         prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i];
969
970         if (prStaRec->fgIsInUse &&
971             prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex) {
972
973             cnmStaRecFree(prAdapter, prStaRec, fgSyncToChip);
974         }
975     } /* end of for loop */
976 }
977
978 /*----------------------------------------------------------------------------*/
979 /*!
980 * \brief
981 *
982 * \param[in]
983 *
984 * \return none
985 */
986 /*----------------------------------------------------------------------------*/
987 P_STA_RECORD_T
988 cnmGetStaRecByIndex (
989     P_ADAPTER_T     prAdapter,
990     UINT_8          ucIndex
991     )
992 {
993     P_STA_RECORD_T  prStaRec;
994
995     ASSERT(prAdapter);
996
997     prStaRec = (ucIndex < CFG_STA_REC_NUM) ?
998                &prAdapter->arStaRec[ucIndex] : NULL;
999
1000     if (prStaRec && prStaRec->fgIsInUse == FALSE) {
1001         prStaRec = NULL;
1002     }
1003
1004     return prStaRec;
1005 }
1006
1007 /*----------------------------------------------------------------------------*/
1008 /*!
1009 * @brief Get STA_RECORD_T by Peer MAC Address(Usually TA).
1010 *
1011 * @param[in] pucPeerMacAddr      Given Peer MAC Address.
1012 *
1013 * @retval   Pointer to STA_RECORD_T, if found. NULL, if not found
1014 */
1015 /*----------------------------------------------------------------------------*/
1016 P_STA_RECORD_T
1017 cnmGetStaRecByAddress (
1018     P_ADAPTER_T     prAdapter,
1019     UINT_8          ucNetTypeIndex,
1020     PUINT_8         pucPeerMacAddr
1021     )
1022 {
1023     P_STA_RECORD_T  prStaRec;
1024     UINT_16         i;
1025
1026     ASSERT(prAdapter);
1027     ASSERT(pucPeerMacAddr);
1028
1029     for (i = 0; i < CFG_STA_REC_NUM; i++) {
1030         prStaRec = &prAdapter->arStaRec[i];
1031
1032         if (prStaRec->fgIsInUse &&
1033             prStaRec->ucNetTypeIndex == ucNetTypeIndex &&
1034             EQUAL_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMacAddr)) {
1035             break;
1036         }
1037     }
1038
1039     return (i < CFG_STA_REC_NUM) ? prStaRec : NULL;
1040 }
1041
1042 /*----------------------------------------------------------------------------*/
1043 /*!
1044 * @brief Reset the Status and Reason Code Field to 0 of all Station Records for
1045 *        the specified Network Type
1046 *
1047 * @param[in] eNetType       Specify Network Type
1048 *
1049 * @return   (none)
1050 */
1051 /*----------------------------------------------------------------------------*/
1052 VOID
1053 cnmStaRecResetStatus (
1054     P_ADAPTER_T                 prAdapter,
1055     ENUM_NETWORK_TYPE_INDEX_T   eNetTypeIndex
1056     )
1057 {
1058     cnmStaFreeAllStaByNetType(prAdapter, eNetTypeIndex, FALSE);
1059
1060 #if 0
1061     P_STA_RECORD_T  prStaRec;
1062     UINT_16         i;
1063
1064     ASSERT(prAdapter);
1065
1066     for (i = 0; i < CFG_STA_REC_NUM; i++) {
1067         prStaRec = &prAdapter->arStaRec[i];
1068
1069         if (prStaRec->fgIsInUse) {
1070             if ((NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) &&
1071                 IS_STA_IN_AIS(prStaRec->eStaType)) {
1072
1073                 prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL;
1074                 prStaRec->u2ReasonCode = REASON_CODE_RESERVED;
1075                 prStaRec->ucJoinFailureCount = 0;
1076                 prStaRec->fgTransmitKeyExist = FALSE;
1077
1078                 prStaRec->fgSetPwrMgtBit = FALSE;
1079             }
1080
1081             /* TODO(Kevin): For P2P and BOW */
1082         }
1083     }
1084
1085     return;
1086 #endif
1087 }
1088
1089 /*----------------------------------------------------------------------------*/
1090 /*!
1091 * @brief This function will change the ucStaState of STA_RECORD_T and also do
1092 *        event indication to HOST to sync the STA_RECORD_T in driver.
1093 *
1094 * @param[in] prStaRec       Pointer to the STA_RECORD_T
1095 * @param[in] u4NewState     New STATE to change.
1096 *
1097 * @return (none)
1098 */
1099 /*----------------------------------------------------------------------------*/
1100 VOID
1101 cnmStaRecChangeState (
1102     P_ADAPTER_T     prAdapter,
1103     P_STA_RECORD_T  prStaRec,
1104     UINT_8          ucNewState
1105     )
1106 {
1107     BOOLEAN         fgNeedResp;
1108
1109     ASSERT(prAdapter);
1110     ASSERT(prStaRec);
1111     ASSERT(prStaRec->fgIsInUse);
1112
1113     /* Do nothing when following state transitions happen,
1114      * other 6 conditions should be sync to FW, including 1-->1, 3-->3
1115      */
1116     if ((ucNewState == STA_STATE_2 && prStaRec->ucStaState != STA_STATE_3) ||
1117         (ucNewState == STA_STATE_1 && prStaRec->ucStaState == STA_STATE_2)) {
1118         prStaRec->ucStaState = ucNewState;
1119         return;
1120     }
1121
1122     fgNeedResp = FALSE;
1123     if (ucNewState == STA_STATE_3) {
1124         secFsmEventStart(prAdapter, prStaRec);
1125         if (ucNewState != prStaRec->ucStaState) {
1126             fgNeedResp = TRUE;
1127         }
1128     }
1129     else {
1130         if (ucNewState != prStaRec->ucStaState &&
1131             prStaRec->ucStaState == STA_STATE_3) {
1132             qmDeactivateStaRec(prAdapter, prStaRec->ucIndex);
1133         }
1134         fgNeedResp = FALSE;
1135     }
1136     prStaRec->ucStaState = ucNewState;
1137
1138     cnmStaSendUpdateCmd(prAdapter, prStaRec, fgNeedResp);
1139
1140 #if CFG_ENABLE_WIFI_DIRECT
1141     /* To do: Confirm if it is invoked here or other location, but it should
1142      *        be invoked after state sync of STA_REC
1143      * Update system operation parameters for AP mode
1144      */
1145     if (prAdapter->fgIsP2PRegistered && (IS_STA_IN_P2P(prStaRec))) {
1146         P_BSS_INFO_T    prBssInfo;
1147
1148         prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
1149
1150         if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
1151             if(prAdapter->rP2pFuncLkr.prRlmUpdateParamsForAp) {
1152                 prAdapter->rP2pFuncLkr.prRlmUpdateParamsForAp(prAdapter, prBssInfo, FALSE);
1153             } else {
1154                 ASSERT(0);
1155             }
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     DBGLOG(REQ, TRACE, ("STA "MACSTR" type=%d state = %d\n", MAC2STR(prStaRec->aucMacAddr), prStaRec->eStaType, prStaRec->ucStaState));
1277
1278     rStatus = wlanSendSetQueryCmd (
1279                 prAdapter,                  /* prAdapter */
1280                 CMD_ID_UPDATE_STA_RECORD,   /* ucCID */
1281                 TRUE,                       /* fgSetQuery */
1282                 fgNeedResp,                /* fgNeedResp */
1283                 FALSE,                      /* fgIsOid */
1284                 fgNeedResp? cnmStaRecHandleEventPkt : NULL,
1285                 NULL,                       /* pfCmdTimeoutHandler */
1286                 sizeof(CMD_UPDATE_STA_RECORD_T),    /* u4SetQueryInfoLen */
1287                 (PUINT_8) prCmdContent,     /* pucInfoBuffer */
1288                 NULL,                       /* pvSetQueryBuffer */
1289                 0                           /* u4SetQueryBufferLen */
1290                 );
1291
1292     ASSERT(rStatus == WLAN_STATUS_PENDING);
1293
1294     cnmMemFree(prAdapter, prCmdContent);
1295 }
1296
1297 /*----------------------------------------------------------------------------*/
1298 /*!
1299 * @brief
1300 *
1301 * @param[in]
1302 *
1303 * @return (none)
1304 */
1305 /*----------------------------------------------------------------------------*/
1306 static VOID
1307 cnmStaSendRemoveCmd (
1308     P_ADAPTER_T     prAdapter,
1309     P_STA_RECORD_T  prStaRec
1310     )
1311 {
1312     CMD_REMOVE_STA_RECORD_T     rCmdContent;
1313     WLAN_STATUS                 rStatus;
1314
1315     ASSERT(prAdapter);
1316     ASSERT(prStaRec);
1317
1318     rCmdContent.ucIndex = prStaRec->ucIndex;
1319     kalMemCopy(&rCmdContent.aucMacAddr[0], &prStaRec->aucMacAddr[0],
1320                MAC_ADDR_LEN);
1321
1322     rStatus = wlanSendSetQueryCmd (
1323                 prAdapter,                  /* prAdapter */
1324                 CMD_ID_REMOVE_STA_RECORD,   /* ucCID */
1325                 TRUE,                       /* fgSetQuery */
1326                 FALSE,                      /* fgNeedResp */
1327                 FALSE,                      /* fgIsOid */
1328                 NULL,                       /* pfCmdDoneHandler */
1329                 NULL,                       /* pfCmdTimeoutHandler */
1330                 sizeof(CMD_REMOVE_STA_RECORD_T),    /* u4SetQueryInfoLen */
1331                 (PUINT_8) &rCmdContent,     /* pucInfoBuffer */
1332                 NULL,                       /* pvSetQueryBuffer */
1333                 0                           /* u4SetQueryBufferLen */
1334                 );
1335
1336     ASSERT(rStatus == WLAN_STATUS_PENDING);
1337 }
1338
1339