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