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