add MTK-combo-module,continue with commit 17f39ed917874e77e80411f33faba1b7ee8138c8
[firefly-linux-kernel-4.4.55.git] / drivers / mtk_wcn_combo / drv_wlan / wlan / mgmt / auth.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/auth.c#1 $
3 */
4
5 /*! \file   "auth.c"
6     \brief  This file includes the authentication-related functions.
7
8     This file includes the authentication-related functions.
9 */
10
11 /*******************************************************************************
12 * Copyright (c) 2007 MediaTek Inc.
13 *
14 * All rights reserved. Copying, compilation, modification, distribution
15 * or any other use whatsoever of this material is strictly prohibited
16 * except in accordance with a Software License Agreement with
17 * MediaTek Inc.
18 ********************************************************************************
19 */
20
21 /*******************************************************************************
22 * LEGAL DISCLAIMER
23 *
24 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
25 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
26 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
27 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
28 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
29 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
30 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
31 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
32 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
33 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
34 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
35 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
36 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
37 *
38 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
39 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
40 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
41 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
42 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
43 *
44 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
45 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
46 * OF LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
47 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
48 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
49 * (ICC).
50 ********************************************************************************
51 */
52
53 /*
54 ** $Log: auth.c $
55  *
56  * 11 09 2011 yuche.tsai
57  * NULL
58  * Fix Network Index & Station Record Index when TX deauth issue.
59  *
60  * 10 19 2011 yuche.tsai
61  * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch.
62  * Branch 2.1
63  * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926.
64  *
65  * 06 22 2011 yuche.tsai
66  * NULL
67  * Fix coding error.
68  *
69  * 06 20 2011 yuche.tsai
70  * [WCXRP00000796] [Volunteer Patch][MT6620][Driver] Add BC deauth frame TX feature.
71  * Add feature to send BC deauth frame when under AP/GO mode.
72  *
73  * 04 21 2011 terry.wu
74  * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame
75  * Add network type parameter to authSendAuthFrame.
76  *
77  * 04 15 2011 chinghwa.yu
78  * [WCXRP00000065] Update BoW design and settings
79  * Add BOW short range mode.
80  *
81  * 03 18 2011 cp.wu
82  * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver
83  * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk
84  *
85  * 02 08 2011 yuche.tsai
86  * [WCXRP00000245] 1. Invitation Request/Response.
87
88 2. Provision Discovery Request/Response
89
90  * 1. Fix Service Disocvery Logical issue.
91  * 2. Fix a NULL pointer access violation issue when sending deauthentication packet to a class error station.
92  *
93  * 01 24 2011 cp.wu
94  * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
95  * 1. add an extra counter for tracking pending forward frames.
96  * 2. notify TX service thread as well when there is pending forward frame
97  * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
98  *
99  * 01 21 2011 terry.wu
100  * [WCXRP00000381] [MT6620 Wi-Fi][Driver] Kernel panic when replying unaccept Auth in AP mode
101  * In AP mode, use STA_REC_INDEX_NOT_FOUND(0xFE) instead of StaRec index when replying an unaccept Auth frame.
102  *
103  * 10 18 2010 cp.wu
104  * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
105  * use definition macro to replace hard-coded constant
106  *
107  * 09 03 2010 kevin.huang
108  * NULL
109  * Refine #include sequence and solve recursive/nested #include issue
110  *
111  * 08 30 2010 cp.wu
112  * NULL
113  * eliminate klockwork errors
114  *
115  * 08 16 2010 cp.wu
116  * NULL
117  * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI.
118  * There is no CFG_SUPPORT_BOW in driver domain source.
119  *
120  * 08 16 2010 kevin.huang
121  * NULL
122  * Refine AAA functions
123  *
124  * 08 03 2010 cp.wu
125  * NULL
126  * surpress compilation warning.
127  *
128  * 07 08 2010 cp.wu
129  *
130  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
131  *
132  * 06 28 2010 cp.wu
133  * [WPD00003833][MT6620 and MT5931] Driver migration
134  * send MMPDU in basic rate.
135  *
136  * 06 21 2010 cp.wu
137  * [WPD00003833][MT6620 and MT5931] Driver migration
138  * specify correct value for management frames.
139  *
140  * 06 18 2010 cm.chang
141  * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
142  * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
143  *
144  * 06 14 2010 cp.wu
145  * [WPD00003833][MT6620 and MT5931] Driver migration
146  * add management dispatching function table.
147  *
148  * 06 11 2010 cp.wu
149  * [WPD00003833][MT6620 and MT5931] Driver migration
150  * auth.c is migrated.
151  *
152  * 05 28 2010 kevin.huang
153  * [BORA00000794][WIFISYS][New Feature]Power Management Support
154  * Update authSendDeauthFrame() for correct the value of eNetTypeIndex in MSDU_INFO_T
155  *
156  * 05 24 2010 kevin.huang
157  * [BORA00000794][WIFISYS][New Feature]Power Management Support
158  * Check Net is active before sending Deauth frame.
159  *
160  * 05 24 2010 kevin.huang
161  * [BORA00000794][WIFISYS][New Feature]Power Management Support
162  * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval.
163  *
164  * 04 24 2010 cm.chang
165  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
166  * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
167  *
168  * 04 19 2010 kevin.huang
169  * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
170  * Add Send Deauth for Class 3 Error and Leave Network Support
171  *
172  * 02 23 2010 kevin.huang
173  * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
174  * Fix compile warning
175  *
176  * 02 05 2010 kevin.huang
177  * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
178  * Add debug message for abnormal authentication frame from AP
179  *
180  * 02 04 2010 kevin.huang
181  * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
182  * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
183  *
184  * 01 11 2010 kevin.huang
185  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
186  * Add Deauth and Disassoc Handler
187  *
188  * 01 07 2010 kevin.huang
189  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
190  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
191  *
192  * Fix the Debug Label
193  *
194  * 12 18 2009 cm.chang
195  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
196  * .
197  *
198  * Dec 7 2009 mtk01461
199  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
200  * Update the authComposeAuthFrameHeader()
201  *
202  * Dec 7 2009 mtk01088
203  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
204  * adding the send deauth frame function
205  *
206  * Dec 3 2009 mtk01461
207  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
208  * Integrate send Auth with TXM
209  *
210  * Nov 24 2009 mtk01461
211  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
212  * Revise MGMT Handler with Retain Status
213  *
214  * Nov 23 2009 mtk01461
215  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
216  *
217 */
218
219 /*******************************************************************************
220 *                         C O M P I L E R   F L A G S
221 ********************************************************************************
222 */
223
224 /*******************************************************************************
225 *                    E X T E R N A L   R E F E R E N C E S
226 ********************************************************************************
227 */
228 #include "precomp.h"
229
230 /*******************************************************************************
231 *                              C O N S T A N T S
232 ********************************************************************************
233 */
234
235 /*******************************************************************************
236 *                             D A T A   T Y P E S
237 ********************************************************************************
238 */
239
240 /*******************************************************************************
241 *                            P U B L I C   D A T A
242 ********************************************************************************
243 */
244 APPEND_IE_ENTRY_T txAuthIETable[] = {
245     { (ELEM_HDR_LEN + ELEM_MAX_LEN_CHALLENGE_TEXT), authAddIEChallengeText }
246 };
247
248 HANDLE_IE_ENTRY_T rxAuthIETable[] = {
249     { ELEM_ID_CHALLENGE_TEXT,                       authHandleIEChallengeText }
250 };
251
252 /*******************************************************************************
253 *                           P R I V A T E   D A T A
254 ********************************************************************************
255 */
256
257 /*******************************************************************************
258 *                                 M A C R O S
259 ********************************************************************************
260 */
261
262 /*******************************************************************************
263 *                   F U N C T I O N   D E C L A R A T I O N S
264 ********************************************************************************
265 */
266
267 /*******************************************************************************
268 *                              F U N C T I O N S
269 ********************************************************************************
270 */
271 /*----------------------------------------------------------------------------*/
272 /*!
273 * @brief This function will compose the Authentication frame header and fixed fields.
274 *
275 * @param[in] pucBuffer              Pointer to the frame buffer.
276 * @param[in] aucPeerMACAddress      Given Peer MAC Address.
277 * @param[in] aucMACAddress          Given Our MAC Address.
278 * @param[in] u2AuthAlgNum           Authentication Algorithm Number
279 * @param[in] u2TransactionSeqNum    Transaction Sequence Number
280 * @param[in] u2StatusCode           Status Code
281 *
282 * \return (none)
283 */
284 /*----------------------------------------------------------------------------*/
285 __KAL_INLINE__ VOID
286 authComposeAuthFrameHeaderAndFF (
287     IN PUINT_8 pucBuffer,
288     IN UINT_8 aucPeerMACAddress[],
289     IN UINT_8 aucMACAddress[],
290     IN UINT_16 u2AuthAlgNum,
291     IN UINT_16 u2TransactionSeqNum,
292     IN UINT_16 u2StatusCode
293     )
294 {
295     P_WLAN_AUTH_FRAME_T prAuthFrame;
296     UINT_16 u2FrameCtrl;
297
298
299     ASSERT(pucBuffer);
300     ASSERT(aucPeerMACAddress);
301     ASSERT(aucMACAddress);
302
303     prAuthFrame = (P_WLAN_AUTH_FRAME_T)pucBuffer;
304
305     //4 <1> Compose the frame header of the Authentication frame.
306     /* Fill the Frame Control field. */
307     u2FrameCtrl = MAC_FRAME_AUTH;
308
309     /* If this frame is the third frame in the shared key authentication
310      * sequence, it shall be encrypted.
311      */
312     if ((u2AuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) &&
313         (u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3)) {
314
315         u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; /* HW will also detect this bit for applying encryption */
316     }
317
318     //WLAN_SET_FIELD_16(&prAuthFrame->u2FrameCtrl, u2FrameCtrl);
319     prAuthFrame->u2FrameCtrl = u2FrameCtrl; // NOTE(Kevin): Optimized for ARM
320
321     /* Fill the DA field with Target BSSID. */
322     COPY_MAC_ADDR(prAuthFrame->aucDestAddr, aucPeerMACAddress);
323
324     /* Fill the SA field with our MAC Address. */
325     COPY_MAC_ADDR(prAuthFrame->aucSrcAddr, aucMACAddress);
326
327     switch (u2TransactionSeqNum) {
328     case AUTH_TRANSACTION_SEQ_1:
329     case AUTH_TRANSACTION_SEQ_3:
330
331         /* Fill the BSSID field with Target BSSID. */
332         COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucPeerMACAddress);
333         break;
334
335     case AUTH_TRANSACTION_SEQ_2:
336     case AUTH_TRANSACTION_SEQ_4:
337
338         /* Fill the BSSID field with Current BSSID. */
339         COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucMACAddress);
340         break;
341
342     default:
343         ASSERT(0);
344     }
345
346     /* Clear the SEQ/FRAG_NO field. */
347     prAuthFrame->u2SeqCtrl = 0;
348
349
350     //4 <2> Compose the frame body's fixed field part of the Authentication frame.
351     /* Fill the Authentication Algorithm Number field. */
352     //WLAN_SET_FIELD_16(&prAuthFrame->u2AuthAlgNum, u2AuthAlgNum);
353     prAuthFrame->u2AuthAlgNum = u2AuthAlgNum; // NOTE(Kevin): Optimized for ARM
354
355     /* Fill the Authentication Transaction Sequence Number field. */
356     //WLAN_SET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, u2TransactionSeqNum);
357     prAuthFrame->u2AuthTransSeqNo = u2TransactionSeqNum; // NOTE(Kevin): Optimized for ARM
358
359     /* Fill the Status Code field. */
360     //WLAN_SET_FIELD_16(&prAuthFrame->u2StatusCode, u2StatusCode);
361     prAuthFrame->u2StatusCode = u2StatusCode; // NOTE(Kevin): Optimized for ARM
362
363     return;
364 } /* end of authComposeAuthFrameHeaderAndFF() */
365
366
367 /*----------------------------------------------------------------------------*/
368 /*!
369 * @brief This function will append Challenge Text IE to the Authentication frame
370 *
371 * @param[in] prMsduInfo     Pointer to the composed MSDU_INFO_T.
372 *
373 * @return (none)
374 */
375 /*----------------------------------------------------------------------------*/
376 VOID
377 authAddIEChallengeText (
378     IN P_ADAPTER_T prAdapter,
379     IN OUT P_MSDU_INFO_T prMsduInfo
380     )
381 {
382     P_WLAN_AUTH_FRAME_T prAuthFrame;
383     P_STA_RECORD_T prStaRec;
384     UINT_16 u2TransactionSeqNum;
385
386
387     ASSERT(prMsduInfo);
388
389     prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
390
391     if(!prStaRec) {
392         return;
393     }
394
395     ASSERT(prStaRec);
396
397     /* For Management, frame header and payload are in a continuous buffer */
398     prAuthFrame = (P_WLAN_AUTH_FRAME_T)prMsduInfo->prPacket;
399
400     WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum)
401
402     /* Only consider SEQ_3 for Challenge Text */
403     if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3) &&
404         (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) &&
405         (prStaRec->prChallengeText != NULL)) {
406
407         COPY_IE(((UINT_32)(prMsduInfo->prPacket) + prMsduInfo->u2FrameLength),
408                 (prStaRec->prChallengeText));
409
410         prMsduInfo->u2FrameLength += IE_SIZE(prStaRec->prChallengeText);
411     }
412
413     return;
414
415 } /* end of authAddIEChallengeText() */
416
417
418 #if !CFG_SUPPORT_AAA
419 /*----------------------------------------------------------------------------*/
420 /*!
421 * @brief This function will send the Authenticiation frame
422 *
423 * @param[in] prStaRec               Pointer to the STA_RECORD_T
424 * @param[in] u2TransactionSeqNum    Transaction Sequence Number
425 *
426 * @retval WLAN_STATUS_RESOURCES No available resource for frame composing.
427 * @retval WLAN_STATUS_SUCCESS   Successfully send frame to TX Module
428 */
429 /*----------------------------------------------------------------------------*/
430 WLAN_STATUS
431 authSendAuthFrame (
432     IN P_ADAPTER_T prAdapter,
433     IN P_STA_RECORD_T prStaRec,
434     IN UINT_16 u2TransactionSeqNum
435     )
436 {
437     P_MSDU_INFO_T prMsduInfo;
438     P_BSS_INFO_T prBssInfo;
439     UINT_16 u2EstimatedFrameLen;
440     UINT_16 u2EstimatedExtraIELen;
441     UINT_16 u2PayloadLen;
442     UINT_32 i;
443
444
445     DBGLOG(SAA, LOUD, ("Send Auth Frame\n"));
446
447     ASSERT(prStaRec);
448
449     //4 <1> Allocate a PKT_INFO_T for Authentication Frame
450     /* Init with MGMT Header Length + Length of Fixed Fields */
451     u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD +
452                            WLAN_MAC_MGMT_HEADER_LEN +
453                            AUTH_ALGORITHM_NUM_FIELD_LEN +
454                            AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN +
455                            STATUS_CODE_FIELD_LEN);
456
457     /* + Extra IE Length */
458     u2EstimatedExtraIELen = 0;
459
460     for (i = 0; i < sizeof(txAuthIETable)/sizeof(APPEND_IE_ENTRY_T); i++) {
461         u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen;
462     }
463
464     u2EstimatedFrameLen += u2EstimatedExtraIELen;
465
466     /* Allocate a MSDU_INFO_T */
467     if ( (prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == NULL) {
468         DBGLOG(SAA, WARN, ("No PKT_INFO_T for sending Auth Frame.\n"));
469         return WLAN_STATUS_RESOURCES;
470     }
471
472     //4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T.
473     ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
474     prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
475
476     /* Compose Header and some Fixed Fields */
477     authComposeAuthFrameHeaderAndFF(
478             (PUINT_8)((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
479             prStaRec->aucMacAddr,
480             prBssInfo->aucOwnMacAddr,
481             prStaRec->ucAuthAlgNum,
482             u2TransactionSeqNum,
483             STATUS_CODE_RESERVED);
484
485     u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN +
486                     AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN +
487                     STATUS_CODE_FIELD_LEN);
488
489     //4 <3> Update information of MSDU_INFO_T
490     prMsduInfo->eSrc = TX_PACKET_MGMT;
491     prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
492     prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
493     prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex;
494     prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
495     prMsduInfo->fgIs802_1x = FALSE;
496     prMsduInfo->fgIs802_11 = TRUE;
497     prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
498     prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
499     prMsduInfo->pfTxDoneHandler = saaFsmRunEventTxDone;
500     prMsduInfo->fgIsBasicRate = TRUE;
501
502     //4 <4> Compose IEs in MSDU_INFO_T
503     for (i = 0; i < sizeof(txAuthIETable)/sizeof(APPEND_IE_ENTRY_T); i++) {
504         if (txAuthIETable[i].pfnAppendIE) {
505             txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo);
506         }
507     }
508
509     /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */
510
511     //4 <6> Inform TXM  to send this Authentication frame.
512     nicTxEnqueueMsdu(prAdapter, prMsduInfo);
513
514     return WLAN_STATUS_SUCCESS;
515 } /* end of authSendAuthFrame() */
516
517 #else
518
519 /*----------------------------------------------------------------------------*/
520 /*!
521 * @brief This function will send the Authenticiation frame
522 *
523 * @param[in] prStaRec               Pointer to the STA_RECORD_T
524 * @param[in] u2TransactionSeqNum    Transaction Sequence Number
525 *
526 * @retval WLAN_STATUS_RESOURCES No available resource for frame composing.
527 * @retval WLAN_STATUS_SUCCESS   Successfully send frame to TX Module
528 */
529 /*----------------------------------------------------------------------------*/
530 WLAN_STATUS
531 authSendAuthFrame (
532     IN P_ADAPTER_T prAdapter,
533     IN P_STA_RECORD_T prStaRec,
534     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
535     IN P_SW_RFB_T prFalseAuthSwRfb,
536     IN UINT_16 u2TransactionSeqNum,
537     IN UINT_16 u2StatusCode
538     )
539 {
540     PUINT_8 pucReceiveAddr;
541     PUINT_8 pucTransmitAddr;
542     P_MSDU_INFO_T prMsduInfo;
543     P_BSS_INFO_T prBssInfo;
544     /*get from input parameter*/
545     //ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX;
546     PFN_TX_DONE_HANDLER pfTxDoneHandler = (PFN_TX_DONE_HANDLER)NULL;
547     UINT_16 u2EstimatedFrameLen;
548     UINT_16 u2EstimatedExtraIELen;
549     UINT_16 u2PayloadLen;
550     UINT_16 ucAuthAlgNum;
551     UINT_32 i;
552
553
554     DBGLOG(SAA, LOUD, ("Send Auth Frame %d, Status Code = %d\n",
555         u2TransactionSeqNum, u2StatusCode));
556
557     //4 <1> Allocate a PKT_INFO_T for Authentication Frame
558     /* Init with MGMT Header Length + Length of Fixed Fields */
559     u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD +
560                            WLAN_MAC_MGMT_HEADER_LEN +
561                            AUTH_ALGORITHM_NUM_FIELD_LEN +
562                            AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN +
563                            STATUS_CODE_FIELD_LEN);
564
565     /* + Extra IE Length */
566     u2EstimatedExtraIELen = 0;
567
568     for (i = 0; i < sizeof(txAuthIETable)/sizeof(APPEND_IE_ENTRY_T); i++) {
569         u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen;
570     }
571
572     u2EstimatedFrameLen += u2EstimatedExtraIELen;
573
574     /* Allocate a MSDU_INFO_T */
575     if ( (prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == NULL) {
576         DBGLOG(SAA, WARN, ("No PKT_INFO_T for sending Auth Frame.\n"));
577         return WLAN_STATUS_RESOURCES;
578     }
579
580     //4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T.
581     if (prStaRec) {
582         ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
583
584         prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
585
586         pucTransmitAddr = prBssInfo->aucOwnMacAddr;
587
588         pucReceiveAddr = prStaRec->aucMacAddr;
589
590         ucAuthAlgNum = prStaRec->ucAuthAlgNum;
591
592         switch (u2TransactionSeqNum) {
593         case AUTH_TRANSACTION_SEQ_1:
594         case AUTH_TRANSACTION_SEQ_3:
595             pfTxDoneHandler = saaFsmRunEventTxDone;
596             break;
597
598         case AUTH_TRANSACTION_SEQ_2:
599         case AUTH_TRANSACTION_SEQ_4:
600             pfTxDoneHandler = aaaFsmRunEventTxDone;
601             break;
602         }
603
604     }
605     else { /* For Error Status Code */
606         P_WLAN_AUTH_FRAME_T prFalseAuthFrame;
607
608
609         ASSERT(prFalseAuthSwRfb);
610         prFalseAuthFrame = (P_WLAN_AUTH_FRAME_T)prFalseAuthSwRfb->pvHeader;
611
612         ASSERT(u2StatusCode != STATUS_CODE_SUCCESSFUL);
613
614         pucTransmitAddr = prFalseAuthFrame->aucDestAddr;
615
616         pucReceiveAddr = prFalseAuthFrame->aucSrcAddr;
617
618         ucAuthAlgNum = prFalseAuthFrame->u2AuthAlgNum;
619
620         u2TransactionSeqNum = (prFalseAuthFrame->u2AuthTransSeqNo + 1);
621     }
622
623     /* Compose Header and some Fixed Fields */
624     authComposeAuthFrameHeaderAndFF((PUINT_8)((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
625                                     pucReceiveAddr,
626                                     pucTransmitAddr,
627                                     ucAuthAlgNum,
628                                     u2TransactionSeqNum,
629                                     u2StatusCode);
630
631     u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN +
632                     AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN +
633                     STATUS_CODE_FIELD_LEN);
634
635     //4 <3> Update information of MSDU_INFO_T
636     prMsduInfo->eSrc = TX_PACKET_MGMT;
637     prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
638     if(prStaRec) {
639         prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
640     }
641     else {
642         prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND;  //false Auth frame
643     }
644     prMsduInfo->ucNetworkType = (UINT_8)eNetTypeIndex;
645     prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
646     prMsduInfo->fgIs802_1x = FALSE;
647     prMsduInfo->fgIs802_11 = TRUE;
648     prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
649     prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
650     prMsduInfo->pfTxDoneHandler = pfTxDoneHandler;
651     prMsduInfo->fgIsBasicRate = TRUE;
652
653     //4 <4> Compose IEs in MSDU_INFO_T
654     for (i = 0; i < sizeof(txAuthIETable)/sizeof(APPEND_IE_ENTRY_T); i++) {
655         if (txAuthIETable[i].pfnAppendIE) {
656             txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo);
657         }
658     }
659
660     /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */
661
662     //4 <6> Inform TXM  to send this Authentication frame.
663     nicTxEnqueueMsdu(prAdapter, prMsduInfo);
664
665     return WLAN_STATUS_SUCCESS;
666 } /* end of authSendAuthFrame() */
667
668 #endif /* CFG_SUPPORT_AAA */
669
670
671 /*----------------------------------------------------------------------------*/
672 /*!
673 * @brief This function will strictly check the TX Authentication frame for SAA/AAA event
674 *        handling.
675 *
676 * @param[in] prMsduInfo             Pointer of MSDU_INFO_T
677 * @param[in] u2TransactionSeqNum    Transaction Sequence Number
678 *
679 * @retval WLAN_STATUS_FAILURE   This is not the frame we should handle at current state.
680 * @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
681 */
682 /*----------------------------------------------------------------------------*/
683 WLAN_STATUS
684 authCheckTxAuthFrame (
685     IN P_ADAPTER_T prAdapter,
686     IN P_MSDU_INFO_T prMsduInfo,
687     IN UINT_16 u2TransactionSeqNum
688     )
689 {
690     P_WLAN_AUTH_FRAME_T prAuthFrame;
691     P_STA_RECORD_T prStaRec;
692     UINT_16 u2TxFrameCtrl;
693     UINT_16 u2TxAuthAlgNum;
694     UINT_16 u2TxTransactionSeqNum;
695
696
697     ASSERT(prMsduInfo);
698
699     prAuthFrame = (P_WLAN_AUTH_FRAME_T)(prMsduInfo->prPacket);
700     ASSERT(prAuthFrame);
701
702     prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
703     ASSERT(prStaRec);
704
705     if(!prStaRec) {
706         return WLAN_STATUS_INVALID_PACKET;
707     }
708
709     //WLAN_GET_FIELD_16(&prAuthFrame->u2FrameCtrl, &u2TxFrameCtrl)
710     u2TxFrameCtrl = prAuthFrame->u2FrameCtrl; // NOTE(Kevin): Optimized for ARM
711     u2TxFrameCtrl &= MASK_FRAME_TYPE;
712     if (u2TxFrameCtrl != MAC_FRAME_AUTH) {
713         return WLAN_STATUS_FAILURE;
714     }
715
716     //WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2TxAuthAlgNum)
717     u2TxAuthAlgNum = prAuthFrame->u2AuthAlgNum; // NOTE(Kevin): Optimized for ARM
718     if (u2TxAuthAlgNum != (UINT_16)(prStaRec->ucAuthAlgNum)) {
719         return WLAN_STATUS_FAILURE;
720     }
721
722     //WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TxTransactionSeqNum)
723     u2TxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; // NOTE(Kevin): Optimized for ARM
724     if (u2TxTransactionSeqNum != u2TransactionSeqNum) {
725         return WLAN_STATUS_FAILURE;
726     }
727
728     return WLAN_STATUS_SUCCESS;
729
730 } /* end of authCheckTxAuthFrame() */
731
732
733 /*----------------------------------------------------------------------------*/
734 /*!
735 * @brief This function will check the incoming Auth Frame's Transaction Sequence
736 *        Number before delivering it to the corresponding SAA or AAA Module.
737 *
738 * @param[in] prSwRfb            Pointer to the SW_RFB_T structure.
739 *
740 * @retval WLAN_STATUS_SUCCESS   Always not retain authentication frames
741 */
742 /*----------------------------------------------------------------------------*/
743 WLAN_STATUS
744 authCheckRxAuthFrameTransSeq (
745     IN P_ADAPTER_T prAdapter,
746     IN P_SW_RFB_T prSwRfb
747     )
748 {
749     P_WLAN_AUTH_FRAME_T prAuthFrame;
750     UINT_16 u2RxTransactionSeqNum;
751
752
753     ASSERT(prSwRfb);
754
755     //4 <1> locate the Authentication Frame.
756     prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader;
757
758     //4 <2> Parse the Header of Authentication Frame.
759     if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (AUTH_ALGORITHM_NUM_FIELD_LEN +
760                                     AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN +
761                                     STATUS_CODE_FIELD_LEN)) {
762         ASSERT(0);
763         return WLAN_STATUS_SUCCESS;
764     }
765
766     //4 <3> Parse the Fixed Fields of Authentication Frame Body.
767     //WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2RxTransactionSeqNum);
768     u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; // NOTE(Kevin): Optimized for ARM
769
770     switch (u2RxTransactionSeqNum) {
771     case AUTH_TRANSACTION_SEQ_2:
772     case AUTH_TRANSACTION_SEQ_4:
773         saaFsmRunEventRxAuth(prAdapter, prSwRfb);
774         break;
775
776     case AUTH_TRANSACTION_SEQ_1:
777     case AUTH_TRANSACTION_SEQ_3:
778 #if CFG_SUPPORT_AAA
779         aaaFsmRunEventRxAuth(prAdapter, prSwRfb);
780 #endif /* CFG_SUPPORT_AAA */
781         break;
782
783     default:
784         if (prAuthFrame->u2StatusCode != STATUS_CODE_SUCCESSFUL) {
785             DBGLOG(SAA, WARN, ("Strange Authentication Packet: Auth Trans Seq No = %d, Error Status Code = %d\n",
786                 u2RxTransactionSeqNum, prAuthFrame->u2StatusCode));
787         }
788         else {
789             ASSERT(0);
790         }
791         /* TODO(Kevin): Free SW_RFB_T */
792         break;
793     }
794
795     return WLAN_STATUS_SUCCESS;
796
797 } /* end of authCheckRxAuthFrameTransSeq() */
798
799
800 /*----------------------------------------------------------------------------*/
801 /*!
802 * @brief This function will validate the incoming Authentication Frame and take
803 *        the status code out.
804 *
805 * @param[in] prSwRfb                Pointer to SW RFB data structure.
806 * @param[in] u2TransactionSeqNum    Transaction Sequence Number
807 * @param[out] pu2StatusCode         Pointer to store the Status Code from Authentication.
808 *
809 * @retval WLAN_STATUS_FAILURE   This is not the frame we should handle at current state.
810 * @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
811 */
812 /*----------------------------------------------------------------------------*/
813 WLAN_STATUS
814 authCheckRxAuthFrameStatus (
815     IN P_ADAPTER_T prAdapter,
816     IN P_SW_RFB_T prSwRfb,
817     IN UINT_16 u2TransactionSeqNum,
818     OUT PUINT_16 pu2StatusCode
819     )
820 {
821     P_STA_RECORD_T prStaRec;
822     P_WLAN_AUTH_FRAME_T prAuthFrame;
823     UINT_16 u2RxAuthAlgNum;
824     UINT_16 u2RxTransactionSeqNum;
825     //UINT_16 u2RxStatusCode; // NOTE(Kevin): Optimized for ARM
826
827
828     ASSERT(prSwRfb);
829     ASSERT(pu2StatusCode);
830
831     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
832     ASSERT(prStaRec);
833
834     if(!prStaRec) {
835         return WLAN_STATUS_INVALID_PACKET;
836     }
837
838     //4 <1> locate the Authentication Frame.
839     prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader;
840
841     //4 <2> Parse the Fixed Fields of Authentication Frame Body.
842     //WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2RxAuthAlgNum);
843     u2RxAuthAlgNum = prAuthFrame->u2AuthAlgNum; // NOTE(Kevin): Optimized for ARM
844     if (u2RxAuthAlgNum != (UINT_16)prStaRec->ucAuthAlgNum) {
845         DBGLOG(SAA, LOUD, ("Discard Auth frame with auth type = %d, current = %d\n",
846             u2RxAuthAlgNum, prStaRec->ucAuthAlgNum));
847         return WLAN_STATUS_FAILURE;
848     }
849
850     //WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2RxTransactionSeqNum);
851     u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; // NOTE(Kevin): Optimized for ARM
852     if (u2RxTransactionSeqNum != u2TransactionSeqNum) {
853         DBGLOG(SAA, LOUD, ("Discard Auth frame with Transaction Seq No = %d\n",
854             u2RxTransactionSeqNum));
855         return WLAN_STATUS_FAILURE;
856     }
857
858     //4 <3> Get the Status code
859     //WLAN_GET_FIELD_16(&prAuthFrame->u2StatusCode, &u2RxStatusCode);
860     //*pu2StatusCode = u2RxStatusCode;
861     *pu2StatusCode = prAuthFrame->u2StatusCode; // NOTE(Kevin): Optimized for ARM
862
863     return WLAN_STATUS_SUCCESS;
864
865 } /* end of authCheckRxAuthFrameStatus() */
866
867
868 /*----------------------------------------------------------------------------*/
869 /*!
870 * @brief This function will handle the Challenge Text IE from the Authentication frame
871 *
872 * @param[in] prSwRfb                Pointer to SW RFB data structure.
873 * @param[in] prIEHdr                Pointer to start address of IE
874 *
875 * @return (none)
876 */
877 /*----------------------------------------------------------------------------*/
878 VOID
879 authHandleIEChallengeText (
880     P_ADAPTER_T prAdapter,
881     P_SW_RFB_T prSwRfb,
882     P_IE_HDR_T prIEHdr
883     )
884 {
885     P_WLAN_AUTH_FRAME_T prAuthFrame;
886     P_STA_RECORD_T prStaRec;
887     UINT_16 u2TransactionSeqNum;
888
889
890     ASSERT(prSwRfb);
891     ASSERT(prIEHdr);
892
893     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
894     ASSERT(prStaRec);
895
896     if(!prStaRec) {
897         return;
898     }
899
900     /* For Management, frame header and payload are in a continuous buffer */
901     prAuthFrame = (P_WLAN_AUTH_FRAME_T)prSwRfb->pvHeader;
902
903     //WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum)
904     u2TransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; // NOTE(Kevin): Optimized for ARM
905
906     /* Only consider SEQ_2 for Challenge Text */
907     if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_2) &&
908         (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY)) {
909
910         /* Free previous allocated TCM memory */
911         if (prStaRec->prChallengeText) {
912             ASSERT(0);
913             cnmMemFree(prAdapter, prStaRec->prChallengeText);
914             prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T)NULL;
915         }
916
917         if ( ( prStaRec->prChallengeText = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, IE_SIZE(prIEHdr)) ) == NULL) {
918             return;
919         }
920
921         /* Save the Challenge Text from Auth Seq 2 Frame, before sending Auth Seq 3 Frame */
922         COPY_IE(prStaRec->prChallengeText, prIEHdr);
923     }
924
925     return;
926
927 } /* end of authAddIEChallengeText() */
928
929
930 /*----------------------------------------------------------------------------*/
931 /*!
932 * @brief This function will parse and process the incoming Authentication frame.
933 *
934 * @param[in] prSwRfb            Pointer to SW RFB data structure.
935 *
936 * @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
937 */
938 /*----------------------------------------------------------------------------*/
939 WLAN_STATUS
940 authProcessRxAuth2_Auth4Frame (
941     IN P_ADAPTER_T prAdapter,
942     IN P_SW_RFB_T prSwRfb
943     )
944 {
945     P_WLAN_AUTH_FRAME_T prAuthFrame;
946     PUINT_8 pucIEsBuffer;
947     UINT_16 u2IEsLen;
948     UINT_16 u2Offset;
949     UINT_8 ucIEID;
950     UINT_32 i;
951
952
953     ASSERT(prSwRfb);
954
955     prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader;
956
957     pucIEsBuffer = &prAuthFrame->aucInfoElem[0];
958     u2IEsLen = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
959             (AUTH_ALGORITHM_NUM_FIELD_LEN +
960              AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN +
961              STATUS_CODE_FIELD_LEN);
962
963     IE_FOR_EACH(pucIEsBuffer, u2IEsLen, u2Offset) {
964         ucIEID = IE_ID(pucIEsBuffer);
965
966         for (i = 0; i < (sizeof(rxAuthIETable) / sizeof(HANDLE_IE_ENTRY_T)); i++) {
967
968             if (ucIEID == rxAuthIETable[i].ucElemID) {
969                 rxAuthIETable[i].pfnHandleIE(prAdapter, prSwRfb, (P_IE_HDR_T)pucIEsBuffer);
970             }
971         }
972     }
973
974     return WLAN_STATUS_SUCCESS;
975
976 } /* end of authProcessRxAuth2_Auth4Frame() */
977
978
979 /*----------------------------------------------------------------------------*/
980 /*!
981 * @brief This function will compose the Deauthentication frame
982 *
983 * @param[in] pucBuffer              Pointer to the frame buffer.
984 * @param[in] aucPeerMACAddress      Given Peer MAC Address.
985 * @param[in] aucMACAddress          Given Our MAC Address.
986 * @param[in] u2StatusCode           Status Code
987 *
988 * @return (none)
989 */
990 /*----------------------------------------------------------------------------*/
991 __KAL_INLINE__ VOID
992 authComposeDeauthFrameHeaderAndFF (
993     IN PUINT_8       pucBuffer,
994     IN UINT_8        aucPeerMACAddress[],
995     IN UINT_8        aucMACAddress[],
996     IN UINT_8        aucBssid[],
997     IN UINT_16       u2ReasonCode
998     )
999 {
1000     P_WLAN_DEAUTH_FRAME_T prDeauthFrame;
1001     UINT_16 u2FrameCtrl;
1002
1003     ASSERT(pucBuffer);
1004     ASSERT(aucPeerMACAddress);
1005     ASSERT(aucMACAddress);
1006     ASSERT(aucBssid);
1007
1008     prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T)pucBuffer;
1009
1010     //4 <1> Compose the frame header of the Deauthentication frame.
1011     /* Fill the Frame Control field. */
1012     u2FrameCtrl = MAC_FRAME_DEAUTH;
1013
1014     //WLAN_SET_FIELD_16(&prDeauthFrame->u2FrameCtrl, u2FrameCtrl);
1015     prDeauthFrame->u2FrameCtrl = u2FrameCtrl; // NOTE(Kevin): Optimized for ARM
1016
1017     /* Fill the DA field with Target BSSID. */
1018     COPY_MAC_ADDR(prDeauthFrame->aucDestAddr, aucPeerMACAddress);
1019
1020     /* Fill the SA field with our MAC Address. */
1021     COPY_MAC_ADDR(prDeauthFrame->aucSrcAddr, aucMACAddress);
1022
1023     /* Fill the BSSID field with Target BSSID. */
1024     COPY_MAC_ADDR(prDeauthFrame->aucBSSID, aucBssid);
1025
1026     /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */
1027     prDeauthFrame->u2SeqCtrl = 0;
1028
1029     //4 <2> Compose the frame body's fixed field part of the Authentication frame.
1030     /* Fill the Status Code field. */
1031     //WLAN_SET_FIELD_16(&prDeauthFrame->u2ReasonCode, u2ReasonCode);
1032     prDeauthFrame->u2ReasonCode = u2ReasonCode; // NOTE(Kevin): Optimized for ARM
1033
1034     return;
1035 } /* end of authComposeDeauthFrameHeaderAndFF() */
1036
1037
1038
1039 /*----------------------------------------------------------------------------*/
1040 /*!
1041 * @brief This function will send the Deauthenticiation frame
1042 *
1043 * @param[in] prStaRec           Pointer to the STA_RECORD_T
1044 * @param[in] prClassErrSwRfb    Pointer to the SW_RFB_T which is Class Error.
1045 * @param[in] u2ReasonCode       A reason code to indicate why to leave BSS.
1046 * @param[in] pfTxDoneHandler    TX Done call back function
1047 *
1048 * @retval WLAN_STATUS_RESOURCES No available resource for frame composing.
1049 * @retval WLAN_STATUS_SUCCESS   Successfully send frame to TX Module
1050 * @retval WLAN_STATUS_FAILURE   Didn't send Deauth frame for various reasons.
1051 */
1052 /*----------------------------------------------------------------------------*/
1053 WLAN_STATUS
1054 authSendDeauthFrame (
1055     IN P_ADAPTER_T          prAdapter,
1056     IN P_STA_RECORD_T       prStaRec,
1057     IN P_SW_RFB_T           prClassErrSwRfb,
1058     IN UINT_16              u2ReasonCode,
1059     IN PFN_TX_DONE_HANDLER  pfTxDoneHandler
1060     )
1061 {
1062     P_WLAN_MAC_HEADER_A4_T  prWlanMacHeader = NULL;
1063     PUINT_8                 pucReceiveAddr;
1064     PUINT_8                 pucTransmitAddr;
1065     PUINT_8                 pucBssid = NULL;
1066
1067     ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX;
1068     P_MSDU_INFO_T   prMsduInfo;
1069     UINT_16         u2EstimatedFrameLen;
1070     UINT_16         u2RxFrameCtrl;
1071     P_BSS_INFO_T    prBssInfo;
1072
1073     P_DEAUTH_INFO_T prDeauthInfo;
1074     OS_SYSTIME      rCurrentTime;
1075     INT_32 i4NewEntryIndex, i;
1076     UINT_8 ucStaRecIdx = STA_REC_INDEX_NOT_FOUND;
1077
1078 #if CFG_ENABLE_WIFI_DIRECT
1079     UINT_8 aucBMC[] = BC_MAC_ADDR;
1080 #endif
1081
1082     /* NOTE(Kevin): The best way to reply the Deauth is according to the incoming data
1083      * frame
1084      */
1085     //4 <1> Find the Receiver Address first.
1086     if (prClassErrSwRfb) {
1087         BOOLEAN fgIsAbleToSendDeauth = FALSE;
1088
1089         prWlanMacHeader = (P_WLAN_MAC_HEADER_A4_T) prClassErrSwRfb->pvHeader;
1090
1091         //WLAN_GET_FIELD_16(&prWlanMacHeader->u2FrameCtrl, &u2RxFrameCtrl);
1092         u2RxFrameCtrl = prWlanMacHeader->u2FrameCtrl; // NOTE(Kevin): Optimized for ARM
1093
1094         /* TODO(Kevin): Currently we won't send Deauth for IBSS node. How about DLS ? */
1095         if ((prWlanMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) == 0) {
1096             return WLAN_STATUS_FAILURE;
1097         }
1098
1099         /* Check if corresponding BSS is able to send Deauth */
1100         for (i = NETWORK_TYPE_AIS_INDEX; i < NETWORK_TYPE_INDEX_NUM; i++) {
1101             prBssInfo = &(prAdapter->rWifiVar.arBssInfo[i]);
1102
1103             if (IS_NET_ACTIVE(prAdapter, i) &&
1104                 (EQUAL_MAC_ADDR(prWlanMacHeader->aucAddr1, prBssInfo->aucOwnMacAddr))) {
1105                 {
1106                     fgIsAbleToSendDeauth = TRUE;
1107                     eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T)i;
1108                     break;
1109                 }
1110             }
1111         }
1112
1113         if (!fgIsAbleToSendDeauth) {
1114             return WLAN_STATUS_FAILURE;
1115         }
1116
1117         pucReceiveAddr = prWlanMacHeader->aucAddr2;
1118
1119     }
1120     else if (prStaRec) {
1121
1122         pucReceiveAddr = prStaRec->aucMacAddr;
1123     }
1124     else {
1125 #if CFG_ENABLE_WIFI_DIRECT
1126         pucReceiveAddr = aucBMC;
1127 #else
1128         return WLAN_STATUS_FAILURE;
1129 #endif
1130     }
1131
1132     //4 <2> Check if already send a Deauth frame in MIN_DEAUTH_INTERVAL_MSEC
1133     GET_CURRENT_SYSTIME(&rCurrentTime);
1134
1135     i4NewEntryIndex = -1;
1136     for (i = 0; i < MAX_DEAUTH_INFO_COUNT; i++) {
1137         prDeauthInfo = &(prAdapter->rWifiVar.arDeauthInfo[i]);
1138
1139
1140         /* For continuously sending Deauth frame, the minimum interval is
1141          * MIN_DEAUTH_INTERVAL_MSEC.
1142          */
1143         if (CHECK_FOR_TIMEOUT(rCurrentTime,
1144                               prDeauthInfo->rLastSendTime,
1145                               MSEC_TO_SYSTIME(MIN_DEAUTH_INTERVAL_MSEC))) {
1146
1147             i4NewEntryIndex = i;
1148         }
1149         else if (EQUAL_MAC_ADDR(pucReceiveAddr, prDeauthInfo->aucRxAddr) &&
1150                  (!pfTxDoneHandler)) {
1151
1152             return WLAN_STATUS_FAILURE;
1153         }
1154     }
1155
1156     //4 <3> Update information.
1157     if (i4NewEntryIndex > 0) {
1158
1159         prDeauthInfo = &(prAdapter->rWifiVar.arDeauthInfo[i4NewEntryIndex]);
1160
1161         COPY_MAC_ADDR(prDeauthInfo->aucRxAddr, pucReceiveAddr);
1162         prDeauthInfo->rLastSendTime = rCurrentTime;
1163     }
1164     else {
1165         /* NOTE(Kevin): for the case of AP mode, we may encounter this case
1166          * if deauth all the associated clients.
1167          */
1168         DBGLOG(SAA, WARN, ("No unused DEAUTH_INFO_T !\n"));
1169     }
1170
1171     //4 <4> Allocate a PKT_INFO_T for Deauthentication Frame
1172     /* Init with MGMT Header Length + Length of Fixed Fields + IE Length */
1173     u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD +
1174                            WLAN_MAC_MGMT_HEADER_LEN +
1175                            REASON_CODE_FIELD_LEN);
1176
1177     /* Allocate a MSDU_INFO_T */
1178     if ( (prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == NULL) {
1179         DBGLOG(SAA, WARN, ("No PKT_INFO_T for sending Deauth Request.\n"));
1180         return WLAN_STATUS_RESOURCES;
1181     }
1182
1183     //4 <5> Find the Transmitter Address and BSSID.
1184     if (prClassErrSwRfb) {
1185
1186         /* The TA of Deauth is the A1 of RX frame */
1187         pucTransmitAddr = prWlanMacHeader->aucAddr1;
1188
1189         switch (prWlanMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) {
1190
1191         case MASK_FC_FROM_DS:
1192             /* The BSSID of Deauth is the A2 of RX frame */
1193             pucBssid = prWlanMacHeader->aucAddr2;
1194             break;
1195
1196         case MASK_FC_TO_DS:
1197             /* The BSSID of Deauth is the A1 of RX frame */
1198             pucBssid = prWlanMacHeader->aucAddr1;
1199             break;
1200
1201         case MASK_TO_DS_FROM_DS:
1202             /* TODO(Kevin): Consider BOW, now we set the BSSID of Deauth
1203              * to the A2 of RX frame for temporary solution.
1204              */
1205             pucBssid = prWlanMacHeader->aucAddr2;
1206             break;
1207
1208         /* No Default */
1209         }
1210
1211     }
1212     else if (prStaRec) {
1213         eNetTypeIndex = prStaRec->ucNetTypeIndex;
1214
1215         prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]);
1216
1217         pucTransmitAddr = prBssInfo->aucOwnMacAddr;
1218
1219         pucBssid = prBssInfo->aucBSSID;
1220     }
1221 #if CFG_ENABLE_WIFI_DIRECT
1222     else {
1223         if (prAdapter->fgIsP2PRegistered) {
1224             prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
1225
1226             ucStaRecIdx = STA_REC_INDEX_BMCAST;
1227
1228             pucTransmitAddr = prBssInfo->aucOwnMacAddr;
1229
1230             pucBssid = prBssInfo->aucBSSID;
1231
1232             eNetTypeIndex = NETWORK_TYPE_P2P_INDEX;
1233         }
1234         else {
1235             return WLAN_STATUS_FAILURE;
1236         }
1237     }
1238
1239 #endif
1240
1241
1242     //4 <6> compose Deauthentication frame header and some fixed fields */
1243     authComposeDeauthFrameHeaderAndFF(
1244             (PUINT_8)((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
1245             pucReceiveAddr,
1246             pucTransmitAddr,
1247             pucBssid,
1248             u2ReasonCode);
1249
1250 #if CFG_SUPPORT_802_11W
1251     if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) {
1252         P_WLAN_DEAUTH_FRAME_T prDeauthFrame;
1253
1254         prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T)(PUINT_8)((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
1255
1256         prDeauthFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
1257         DBGLOG(TX, WARN, ("authSendDeauthFrame with protection\n"));
1258     }
1259 #endif
1260
1261     //4 <7> Update information of MSDU_INFO_T
1262     prMsduInfo->eSrc = TX_PACKET_MGMT;
1263     prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
1264     prMsduInfo->ucStaRecIndex = ((prStaRec == NULL)?ucStaRecIdx:prStaRec->ucIndex);
1265     prMsduInfo->ucNetworkType = (UINT_8)eNetTypeIndex;
1266     prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
1267     prMsduInfo->fgIs802_1x = FALSE;
1268     prMsduInfo->fgIs802_11 = TRUE;
1269     prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN;
1270     prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
1271     prMsduInfo->pfTxDoneHandler = pfTxDoneHandler;
1272     prMsduInfo->fgIsBasicRate = TRUE;
1273
1274     //4 <8> Inform TXM to send this Deauthentication frame.
1275     nicTxEnqueueMsdu(prAdapter, prMsduInfo);
1276
1277     return WLAN_STATUS_SUCCESS;
1278 } /* end of authSendDeauthFrame() */
1279
1280
1281
1282 /*----------------------------------------------------------------------------*/
1283 /*!
1284 * @brief This function will parse and process the incoming Deauthentication frame
1285 *        if the given BSSID is matched.
1286 *
1287 * @param[in] prSwRfb            Pointer to SW RFB data structure.
1288 * @param[in] aucBSSID           Given BSSID
1289 * @param[out] pu2ReasonCode     Pointer to store the Reason Code from Deauthentication.
1290 *
1291 * @retval WLAN_STATUS_FAILURE   This is not the frame we should handle at current state.
1292 * @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
1293 */
1294 /*----------------------------------------------------------------------------*/
1295 WLAN_STATUS
1296 authProcessRxDeauthFrame (
1297     IN P_SW_RFB_T prSwRfb,
1298     IN UINT_8 aucBSSID[],
1299     OUT PUINT_16 pu2ReasonCode
1300     )
1301 {
1302     P_WLAN_DEAUTH_FRAME_T prDeauthFrame;
1303     UINT_16 u2RxReasonCode;
1304
1305
1306     ASSERT(prSwRfb);
1307     ASSERT(aucBSSID);
1308     ASSERT(pu2ReasonCode);
1309
1310     //4 <1> locate the Deauthentication Frame.
1311     prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader;
1312
1313     //4 <2> Parse the Header of Deauthentication Frame.
1314 #if 0 // Kevin: Seems redundant
1315     WLAN_GET_FIELD_16(&prDeauthFrame->u2FrameCtrl, &u2RxFrameCtrl)
1316     u2RxFrameCtrl &= MASK_FRAME_TYPE;
1317     if (u2RxFrameCtrl != MAC_FRAME_DEAUTH) {
1318         return WLAN_STATUS_FAILURE;
1319     }
1320 #endif
1321
1322     if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < REASON_CODE_FIELD_LEN) {
1323         ASSERT(0);
1324         return WLAN_STATUS_FAILURE;
1325     }
1326
1327     /* Check if this Deauth Frame is coming from Target BSSID */
1328     if (UNEQUAL_MAC_ADDR(prDeauthFrame->aucBSSID, aucBSSID)) {
1329         DBGLOG(SAA, LOUD, ("Ignore Deauth Frame from other BSS ["MACSTR"]\n",
1330             MAC2STR(prDeauthFrame->aucSrcAddr)));
1331         return WLAN_STATUS_FAILURE;
1332     }
1333
1334     //4 <3> Parse the Fixed Fields of Deauthentication Frame Body.
1335     WLAN_GET_FIELD_16(&prDeauthFrame->u2ReasonCode, &u2RxReasonCode);
1336     *pu2ReasonCode = u2RxReasonCode;
1337
1338     return WLAN_STATUS_SUCCESS;
1339
1340 } /* end of authProcessRxDeauthFrame() */
1341
1342
1343 /*----------------------------------------------------------------------------*/
1344 /*!
1345 * @brief This function will parse and process the incoming Authentication frame.
1346 *
1347 * @param[in] prSwRfb                Pointer to SW RFB data structure.
1348 * @param[in] aucExpectedBSSID       Given Expected BSSID.
1349 * @param[in] u2ExpectedAuthAlgNum   Given Expected Authentication Algorithm Number
1350 * @param[in] u2ExpectedTransSeqNum  Given Expected Transaction Sequence Number.
1351 * @param[out] pu2ReturnStatusCode   Return Status Code.
1352 *
1353 * @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
1354 * @retval WLAN_STATUS_FAILURE   The frame we will ignore.
1355 */
1356 /*----------------------------------------------------------------------------*/
1357 WLAN_STATUS
1358 authProcessRxAuth1Frame (
1359     IN P_ADAPTER_T prAdapter,
1360     IN P_SW_RFB_T prSwRfb,
1361     IN UINT_8 aucExpectedBSSID[],
1362     IN UINT_16 u2ExpectedAuthAlgNum,
1363     IN UINT_16 u2ExpectedTransSeqNum,
1364     OUT PUINT_16 pu2ReturnStatusCode
1365     )
1366 {
1367     P_WLAN_AUTH_FRAME_T prAuthFrame;
1368     UINT_16 u2ReturnStatusCode = STATUS_CODE_SUCCESSFUL;
1369
1370
1371     ASSERT(prSwRfb);
1372     ASSERT(aucExpectedBSSID);
1373     ASSERT(pu2ReturnStatusCode);
1374
1375     //4 <1> locate the Authentication Frame.
1376     prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader;
1377
1378     //4 <2> Check the BSSID
1379     if (UNEQUAL_MAC_ADDR(prAuthFrame->aucBSSID, aucExpectedBSSID)) {
1380         return WLAN_STATUS_FAILURE; /* Just Ignore this MMPDU */
1381     }
1382
1383     //4 <3> Parse the Fixed Fields of Authentication Frame Body.
1384     if (prAuthFrame->u2AuthAlgNum != u2ExpectedAuthAlgNum) {
1385         u2ReturnStatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED;
1386     }
1387
1388     if (prAuthFrame->u2AuthTransSeqNo != u2ExpectedTransSeqNum) {
1389         u2ReturnStatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ;
1390     }
1391
1392     *pu2ReturnStatusCode = u2ReturnStatusCode;
1393
1394     return WLAN_STATUS_SUCCESS;
1395
1396 } /* end of authProcessRxAuth1Frame() */
1397
1398