f148e49160932d6a7c5e5c48a5f574714fe48a03
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / mt5931_kk / drv_wlan / mgmt / rsn.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT662X_593X_WIFI_DRIVER_V2_3/mgmt/rsn.c#1 $
3 */
4
5 /*! \file   "rsn.c"
6     \brief  This file including the 802.11i, wpa and wpa2(rsn) related function.
7
8     This file provided the macros and functions library support the wpa/rsn ie parsing,
9     cipher and AKM check to help the AP seleced deciding, tkip mic error handler and rsn PMKID support.
10 */
11
12 /*******************************************************************************
13 * Copyright (c) 2007 MediaTek Inc.
14 *
15 * All rights reserved. Copying, compilation, modification, distribution
16 * or any other use whatsoever of this material is strictly prohibited
17 * except in accordance with a Software License Agreement with
18 * MediaTek Inc.
19 ********************************************************************************
20 */
21
22 /*******************************************************************************
23 * LEGAL DISCLAIMER
24 *
25 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
26 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
27 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
28 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
29 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
30 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
31 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
32 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
33 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
34 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
35 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
36 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
37 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
38 *
39 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
40 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
41 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
42 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
43 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
44 *
45 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
46 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
47 * OF LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
48 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
49 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
50 * (ICC).
51 ********************************************************************************
52 */
53
54 /*
55 ** $Log: rsn.c $
56 ** 
57 ** 08 24 2012 cp.wu
58 ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
59 ** .
60 ** 
61 ** 08 24 2012 cp.wu
62 ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
63 ** cfg80211 support merge back from ALPS.JB to DaVinci - MT6620 Driver v2.3 branch.
64  *
65  * 07 17 2012 yuche.tsai
66  * NULL
67  * Compile no error before trial run.
68  *
69  * 03 09 2012 chinglan.wang
70  * NULL
71  * Fix the condition error.
72  *
73  * 03 02 2012 terry.wu
74  * NULL
75  * Snc CFG80211 modification for ICS migration from branch 2.2.
76  *
77  * 03 02 2012 terry.wu
78  * NULL
79  * Sync CFG80211 modification from branch 2,2.
80  *
81  * 11 11 2011 wh.su
82  * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
83  * modify the xlog related code.
84  *
85  * 11 10 2011 wh.su
86  * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
87  * change the debug module level.
88  *
89  * 10 12 2011 wh.su
90  * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
91  * adding the 802.11w related function and define .
92  *
93  * 03 17 2011 chinglan.wang
94  * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
95  * .
96  *
97  * 02 09 2011 wh.su
98  * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode
99  * adding the code for check STA privacy bit at AP mode, .
100  *
101  * 12 24 2010 chinglan.wang
102  * NULL
103  * [MT6620][Wi-Fi] Modify the key management in the driver for WPS function.
104  *
105  * 12 13 2010 cp.wu
106  * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver
107  * create branch for Wi-Fi driver v1.1
108  *
109  * 11 05 2010 wh.su
110  * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value
111  * fixed the.pmkid value mismatch issue
112  *
113  * 11 03 2010 wh.su
114  * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
115  * Refine the HT rate disallow TKIP pairwise cipher .
116  *
117  * 10 04 2010 cp.wu
118  * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by ENUM_NETWORK_TYPE_INDEX_T only
119  * remove ENUM_NETWORK_TYPE_T definitions
120  *
121  * 09 29 2010 yuche.tsai
122  * NULL
123  * Fix compile error, remove unused pointer in rsnGenerateRSNIE().
124  *
125  * 09 28 2010 wh.su
126  * NULL
127  * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo.
128  *
129  * 09 24 2010 wh.su
130  * NULL
131  * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning.
132  *
133  * 09 06 2010 wh.su
134  * NULL
135  * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state.
136  *
137  * 08 30 2010 wh.su
138  * NULL
139  * remove non-used code.
140  *
141  * 08 19 2010 wh.su
142  * NULL
143  * adding the tx pkt call back handle for countermeasure.
144  *
145  * 07 24 2010 wh.su
146  *
147  * .support the Wi-Fi RSN
148  *
149  * 07 08 2010 cp.wu
150  *
151  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
152  *
153  * 06 21 2010 wh.su
154  * [WPD00003840][MT6620 5931] Security migration
155  * modify some code for concurrent network.
156  *
157  * 06 21 2010 cp.wu
158  * [WPD00003833][MT6620 and MT5931] Driver migration
159  * [WPD00003833][MT6620 and MT5931] Driver migration
160  * enable RX management frame handling.
161  *
162  * 06 19 2010 wh.su
163  * [WPD00003840][MT6620 5931] Security migration
164  * consdier the concurrent network setting.
165  *
166  * 06 18 2010 wh.su
167  * [WPD00003840][MT6620 5931] Security migration
168  * [WPD00003840] [MT6620 5931] Security migration
169  * migration from firmware.
170  *
171  * 05 27 2010 wh.su
172  * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
173  * not indiate pmkid candidate while no new one scaned.
174  *
175  * 04 29 2010 wh.su
176  * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
177  * adjsut the pre-authentication code.
178  *
179  * 03 03 2010 wh.su
180  * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
181  * move the AIS specific variable for security to AIS specific structure.
182  *
183  * 03 03 2010 wh.su
184  * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
185  * Fixed the pre-authentication timer not correctly init issue, and modify the security related callback function prototype.
186  *
187  * 01 27 2010 wh.su
188  * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
189  * add and fixed some security function.
190  *
191  * 12 18 2009 cm.chang
192  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
193  * .
194  *
195  * Dec 8 2009 mtk01088
196  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
197  * change the name
198  *
199  * Dec 7 2009 mtk01088
200  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
201  * using the Rx0 port to indicate event
202  *
203  * Dec 4 2009 mtk01088
204  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
205  * refine the code for generate the WPA/RSN IE for assoc req
206  *
207  * Dec 3 2009 mtk01088
208  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
209  * adjust code for pmkid event
210  *
211  * Dec 1 2009 mtk01088
212  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
213  * adding the code for event (mic error and pmkid indicate) and do some function rename
214  *
215  * Nov 23 2009 mtk01088
216  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
217  * adding some security function
218  *
219  * Nov 19 2009 mtk01088
220  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
221  * adding some security feature, including pmkid
222  *
223  * Nov 18 2009 mtk01088
224  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
225  *
226 **
227 */
228
229 /*******************************************************************************
230 *                         C O M P I L E R   F L A G S
231 ********************************************************************************
232 */
233
234 /*******************************************************************************
235 *                    E X T E R N A L   R E F E R E N C E S
236 ********************************************************************************
237 */
238 #include "precomp.h"
239
240 #if CFG_RSN_MIGRATION
241
242 //extern PHY_ATTRIBUTE_T rPhyAttributes[];
243
244 /*******************************************************************************
245 *                              C O N S T A N T S
246 ********************************************************************************
247 */
248
249 /*******************************************************************************
250 *                             D A T A   T Y P E S
251 ********************************************************************************
252 */
253
254 /*******************************************************************************
255 *                            P U B L I C   D A T A
256 ********************************************************************************
257 */
258
259 /*******************************************************************************
260 *                           P R I V A T E   D A T A
261 ********************************************************************************
262 */
263
264 /*******************************************************************************
265 *                                 M A C R O S
266 ********************************************************************************
267 */
268
269 /*******************************************************************************
270 *                   F U N C T I O N   D E C L A R A T I O N S
271 ********************************************************************************
272 */
273
274 /*******************************************************************************
275 *                              F U N C T I O N S
276 ********************************************************************************
277 */
278
279 /*----------------------------------------------------------------------------*/
280 /*!
281 * \brief This routine is called to parse RSN IE.
282 *
283 * \param[in]  prInfoElem Pointer to the RSN IE
284 * \param[out] prRsnInfo Pointer to the BSSDescription structure to store the
285 **                  RSN information from the given RSN IE
286 *
287 * \retval TRUE - Succeeded
288 * \retval FALSE - Failed
289 */
290 /*----------------------------------------------------------------------------*/
291 BOOLEAN
292 rsnParseRsnIE (
293     IN  P_ADAPTER_T       prAdapter,
294     IN  P_RSN_INFO_ELEM_T prInfoElem,
295     OUT P_RSN_INFO_T      prRsnInfo
296     )
297 {
298     UINT_32               i;
299     INT_32                u4RemainRsnIeLen;
300     UINT_16               u2Version;
301     UINT_16               u2Cap = 0;
302     UINT_32               u4GroupSuite = RSN_CIPHER_SUITE_CCMP;
303     UINT_16               u2PairSuiteCount = 0;
304     UINT_16               u2AuthSuiteCount = 0;
305     PUINT_8               pucPairSuite = NULL;
306     PUINT_8               pucAuthSuite = NULL;
307     PUINT_8               cp;
308
309     DEBUGFUNC("rsnParseRsnIE");
310
311     ASSERT(prInfoElem);
312     ASSERT(prRsnInfo);
313
314     /* Verify the length of the RSN IE. */
315     if (prInfoElem->ucLength < 2) {
316         DBGLOG(RSN, TRACE, ("RSN IE length too short (length=%d)\n", prInfoElem->ucLength));
317         return FALSE;
318     }
319
320     /* Check RSN version: currently, we only support version 1. */
321     WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version);
322     if (u2Version != 1) {
323         DBGLOG(RSN, TRACE,("Unsupported RSN IE version: %d\n", u2Version));
324         return FALSE;
325     }
326
327     cp = (PUCHAR) &prInfoElem->u4GroupKeyCipherSuite;
328     u4RemainRsnIeLen = (INT_32) prInfoElem->ucLength - 2;
329
330     do {
331         if (u4RemainRsnIeLen == 0) {
332             break;
333         }
334
335         /* Parse the Group Key Cipher Suite field. */
336         if (u4RemainRsnIeLen < 4) {
337             DBGLOG(RSN, TRACE, ("Fail to parse RSN IE in group cipher suite (IE len: %d)\n",
338                 prInfoElem->ucLength));
339             return FALSE;
340         }
341
342         WLAN_GET_FIELD_32(cp, &u4GroupSuite);
343         cp += 4;
344         u4RemainRsnIeLen -= 4;
345
346         if (u4RemainRsnIeLen == 0) {
347             break;
348         }
349
350         /* Parse the Pairwise Key Cipher Suite Count field. */
351         if (u4RemainRsnIeLen < 2) {
352             DBGLOG(RSN, TRACE,("Fail to parse RSN IE in pairwise cipher suite count (IE len: %d)\n",
353                 prInfoElem->ucLength));
354             return FALSE;
355         }
356
357         WLAN_GET_FIELD_16(cp, &u2PairSuiteCount);
358         cp += 2;
359         u4RemainRsnIeLen -= 2;
360
361         /* Parse the Pairwise Key Cipher Suite List field. */
362         i = (UINT_32) u2PairSuiteCount * 4;
363         if (u4RemainRsnIeLen < (INT_32) i) {
364             DBGLOG(RSN, TRACE,("Fail to parse RSN IE in pairwise cipher suite list (IE len: %d)\n",
365                 prInfoElem->ucLength));
366             return FALSE;
367         }
368
369         pucPairSuite = cp;
370
371         cp += i;
372         u4RemainRsnIeLen -= (INT_32) i;
373
374         if (u4RemainRsnIeLen == 0) {
375             break;
376         }
377
378         /* Parse the Authentication and Key Management Cipher Suite Count field. */
379         if (u4RemainRsnIeLen < 2) {
380             DBGLOG(RSN, TRACE,("Fail to parse RSN IE in auth & key mgt suite count (IE len: %d)\n",
381                 prInfoElem->ucLength));
382             return FALSE;
383         }
384
385         WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount);
386         cp += 2;
387         u4RemainRsnIeLen -= 2;
388
389         /* Parse the Authentication and Key Management Cipher Suite List
390            field. */
391         i = (UINT_32) u2AuthSuiteCount * 4;
392         if (u4RemainRsnIeLen < (INT_32) i) {
393             DBGLOG(RSN, TRACE, ("Fail to parse RSN IE in auth & key mgt suite list (IE len: %d)\n",
394                 prInfoElem->ucLength));
395             return FALSE;
396         }
397
398         pucAuthSuite = cp;
399
400         cp += i;
401         u4RemainRsnIeLen -= (INT_32) i;
402
403         if (u4RemainRsnIeLen == 0) {
404             break;
405         }
406
407         /* Parse the RSN u2Capabilities field. */
408         if (u4RemainRsnIeLen < 2) {
409             DBGLOG(RSN, TRACE, ("Fail to parse RSN IE in RSN capabilities (IE len: %d)\n",
410                 prInfoElem->ucLength));
411             return FALSE;
412         }
413
414         WLAN_GET_FIELD_16(cp, &u2Cap);
415     } while (FALSE);
416
417     /* Save the RSN information for the BSS. */
418     prRsnInfo->ucElemId = ELEM_ID_RSN;
419
420     prRsnInfo->u2Version = u2Version;
421
422     prRsnInfo->u4GroupKeyCipherSuite = u4GroupSuite;
423
424     DBGLOG(RSN, LOUD, ("RSN: version %d, group key cipher suite %02x-%02x-%02x-%02x\n",
425         u2Version, (UCHAR) (u4GroupSuite & 0x000000FF),
426         (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF),
427         (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF),
428         (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)));
429
430     if (pucPairSuite) {
431         /* The information about the pairwise key cipher suites is present. */
432         if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) {
433             u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES;
434         }
435
436         prRsnInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount;
437
438         for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) {
439             WLAN_GET_FIELD_32(pucPairSuite,
440                 &prRsnInfo->au4PairwiseKeyCipherSuite[i]);
441             pucPairSuite += 4;
442
443             DBGLOG(RSN, LOUD, ("RSN: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n",
444                 (UINT_8)i, (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF),
445                 (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF),
446                 (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF),
447                 (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)));
448         }
449     }
450     else {
451         /* The information about the pairwise key cipher suites is not present.
452            Use the default chipher suite for RSN: CCMP. */
453         prRsnInfo->u4PairwiseKeyCipherSuiteCount = 1;
454         prRsnInfo->au4PairwiseKeyCipherSuite[0] = RSN_CIPHER_SUITE_CCMP;
455
456         DBGLOG(RSN, LOUD, ("RSN: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n",
457             (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF),
458             (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF),
459             (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF),
460             (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)));
461     }
462
463     if (pucAuthSuite) {
464         /* The information about the authentication and key management suites
465            is present. */
466         if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) {
467             u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES;
468         }
469
470         prRsnInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount;
471
472         for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) {
473             WLAN_GET_FIELD_32(pucAuthSuite, &prRsnInfo->au4AuthKeyMgtSuite[i]);
474             pucAuthSuite += 4;
475
476             DBGLOG(RSN, LOUD, ("RSN: AKM suite [%d]: %02x-%02x-%02x-%02x\n",
477                 (UINT_8)i, (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[i] & 0x000000FF),
478                 (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF),
479                 (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF),
480                 (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)));
481         }
482     }
483     else {
484         /* The information about the authentication and key management suites
485            is not present. Use the default AKM suite for RSN. */
486         prRsnInfo->u4AuthKeyMgtSuiteCount = 1;
487         prRsnInfo->au4AuthKeyMgtSuite[0] = RSN_AKM_SUITE_802_1X;
488
489         DBGLOG(RSN, LOUD, ("RSN: AKM suite: %02x-%02x-%02x-%02x (default)\n",
490             (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[0] & 0x000000FF),
491             (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF),
492             (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF),
493             (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)));
494     }
495
496     prRsnInfo->u2RsnCap = u2Cap;
497 #if CFG_SUPPORT_802_11W
498     prRsnInfo->fgRsnCapPresent = TRUE;
499 #endif
500     DBGLOG(RSN, LOUD, ("RSN cap: 0x%04x\n", prRsnInfo->u2RsnCap));
501
502     return TRUE;
503 }   /* rsnParseRsnIE */
504
505
506 /*----------------------------------------------------------------------------*/
507 /*!
508 * \brief This routine is called to parse WPA IE.
509 *
510 * \param[in]  prInfoElem Pointer to the WPA IE.
511 * \param[out] prWpaInfo Pointer to the BSSDescription structure to store the
512 *                       WPA information from the given WPA IE.
513 *
514 * \retval TRUE Succeeded.
515 * \retval FALSE Failed.
516 */
517 /*----------------------------------------------------------------------------*/
518 BOOLEAN
519 rsnParseWpaIE (
520     IN  P_ADAPTER_T       prAdapter,
521     IN  P_WPA_INFO_ELEM_T prInfoElem,
522     OUT P_RSN_INFO_T      prWpaInfo
523     )
524 {
525     UINT_32               i;
526     INT_32                u4RemainWpaIeLen;
527     UINT_16               u2Version;
528     UINT_16               u2Cap = 0;
529     UINT_32               u4GroupSuite = WPA_CIPHER_SUITE_TKIP;
530     UINT_16               u2PairSuiteCount = 0;
531     UINT_16               u2AuthSuiteCount = 0;
532     PUCHAR                pucPairSuite = NULL;
533     PUCHAR                pucAuthSuite = NULL;
534     PUCHAR                cp;
535     BOOLEAN               fgCapPresent = FALSE;
536
537     DEBUGFUNC("rsnParseWpaIE");
538
539     ASSERT(prInfoElem);
540     ASSERT(prWpaInfo);
541
542     /* Verify the length of the WPA IE. */
543     if (prInfoElem->ucLength < 6) {
544         DBGLOG(RSN, TRACE,("WPA IE length too short (length=%d)\n", prInfoElem->ucLength));
545         return FALSE;
546     }
547
548     /* Check WPA version: currently, we only support version 1. */
549     WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version);
550     if (u2Version != 1) {
551         DBGLOG(RSN, TRACE, ("Unsupported WPA IE version: %d\n", u2Version));
552         return FALSE;
553     }
554
555     cp = (PUCHAR) &prInfoElem->u4GroupKeyCipherSuite;
556     u4RemainWpaIeLen = (INT_32) prInfoElem->ucLength - 6;
557
558     do {
559         if (u4RemainWpaIeLen == 0) {
560             break;
561         }
562
563         /* WPA_OUI      : 4
564            Version      : 2
565            GroupSuite   : 4
566            PairwiseCount: 2
567            PairwiseSuite: 4 * pairSuiteCount
568            AuthCount    : 2
569            AuthSuite    : 4 * authSuiteCount
570            Cap          : 2 */
571
572         /* Parse the Group Key Cipher Suite field. */
573         if (u4RemainWpaIeLen < 4) {
574             DBGLOG(RSN, TRACE,("Fail to parse WPA IE in group cipher suite (IE len: %d)\n",
575                 prInfoElem->ucLength));
576             return FALSE;
577         }
578
579         WLAN_GET_FIELD_32(cp, &u4GroupSuite);
580         cp += 4;
581         u4RemainWpaIeLen -= 4;
582
583         if (u4RemainWpaIeLen == 0) {
584             break;
585         }
586
587         /* Parse the Pairwise Key Cipher Suite Count field. */
588         if (u4RemainWpaIeLen < 2) {
589             DBGLOG(RSN, TRACE,("Fail to parse WPA IE in pairwise cipher suite count (IE len: %d)\n",
590                 prInfoElem->ucLength));
591             return FALSE;
592         }
593
594         WLAN_GET_FIELD_16(cp, &u2PairSuiteCount);
595         cp += 2;
596         u4RemainWpaIeLen -= 2;
597
598         /* Parse the Pairwise Key Cipher Suite List field. */
599         i = (UINT_32) u2PairSuiteCount * 4;
600         if (u4RemainWpaIeLen < (INT_32) i) {
601             DBGLOG(RSN, TRACE,("Fail to parse WPA IE in pairwise cipher suite list (IE len: %d)\n",
602                 prInfoElem->ucLength));
603             return FALSE;
604         }
605
606         pucPairSuite = cp;
607
608         cp += i;
609         u4RemainWpaIeLen -= (INT_32) i;
610
611         if (u4RemainWpaIeLen == 0) {
612             break;
613         }
614
615         /* Parse the Authentication and Key Management Cipher Suite Count
616            field. */
617         if (u4RemainWpaIeLen < 2) {
618             DBGLOG(RSN, TRACE,("Fail to parse WPA IE in auth & key mgt suite count (IE len: %d)\n",
619                 prInfoElem->ucLength));
620             return FALSE;
621         }
622
623         WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount);
624         cp += 2;
625         u4RemainWpaIeLen -= 2;
626
627         /* Parse the Authentication and Key Management Cipher Suite List
628            field. */
629         i = (UINT_32) u2AuthSuiteCount * 4;
630         if (u4RemainWpaIeLen < (INT_32) i) {
631             DBGLOG(RSN, TRACE, ("Fail to parse WPA IE in auth & key mgt suite list (IE len: %d)\n",
632                 prInfoElem->ucLength));
633             return FALSE;
634         }
635
636         pucAuthSuite = cp;
637
638         cp += i;
639         u4RemainWpaIeLen -= (INT_32) i;
640
641         if (u4RemainWpaIeLen == 0) {
642             break;
643         }
644
645         /* Parse the WPA u2Capabilities field. */
646         if (u4RemainWpaIeLen < 2) {
647             DBGLOG(RSN, TRACE, ("Fail to parse WPA IE in WPA capabilities (IE len: %d)\n",
648                 prInfoElem->ucLength));
649             return FALSE;
650         }
651
652         fgCapPresent = TRUE;
653         WLAN_GET_FIELD_16(cp, &u2Cap);
654         u4RemainWpaIeLen -= 2;
655     } while (FALSE);
656
657     /* Save the WPA information for the BSS. */
658
659     prWpaInfo->ucElemId = ELEM_ID_WPA;
660
661     prWpaInfo->u2Version = u2Version;
662
663     prWpaInfo->u4GroupKeyCipherSuite = u4GroupSuite;
664
665     DBGLOG(RSN, LOUD, ("WPA: version %d, group key cipher suite %02x-%02x-%02x-%02x\n",
666         u2Version, (UCHAR) (u4GroupSuite & 0x000000FF),
667         (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF),
668         (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF),
669         (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)));
670
671     if (pucPairSuite) {
672         /* The information about the pairwise key cipher suites is present. */
673         if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) {
674             u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES;
675         }
676
677         prWpaInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount;
678
679         for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) {
680             WLAN_GET_FIELD_32(pucPairSuite,
681                               &prWpaInfo->au4PairwiseKeyCipherSuite[i]);
682             pucPairSuite += 4;
683
684             DBGLOG(RSN, LOUD, ("WPA: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n",
685                 (UINT_8)i, (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF),
686                 (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF),
687                 (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF),
688                 (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)));
689         }
690     }
691     else {
692         /* The information about the pairwise key cipher suites is not present.
693            Use the default chipher suite for WPA: TKIP. */
694         prWpaInfo->u4PairwiseKeyCipherSuiteCount = 1;
695         prWpaInfo->au4PairwiseKeyCipherSuite[0] = WPA_CIPHER_SUITE_TKIP;
696
697         DBGLOG(RSN, LOUD, ("WPA: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n",
698             (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF),
699             (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF),
700             (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF),
701             (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)));
702     }
703
704     if (pucAuthSuite) {
705         /* The information about the authentication and key management suites
706            is present. */
707         if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) {
708             u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES;
709         }
710
711         prWpaInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount;
712
713         for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) {
714             WLAN_GET_FIELD_32(pucAuthSuite, &prWpaInfo->au4AuthKeyMgtSuite[i]);
715             pucAuthSuite += 4;
716
717             DBGLOG(RSN, LOUD, ("WPA: AKM suite [%d]: %02x-%02x-%02x-%02x\n",
718                 (UINT_8)i, (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[i] & 0x000000FF),
719                 (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF),
720                 (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF),
721                 (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)));
722         }
723     }
724     else {
725         /* The information about the authentication and key management suites
726            is not present. Use the default AKM suite for WPA. */
727         prWpaInfo->u4AuthKeyMgtSuiteCount = 1;
728         prWpaInfo->au4AuthKeyMgtSuite[0] = WPA_AKM_SUITE_802_1X;
729
730         DBGLOG(RSN, LOUD, ("WPA: AKM suite: %02x-%02x-%02x-%02x (default)\n",
731             (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[0] & 0x000000FF),
732             (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF),
733             (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF),
734             (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)));
735     }
736
737     if (fgCapPresent) {
738         prWpaInfo->fgRsnCapPresent = TRUE;
739         prWpaInfo->u2RsnCap = u2Cap;
740         DBGLOG(RSN, LOUD, ("WPA: RSN cap: 0x%04x\n", prWpaInfo->u2RsnCap));
741     }
742     else {
743         prWpaInfo->fgRsnCapPresent = FALSE;
744         prWpaInfo->u2RsnCap = 0;
745     }
746
747     return TRUE;
748 }   /* rsnParseWpaIE */
749
750
751 /*----------------------------------------------------------------------------*/
752 /*!
753 * \brief This routine is called to search the desired pairwise
754 *        cipher suite from the MIB Pairwise Cipher Suite
755 *        configuration table.
756 *
757 * \param[in] u4Cipher The desired pairwise cipher suite to be searched
758 * \param[out] pu4Index Pointer to the index of the desired pairwise cipher in
759 *                      the table
760 *
761 * \retval TRUE - The desired pairwise cipher suite is found in the table.
762 * \retval FALSE - The desired pairwise cipher suite is not found in the
763 *                 table.
764 */
765 /*----------------------------------------------------------------------------*/
766 BOOLEAN
767 rsnSearchSupportedCipher (
768     IN  P_ADAPTER_T       prAdapter,
769     IN  UINT_32           u4Cipher,
770     OUT PUINT_32          pu4Index
771     )
772 {
773     UINT_8 i;
774     P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY prEntry;
775
776     DEBUGFUNC("rsnSearchSupportedCipher");
777
778     ASSERT(pu4Index);
779
780     for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) {
781         prEntry = &prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[i];
782         if (prEntry->dot11RSNAConfigPairwiseCipher == u4Cipher &&
783             prEntry->dot11RSNAConfigPairwiseCipherEnabled) {
784             *pu4Index = i;
785             return TRUE;
786         }
787     }
788     return FALSE;
789 }   /* rsnSearchSupportedCipher */
790
791
792 /*----------------------------------------------------------------------------*/
793 /*!
794 *
795 * \brief This routine is called to search the desired
796 *        authentication and key management (AKM) suite from the
797 *        MIB Authentication and Key Management Suites table.
798 *
799 * \param[in]  u4AkmSuite The desired AKM suite to be searched
800 * \param[out] pu4Index   Pointer to the index of the desired AKM suite in the
801 *                        table
802 *
803 * \retval TRUE  The desired AKM suite is found in the table.
804 * \retval FALSE The desired AKM suite is not found in the table.
805 *
806 * \note
807 */
808 /*----------------------------------------------------------------------------*/
809 BOOLEAN
810 rsnSearchAKMSuite (
811     IN  P_ADAPTER_T       prAdapter,
812     IN  UINT_32           u4AkmSuite,
813     OUT PUINT_32          pu4Index
814     )
815 {
816     UINT_8 i;
817     P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry;
818
819     DEBUGFUNC("rsnSearchAKMSuite");
820
821     ASSERT(pu4Index);
822
823     for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) {
824         prEntry = &prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i];
825         if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite &&
826             prEntry->dot11RSNAConfigAuthenticationSuiteEnabled) {
827             *pu4Index = i;
828             return TRUE;
829         }
830     }
831     return FALSE;
832 }   /* rsnSearchAKMSuite */
833
834
835 /*----------------------------------------------------------------------------*/
836 /*!
837 * \brief This routine is called to perform RSNA or TSN policy
838 *        selection for a given BSS.
839 *
840 * \param[in]  prBss Pointer to the BSS description
841 *
842 * \retval TRUE - The RSNA/TSN policy selection for the given BSS is
843 *                successful. The selected pairwise and group cipher suites
844 *                are returned in the BSS description.
845 * \retval FALSE - The RSNA/TSN policy selection for the given BSS is failed.
846 *                 The driver shall not attempt to join the given BSS.
847 *
848 * \note The Encrypt status matched score will save to bss for final ap select.
849 */
850 /*----------------------------------------------------------------------------*/
851 BOOLEAN
852 rsnPerformPolicySelection (
853     IN  P_ADAPTER_T         prAdapter,
854     IN  P_BSS_DESC_T        prBss
855     )
856 {
857 #if CFG_SUPPORT_802_11W
858     INT_32                  i;
859     UINT_32                 j;
860 #else
861     UINT_32                 i, j;
862 #endif
863     BOOLEAN                 fgSuiteSupported;
864     UINT_32                 u4PairwiseCipher = 0;
865     UINT_32                 u4GroupCipher = 0;
866     UINT_32                 u4AkmSuite = 0;
867     P_RSN_INFO_T            prBssRsnInfo;
868     ENUM_NETWORK_TYPE_INDEX_T eNetwotkType;
869     BOOLEAN                 fgIsWpsActive = (BOOLEAN)FALSE;
870
871     DEBUGFUNC("rsnPerformPolicySelection");
872
873     ASSERT(prBss);
874
875     DBGLOG(RSN, TRACE, ("rsnPerformPolicySelection\n"));
876     //Todo::
877     eNetwotkType = NETWORK_TYPE_AIS_INDEX;
878
879     prBss->u4RsnSelectedPairwiseCipher = 0;
880     prBss->u4RsnSelectedGroupCipher = 0;
881     prBss->u4RsnSelectedAKMSuite = 0;
882     prBss->ucEncLevel = 0;
883
884 #if CFG_SUPPORT_WPS
885     fgIsWpsActive = kalWSCGetActiveState(prAdapter->prGlueInfo);
886
887     /* CR1640, disable the AP select privacy check */
888     if ( fgIsWpsActive &&
889         (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) &&
890         (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA)) {
891         DBGLOG(RSN, TRACE,("-- Skip the Protected BSS check\n"));
892         return TRUE;
893     }
894 #endif
895
896     /* Protection is not required in this BSS. */
897     if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) == 0 ) {
898
899         if (secEnabledInAis(prAdapter) == FALSE) {
900             DBGLOG(RSN, TRACE,("-- No Protected BSS\n"));
901             return TRUE;
902         }
903         else {
904             DBGLOG(RSN, TRACE,("-- Protected BSS\n"));
905             return FALSE;
906         }
907     }
908
909     /* Protection is required in this BSS. */
910     if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) != 0) {
911         if (secEnabledInAis(prAdapter) == FALSE) {
912             DBGLOG(RSN, TRACE,("-- Protected BSS\n"));
913             return FALSE;
914         }
915     }
916
917     if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA ||
918         prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK ||
919         prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_NONE) {
920
921         if (prBss->fgIEWPA) {
922             prBssRsnInfo = &prBss->rWPAInfo;
923         }
924         else {
925             DBGLOG(RSN, TRACE, ("WPA Information Element does not exist.\n"));
926             return FALSE;
927         }
928     }
929     else if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2 ||
930         prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK) {
931
932         if (prBss->fgIERSN) {
933             prBssRsnInfo = &prBss->rRSNInfo;
934         }
935         else {
936             DBGLOG(RSN, TRACE, ("RSN Information Element does not exist.\n"));
937             return FALSE;
938         }
939     }
940     else if (prAdapter->rWifiVar.rConnSettings.eEncStatus != ENUM_ENCRYPTION1_ENABLED) {
941         /* If the driver is configured to use WEP only, ignore this BSS. */
942         DBGLOG(RSN, TRACE, ("-- Not WEP-only legacy BSS\n"));
943         return FALSE;
944     }
945     else if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED) {
946         /* If the driver is configured to use WEP only, use this BSS. */
947         DBGLOG(RSN, TRACE, ("-- WEP-only legacy BSS\n"));
948         return TRUE;
949     }
950
951     if (prBssRsnInfo->u4PairwiseKeyCipherSuiteCount == 1 &&
952         GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[0]) ==
953         CIPHER_SUITE_NONE) {
954         /* Since the pairwise cipher use the same cipher suite as the group
955            cipher in the BSS, we check the group cipher suite against the
956            current encryption status. */
957         fgSuiteSupported = FALSE;
958
959         switch (prBssRsnInfo->u4GroupKeyCipherSuite) {
960         case WPA_CIPHER_SUITE_CCMP:
961         case RSN_CIPHER_SUITE_CCMP:
962              if (prAdapter->rWifiVar.rConnSettings.eEncStatus ==
963                  ENUM_ENCRYPTION3_ENABLED) {
964                  fgSuiteSupported = TRUE;
965              }
966              break;
967
968         case WPA_CIPHER_SUITE_TKIP:
969         case RSN_CIPHER_SUITE_TKIP:
970              if (prAdapter->rWifiVar.rConnSettings.eEncStatus ==
971                  ENUM_ENCRYPTION2_ENABLED) {
972                  fgSuiteSupported = TRUE;
973              }
974              break;
975
976         case WPA_CIPHER_SUITE_WEP40:
977         case WPA_CIPHER_SUITE_WEP104:
978              if (prAdapter->rWifiVar.rConnSettings.eEncStatus ==
979                  ENUM_ENCRYPTION1_ENABLED) {
980                  fgSuiteSupported = TRUE;
981              }
982              break;
983         }
984
985         if (fgSuiteSupported) {
986             u4PairwiseCipher = WPA_CIPHER_SUITE_NONE;
987             u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
988         }
989 #if DBG
990         else {
991             DBGLOG(RSN, TRACE, ("Inproper encryption status %d for group-key-only BSS\n",
992                 prAdapter->rWifiVar.rConnSettings.eEncStatus));
993         }
994 #endif
995     }
996     else {
997         fgSuiteSupported = FALSE;
998
999         DBGLOG(RSN, TRACE, ("eEncStatus %d %d 0x%x\n", prAdapter->rWifiVar.rConnSettings.eEncStatus,
1000             prBssRsnInfo->u4PairwiseKeyCipherSuiteCount,
1001             prBssRsnInfo->au4PairwiseKeyCipherSuite[0]));
1002         /* Select pairwise/group ciphers */
1003         switch (prAdapter->rWifiVar.rConnSettings.eEncStatus)
1004         {
1005         case ENUM_ENCRYPTION3_ENABLED:
1006              for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) {
1007                  if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
1008                      == CIPHER_SUITE_CCMP) {
1009                      u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i];
1010                  }
1011              }
1012              u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
1013              break;
1014
1015         case ENUM_ENCRYPTION2_ENABLED:
1016              for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) {
1017                  if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
1018                      == CIPHER_SUITE_TKIP) {
1019                      u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i];
1020                  }
1021              }
1022              if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) ==
1023                  CIPHER_SUITE_CCMP) {
1024                  DBGLOG(RSN, TRACE, ("Cannot join CCMP BSS\n"));
1025              }
1026              else {
1027                  u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
1028              }
1029              break;
1030
1031         case ENUM_ENCRYPTION1_ENABLED:
1032              for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) {
1033                  if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
1034                      == CIPHER_SUITE_WEP40 ||
1035                      GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
1036                      == CIPHER_SUITE_WEP104) {
1037                      u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i];
1038                  }
1039              }
1040              if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) ==
1041                  CIPHER_SUITE_CCMP ||
1042                  GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) ==
1043                  CIPHER_SUITE_TKIP) {
1044                  DBGLOG(RSN, TRACE, ("Cannot join CCMP/TKIP BSS\n"));
1045              }
1046              else {
1047                  u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
1048              }
1049              break;
1050
1051         default:
1052              break;
1053         }
1054     }
1055
1056     /* Exception handler */
1057     /* If we cannot find proper pairwise and group cipher suites to join the
1058        BSS, do not check the supported AKM suites. */
1059     if (u4PairwiseCipher == 0 || u4GroupCipher == 0) {
1060         DBGLOG(RSN, TRACE, ("Failed to select pairwise/group cipher (0x%08lx/0x%08lx)\n",
1061             u4PairwiseCipher, u4GroupCipher));
1062         return FALSE;
1063     }
1064
1065 #if CFG_ENABLE_WIFI_DIRECT
1066     if ((prAdapter->fgIsP2PRegistered) &&
1067         (eNetwotkType == NETWORK_TYPE_P2P_INDEX)) {
1068         if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP ||
1069             u4GroupCipher != RSN_CIPHER_SUITE_CCMP ||
1070             u4AkmSuite != RSN_AKM_SUITE_PSK) {
1071             DBGLOG(RSN, TRACE, ("Failed to select pairwise/group cipher for P2P network (0x%08lx/0x%08lx)\n",
1072                 u4PairwiseCipher, u4GroupCipher));
1073             return FALSE;
1074         }
1075     }
1076 #endif
1077
1078 #if CFG_ENABLE_BT_OVER_WIFI
1079         if (eNetwotkType == NETWORK_TYPE_BOW_INDEX) {
1080             if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP ||
1081                 u4GroupCipher != RSN_CIPHER_SUITE_CCMP ||
1082                 u4AkmSuite != RSN_AKM_SUITE_PSK) {
1083             }
1084             DBGLOG(RSN, TRACE, ("Failed to select pairwise/group cipher for BT over Wi-Fi network (0x%08lx/0x%08lx)\n",
1085                 u4PairwiseCipher, u4GroupCipher));
1086             return FALSE;
1087         }
1088 #endif
1089
1090
1091     /* Verify if selected pairwisse cipher is supported */
1092     fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4PairwiseCipher, &i);
1093
1094     /* Verify if selected group cipher is supported */
1095     if (fgSuiteSupported) {
1096         fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4GroupCipher, &i);
1097     }
1098
1099     if (!fgSuiteSupported) {
1100         DBGLOG(RSN, TRACE, ("Failed to support selected pairwise/group cipher (0x%08lx/0x%08lx)\n",
1101             u4PairwiseCipher, u4GroupCipher));
1102         return FALSE;
1103     }
1104
1105     /* Select AKM */
1106     /* If the driver cannot support any authentication suites advertised in
1107        the given BSS, we fail to perform RSNA policy selection. */
1108     /* Attempt to find any overlapping supported AKM suite. */
1109 #if CFG_SUPPORT_802_11W
1110     if (i != 0)
1111         for (i = (prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1); i >= 0; i--)
1112 #else
1113     for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++)
1114 #endif
1115     {
1116         if (rsnSearchAKMSuite(prAdapter,
1117             prBssRsnInfo->au4AuthKeyMgtSuite[i],
1118             &j)) {
1119             u4AkmSuite = prBssRsnInfo->au4AuthKeyMgtSuite[i];
1120             break;
1121         }
1122     }
1123
1124     if (u4AkmSuite == 0) {
1125         DBGLOG(RSN, TRACE, ("Cannot support any AKM suites\n"));
1126         return FALSE;
1127     }
1128
1129     DBGLOG(RSN, TRACE, ("Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n",
1130         (UINT_8) (u4PairwiseCipher & 0x000000FF),
1131         (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF),
1132         (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF),
1133         (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF),
1134         (UINT_8) (u4GroupCipher & 0x000000FF),
1135         (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF),
1136         (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF),
1137         (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF)));
1138
1139     DBGLOG(RSN, TRACE, ("Selected AKM suite: %02x-%02x-%02x-%02x\n",
1140         (UINT_8) (u4AkmSuite & 0x000000FF),
1141         (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF),
1142         (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF),
1143         (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF)));
1144
1145 #if CFG_SUPPORT_802_11W
1146     DBGLOG(RSN, TRACE, ("MFP setting = %d\n ", kalGetMfpSetting(prAdapter->prGlueInfo)));
1147
1148     if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) {
1149         if (!prBssRsnInfo->fgRsnCapPresent) {
1150             DBGLOG(RSN, TRACE, ("Skip RSN IE, No MFP Required Capability.\n"));
1151             return FALSE;
1152         }
1153         else if (!(prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC)) {
1154             DBGLOG(RSN, TRACE, ("Skip RSN IE, No MFP Required\n"));
1155             return FALSE;
1156         }
1157         prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE;
1158     }
1159     else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) {
1160         if (prBssRsnInfo->u2RsnCap && ((prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR) ||
1161             (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC))) {
1162             prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE;
1163         }
1164         else {
1165             prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE;
1166         }
1167     }
1168     else {
1169         if (prBssRsnInfo->fgRsnCapPresent && (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR)) {
1170             DBGLOG(RSN, TRACE, ("Skip RSN IE, No MFP Required Capability\n"));
1171             return FALSE;
1172         }
1173         prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE;
1174     }
1175     DBGLOG(RSN, TRACE, ("fgMgmtProtection = %d\n ", prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection));
1176 #endif
1177
1178     if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_CCMP){
1179         prBss->ucEncLevel = 3;
1180     }
1181     else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_TKIP){
1182         prBss->ucEncLevel = 2;
1183     }
1184     else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP40 ||
1185         GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP104) {
1186         prBss->ucEncLevel = 1;
1187     }
1188     else {
1189         ASSERT(FALSE);
1190     }
1191     prBss->u4RsnSelectedPairwiseCipher = u4PairwiseCipher;
1192     prBss->u4RsnSelectedGroupCipher = u4GroupCipher;
1193     prBss->u4RsnSelectedAKMSuite = u4AkmSuite;
1194
1195     return TRUE;
1196
1197 }  /* rsnPerformPolicySelection */
1198
1199
1200 /*----------------------------------------------------------------------------*/
1201 /*!
1202 * \brief This routine is called to generate WPA IE for beacon frame.
1203 *
1204 * \param[in] pucIeStartAddr Pointer to put the generated WPA IE.
1205 *
1206 * \return The append WPA-None IE length
1207 * \note
1208 *      Called by: JOIN module, compose beacon IE
1209 */
1210 /*----------------------------------------------------------------------------*/
1211 VOID
1212 rsnGenerateWpaNoneIE (
1213     IN  P_ADAPTER_T       prAdapter,
1214     IN  P_MSDU_INFO_T     prMsduInfo
1215     )
1216 {
1217     UINT_32               i;
1218     P_WPA_INFO_ELEM_T     prWpaIE;
1219     UINT_32               u4Suite;
1220     UINT_16               u2SuiteCount;
1221     PUINT_8               cp, cp2;
1222     UINT_8                ucExpendedLen = 0;
1223     PUINT_8               pucBuffer;
1224     ENUM_NETWORK_TYPE_INDEX_T eNetworkId;
1225
1226     DEBUGFUNC("rsnGenerateWpaNoneIE");
1227
1228     ASSERT(prMsduInfo);
1229
1230     if (prAdapter->rWifiVar.rConnSettings.eAuthMode != AUTH_MODE_WPA_NONE) {
1231         return;
1232     }
1233
1234     eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T)prMsduInfo->ucNetworkType;
1235
1236     if (eNetworkId != NETWORK_TYPE_AIS_INDEX)
1237         return;
1238
1239     pucBuffer = (PUINT_8)((UINT_32)prMsduInfo->prPacket +
1240                           (UINT_32)prMsduInfo->u2FrameLength);
1241
1242     ASSERT(pucBuffer);
1243
1244     prWpaIE = (P_WPA_INFO_ELEM_T)(pucBuffer);
1245
1246     /* Start to construct a WPA IE. */
1247     /* Fill the Element ID field. */
1248     prWpaIE->ucElemId = ELEM_ID_WPA;
1249
1250     /* Fill the OUI and OUI Type fields. */
1251     prWpaIE->aucOui[0] = 0x00;
1252     prWpaIE->aucOui[1] = 0x50;
1253     prWpaIE->aucOui[2] = 0xF2;
1254     prWpaIE->ucOuiType = VENDOR_OUI_TYPE_WPA;
1255
1256     /* Fill the Version field. */
1257     WLAN_SET_FIELD_16(&prWpaIE->u2Version, 1);    /* version 1 */
1258     ucExpendedLen = 6;
1259
1260     /* Fill the Pairwise Key Cipher Suite List field. */
1261     u2SuiteCount = 0;
1262     cp = (PUINT_8)&prWpaIE->aucPairwiseKeyCipherSuite1[0];
1263
1264     if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_CCMP, &i)) {
1265         u4Suite = WPA_CIPHER_SUITE_CCMP;
1266     }
1267     else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_TKIP, &i)) {
1268         u4Suite = WPA_CIPHER_SUITE_TKIP;
1269     }
1270     else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP104, &i)) {
1271         u4Suite = WPA_CIPHER_SUITE_WEP104;
1272     }
1273     else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP40, &i)) {
1274         u4Suite = WPA_CIPHER_SUITE_WEP40;
1275     }
1276     else {
1277         u4Suite = WPA_CIPHER_SUITE_TKIP;
1278     }
1279
1280     WLAN_SET_FIELD_32(cp, u4Suite);
1281     u2SuiteCount++;
1282     ucExpendedLen += 4;
1283     cp += 4;
1284
1285     /* Fill the Group Key Cipher Suite field as the same in pair-wise key. */
1286     WLAN_SET_FIELD_32(&prWpaIE->u4GroupKeyCipherSuite, u4Suite);
1287     ucExpendedLen += 4;
1288
1289     /* Fill the Pairwise Key Cipher Suite Count field. */
1290     WLAN_SET_FIELD_16(&prWpaIE->u2PairwiseKeyCipherSuiteCount, u2SuiteCount);
1291     ucExpendedLen += 2;
1292
1293     cp2 = cp;
1294
1295     /* Fill the Authentication and Key Management Suite List field. */
1296     u2SuiteCount = 0;
1297     cp += 2;
1298
1299     if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_802_1X, &i)) {
1300         u4Suite = WPA_AKM_SUITE_802_1X;
1301     }
1302     else if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_PSK, &i)) {
1303         u4Suite = WPA_AKM_SUITE_PSK;
1304     }
1305     else {
1306         u4Suite = WPA_AKM_SUITE_NONE;
1307     }
1308
1309     /* This shall be the only avaiable value for current implementation */
1310     ASSERT(u4Suite == WPA_AKM_SUITE_NONE);
1311
1312     WLAN_SET_FIELD_32(cp, u4Suite);
1313     u2SuiteCount++;
1314     ucExpendedLen += 4;
1315     cp += 4;
1316
1317     /* Fill the Authentication and Key Management Suite Count field. */
1318     WLAN_SET_FIELD_16(cp2, u2SuiteCount);
1319     ucExpendedLen += 2;
1320
1321     /* Fill the Length field. */
1322     prWpaIE->ucLength = (UINT_8)ucExpendedLen;
1323
1324     /* Increment the total IE length for the Element ID and Length fields. */
1325     prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
1326
1327 } /* rsnGenerateWpaNoneIE */
1328
1329
1330 /*----------------------------------------------------------------------------*/
1331 /*!
1332 *
1333 * \brief This routine is called to generate WPA IE for
1334 *        associate request frame.
1335 *
1336 * \param[in]  prCurrentBss     The Selected BSS description
1337 *
1338 * \retval The append WPA IE length
1339 *
1340 * \note
1341 *      Called by: AIS module, Associate request
1342 */
1343 /*----------------------------------------------------------------------------*/
1344 VOID
1345 rsnGenerateWPAIE (
1346     IN  P_ADAPTER_T       prAdapter,
1347     IN  P_MSDU_INFO_T     prMsduInfo
1348     )
1349 {
1350     PUCHAR                cp;
1351     PUINT_8               pucBuffer;
1352     ENUM_NETWORK_TYPE_INDEX_T eNetworkId;
1353
1354     DEBUGFUNC("rsnGenerateWPAIE");
1355
1356     ASSERT(prMsduInfo);
1357
1358         P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T)NULL;
1359         prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
1360
1361     pucBuffer = (PUINT_8)((UINT_32)prMsduInfo->prPacket +
1362                           (UINT_32)prMsduInfo->u2FrameLength);
1363
1364     ASSERT(pucBuffer);
1365
1366     eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T)prMsduInfo->ucNetworkType;
1367
1368     //if (eNetworkId != NETWORK_TYPE_AIS_INDEX)
1369     //    return;
1370
1371 #if CFG_ENABLE_WIFI_DIRECT 
1372     if ((1 /* prCurrentBss->fgIEWPA */ && 
1373                 ((prAdapter->fgIsP2PRegistered) && 
1374                 (eNetworkId == NETWORK_TYPE_P2P_INDEX) && 
1375                 (kalP2PGetTkipCipher(prAdapter->prGlueInfo)))) || 
1376                 ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) || 
1377         (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK))) 
1378 #else 
1379         if ((1 /* prCurrentBss->fgIEWPA */ && 
1380         ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) || 
1381         (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK)))) 
1382 #endif
1383     {
1384         if (prP2pSpecificBssInfo->u2WpaIeLen!=0)
1385                 {
1386              kalMemCopy(pucBuffer,prP2pSpecificBssInfo->aucWpaIeBuffer,
1387                          prP2pSpecificBssInfo->u2WpaIeLen);
1388              prMsduInfo->u2FrameLength += prP2pSpecificBssInfo->u2WpaIeLen;
1389                          return;
1390
1391                 }
1392         /* Construct a WPA IE for association request frame. */
1393         WPA_IE(pucBuffer)->ucElemId = ELEM_ID_WPA;
1394         WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED;
1395         WPA_IE(pucBuffer)->aucOui[0] = 0x00;
1396         WPA_IE(pucBuffer)->aucOui[1] = 0x50;
1397         WPA_IE(pucBuffer)->aucOui[2] = 0xF2;
1398         WPA_IE(pucBuffer)->ucOuiType = VENDOR_OUI_TYPE_WPA;
1399         WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2Version, 1);
1400
1401 #if CFG_ENABLE_WIFI_DIRECT
1402         if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX)
1403         {
1404             WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite, WPA_CIPHER_SUITE_TKIP);
1405         }
1406         else
1407 #endif
1408         WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite,
1409             prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedGroupCipher);
1410
1411         cp = (PUCHAR) &WPA_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0];
1412
1413         WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1);
1414 #if CFG_ENABLE_WIFI_DIRECT
1415         if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX)
1416         {
1417             WLAN_SET_FIELD_32(cp, WPA_CIPHER_SUITE_TKIP);
1418         }
1419         else
1420 #endif
1421         WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedPairwiseCipher);
1422         cp += 4;
1423
1424         WLAN_SET_FIELD_16(cp, 1);
1425         cp += 2;
1426 #if CFG_ENABLE_WIFI_DIRECT
1427         if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX)
1428         {
1429             WLAN_SET_FIELD_32(cp, WPA_AKM_SUITE_PSK);
1430         }
1431         else
1432 #endif
1433         WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedAKMSuite);
1434         cp += 4;
1435
1436         WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED;
1437
1438         prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
1439     }
1440
1441 } /* rsnGenerateWPAIE */
1442
1443
1444 /*----------------------------------------------------------------------------*/
1445 /*!
1446 *
1447 * \brief This routine is called to generate RSN IE for
1448 *        associate request frame.
1449 *
1450 * \param[in]  prMsduInfo     The Selected BSS description
1451 *
1452 * \retval The append RSN IE length
1453 *
1454 * \note
1455 *      Called by: AIS module, P2P module, BOW module Associate request
1456 */
1457 /*----------------------------------------------------------------------------*/
1458 VOID
1459 rsnGenerateRSNIE (
1460     IN  P_ADAPTER_T       prAdapter,
1461     IN  P_MSDU_INFO_T     prMsduInfo
1462     )
1463 {
1464     UINT_32               u4Entry;
1465     PUCHAR                cp;
1466     //UINT_8                ucExpendedLen = 0;
1467     PUINT_8               pucBuffer;
1468     ENUM_NETWORK_TYPE_INDEX_T eNetworkId;
1469     P_STA_RECORD_T  prStaRec;
1470
1471     DEBUGFUNC("rsnGenerateRSNIE");
1472
1473     ASSERT(prMsduInfo);
1474
1475     pucBuffer = (PUINT_8)((UINT_32)prMsduInfo->prPacket +
1476                           (UINT_32)prMsduInfo->u2FrameLength);
1477
1478     ASSERT(pucBuffer);
1479
1480     /* Todo:: network id */
1481     eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T)prMsduInfo->ucNetworkType;
1482
1483     if (
1484 #if CFG_ENABLE_WIFI_DIRECT
1485         ((prAdapter->fgIsP2PRegistered) &&
1486         (eNetworkId == NETWORK_TYPE_P2P_INDEX) &&
1487         (kalP2PGetCcmpCipher(prAdapter->prGlueInfo))) ||
1488 #endif
1489 #if CFG_ENABLE_BT_OVER_WIFI
1490         (eNetworkId == NETWORK_TYPE_BOW_INDEX) ||
1491 #endif
1492         (eNetworkId == NETWORK_TYPE_AIS_INDEX /* prCurrentBss->fgIERSN */ &&
1493         ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) ||
1494         (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK))))
1495     {
1496         /* Construct a RSN IE for association request frame. */
1497         RSN_IE(pucBuffer)->ucElemId = ELEM_ID_RSN;
1498         RSN_IE(pucBuffer)->ucLength = ELEM_ID_RSN_LEN_FIXED;
1499         WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2Version, 1); // Version
1500         WLAN_SET_FIELD_32(&RSN_IE(pucBuffer)->u4GroupKeyCipherSuite,
1501             prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedGroupCipher); // Group key suite
1502         cp = (PUCHAR) &RSN_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0];
1503         WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1);
1504         WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedPairwiseCipher);
1505         cp += 4;
1506         WLAN_SET_FIELD_16(cp, 1); // AKM suite count
1507         cp += 2;
1508         WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedAKMSuite); // AKM suite
1509         cp += 4;
1510         WLAN_SET_FIELD_16(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u2RsnSelectedCapInfo); // Capabilities
1511 #if CFG_SUPPORT_802_11W
1512         if (eNetworkId == NETWORK_TYPE_AIS_INDEX && prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection) {
1513             if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) {
1514                 WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC | ELEM_WPA_CAP_MFPR); // Capabilities
1515             }
1516             else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) {
1517                 WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC); // Capabilities
1518             }
1519         }
1520 #endif
1521         cp += 2;
1522
1523         if (eNetworkId == NETWORK_TYPE_AIS_INDEX)
1524             prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
1525
1526         if (eNetworkId == NETWORK_TYPE_AIS_INDEX &&
1527             rsnSearchPmkidEntry(prAdapter, prStaRec->aucMacAddr, &u4Entry)) {
1528             //DBGLOG(RSN, TRACE, ("Add Pmk at assoc req\n"));
1529             //DBGLOG(RSN, TRACE, ("addr " MACSTR" PMKID "MACSTR"\n",
1530             //    MAC2STR(prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arBSSID), MAC2STR(prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arPMKID)));
1531             if (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].fgPmkidExist) {
1532                 RSN_IE(pucBuffer)->ucLength = 38;
1533                 WLAN_SET_FIELD_16(cp, 1); // PMKID count
1534                 cp += 2;
1535                 DBGLOG(RSN, TRACE, ("BSSID "MACSTR" ind=%d\n", MAC2STR(prStaRec->aucMacAddr), u4Entry));
1536                 DBGLOG(RSN, TRACE, ("use PMKID "MACSTR"\n", MAC2STR(prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arPMKID)));
1537                 kalMemCopy(cp, (PVOID)prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arPMKID,
1538                     sizeof(PARAM_PMKID_VALUE));
1539                 //ucExpendedLen = 40;
1540             }
1541             else {
1542                 WLAN_SET_FIELD_16(cp, 0); // PMKID count
1543                 //ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2;
1544 #if CFG_SUPPORT_802_11W
1545                 cp += 2;
1546                 RSN_IE(pucBuffer)->ucLength += 2;
1547 #endif
1548             }
1549         }
1550         else {
1551             WLAN_SET_FIELD_16(cp, 0); // PMKID count
1552             //ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2;
1553 #if CFG_SUPPORT_802_11W
1554             cp += 2;
1555             RSN_IE(pucBuffer)->ucLength += 2;
1556 #endif
1557         }
1558
1559 #if CFG_SUPPORT_802_11W
1560         if ((eNetworkId == NETWORK_TYPE_AIS_INDEX) && (kalGetMfpSetting(prAdapter->prGlueInfo) != RSN_AUTH_MFP_DISABLED) /* (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) */ ) {
1561             WLAN_SET_FIELD_32(cp, RSN_CIPHER_SUITE_AES_128_CMAC);
1562             cp += 4;
1563             RSN_IE(pucBuffer)->ucLength += 4;
1564         }
1565 #endif
1566         prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
1567     }
1568
1569 } /* rsnGenerateRSNIE */
1570
1571 /*----------------------------------------------------------------------------*/
1572 /*!
1573 * \brief Parse the given IE buffer and check if it is WFA IE and return Type and
1574 *        SubType for further process.
1575 *
1576 * \param[in] pucBuf             Pointer to the buffer of WFA Information Element.
1577 * \param[out] pucOuiType        Pointer to the storage of OUI Type.
1578 * \param[out] pu2SubTypeVersion Pointer to the storage of OUI SubType and Version.
1579
1580 * \retval TRUE  Parse IE ok
1581 * \retval FALSE Parse IE fail
1582 */
1583 /*----------------------------------------------------------------------------*/
1584 BOOLEAN
1585 rsnParseCheckForWFAInfoElem (
1586     IN  P_ADAPTER_T       prAdapter,
1587     IN  PUINT_8           pucBuf,
1588     OUT PUINT_8           pucOuiType,
1589     OUT PUINT_16          pu2SubTypeVersion
1590     )
1591 {
1592     UINT_8 aucWfaOui[] = VENDOR_OUI_WFA;
1593     P_IE_WFA_T prWfaIE;
1594
1595     ASSERT(pucBuf);
1596     ASSERT(pucOuiType);
1597     ASSERT(pu2SubTypeVersion);
1598     prWfaIE = (P_IE_WFA_T)pucBuf;
1599
1600     do {
1601         if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) {
1602             break;
1603         }
1604         else if (prWfaIE->aucOui[0] != aucWfaOui[0] ||
1605                  prWfaIE->aucOui[1] != aucWfaOui[1] ||
1606                  prWfaIE->aucOui[2] != aucWfaOui[2]) {
1607             break;
1608         }
1609
1610         *pucOuiType = prWfaIE->ucOuiType;
1611         WLAN_GET_FIELD_16(&prWfaIE->aucOuiSubTypeVersion[0], pu2SubTypeVersion);
1612
1613         return TRUE;
1614     }
1615     while (FALSE);
1616
1617     return FALSE;
1618
1619 } /* end of rsnParseCheckForWFAInfoElem() */
1620
1621 #if CFG_SUPPORT_AAA
1622 /*----------------------------------------------------------------------------*/
1623 /*!
1624 * \brief Parse the given IE buffer and check if it is RSN IE with CCMP PSK
1625 *
1626 * \param[in] prAdapter             Pointer to Adapter
1627 * \param[in] prSwRfb               Pointer to the rx buffer
1628 * \param[in] pIE                      Pointer rthe buffer of Information Element.
1629 * \param[out] prStatusCode     Pointer to the return status code.
1630
1631 * \retval none
1632 */
1633 /*----------------------------------------------------------------------------*/
1634 void
1635 rsnParserCheckForRSNCCMPPSK(
1636     P_ADAPTER_T           prAdapter,
1637     P_RSN_INFO_ELEM_T     prIe,
1638     PUINT_16              pu2StatusCode
1639     )
1640 {
1641
1642     RSN_INFO_T            rRsnIe;
1643
1644     ASSERT(prAdapter);
1645     ASSERT(prIe);
1646     ASSERT(pu2StatusCode);
1647
1648     *pu2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT;
1649
1650     if (rsnParseRsnIE(prAdapter, prIe, &rRsnIe)) {
1651         if ((rRsnIe.u4PairwiseKeyCipherSuiteCount != 1) || (rRsnIe.au4PairwiseKeyCipherSuite[0] != RSN_CIPHER_SUITE_CCMP)) {
1652             *pu2StatusCode = STATUS_CODE_INVALID_PAIRWISE_CIPHER;
1653             return;
1654         }
1655         if ((rRsnIe.u4GroupKeyCipherSuite != RSN_CIPHER_SUITE_CCMP)) {
1656             *pu2StatusCode = STATUS_CODE_INVALID_GROUP_CIPHER;
1657             return;
1658         }
1659         if ((rRsnIe.u4AuthKeyMgtSuiteCount != 1) || (rRsnIe.au4AuthKeyMgtSuite[0] != RSN_AKM_SUITE_PSK)) {
1660             *pu2StatusCode = STATUS_CODE_INVALID_AKMP;
1661             return;
1662         }
1663
1664         DBGLOG(RSN, TRACE, ("RSN with CCMP-PSK\n" ));
1665             *pu2StatusCode = WLAN_STATUS_SUCCESS;
1666     }
1667
1668 }
1669 #endif
1670
1671 /*----------------------------------------------------------------------------*/
1672 /*!
1673 * \brief This routine is called to generate an authentication event to NDIS.
1674 *
1675 * \param[in] u4Flags Authentication event: \n
1676 *                     PARAM_AUTH_REQUEST_REAUTH 0x01 \n
1677 *                     PARAM_AUTH_REQUEST_KEYUPDATE 0x02 \n
1678 *                     PARAM_AUTH_REQUEST_PAIRWISE_ERROR 0x06 \n
1679 *                     PARAM_AUTH_REQUEST_GROUP_ERROR 0x0E \n
1680 *
1681 * \return (none)
1682 */
1683 /*----------------------------------------------------------------------------*/
1684 VOID
1685 rsnGenMicErrorEvent (
1686     IN  P_ADAPTER_T       prAdapter,
1687     IN  BOOLEAN           fgFlags
1688     )
1689 {
1690     P_PARAM_AUTH_EVENT_T prAuthEvent;
1691
1692     DEBUGFUNC("rsnGenMicErrorEvent");
1693
1694     prAuthEvent = (P_PARAM_AUTH_EVENT_T)prAdapter->aucIndicationEventBuffer;
1695
1696     /* Status type: Authentication Event */
1697     prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION;
1698
1699     /* Authentication request */
1700     prAuthEvent->arRequest[0].u4Length = sizeof(PARAM_AUTH_REQUEST_T);
1701     kalMemCopy((PVOID)prAuthEvent->arRequest[0].arBssid, (PVOID)prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].aucBSSID, MAC_ADDR_LEN);
1702
1703     if (fgFlags == TRUE)
1704         prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR;
1705     else
1706         prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR;
1707
1708     kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
1709         WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
1710         (PVOID)prAuthEvent,
1711         sizeof(PARAM_STATUS_INDICATION_T) + sizeof(PARAM_AUTH_REQUEST_T));
1712
1713 } /* rsnGenMicErrorEvent */
1714
1715
1716 /*----------------------------------------------------------------------------*/
1717 /*!
1718 * \brief This routine is called to handle TKIP MIC failures.
1719 *
1720 * \param[in] adapter_p Pointer to the adapter object data area.
1721 * \param[in] prSta Pointer to the STA which occur MIC Error
1722 * \param[in] fgErrorKeyType type of error key
1723 *
1724 * \retval none
1725 */
1726 /*----------------------------------------------------------------------------*/
1727 VOID
1728 rsnTkipHandleMICFailure (
1729     IN  P_ADAPTER_T       prAdapter,
1730     IN  P_STA_RECORD_T    prSta,
1731     IN  BOOLEAN           fgErrorKeyType
1732     )
1733 {
1734     //UINT_32               u4RsnaCurrentMICFailTime;
1735     //P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
1736
1737     DEBUGFUNC("rsnTkipHandleMICFailure");
1738
1739     ASSERT(prAdapter);
1740 #if 1
1741     rsnGenMicErrorEvent(prAdapter,/* prSta,*/ fgErrorKeyType);
1742
1743     /* Generate authentication request event. */
1744     DBGLOG(RSN, INFO, ("Generate TKIP MIC error event (type: 0%d)\n",
1745         fgErrorKeyType));
1746 #else
1747     ASSERT(prSta);
1748
1749     prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
1750
1751     /* Record the MIC error occur time. */
1752     GET_CURRENT_SYSTIME(&u4RsnaCurrentMICFailTime);
1753
1754     /* Generate authentication request event. */
1755     DBGLOG(RSN, INFO, ("Generate TKIP MIC error event (type: 0%d)\n",
1756         fgErrorKeyType));
1757
1758     /* If less than 60 seconds have passed since a previous TKIP MIC failure,
1759        disassociate from the AP and wait for 60 seconds before (re)associating
1760        with the same AP. */
1761     if (prAisSpecBssInfo->u4RsnaLastMICFailTime != 0 &&
1762         !CHECK_FOR_TIMEOUT(u4RsnaCurrentMICFailTime,
1763             prAisSpecBssInfo->u4RsnaLastMICFailTime,
1764             SEC_TO_SYSTIME(TKIP_COUNTERMEASURE_SEC))) {
1765         /* If less than 60 seconds expired since last MIC error, we have to
1766            block traffic. */
1767
1768         DBGLOG(RSN, INFO, ("Start blocking traffic!\n"));
1769         rsnGenMicErrorEvent( prAdapter,/* prSta,*/ fgErrorKeyType);
1770
1771         secFsmEventStartCounterMeasure(prAdapter, prSta);
1772     }
1773     else {
1774         rsnGenMicErrorEvent( prAdapter,/* prSta,*/ fgErrorKeyType);
1775         DBGLOG(RSN, INFO, ("First TKIP MIC error!\n"));
1776     }
1777
1778     COPY_SYSTIME(prAisSpecBssInfo->u4RsnaLastMICFailTime, u4RsnaCurrentMICFailTime);
1779 #endif
1780 }   /* rsnTkipHandleMICFailure */
1781
1782
1783 /*----------------------------------------------------------------------------*/
1784 /*!
1785 * \brief This function is called to select a list of BSSID from
1786 *        the scan results for PMKID candidate list.
1787 *
1788 * \param[in] prBssDesc the BSS Desc at scan result list
1789 * \param[out] pu4CandidateCount Pointer to the number of selected candidates.
1790 *                         It is set to zero if no BSSID matches our requirement.
1791 *
1792 * \retval none
1793 */
1794 /*----------------------------------------------------------------------------*/
1795 VOID
1796 rsnSelectPmkidCandidateList (
1797     IN  P_ADAPTER_T       prAdapter,
1798     IN P_BSS_DESC_T       prBssDesc
1799     )
1800 {
1801     P_CONNECTION_SETTINGS_T prConnSettings;
1802     P_AIS_BSS_INFO_T      prAisBssInfo;
1803
1804     DEBUGFUNC("rsnSelectPmkidCandidateList");
1805
1806     ASSERT(prBssDesc);
1807
1808     prConnSettings = &prAdapter->rWifiVar.rConnSettings;
1809     prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
1810
1811     /* Search a BSS with the same SSID from the given BSS description set. */
1812     //DBGLOG(RSN, TRACE, ("Check scan result ["MACSTR"]\n",
1813     //    MAC2STR(prBssDesc->aucBSSID)));
1814
1815     if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen,
1816                    prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) {
1817         DBGLOG(RSN, TRACE, ("-- SSID not matched\n"));
1818         return;
1819     }
1820
1821 #if 0
1822     if ((prBssDesc->u2BSSBasicRateSet &
1823          ~(rPhyAttributes[prAisBssInfo->ePhyType].u2SupportedRateSet)) ||
1824         prBssDesc->fgIsUnknownBssBasicRate) {
1825         DBGLOG(RSN, TRACE, ("-- Rate set not matched\n"));
1826         return;
1827     }
1828
1829     if (/* prBssDesc->u4RsnSelectedPairwiseCipher != prAisBssInfo->u4RsnSelectedPairwiseCipher ||*/
1830         prBssDesc->u4RsnSelectedGroupCipher != prAisBssInfo->u4RsnSelectedGroupCipher /*||
1831         prBssDesc->u4RsnSelectedAKMSuite != prAisBssInfo->u4RsnSelectedAKMSuite */) {
1832         DBGLOG(RSN, TRACE, ("-- Encrypt status not matched for PMKID \n"));
1833         return;
1834     }
1835 #endif
1836
1837     rsnUpdatePmkidCandidateList(prAdapter, prBssDesc);
1838
1839 }   /* rsnSelectPmkidCandidateList */
1840
1841
1842 /*----------------------------------------------------------------------------*/
1843 /*!
1844 * \brief This function is called to select a list of BSSID from
1845 *        the scan results for PMKID candidate list.
1846 *
1847 * \param[in] prBssDesc the BSS DESC at scan result list
1848 *
1849 * \retval none
1850 */
1851 /*----------------------------------------------------------------------------*/
1852 VOID
1853 rsnUpdatePmkidCandidateList (
1854     IN  P_ADAPTER_T       prAdapter,
1855     IN  P_BSS_DESC_T      prBssDesc
1856     )
1857 {
1858     UINT_32                   i;
1859     P_CONNECTION_SETTINGS_T   prConnSettings;
1860     P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
1861
1862     DEBUGFUNC("rsnUpdatePmkidCandidateList");
1863
1864     ASSERT(prBssDesc);
1865
1866     prConnSettings = &prAdapter->rWifiVar.rConnSettings;
1867     prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
1868
1869     if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen,
1870                    prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) {
1871         DBGLOG(RSN, TRACE, ("-- SSID not matched\n"));
1872         return;
1873     }
1874
1875     for (i = 0; i < CFG_MAX_PMKID_CACHE; i++) {
1876         if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisSpecBssInfo->arPmkidCandicate[i].aucBssid))
1877             return;
1878     }
1879
1880     /* If the number of selected BSSID exceed MAX_NUM_PMKID_CACHE(16),
1881        then we only store MAX_NUM_PMKID_CACHE(16) in PMKID cache */
1882     if ((prAisSpecBssInfo->u4PmkidCandicateCount + 1)  > CFG_MAX_PMKID_CACHE) {
1883         prAisSpecBssInfo->u4PmkidCandicateCount --;
1884     }
1885
1886     i = prAisSpecBssInfo->u4PmkidCandicateCount;
1887
1888     COPY_MAC_ADDR((PVOID)prAisSpecBssInfo->arPmkidCandicate[i].aucBssid,
1889         (PVOID)prBssDesc->aucBSSID);
1890
1891     if (prBssDesc->u2RsnCap & MASK_RSNIE_CAP_PREAUTH) {
1892         prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 1;
1893         DBGLOG(RSN, TRACE, ("Add " MACSTR " with pre-auth to candidate list\n",
1894             MAC2STR(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)));
1895     }
1896     else {
1897         prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 0;
1898         DBGLOG(RSN, TRACE, ("Add " MACSTR " without pre-auth to candidate list\n",
1899             MAC2STR(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)));
1900     }
1901
1902     prAisSpecBssInfo->u4PmkidCandicateCount ++;
1903
1904 }   /* rsnUpdatePmkidCandidateList */
1905
1906
1907 /*----------------------------------------------------------------------------*/
1908 /*!
1909 * \brief This routine is called to search the desired entry in
1910 *        PMKID cache according to the BSSID
1911 *
1912 * \param[in] pucBssid Pointer to the BSSID
1913 * \param[out] pu4EntryIndex Pointer to place the found entry index
1914 *
1915 * \retval TRUE, if found one entry for specified BSSID
1916 * \retval FALSE, if not found
1917 */
1918 /*----------------------------------------------------------------------------*/
1919 BOOLEAN
1920 rsnSearchPmkidEntry (
1921     IN  P_ADAPTER_T       prAdapter,
1922     IN  PUINT_8           pucBssid,
1923     OUT PUINT_32          pu4EntryIndex
1924     )
1925 {
1926     UINT_32 i;
1927     P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
1928
1929     DEBUGFUNC("rsnSearchPmkidEntry");
1930
1931     ASSERT(pucBssid);
1932     ASSERT(pu4EntryIndex);
1933
1934     prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
1935
1936     if (prAisSpecBssInfo->u4PmkidCacheCount > CFG_MAX_PMKID_CACHE) {
1937         return FALSE;
1938     }
1939
1940     ASSERT(prAisSpecBssInfo->u4PmkidCacheCount <= CFG_MAX_PMKID_CACHE);
1941
1942     /* Search for desired BSSID */
1943     for (i = 0; i < prAisSpecBssInfo->u4PmkidCacheCount; i++) {
1944         if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arBSSID, pucBssid,
1945             MAC_ADDR_LEN)) {
1946             break;
1947         }
1948     }
1949
1950     /* If desired BSSID is found, then set the PMKID */
1951     if (i < prAisSpecBssInfo->u4PmkidCacheCount) {
1952         *pu4EntryIndex = i;
1953
1954         return TRUE;
1955     }
1956
1957     return FALSE;
1958 }   /* rsnSearchPmkidEntry */
1959
1960
1961 /*----------------------------------------------------------------------------*/
1962 /*!
1963 * \brief This routine is called to check if there is difference
1964 *        between PMKID candicate list and PMKID cache. If there
1965 *        is new candicate that no cache entry is available, then
1966 *        add a new entry for the new candicate in the PMKID cache
1967 *        and set the PMKID indication flag to TRUE.
1968 *
1969 * \retval TRUE, if new member in the PMKID candicate list
1970 * \retval FALSe, if no new member in the PMKID candicate list
1971 */
1972 /*----------------------------------------------------------------------------*/
1973 BOOLEAN
1974 rsnCheckPmkidCandicate (
1975     IN  P_ADAPTER_T       prAdapter
1976    )
1977 {
1978     P_AIS_SPECIFIC_BSS_INFO_T  prAisSpecBssInfo;
1979     UINT_32                    i; // Index for PMKID candicate
1980     UINT_32                    j; // Indix for PMKID cache
1981     BOOLEAN                    status = FALSE;
1982
1983     DEBUGFUNC("rsnCheckPmkidCandicate");
1984
1985     prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
1986
1987     /* Check for each candicate */
1988     for (i = 0; i < prAisSpecBssInfo->u4PmkidCandicateCount; i++) {
1989         for (j = 0; j < prAisSpecBssInfo->u4PmkidCacheCount; j++) {
1990             if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID,
1991                     prAisSpecBssInfo->arPmkidCandicate[i].aucBssid,
1992                     MAC_ADDR_LEN)) {
1993                 //DBGLOG(RSN, TRACE, (MACSTR" at PMKID cache!!\n", MAC2STR(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)));
1994                 break;
1995             }
1996         }
1997
1998         /* No entry found in PMKID cache for the candicate, add new one */
1999         if (j == prAisSpecBssInfo->u4PmkidCacheCount && prAisSpecBssInfo->u4PmkidCacheCount < CFG_MAX_PMKID_CACHE) {
2000             DBGLOG(RSN, TRACE, ("Add "MACSTR" to PMKID cache!!\n", MAC2STR(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)));
2001             kalMemCopy((PVOID)prAisSpecBssInfo->arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].rBssidInfo.arBSSID,
2002                 (PVOID)prAisSpecBssInfo->arPmkidCandicate[i].aucBssid,
2003                 MAC_ADDR_LEN);
2004             prAisSpecBssInfo->arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].fgPmkidExist = FALSE;
2005             prAisSpecBssInfo->u4PmkidCacheCount++;
2006
2007             status = TRUE;
2008         }
2009     }
2010
2011     return status;
2012 } /* rsnCheckPmkidCandicate */
2013
2014
2015 /*----------------------------------------------------------------------------*/
2016 /*!
2017 * \brief This function is called to wait a duration to indicate the pre-auth AP candicate
2018 *
2019 * \return (none)
2020 */
2021 /*----------------------------------------------------------------------------*/
2022 VOID
2023 rsnIndicatePmkidCand (
2024     IN  P_ADAPTER_T       prAdapter,
2025     IN  UINT_32           u4Parm
2026     )
2027 {
2028     DBGLOG(RSN, EVENT, ("Security - Time to indicate the PMKID cand.\n"));
2029
2030     /* If the authentication mode is WPA2 and indication PMKID flag
2031        is available, then we indicate the PMKID candidate list to NDIS and
2032        clear the flag, indicatePMKID */
2033
2034     if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED &&
2035         prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
2036         rsnGeneratePmkidIndication(prAdapter);
2037     }
2038
2039     return;
2040 } /* end of rsnIndicatePmkidCand() */
2041
2042
2043 /*----------------------------------------------------------------------------*/
2044 /*!
2045 * \brief This routine is called to check the BSS Desc at scan result
2046 *             with pre-auth cap at wpa2 mode. If there
2047 *             is candicate that no cache entry is available, then
2048 *             add a new entry for the new candicate in the PMKID cache
2049 *             and set the PMKID indication flag to TRUE.
2050 *
2051 * \param[in] prBss The BSS Desc at scan result
2052 *
2053 * \return none
2054 */
2055 /*----------------------------------------------------------------------------*/
2056 VOID
2057 rsnCheckPmkidCache (
2058     IN  P_ADAPTER_T       prAdapter,
2059     IN  P_BSS_DESC_T      prBss
2060     )
2061 {
2062     P_AIS_BSS_INFO_T           prAisBssInfo;
2063     P_AIS_SPECIFIC_BSS_INFO_T  prAisSpecBssInfo;
2064     P_CONNECTION_SETTINGS_T    prConnSettings;
2065
2066     DEBUGFUNC("rsnCheckPmkidCandicate");
2067
2068     ASSERT(prBss);
2069
2070     prConnSettings = &prAdapter->rWifiVar.rConnSettings;
2071     prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
2072     prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2073
2074     if ((prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) &&
2075        (prConnSettings->eAuthMode == AUTH_MODE_WPA2)) {
2076         rsnSelectPmkidCandidateList(prAdapter, prBss);
2077
2078         /* Set indication flag of PMKID to TRUE, and then connHandleNetworkConnection()
2079            will indicate this later */
2080         if (rsnCheckPmkidCandicate(prAdapter)) {
2081             DBGLOG(RSN, TRACE, ("Prepare a timer to indicate candidate PMKID Candidate\n"));
2082             cnmTimerStopTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer);
2083             cnmTimerStartTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer,
2084                     SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC));
2085         }
2086     }
2087 }
2088
2089
2090 /*----------------------------------------------------------------------------*/
2091 /*!
2092 * \brief This routine is called to generate an PMKID candidate list
2093 *        indication to NDIS.
2094 *
2095 * \param[in] prAdapter Pointer to the adapter object data area.
2096 * \param[in] u4Flags PMKID candidate list event:
2097 *                    PARAM_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01
2098 *
2099 * \retval none
2100 */
2101 /*----------------------------------------------------------------------------*/
2102 VOID
2103 rsnGeneratePmkidIndication (
2104     IN  P_ADAPTER_T       prAdapter
2105     )
2106 {
2107     P_PARAM_STATUS_INDICATION_T    prStatusEvent;
2108     P_PARAM_PMKID_CANDIDATE_LIST_T prPmkidEvent;
2109     P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo;
2110     UINT_8                i, j = 0, count = 0;
2111     UINT_32               u4LenOfUsedBuffer;
2112
2113     DEBUGFUNC("rsnGeneratePmkidIndication");
2114
2115     ASSERT(prAdapter);
2116
2117     prStatusEvent =
2118         (P_PARAM_STATUS_INDICATION_T)prAdapter->aucIndicationEventBuffer;
2119
2120     /* Status type: PMKID Candidatelist Event */
2121     prStatusEvent->eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST;
2122     ASSERT(prStatusEvent);
2123
2124     prPmkidEvent = (P_PARAM_PMKID_CANDIDATE_LIST_T)(&prStatusEvent->eStatusType + 1);
2125     ASSERT(prPmkidEvent);
2126
2127     prAisSpecificBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2128     ASSERT(prAisSpecificBssInfo);
2129
2130     for (i = 0; i < prAisSpecificBssInfo->u4PmkidCandicateCount; i++) {
2131         for (j = 0; j < prAisSpecificBssInfo->u4PmkidCacheCount; j++) {
2132             if (EQUAL_MAC_ADDR( prAisSpecificBssInfo->arPmkidCache[j].rBssidInfo.arBSSID,
2133                 prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid) &&
2134                 (prAisSpecificBssInfo->arPmkidCache[j].fgPmkidExist == TRUE)){
2135                 break;
2136             }
2137         }
2138         if (count >= CFG_MAX_PMKID_CACHE) {
2139             break;
2140         }
2141
2142         if (j == prAisSpecificBssInfo->u4PmkidCacheCount) {
2143             kalMemCopy((PVOID)prPmkidEvent->arCandidateList[count].arBSSID,
2144                 (PVOID)prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid,
2145                 PARAM_MAC_ADDR_LEN);
2146             prPmkidEvent->arCandidateList[count].u4Flags =
2147                 prAisSpecificBssInfo->arPmkidCandicate[i].u4PreAuthFlags;
2148             DBGLOG(RSN, TRACE, (MACSTR" %d\n", MAC2STR(prPmkidEvent->arCandidateList[count].arBSSID),
2149                 prPmkidEvent->arCandidateList[count].u4Flags));
2150             count++;
2151         }
2152     }
2153
2154     /* PMKID Candidate List */
2155     prPmkidEvent->u4Version = 1;
2156     prPmkidEvent->u4NumCandidates = count;
2157     DBGLOG(RSN, TRACE, ("rsnGeneratePmkidIndication #%d\n", prPmkidEvent->u4NumCandidates));
2158     u4LenOfUsedBuffer = sizeof(ENUM_STATUS_TYPE_T) + (2 * sizeof(UINT_32)) +
2159         (count * sizeof(PARAM_PMKID_CANDIDATE_T));
2160     //dumpMemory8((PUINT_8)prAdapter->aucIndicationEventBuffer, u4LenOfUsedBuffer);
2161
2162     kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
2163         WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
2164         (PVOID) prAdapter->aucIndicationEventBuffer,
2165         u4LenOfUsedBuffer);
2166
2167 }   /* rsnGeneratePmkidIndication */
2168 #endif
2169
2170 #if CFG_SUPPORT_WPS2
2171 /*----------------------------------------------------------------------------*/
2172 /*!
2173 *
2174 * \brief This routine is called to generate WSC IE for
2175 *        associate request frame.
2176 *
2177 * \param[in]  prCurrentBss     The Selected BSS description
2178 *
2179 * \retval The append WSC IE length
2180 *
2181 * \note
2182 *      Called by: AIS module, Associate request
2183 */
2184 /*----------------------------------------------------------------------------*/
2185 VOID
2186 rsnGenerateWSCIE (
2187     IN P_ADAPTER_T          prAdapter,
2188     IN P_MSDU_INFO_T        prMsduInfo
2189     )
2190 {
2191     PUINT_8                 pucBuffer;
2192
2193     ASSERT(prAdapter);
2194     ASSERT(prMsduInfo);
2195
2196     if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX)
2197         return;
2198
2199     pucBuffer = (PUINT_8)((UINT_32)prMsduInfo->prPacket +
2200                           (UINT_32)prMsduInfo->u2FrameLength);
2201
2202     /* ASSOC INFO IE ID: 221 :0xDD */
2203     if (prAdapter->prGlueInfo->u2WSCAssocInfoIELen) {
2204         kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWSCAssocInfoIE, prAdapter->prGlueInfo->u2WSCAssocInfoIELen);
2205         prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WSCAssocInfoIELen;
2206     }
2207
2208 }
2209 #endif
2210
2211
2212 #if CFG_SUPPORT_802_11W
2213
2214 /*----------------------------------------------------------------------------*/
2215 /*!
2216 * \brief to check if the Bip Key installed or not
2217 *
2218 * \param[in]
2219 *           prAdapter
2220 *
2221 * \return
2222 *           TRUE
2223 *           FALSE
2224 */
2225 /*----------------------------------------------------------------------------*/
2226 UINT_32
2227 rsnCheckBipKeyInstalled (
2228     IN P_ADAPTER_T                  prAdapter,
2229     IN P_STA_RECORD_T               prStaRec
2230     )
2231 {
2232     if (prStaRec && prStaRec->ucNetTypeIndex == (UINT_8)NETWORK_TYPE_AIS_INDEX)
2233         return prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled;
2234     else
2235         return FALSE;
2236 }
2237
2238 /*----------------------------------------------------------------------------*/
2239 /*!
2240 *
2241 * \brief This routine is called to check the Sa query timeout.
2242 *
2243 *
2244 * \note
2245 *      Called by: AIS module, Handle by Sa Quert timeout
2246 */
2247 /*----------------------------------------------------------------------------*/
2248 UINT_8
2249 rsnCheckSaQueryTimeout (
2250     IN P_ADAPTER_T                  prAdapter
2251     )
2252 {
2253     P_AIS_SPECIFIC_BSS_INFO_T       prBssSpecInfo;
2254     UINT_32 now;
2255
2256     prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2257     ASSERT(prBssSpecInfo);
2258
2259     GET_CURRENT_SYSTIME(&now);
2260
2261     if (CHECK_FOR_TIMEOUT(now,
2262                 prBssSpecInfo->u4SaQueryStart,
2263                 TU_TO_MSEC(1000))) {
2264         LOG_FUNC("association SA Query timed out\n");
2265
2266         prBssSpecInfo->ucSaQueryTimedOut = 1;
2267         kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
2268         prBssSpecInfo->pucSaQueryTransId = NULL;
2269         prBssSpecInfo->u4SaQueryCount = 0;
2270         cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer);
2271         /* Re-connect */
2272         kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
2273                 WLAN_STATUS_MEDIA_DISCONNECT,
2274                 NULL,
2275                 0);
2276
2277         return 1;
2278     }
2279
2280     return 0;
2281 }
2282
2283 /*----------------------------------------------------------------------------*/
2284 /*!
2285 *
2286 * \brief This routine is called to start the 802.11w sa query timer.
2287 *
2288 *
2289 * \note
2290 *      Called by: AIS module, Handle Rx mgmt request
2291 */
2292 /*----------------------------------------------------------------------------*/
2293 void rsnStartSaQueryTimer (
2294     IN P_ADAPTER_T                  prAdapter
2295     )
2296 {
2297     P_BSS_INFO_T                    prBssInfo;
2298     P_AIS_SPECIFIC_BSS_INFO_T       prBssSpecInfo;
2299     P_MSDU_INFO_T                   prMsduInfo;
2300     P_ACTION_SA_QUERY_FRAME         prTxFrame;
2301     UINT_16                         u2PayloadLen;
2302     PUINT_8                         pucTmp = NULL;
2303     UINT_8                          ucTransId[ACTION_SA_QUERY_TR_ID_LEN];
2304
2305     prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
2306     ASSERT(prBssInfo);
2307
2308     prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2309     ASSERT(prBssSpecInfo);
2310
2311     LOG_FUNC("MFP: Start Sa Query\n");
2312
2313     if (prBssSpecInfo->u4SaQueryCount > 0 &&
2314         rsnCheckSaQueryTimeout(prAdapter)) {
2315         LOG_FUNC("MFP: u4SaQueryCount count =%d\n", prBssSpecInfo->u4SaQueryCount);
2316         return;
2317     }
2318
2319     prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter,
2320                       MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);
2321
2322     if (!prMsduInfo)
2323         return;
2324
2325     prTxFrame = (P_ACTION_SA_QUERY_FRAME)
2326         ((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
2327
2328     prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
2329     prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
2330
2331     COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID);
2332     COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
2333     COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
2334
2335     prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION;
2336     prTxFrame->ucAction = ACTION_SA_QUERY_REQUEST;
2337
2338     if (prBssSpecInfo->u4SaQueryCount == 0) {
2339         GET_CURRENT_SYSTIME(&prBssSpecInfo->u4SaQueryStart);
2340     }
2341
2342     if (prBssSpecInfo->u4SaQueryCount) {
2343         pucTmp = kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE);
2344         if (!pucTmp) {
2345             DBGLOG(RSN, INFO, ("MFP: Fail to alloc tmp buffer for backup sa query id\n"));
2346             return;
2347         }
2348         kalMemCopy(pucTmp, prBssSpecInfo->pucSaQueryTransId, prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
2349     }
2350
2351     kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
2352
2353     ucTransId[0] = (UINT_8)(kalRandomNumber() & 0xFF);
2354     ucTransId[1] = (UINT_8)(kalRandomNumber() & 0xFF);
2355
2356     kalMemCopy(prTxFrame->ucTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
2357
2358     prBssSpecInfo->u4SaQueryCount++;
2359
2360     prBssSpecInfo->pucSaQueryTransId = kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE);
2361     if (!prBssSpecInfo->pucSaQueryTransId) {
2362         DBGLOG(RSN, INFO, ("MFP: Fail to alloc buffer for sa query id list\n"));
2363         return;
2364     }
2365
2366     if (pucTmp) {
2367         kalMemCopy(prBssSpecInfo->pucSaQueryTransId, pucTmp, (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN);
2368         kalMemCopy(&prBssSpecInfo->pucSaQueryTransId[(prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN],
2369             ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
2370         kalMemFree(pucTmp, VIR_MEM_TYPE, (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN);
2371     }
2372     else {
2373         kalMemCopy(prBssSpecInfo->pucSaQueryTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
2374     }
2375
2376     u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN;
2377
2378     //4 Update information of MSDU_INFO_T
2379     prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;   /* Management frame */
2380     prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
2381     prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex;
2382     prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
2383     prMsduInfo->fgIs802_1x = FALSE;
2384     prMsduInfo->fgIs802_11 = TRUE;
2385     prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
2386     prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
2387     prMsduInfo->pfTxDoneHandler = NULL;
2388     prMsduInfo->fgIsBasicRate = FALSE;
2389
2390     //4 Enqueue the frame to send this action frame.
2391     nicTxEnqueueMsdu(prAdapter, prMsduInfo);
2392
2393     DBGLOG(RSN, TRACE, ("Set SA Query timer %d (%d sec)\n", prBssSpecInfo->u4SaQueryCount, prBssInfo->u2ObssScanInterval));
2394
2395     cnmTimerStartTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer,
2396         TU_TO_MSEC(201));
2397
2398 }
2399
2400
2401 /*----------------------------------------------------------------------------*/
2402 /*!
2403 *
2404 * \brief This routine is called to start the 802.11w sa query.
2405 *
2406 *
2407 * \note
2408 *      Called by: AIS module, Handle Rx mgmt request
2409 */
2410 /*----------------------------------------------------------------------------*/
2411 void rsnStartSaQuery (
2412     IN P_ADAPTER_T                  prAdapter
2413     )
2414 {
2415     rsnStartSaQueryTimer(prAdapter);
2416 }
2417
2418
2419 /*----------------------------------------------------------------------------*/
2420 /*!
2421 *
2422 * \brief This routine is called to stop the 802.11w sa query.
2423 *
2424 *
2425 * \note
2426 *      Called by: AIS module, Handle Rx mgmt request
2427 */
2428 /*----------------------------------------------------------------------------*/
2429 void rsnStopSaQuery (
2430     IN P_ADAPTER_T                  prAdapter
2431     )
2432 {
2433     P_AIS_SPECIFIC_BSS_INFO_T       prBssSpecInfo;
2434
2435     prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2436     ASSERT(prBssSpecInfo);
2437
2438     cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer);
2439     kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
2440     prBssSpecInfo->pucSaQueryTransId = NULL;
2441     prBssSpecInfo->u4SaQueryCount = 0;
2442 }
2443
2444 /*----------------------------------------------------------------------------*/
2445 /*!
2446 *
2447 * \brief This routine is called to process the 802.11w sa query action frame.
2448 *
2449 *
2450 * \note
2451 *      Called by: AIS module, Handle Rx mgmt request
2452 */
2453 /*----------------------------------------------------------------------------*/
2454 void
2455 rsnSaQueryRequest (
2456     IN P_ADAPTER_T                  prAdapter,
2457     IN P_SW_RFB_T                   prSwRfb
2458     )
2459 {
2460     P_BSS_INFO_T                    prBssInfo;
2461     P_MSDU_INFO_T                   prMsduInfo;
2462     P_ACTION_SA_QUERY_FRAME         prRxFrame = NULL;
2463     UINT_16                         u2PayloadLen;
2464     P_STA_RECORD_T                  prStaRec;
2465     P_ACTION_SA_QUERY_FRAME         prTxFrame;
2466
2467     prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
2468     ASSERT(prBssInfo);
2469
2470     prRxFrame = (P_ACTION_SA_QUERY_FRAME)prSwRfb->pvHeader;
2471     if (!prRxFrame)
2472         return;
2473
2474     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
2475
2476     DBGLOG(RSN, TRACE, ("IEEE 802.11: Received SA Query Request from "
2477            MACSTR"\n", MAC2STR(prStaRec->aucMacAddr)));
2478
2479     DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId,
2480             ACTION_SA_QUERY_TR_ID_LEN);
2481
2482     if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_DISCONNECTED) {
2483         DBGLOG(RSN, TRACE, ("IEEE 802.11: Ignore SA Query Request "
2484                "from unassociated STA " MACSTR"\n", MAC2STR(prStaRec->aucMacAddr)));
2485         return;
2486     }
2487     DBGLOG(RSN, TRACE, ("IEEE 802.11: Sending SA Query Response to "
2488            MACSTR"\n", MAC2STR(prStaRec->aucMacAddr)));
2489
2490     prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter,
2491                       MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);
2492
2493     if (!prMsduInfo)
2494         return;
2495
2496     prTxFrame = (P_ACTION_SA_QUERY_FRAME)
2497         ((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
2498
2499     prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
2500     /* SA Query always with protected */
2501     prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
2502
2503     COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID);
2504     COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
2505     COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
2506
2507     prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION;
2508     prTxFrame->ucAction = ACTION_SA_QUERY_RESPONSE;
2509
2510     kalMemCopy(prTxFrame->ucTransId,
2511           prRxFrame->ucTransId,
2512           ACTION_SA_QUERY_TR_ID_LEN);
2513
2514     u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN;
2515
2516     //4 Update information of MSDU_INFO_T
2517     prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;   /* Management frame */
2518     prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
2519     prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex;
2520     prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
2521     prMsduInfo->fgIs802_1x = FALSE;
2522     prMsduInfo->fgIs802_11 = TRUE;
2523     prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
2524     prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
2525     prMsduInfo->pfTxDoneHandler = NULL;
2526     prMsduInfo->fgIsBasicRate = FALSE;
2527
2528     //4 Enqueue the frame to send this action frame.
2529     nicTxEnqueueMsdu(prAdapter, prMsduInfo);
2530
2531 }
2532
2533
2534 /*----------------------------------------------------------------------------*/
2535 /*!
2536 *
2537 * \brief This routine is called to process the 802.11w sa query action frame.
2538 *
2539 *
2540 * \note
2541 *      Called by: AIS module, Handle Rx mgmt request
2542 */
2543 /*----------------------------------------------------------------------------*/
2544 void
2545 rsnSaQueryAction (
2546     IN P_ADAPTER_T                  prAdapter,
2547     IN P_SW_RFB_T                   prSwRfb
2548     )
2549 {
2550     P_AIS_SPECIFIC_BSS_INFO_T       prBssSpecInfo;
2551     P_ACTION_SA_QUERY_FRAME         prRxFrame;
2552     P_STA_RECORD_T                  prStaRec;
2553     UINT_32                         i;
2554
2555     prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2556     ASSERT(prBssSpecInfo);
2557
2558     prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader;
2559     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
2560
2561     if (prSwRfb->u2PacketLen < ACTION_SA_QUERY_TR_ID_LEN) {
2562         DBGLOG(RSN, TRACE, ("IEEE 802.11: Too short SA Query Action "
2563                "frame (len=%lu)\n", (unsigned long) prSwRfb->u2PacketLen));
2564         return;
2565     }
2566
2567     if (prRxFrame->ucAction == ACTION_SA_QUERY_REQUEST) {
2568         rsnSaQueryRequest(prAdapter, prSwRfb);
2569         return;
2570     }
2571
2572     if (prRxFrame->ucAction != ACTION_SA_QUERY_RESPONSE) {
2573         DBGLOG(RSN, TRACE, ("IEEE 802.11: Unexpected SA Query "
2574                "Action %d\n", prRxFrame->ucAction));
2575         return;
2576     }
2577
2578     DBGLOG(RSN, TRACE, ("IEEE 802.11: Received SA Query Response from "
2579            MACSTR"\n", MAC2STR(prStaRec->aucMacAddr)));
2580
2581     DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId,
2582            ACTION_SA_QUERY_TR_ID_LEN);
2583
2584     /* MLME-SAQuery.confirm */
2585
2586     for (i = 0; i < prBssSpecInfo->u4SaQueryCount; i++) {
2587         if (kalMemCmp(prBssSpecInfo->pucSaQueryTransId +
2588                   i * ACTION_SA_QUERY_TR_ID_LEN,
2589                   prRxFrame->ucTransId,
2590                   ACTION_SA_QUERY_TR_ID_LEN) == 0)
2591             break;
2592     }
2593
2594     if (i >= prBssSpecInfo->u4SaQueryCount) {
2595         DBGLOG(RSN, TRACE, ("IEEE 802.11: No matching SA Query "
2596                "transaction identifier found\n"));
2597         return;
2598     }
2599
2600     DBGLOG(RSN, TRACE, ("Reply to pending SA Query received\n"));
2601
2602     rsnStopSaQuery(prAdapter);
2603 }
2604
2605
2606 /*----------------------------------------------------------------------------*/
2607 /*!
2608 *
2609 * \brief This routine is called to process the 802.11w mgmt frame.
2610 *
2611 *
2612 * \note
2613 *      Called by: AIS module, Handle Rx mgmt request
2614 */
2615 /*----------------------------------------------------------------------------*/
2616 BOOLEAN
2617 rsnCheckRxMgmt (
2618     IN P_ADAPTER_T                  prAdapter,
2619     IN P_SW_RFB_T                   prSwRfb,
2620     IN UINT_8                       ucSubtype
2621     )
2622 {
2623     P_HIF_RX_HEADER_T               prHifRxHdr;
2624     BOOLEAN                         fgUnicast = TRUE;
2625     BOOLEAN                         fgRobustAction = FALSE;
2626
2627     prHifRxHdr = prSwRfb->prHifRxHdr;
2628
2629     if ((HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) &&
2630         prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection  /* Use MFP */) {
2631
2632         P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame;
2633         prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader;
2634
2635         if (prAssocReqFrame->aucDestAddr[0] & BIT(0))
2636             fgUnicast = FALSE;
2637
2638         LOG_FUNC("QM RX MGT: rsnCheckRxMgmt = %d 0x%x %d ucSubtype=%x\n", fgUnicast, prHifRxHdr->ucReserved, (prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC), ucSubtype);
2639
2640         if (prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC) {
2641             /* "Dropped unprotected Robust Action frame from an MFP STA" */
2642             /* exclude Public Action */
2643             if (ucSubtype == 13 /* 0x1011: MAC_FRAME_ACTION */)
2644             {
2645                 UINT_8 ucAction = *prSwRfb->pucRecvBuff;
2646                 if (ucAction != CATEGORY_PUBLIC_ACTION && ucAction != CATEGORY_HT_ACTION) {
2647 #if DBG && CFG_RX_PKTS_DUMP
2648                     LOG_FUNC("QM RX MGT: UnProtected Robust Action frame = %d\n", ucAction);
2649 #endif
2650                     fgRobustAction = TRUE;
2651                     return TRUE;
2652                 }
2653             }
2654             if (fgUnicast && ((ucSubtype == 10 /* 0x1010: MAC_FRAME_DISASSOC */) || (ucSubtype == 12 /* 0x1100: MAC_FRAME_DEAUTH */))) {
2655                 LOG_FUNC("QM RX MGT: rsnStartSaQuery\n");
2656                 /* MFP test plan 5.3.3.5 */
2657                 rsnStartSaQuery(prAdapter);
2658                 return TRUE;
2659             }
2660         }
2661 #if 0
2662         else {
2663             if (fgUnicast && ((ucSubtype == MAC_FRAME_DISASSOC) || (ucSubtype == MAC_FRAME_DEAUTH))) {
2664                 /* This done by function handler */
2665                 //kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
2666                 //      WLAN_STATUS_MEDIA_DISCONNECT,
2667                 //      NULL,
2668                 //      0);
2669             }
2670         }
2671 #endif
2672     }
2673     return FALSE;
2674 }
2675 #endif
2676