Staging: rt3070: remove dead RT_BIG_ENDIAN code
[linux-2.6] / drivers / staging / rt3070 / sta / assoc.c
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26
27         Module Name:
28         assoc.c
29
30         Abstract:
31
32         Revision History:
33         Who                     When                    What
34         --------        ----------              ----------------------------------------------
35         John            2004-9-3                porting from RT2500
36 */
37 #include "../rt_config.h"
38
39 UCHAR   CipherWpaTemplate[] = {
40                 0xdd,                                   // WPA IE
41                 0x16,                                   // Length
42                 0x00, 0x50, 0xf2, 0x01, // oui
43                 0x01, 0x00,                             // Version
44                 0x00, 0x50, 0xf2, 0x02, // Multicast
45                 0x01, 0x00,                             // Number of unicast
46                 0x00, 0x50, 0xf2, 0x02, // unicast
47                 0x01, 0x00,                             // number of authentication method
48                 0x00, 0x50, 0xf2, 0x01  // authentication
49                 };
50
51 UCHAR   CipherWpa2Template[] = {
52                 0x30,                                   // RSN IE
53                 0x14,                                   // Length
54                 0x01, 0x00,                             // Version
55                 0x00, 0x0f, 0xac, 0x02, // group cipher, TKIP
56                 0x01, 0x00,                             // number of pairwise
57                 0x00, 0x0f, 0xac, 0x02, // unicast
58                 0x01, 0x00,                             // number of authentication method
59                 0x00, 0x0f, 0xac, 0x02, // authentication
60                 0x00, 0x00,                             // RSN capability
61                 };
62
63 UCHAR   Ccx2IeInfo[] = { 0x00, 0x40, 0x96, 0x03, 0x02};
64
65 /*
66         ==========================================================================
67         Description:
68                 association state machine init, including state transition and timer init
69         Parameters:
70                 S - pointer to the association state machine
71
72         IRQL = PASSIVE_LEVEL
73
74         ==========================================================================
75  */
76 VOID AssocStateMachineInit(
77         IN      PRTMP_ADAPTER   pAd,
78         IN  STATE_MACHINE *S,
79         OUT STATE_MACHINE_FUNC Trans[])
80 {
81         StateMachineInit(S, Trans, MAX_ASSOC_STATE, MAX_ASSOC_MSG, (STATE_MACHINE_FUNC)Drop, ASSOC_IDLE, ASSOC_MACHINE_BASE);
82
83         // first column
84         StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)MlmeAssocReqAction);
85         StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)MlmeReassocReqAction);
86         StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)MlmeDisassocReqAction);
87         StateMachineSetAction(S, ASSOC_IDLE, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
88
89         // second column
90         StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
91         StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
92         StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
93         StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
94         StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
95         //
96         // Patch 3Com AP MOde:3CRWE454G72
97         // We send Assoc request frame to this AP, it always send Reassoc Rsp not Associate Rsp.
98         //
99         StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
100         StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_ASSOC_TIMEOUT, (STATE_MACHINE_FUNC)AssocTimeoutAction);
101
102         // third column
103         StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
104         StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
105         StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
106         StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
107         StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
108         //
109         // Patch, AP doesn't send Reassociate Rsp frame to Station.
110         //
111         StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
112         StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_REASSOC_TIMEOUT, (STATE_MACHINE_FUNC)ReassocTimeoutAction);
113
114         // fourth column
115         StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
116         StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
117         StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
118         StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
119         StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_DISASSOC_TIMEOUT, (STATE_MACHINE_FUNC)DisassocTimeoutAction);
120
121         // initialize the timer
122         RTMPInitTimer(pAd, &pAd->MlmeAux.AssocTimer, GET_TIMER_FUNCTION(AssocTimeout), pAd, FALSE);
123         RTMPInitTimer(pAd, &pAd->MlmeAux.ReassocTimer, GET_TIMER_FUNCTION(ReassocTimeout), pAd, FALSE);
124         RTMPInitTimer(pAd, &pAd->MlmeAux.DisassocTimer, GET_TIMER_FUNCTION(DisassocTimeout), pAd, FALSE);
125 }
126
127 /*
128         ==========================================================================
129         Description:
130                 Association timeout procedure. After association timeout, this function
131                 will be called and it will put a message into the MLME queue
132         Parameters:
133                 Standard timer parameters
134
135         IRQL = DISPATCH_LEVEL
136
137         ==========================================================================
138  */
139 VOID AssocTimeout(IN PVOID SystemSpecific1,
140                                  IN PVOID FunctionContext,
141                                  IN PVOID SystemSpecific2,
142                                  IN PVOID SystemSpecific3)
143 {
144         RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
145
146         // Do nothing if the driver is starting halt state.
147         // This might happen when timer already been fired before cancel timer with mlmehalt
148         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
149                 return;
150
151         MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_ASSOC_TIMEOUT, 0, NULL);
152         RT28XX_MLME_HANDLER(pAd);
153 }
154
155 /*
156         ==========================================================================
157         Description:
158                 Reassociation timeout procedure. After reassociation timeout, this
159                 function will be called and put a message into the MLME queue
160         Parameters:
161                 Standard timer parameters
162
163         IRQL = DISPATCH_LEVEL
164
165         ==========================================================================
166  */
167 VOID ReassocTimeout(IN PVOID SystemSpecific1,
168                                         IN PVOID FunctionContext,
169                                         IN PVOID SystemSpecific2,
170                                         IN PVOID SystemSpecific3)
171 {
172         RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
173
174         // Do nothing if the driver is starting halt state.
175         // This might happen when timer already been fired before cancel timer with mlmehalt
176         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
177                 return;
178
179         MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_REASSOC_TIMEOUT, 0, NULL);
180         RT28XX_MLME_HANDLER(pAd);
181 }
182
183 /*
184         ==========================================================================
185         Description:
186                 Disassociation timeout procedure. After disassociation timeout, this
187                 function will be called and put a message into the MLME queue
188         Parameters:
189                 Standard timer parameters
190
191         IRQL = DISPATCH_LEVEL
192
193         ==========================================================================
194  */
195 VOID DisassocTimeout(IN PVOID SystemSpecific1,
196                                         IN PVOID FunctionContext,
197                                         IN PVOID SystemSpecific2,
198                                         IN PVOID SystemSpecific3)
199 {
200         RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
201
202         // Do nothing if the driver is starting halt state.
203         // This might happen when timer already been fired before cancel timer with mlmehalt
204         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
205                 return;
206
207         MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_DISASSOC_TIMEOUT, 0, NULL);
208         RT28XX_MLME_HANDLER(pAd);
209 }
210
211 /*
212         ==========================================================================
213         Description:
214                 mlme assoc req handling procedure
215         Parameters:
216                 Adapter - Adapter pointer
217                 Elem - MLME Queue Element
218         Pre:
219                 the station has been authenticated and the following information is stored in the config
220                         -# SSID
221                         -# supported rates and their length
222                         -# listen interval (Adapter->StaCfg.default_listen_count)
223                         -# Transmit power  (Adapter->StaCfg.tx_power)
224         Post  :
225                 -# An association request frame is generated and sent to the air
226                 -# Association timer starts
227                 -# Association state -> ASSOC_WAIT_RSP
228
229         IRQL = DISPATCH_LEVEL
230
231         ==========================================================================
232  */
233 VOID MlmeAssocReqAction(
234         IN PRTMP_ADAPTER pAd,
235         IN MLME_QUEUE_ELEM *Elem)
236 {
237         UCHAR                   ApAddr[6];
238         HEADER_802_11   AssocHdr;
239         UCHAR                   Ccx2Len = 5;
240         UCHAR                   WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
241         USHORT                  ListenIntv;
242         ULONG                   Timeout;
243         USHORT                  CapabilityInfo;
244         BOOLEAN                 TimerCancelled;
245         PUCHAR                  pOutBuffer = NULL;
246         NDIS_STATUS             NStatus;
247         ULONG                   FrameLen = 0;
248         ULONG                   tmp;
249         USHORT                  VarIesOffset;
250         UCHAR                   CkipFlag;
251         UCHAR                   CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH];
252         UCHAR                   AironetCkipIe = IE_AIRONET_CKIP;
253         UCHAR                   AironetCkipLen = CKIP_NEGOTIATION_LENGTH;
254         UCHAR                   AironetIPAddressIE = IE_AIRONET_IPADDRESS;
255         UCHAR                   AironetIPAddressLen = AIRONET_IPADDRESS_LENGTH;
256         UCHAR                   AironetIPAddressBuffer[AIRONET_IPADDRESS_LENGTH] = {0x00, 0x40, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
257         USHORT                  Status;
258
259         // Block all authentication request durning WPA block period
260         if (pAd->StaCfg.bBlockAssoc == TRUE)
261         {
262                 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Block Assoc request durning WPA block period!\n"));
263                 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
264                 Status = MLME_STATE_MACHINE_REJECT;
265                 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
266         }
267         // check sanity first
268         else if (MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
269         {
270                 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
271                 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
272
273                 // Get an unused nonpaged memory
274                 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
275                 if (NStatus != NDIS_STATUS_SUCCESS)
276                 {
277                         DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeAssocReqAction() allocate memory failed \n"));
278                         pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
279                         Status = MLME_FAIL_NO_RESOURCE;
280                         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
281                         return;
282                 }
283
284                 // Add by James 03/06/27
285                 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
286                 // Association don't need to report MAC address
287                 pAd->StaCfg.AssocInfo.AvailableRequestFixedIEs =
288                         NDIS_802_11_AI_REQFI_CAPABILITIES | NDIS_802_11_AI_REQFI_LISTENINTERVAL;
289                 pAd->StaCfg.AssocInfo.RequestFixedIEs.Capabilities = CapabilityInfo;
290                 pAd->StaCfg.AssocInfo.RequestFixedIEs.ListenInterval = ListenIntv;
291                 // Only reassociate need this
292                 //COPY_MAC_ADDR(pAd->StaCfg.AssocInfo.RequestFixedIEs.CurrentAPAddress, ApAddr);
293                 pAd->StaCfg.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
294
295         NdisZeroMemory(pAd->StaCfg.ReqVarIEs, MAX_VIE_LEN);
296                 // First add SSID
297                 VarIesOffset = 0;
298                 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SsidIe, 1);
299                 VarIesOffset += 1;
300                 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SsidLen, 1);
301                 VarIesOffset += 1;
302                 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
303                 VarIesOffset += pAd->MlmeAux.SsidLen;
304
305                 // Second add Supported rates
306                 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SupRateIe, 1);
307                 VarIesOffset += 1;
308                 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SupRateLen, 1);
309                 VarIesOffset += 1;
310                 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.SupRate, pAd->MlmeAux.SupRateLen);
311                 VarIesOffset += pAd->MlmeAux.SupRateLen;
312                 // End Add by James
313
314         if ((pAd->CommonCfg.Channel > 14) &&
315             (pAd->CommonCfg.bIEEE80211H == TRUE))
316             CapabilityInfo |= 0x0100;
317
318                 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send ASSOC request...\n"));
319                 MgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr, ApAddr);
320
321                 // Build basic frame first
322                 MakeOutgoingFrame(pOutBuffer,                           &FrameLen,
323                                                   sizeof(HEADER_802_11),        &AssocHdr,
324                                                   2,                                            &CapabilityInfo,
325                                                   2,                                            &ListenIntv,
326                                                   1,                                            &SsidIe,
327                                                   1,                                            &pAd->MlmeAux.SsidLen,
328                                                   pAd->MlmeAux.SsidLen,         pAd->MlmeAux.Ssid,
329                                                   1,                                            &SupRateIe,
330                                                   1,                                            &pAd->MlmeAux.SupRateLen,
331                                                   pAd->MlmeAux.SupRateLen,  pAd->MlmeAux.SupRate,
332                                                   END_OF_ARGS);
333
334                 if (pAd->MlmeAux.ExtRateLen != 0)
335                 {
336                         MakeOutgoingFrame(pOutBuffer + FrameLen,    &tmp,
337                                                           1,                        &ExtRateIe,
338                                                           1,                        &pAd->MlmeAux.ExtRateLen,
339                                                           pAd->MlmeAux.ExtRateLen,  pAd->MlmeAux.ExtRate,
340                                                           END_OF_ARGS);
341                         FrameLen += tmp;
342                 }
343
344 #ifdef DOT11_N_SUPPORT
345                 // HT
346                 if ((pAd->MlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
347                 {
348                         ULONG TmpLen;
349                         UCHAR HtLen;
350                         UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
351                         if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE)
352                         {
353                                 HtLen = SIZE_HT_CAP_IE + 4;
354                                 MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
355                                                           1,                                &WpaIe,
356                                                           1,                                &HtLen,
357                                                           4,                                &BROADCOM[0],
358                                                          pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
359                                                           END_OF_ARGS);
360                         }
361                         else
362                         {
363                                 MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
364                                                           1,                                &HtCapIe,
365                                                           1,                                &pAd->MlmeAux.HtCapabilityLen,
366                                                          pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
367                                                           END_OF_ARGS);
368                         }
369                         FrameLen += TmpLen;
370                 }
371 #endif // DOT11_N_SUPPORT //
372
373                 // add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION
374                 // Case I: (Aggregation + Piggy-Back)
375                 // 1. user enable aggregation, AND
376                 // 2. Mac support piggy-back
377                 // 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON
378                 // Case II: (Aggregation)
379                 // 1. user enable aggregation, AND
380                 // 2. AP annouces it's AGGREGATION-capable in BEACON
381                 if (pAd->CommonCfg.bAggregationCapable)
382                 {
383                         if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3))
384                         {
385                                 ULONG TmpLen;
386                                 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00};
387                                 MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
388                                                                   9,                             RalinkIe,
389                                                                   END_OF_ARGS);
390                                 FrameLen += TmpLen;
391                         }
392                         else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
393                         {
394                                 ULONG TmpLen;
395                                 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00};
396                                 MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
397                                                                   9,                             RalinkIe,
398                                                                   END_OF_ARGS);
399                                 FrameLen += TmpLen;
400                         }
401                 }
402                 else
403                 {
404                         ULONG TmpLen;
405                         UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x06, 0x00, 0x00, 0x00};
406                         MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
407                                                           9,                                             RalinkIe,
408                                                           END_OF_ARGS);
409                         FrameLen += TmpLen;
410                 }
411
412                 if (pAd->MlmeAux.APEdcaParm.bValid)
413                 {
414                         if (pAd->CommonCfg.bAPSDCapable && pAd->MlmeAux.APEdcaParm.bAPSDCapable)
415                         {
416                                 QBSS_STA_INFO_PARM QosInfo;
417
418                                 NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM));
419                                 QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
420                                 QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
421                                 QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
422                                 QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
423                                 QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength;
424                                 WmeIe[8] |= *(PUCHAR)&QosInfo;
425                         }
426                         else
427                         {
428                 // The Parameter Set Count is set to Â¡Â§0¡¨ in the association request frames
429                 // WmeIe[8] |= (pAd->MlmeAux.APEdcaParm.EdcaUpdateCount & 0x0f);
430                         }
431
432                         MakeOutgoingFrame(pOutBuffer + FrameLen,    &tmp,
433                                                           9,                        &WmeIe[0],
434                                                           END_OF_ARGS);
435                         FrameLen += tmp;
436                 }
437
438                 //
439                 // Let WPA(#221) Element ID on the end of this association frame.
440                 // Otherwise some AP will fail on parsing Element ID and set status fail on Assoc Rsp.
441                 // For example: Put Vendor Specific IE on the front of WPA IE.
442                 // This happens on AP (Model No:Linksys WRK54G)
443                 //
444                 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
445             (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
446             (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
447             (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
448                         )
449             )
450                 {
451                         UCHAR RSNIe = IE_WPA;
452
453                         if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
454                 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
455                         {
456                                 RSNIe = IE_WPA2;
457                         }
458
459 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
460 #ifdef SIOCSIWGENIE
461                         if (pAd->StaCfg.WpaSupplicantUP != 1)
462 #endif // SIOCSIWGENIE //
463 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
464                 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
465
466             // Check for WPA PMK cache list
467                         if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
468                         {
469                             INT     idx;
470                 BOOLEAN FoundPMK = FALSE;
471                                 // Search chched PMKID, append it if existed
472                                 for (idx = 0; idx < PMKID_NO; idx++)
473                                 {
474                                         if (NdisEqualMemory(ApAddr, &pAd->StaCfg.SavedPMK[idx].BSSID, 6))
475                                         {
476                                                 FoundPMK = TRUE;
477                                                 break;
478                                         }
479                                 }
480
481                                 if (FoundPMK)
482                                 {
483                                         // Set PMK number
484                                         *(PUSHORT) &pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len] = 1;
485                                         NdisMoveMemory(&pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len + 2], &pAd->StaCfg.SavedPMK[idx].PMKID, 16);
486                     pAd->StaCfg.RSNIE_Len += 18;
487                                 }
488                         }
489
490 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
491 #ifdef SIOCSIWGENIE
492                         if (pAd->StaCfg.WpaSupplicantUP == 1)
493                         {
494                                 MakeOutgoingFrame(pOutBuffer + FrameLen,                &tmp,
495                                                 pAd->StaCfg.RSNIE_Len,                  pAd->StaCfg.RSN_IE,
496                                                 END_OF_ARGS);
497                         }
498                         else
499 #endif
500 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
501                         {
502                                 MakeOutgoingFrame(pOutBuffer + FrameLen,                &tmp,
503                                                         1,                              &RSNIe,
504                                                 1,                              &pAd->StaCfg.RSNIE_Len,
505                                                 pAd->StaCfg.RSNIE_Len,                  pAd->StaCfg.RSN_IE,
506                                                 END_OF_ARGS);
507                         }
508
509                         FrameLen += tmp;
510
511 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
512 #ifdef SIOCSIWGENIE
513                         if (pAd->StaCfg.WpaSupplicantUP != 1)
514 #endif
515 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
516                         {
517                     // Append Variable IE
518                     NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &RSNIe, 1);
519                     VarIesOffset += 1;
520                     NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->StaCfg.RSNIE_Len, 1);
521                     VarIesOffset += 1;
522                         }
523                         NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
524                         VarIesOffset += pAd->StaCfg.RSNIE_Len;
525
526                         // Set Variable IEs Length
527                         pAd->StaCfg.ReqVarIELen = VarIesOffset;
528                 }
529
530                 // We have update that at PeerBeaconAtJoinRequest()
531                 CkipFlag = pAd->StaCfg.CkipFlag;
532                 if (CkipFlag != 0)
533                 {
534                         NdisZeroMemory(CkipNegotiationBuffer, CKIP_NEGOTIATION_LENGTH);
535                         CkipNegotiationBuffer[2] = 0x66;
536                         // Make it try KP & MIC, since we have to follow the result from AssocRsp
537                         CkipNegotiationBuffer[8] = 0x18;
538                         CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH - 1] = 0x22;
539                         CkipFlag = 0x18;
540
541                         MakeOutgoingFrame(pOutBuffer + FrameLen,        &tmp,
542                                                 1,                                                              &AironetCkipIe,
543                                                 1,                                                              &AironetCkipLen,
544                                                 AironetCkipLen,                                 CkipNegotiationBuffer,
545                                                 END_OF_ARGS);
546                         FrameLen += tmp;
547                 }
548
549                 // Add CCX v2 request if CCX2 admin state is on
550                 if (pAd->StaCfg.CCXControl.field.Enable == 1)
551                 {
552
553                         //
554                         // Add AironetIPAddressIE for Cisco CCX 2.X
555                         // Add CCX Version
556                         //
557                         MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
558                                                 1,                                                      &AironetIPAddressIE,
559                                                 1,                                                      &AironetIPAddressLen,
560                                                 AironetIPAddressLen,            AironetIPAddressBuffer,
561                                                 1,                                                      &Ccx2Ie,
562                                                 1,                                                      &Ccx2Len,
563                                                 Ccx2Len,                                    Ccx2IeInfo,
564                                                 END_OF_ARGS);
565                         FrameLen += tmp;
566
567                         // Add by James 03/06/27
568                         // Set Variable IEs Length
569                         pAd->StaCfg.ReqVarIELen = VarIesOffset;
570                         pAd->StaCfg.AssocInfo.RequestIELength = VarIesOffset;
571
572                         // OffsetResponseIEs follow ReqVarIE
573                         pAd->StaCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->StaCfg.ReqVarIELen;
574                         // End Add by James
575                 }
576
577
578                 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
579                 MlmeFreeMemory(pAd, pOutBuffer);
580
581                 RTMPSetTimer(&pAd->MlmeAux.AssocTimer, Timeout);
582                 pAd->Mlme.AssocMachine.CurrState = ASSOC_WAIT_RSP;
583         }
584         else
585         {
586                 DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeAssocReqAction() sanity check failed. BUG!!!!!! \n"));
587                 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
588                 Status = MLME_INVALID_FORMAT;
589                 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
590         }
591
592 }
593
594 /*
595         ==========================================================================
596         Description:
597                 mlme reassoc req handling procedure
598         Parameters:
599                 Elem -
600         Pre:
601                 -# SSID  (Adapter->StaCfg.ssid[])
602                 -# BSSID (AP address, Adapter->StaCfg.bssid)
603                 -# Supported rates (Adapter->StaCfg.supported_rates[])
604                 -# Supported rates length (Adapter->StaCfg.supported_rates_len)
605                 -# Tx power (Adapter->StaCfg.tx_power)
606
607         IRQL = DISPATCH_LEVEL
608
609         ==========================================================================
610  */
611 VOID MlmeReassocReqAction(
612         IN PRTMP_ADAPTER pAd,
613         IN MLME_QUEUE_ELEM *Elem)
614 {
615         UCHAR                   ApAddr[6];
616         HEADER_802_11   ReassocHdr;
617         UCHAR                   Ccx2Len = 5;
618         UCHAR                   WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
619         USHORT                  CapabilityInfo, ListenIntv;
620         ULONG                   Timeout;
621         ULONG                   FrameLen = 0;
622         BOOLEAN                 TimerCancelled;
623         NDIS_STATUS             NStatus;
624         ULONG                   tmp;
625         PUCHAR                  pOutBuffer = NULL;
626         USHORT                  Status;
627
628         // Block all authentication request durning WPA block period
629         if (pAd->StaCfg.bBlockAssoc == TRUE)
630         {
631                 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Block ReAssoc request durning WPA block period!\n"));
632                 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
633                 Status = MLME_STATE_MACHINE_REJECT;
634                 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
635         }
636         // the parameters are the same as the association
637         else if(MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
638         {
639                 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
640
641                 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
642                 if(NStatus != NDIS_STATUS_SUCCESS)
643                 {
644                         DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() allocate memory failed \n"));
645                         pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
646                         Status = MLME_FAIL_NO_RESOURCE;
647                         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
648                         return;
649                 }
650
651                 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
652
653                 // make frame, use bssid as the AP address??
654                 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send RE-ASSOC request...\n"));
655                 MgtMacHeaderInit(pAd, &ReassocHdr, SUBTYPE_REASSOC_REQ, 0, ApAddr, ApAddr);
656                 MakeOutgoingFrame(pOutBuffer,               &FrameLen,
657                                                   sizeof(HEADER_802_11),    &ReassocHdr,
658                                                   2,                        &CapabilityInfo,
659                                                   2,                        &ListenIntv,
660                                                   MAC_ADDR_LEN,             ApAddr,
661                                                   1,                        &SsidIe,
662                                                   1,                        &pAd->MlmeAux.SsidLen,
663                                                   pAd->MlmeAux.SsidLen,     pAd->MlmeAux.Ssid,
664                                                   1,                        &SupRateIe,
665                                                   1,                                            &pAd->MlmeAux.SupRateLen,
666                                                   pAd->MlmeAux.SupRateLen,  pAd->MlmeAux.SupRate,
667                                                   END_OF_ARGS);
668
669                 if (pAd->MlmeAux.ExtRateLen != 0)
670                 {
671                         MakeOutgoingFrame(pOutBuffer + FrameLen,        &tmp,
672                                                           1,                            &ExtRateIe,
673                                                           1,                            &pAd->MlmeAux.ExtRateLen,
674                                                           pAd->MlmeAux.ExtRateLen,          pAd->MlmeAux.ExtRate,
675                                                           END_OF_ARGS);
676                         FrameLen += tmp;
677                 }
678
679                 if (pAd->MlmeAux.APEdcaParm.bValid)
680                 {
681                         if (pAd->CommonCfg.bAPSDCapable && pAd->MlmeAux.APEdcaParm.bAPSDCapable)
682                         {
683                                 QBSS_STA_INFO_PARM QosInfo;
684
685                                 NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM));
686                                 QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
687                                 QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
688                                 QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
689                                 QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
690                                 QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength;
691                                 WmeIe[8] |= *(PUCHAR)&QosInfo;
692                         }
693
694                         MakeOutgoingFrame(pOutBuffer + FrameLen,    &tmp,
695                                                           9,                        &WmeIe[0],
696                                                           END_OF_ARGS);
697                         FrameLen += tmp;
698                 }
699
700 #ifdef DOT11_N_SUPPORT
701                 // HT
702                 if ((pAd->MlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
703                 {
704                         ULONG TmpLen;
705                         UCHAR HtLen;
706                         UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
707                         if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE)
708                         {
709                                 HtLen = SIZE_HT_CAP_IE + 4;
710                                 MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
711                                                           1,                                &WpaIe,
712                                                           1,                                &HtLen,
713                                                           4,                                &BROADCOM[0],
714                                                          pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
715                                                           END_OF_ARGS);
716                         }
717                         else
718                         {
719                                 MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
720                                                           1,                                &HtCapIe,
721                                                           1,                                &pAd->MlmeAux.HtCapabilityLen,
722                                                          pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
723                                                           END_OF_ARGS);
724                         }
725                         FrameLen += TmpLen;
726                 }
727 #endif // DOT11_N_SUPPORT //
728
729                 // add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION
730                 // Case I: (Aggregation + Piggy-Back)
731                 // 1. user enable aggregation, AND
732                 // 2. Mac support piggy-back
733                 // 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON
734                 // Case II: (Aggregation)
735                 // 1. user enable aggregation, AND
736                 // 2. AP annouces it's AGGREGATION-capable in BEACON
737                 if (pAd->CommonCfg.bAggregationCapable)
738                 {
739                         if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3))
740                         {
741                                 ULONG TmpLen;
742                                 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00};
743                                 MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
744                                                                   9,                             RalinkIe,
745                                                                   END_OF_ARGS);
746                                 FrameLen += TmpLen;
747                         }
748                         else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
749                         {
750                                 ULONG TmpLen;
751                                 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00};
752                                 MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
753                                                                   9,                             RalinkIe,
754                                                                   END_OF_ARGS);
755                                 FrameLen += TmpLen;
756                         }
757                 }
758                 else
759                 {
760                         ULONG TmpLen;
761                         UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x04, 0x00, 0x00, 0x00};
762                         MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
763                                                           9,                                             RalinkIe,
764                                                           END_OF_ARGS);
765                         FrameLen += TmpLen;
766                 }
767
768                 // Add CCX v2 request if CCX2 admin state is on
769                 if (pAd->StaCfg.CCXControl.field.Enable == 1)
770                 {
771                         //
772                         // Add CCX Version
773                         //
774                         MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
775                                                 1,                                                      &Ccx2Ie,
776                                                 1,                                                      &Ccx2Len,
777                                                 Ccx2Len,                                    Ccx2IeInfo,
778                                                 END_OF_ARGS);
779                         FrameLen += tmp;
780                 }
781
782                 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
783                 MlmeFreeMemory(pAd, pOutBuffer);
784
785                 RTMPSetTimer(&pAd->MlmeAux.ReassocTimer, Timeout); /* in mSec */
786                 pAd->Mlme.AssocMachine.CurrState = REASSOC_WAIT_RSP;
787         }
788         else
789         {
790                 DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() sanity check failed. BUG!!!! \n"));
791                 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
792                 Status = MLME_INVALID_FORMAT;
793                 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
794         }
795 }
796
797 /*
798         ==========================================================================
799         Description:
800                 Upper layer issues disassoc request
801         Parameters:
802                 Elem -
803
804         IRQL = PASSIVE_LEVEL
805
806         ==========================================================================
807  */
808 VOID MlmeDisassocReqAction(
809         IN PRTMP_ADAPTER pAd,
810         IN MLME_QUEUE_ELEM *Elem)
811 {
812         PMLME_DISASSOC_REQ_STRUCT pDisassocReq;
813         HEADER_802_11         DisassocHdr;
814         PHEADER_802_11        pDisassocHdr;
815         PUCHAR                pOutBuffer = NULL;
816         ULONG                 FrameLen = 0;
817         NDIS_STATUS           NStatus;
818         BOOLEAN               TimerCancelled;
819         ULONG                 Timeout = 0;
820         USHORT                Status;
821
822         // skip sanity check
823         pDisassocReq = (PMLME_DISASSOC_REQ_STRUCT)(Elem->Msg);
824
825         NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
826         if (NStatus != NDIS_STATUS_SUCCESS)
827         {
828                 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - MlmeDisassocReqAction() allocate memory failed\n"));
829                 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
830                 Status = MLME_FAIL_NO_RESOURCE;
831                 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
832                 return;
833         }
834
835
836
837         RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &TimerCancelled);
838
839         DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send DISASSOC request[BSSID::%02x:%02x:%02x:%02x:%02x:%02x (Reason=%d)\n",
840                                 pDisassocReq->Addr[0], pDisassocReq->Addr[1], pDisassocReq->Addr[2],
841                                 pDisassocReq->Addr[3], pDisassocReq->Addr[4], pDisassocReq->Addr[5], pDisassocReq->Reason));
842         MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pDisassocReq->Addr, pDisassocReq->Addr);       // patch peap ttls switching issue
843         MakeOutgoingFrame(pOutBuffer,           &FrameLen,
844                                           sizeof(HEADER_802_11),&DisassocHdr,
845                                           2,                    &pDisassocReq->Reason,
846                                           END_OF_ARGS);
847         MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
848
849         // To patch Instance and Buffalo(N) AP
850         // Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
851         // Therefore, we send both of them.
852         pDisassocHdr = (PHEADER_802_11)pOutBuffer;
853         pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
854         MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
855
856         MlmeFreeMemory(pAd, pOutBuffer);
857
858         pAd->StaCfg.DisassocReason = REASON_DISASSOC_STA_LEAVING;
859         COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pDisassocReq->Addr);
860
861         RTMPSetTimer(&pAd->MlmeAux.DisassocTimer, Timeout); /* in mSec */
862         pAd->Mlme.AssocMachine.CurrState = DISASSOC_WAIT_RSP;
863
864 #ifdef WPA_SUPPLICANT_SUPPORT
865 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
866     if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
867         {
868         union iwreq_data    wrqu;
869         //send disassociate event to wpa_supplicant
870         memset(&wrqu, 0, sizeof(wrqu));
871         wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
872         wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
873     }
874 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
875 #endif // WPA_SUPPLICANT_SUPPORT //
876
877 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
878     {
879         union iwreq_data    wrqu;
880         memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
881         wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
882     }
883 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
884
885 }
886
887 /*
888         ==========================================================================
889         Description:
890                 peer sends assoc rsp back
891         Parameters:
892                 Elme - MLME message containing the received frame
893
894         IRQL = DISPATCH_LEVEL
895
896         ==========================================================================
897  */
898 VOID PeerAssocRspAction(
899         IN PRTMP_ADAPTER pAd,
900         IN MLME_QUEUE_ELEM *Elem)
901 {
902         USHORT        CapabilityInfo, Status, Aid;
903         UCHAR         SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
904         UCHAR         ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
905         UCHAR         Addr2[MAC_ADDR_LEN];
906         BOOLEAN       TimerCancelled;
907         UCHAR         CkipFlag;
908         EDCA_PARM     EdcaParm;
909         HT_CAPABILITY_IE                HtCapability;
910         ADD_HT_INFO_IE          AddHtInfo;      // AP might use this additional ht info IE
911         UCHAR                   HtCapabilityLen;
912         UCHAR                   AddHtInfoLen;
913         UCHAR                   NewExtChannelOffset = 0xff;
914
915         if (PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
916                 &HtCapability,&AddHtInfo, &HtCapabilityLen,&AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
917         {
918                 // The frame is for me ?
919                 if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid))
920                 {
921                         DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():ASSOC - receive ASSOC_RSP to me (status=%d)\n", Status));
922 #ifdef DOT11_N_SUPPORT
923                         DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():MacTable [%d].AMsduSize = %d. ClientStatusFlags = 0x%lx \n",Elem->Wcid, pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
924 #endif // DOT11_N_SUPPORT //
925                         RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
926                         if(Status == MLME_SUCCESS)
927                         {
928                                 UCHAR                   MaxSupportedRateIn500Kbps = 0;
929                                 UCHAR                   idx;
930
931                                 // supported rates array may not be sorted. sort it and find the maximum rate
932                             for (idx=0; idx<SupRateLen; idx++)
933                 {
934                                 if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
935                                     MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
936                 }
937
938                                 for (idx=0; idx<ExtRateLen; idx++)
939                 {
940                                 if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
941                                     MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
942                 }
943                                 // go to procedure listed on page 376
944                                 AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
945                                         &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
946
947                                 StaAddMacTableEntry(pAd, &pAd->MacTab.Content[BSSID_WCID], MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo);
948
949                                 pAd->StaCfg.CkipFlag = CkipFlag;
950                                 if (CkipFlag & 0x18)
951                                 {
952                                         NdisZeroMemory(pAd->StaCfg.TxSEQ, 4);
953                                         NdisZeroMemory(pAd->StaCfg.RxSEQ, 4);
954                                         NdisZeroMemory(pAd->StaCfg.CKIPMIC, 4);
955                                         pAd->StaCfg.GIV[0] = RandomByte(pAd);
956                                         pAd->StaCfg.GIV[1] = RandomByte(pAd);
957                                         pAd->StaCfg.GIV[2] = RandomByte(pAd);
958                                         pAd->StaCfg.bCkipOn = TRUE;
959                                         DBGPRINT(RT_DEBUG_TRACE, ("<CCX> pAd->StaCfg.CkipFlag = 0x%02x\n", pAd->StaCfg.CkipFlag));
960                                 }
961                         }
962                         else
963                         {
964                         }
965                         pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
966                         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
967                 }
968         }
969         else
970         {
971                 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerAssocRspAction() sanity check fail\n"));
972         }
973 }
974
975 /*
976         ==========================================================================
977         Description:
978                 peer sends reassoc rsp
979         Parametrs:
980                 Elem - MLME message cntaining the received frame
981
982         IRQL = DISPATCH_LEVEL
983
984         ==========================================================================
985  */
986 VOID PeerReassocRspAction(
987         IN PRTMP_ADAPTER pAd,
988         IN MLME_QUEUE_ELEM *Elem)
989 {
990         USHORT      CapabilityInfo;
991         USHORT      Status;
992         USHORT      Aid;
993         UCHAR       SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
994         UCHAR       ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
995         UCHAR       Addr2[MAC_ADDR_LEN];
996         UCHAR       CkipFlag;
997         BOOLEAN     TimerCancelled;
998         EDCA_PARM   EdcaParm;
999         HT_CAPABILITY_IE                HtCapability;
1000         ADD_HT_INFO_IE          AddHtInfo;      // AP might use this additional ht info IE
1001         UCHAR                   HtCapabilityLen;
1002         UCHAR                   AddHtInfoLen;
1003         UCHAR                   NewExtChannelOffset = 0xff;
1004
1005         if(PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
1006                                                                 &HtCapability,  &AddHtInfo, &HtCapabilityLen, &AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
1007         {
1008                 if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid)) // The frame is for me ?
1009                 {
1010                         DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - receive REASSOC_RSP to me (status=%d)\n", Status));
1011                         RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
1012
1013                         if(Status == MLME_SUCCESS)
1014                         {
1015                                 // go to procedure listed on page 376
1016                                 AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
1017                                          &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
1018
1019 #ifdef WPA_SUPPLICANT_SUPPORT
1020 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1021                 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1022                 {
1023                     union iwreq_data    wrqu;
1024
1025                     SendAssocIEsToWpaSupplicant(pAd);
1026                     memset(&wrqu, 0, sizeof(wrqu));
1027                     wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
1028                     wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1029                 }
1030 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1031 #endif // WPA_SUPPLICANT_SUPPORT //
1032
1033 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1034                 {
1035                     union iwreq_data    wrqu;
1036                     wext_notify_event_assoc(pAd);
1037
1038                     memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1039                     memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
1040                     wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1041
1042                 }
1043 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1044
1045                         }
1046
1047                         {
1048                                 // CkipFlag is no use for reassociate
1049                                 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1050                                 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
1051                         }
1052                 }
1053         }
1054         else
1055         {
1056                 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerReassocRspAction() sanity check fail\n"));
1057         }
1058
1059 }
1060
1061 /*
1062         ==========================================================================
1063         Description:
1064                 procedures on IEEE 802.11/1999 p.376
1065         Parametrs:
1066
1067         IRQL = DISPATCH_LEVEL
1068
1069         ==========================================================================
1070  */
1071 VOID AssocPostProc(
1072         IN PRTMP_ADAPTER pAd,
1073         IN PUCHAR pAddr2,
1074         IN USHORT CapabilityInfo,
1075         IN USHORT Aid,
1076         IN UCHAR SupRate[],
1077         IN UCHAR SupRateLen,
1078         IN UCHAR ExtRate[],
1079         IN UCHAR ExtRateLen,
1080         IN PEDCA_PARM pEdcaParm,
1081         IN HT_CAPABILITY_IE             *pHtCapability,
1082         IN UCHAR HtCapabilityLen,
1083         IN ADD_HT_INFO_IE               *pAddHtInfo)    // AP might use this additional ht info IE
1084 {
1085         ULONG Idx;
1086
1087         pAd->MlmeAux.BssType = BSS_INFRA;
1088         COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pAddr2);
1089         pAd->MlmeAux.Aid = Aid;
1090         pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
1091 #ifdef DOT11_N_SUPPORT
1092         // Some HT AP might lost WMM IE. We add WMM ourselves. beacuase HT requires QoS on.
1093         if ((HtCapabilityLen > 0) && (pEdcaParm->bValid == FALSE))
1094         {
1095                 pEdcaParm->bValid = TRUE;
1096                 pEdcaParm->Aifsn[0] = 3;
1097                 pEdcaParm->Aifsn[1] = 7;
1098                 pEdcaParm->Aifsn[2] = 2;
1099                 pEdcaParm->Aifsn[3] = 2;
1100
1101                 pEdcaParm->Cwmin[0] = 4;
1102                 pEdcaParm->Cwmin[1] = 4;
1103                 pEdcaParm->Cwmin[2] = 3;
1104                 pEdcaParm->Cwmin[3] = 2;
1105
1106                 pEdcaParm->Cwmax[0] = 10;
1107                 pEdcaParm->Cwmax[1] = 10;
1108                 pEdcaParm->Cwmax[2] = 4;
1109                 pEdcaParm->Cwmax[3] = 3;
1110
1111                 pEdcaParm->Txop[0]  = 0;
1112                 pEdcaParm->Txop[1]  = 0;
1113                 pEdcaParm->Txop[2]  = 96;
1114                 pEdcaParm->Txop[3]  = 48;
1115
1116         }
1117 #endif // DOT11_N_SUPPORT //
1118
1119         NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
1120
1121         // filter out un-supported rates
1122         pAd->MlmeAux.SupRateLen = SupRateLen;
1123         NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
1124         RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
1125
1126         // filter out un-supported rates
1127         pAd->MlmeAux.ExtRateLen = ExtRateLen;
1128         NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
1129         RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
1130
1131 #ifdef DOT11_N_SUPPORT
1132         if (HtCapabilityLen > 0)
1133         {
1134                 RTMPCheckHt(pAd, BSSID_WCID, pHtCapability, pAddHtInfo);
1135         }
1136         DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===>  AP.AMsduSize = %d. ClientStatusFlags = 0x%lx \n", pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1137
1138         DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===>    (Mmps=%d, AmsduSize=%d, )\n",
1139                 pAd->MacTab.Content[BSSID_WCID].MmpsMode, pAd->MacTab.Content[BSSID_WCID].AMsduSize));
1140 #endif // DOT11_N_SUPPORT //
1141
1142         // Set New WPA information
1143         Idx = BssTableSearch(&pAd->ScanTab, pAddr2, pAd->MlmeAux.Channel);
1144         if (Idx == BSS_NOT_FOUND)
1145         {
1146                 DBGPRINT_ERR(("ASSOC - Can't find BSS after receiving Assoc response\n"));
1147         }
1148         else
1149         {
1150                 // Init variable
1151                 pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = 0;
1152                 NdisZeroMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, MAX_LEN_OF_RSNIE);
1153
1154                 // Store appropriate RSN_IE for WPA SM negotiation later
1155                 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAd->ScanTab.BssEntry[Idx].VarIELen != 0))
1156                 {
1157                         PUCHAR              pVIE;
1158                         USHORT              len;
1159                         PEID_STRUCT         pEid;
1160
1161                         pVIE = pAd->ScanTab.BssEntry[Idx].VarIEs;
1162                         len      = pAd->ScanTab.BssEntry[Idx].VarIELen;
1163
1164                         while (len > 0)
1165                         {
1166                                 pEid = (PEID_STRUCT) pVIE;
1167                                 // For WPA/WPAPSK
1168                                 if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
1169                                         && (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1170                                 {
1171                                         NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
1172                                         pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
1173                                         DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA SM negotiation \n"));
1174                                 }
1175                                 // For WPA2/WPA2PSK
1176                                 else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
1177                                         && (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1178                                 {
1179                                         NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
1180                                         pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
1181                                         DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA2 SM negotiation \n"));
1182                                 }
1183
1184                                 pVIE += (pEid->Len + 2);
1185                                 len  -= (pEid->Len + 2);
1186                         }
1187                 }
1188
1189                 if (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == 0)
1190                 {
1191                         DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> no RSN_IE \n"));
1192                 }
1193                 else
1194                 {
1195                         hex_dump("RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
1196                 }
1197         }
1198 }
1199
1200 /*
1201         ==========================================================================
1202         Description:
1203                 left part of IEEE 802.11/1999 p.374
1204         Parameters:
1205                 Elem - MLME message containing the received frame
1206
1207         IRQL = DISPATCH_LEVEL
1208
1209         ==========================================================================
1210  */
1211 VOID PeerDisassocAction(
1212         IN PRTMP_ADAPTER pAd,
1213         IN MLME_QUEUE_ELEM *Elem)
1214 {
1215         UCHAR         Addr2[MAC_ADDR_LEN];
1216         USHORT        Reason;
1217
1218         DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction()\n"));
1219         if(PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
1220         {
1221                 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() Reason = %d\n", Reason));
1222                 if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, Addr2))
1223                 {
1224
1225                         if (pAd->CommonCfg.bWirelessEvent)
1226                         {
1227                                 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1228                         }
1229
1230                         //
1231                         // Get Current System time and Turn on AdjacentAPReport
1232                         //
1233                         NdisGetSystemUpTime(&pAd->StaCfg.CCXAdjacentAPLinkDownTime);
1234                         pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
1235                         LinkDown(pAd, TRUE);
1236                         pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1237
1238 #ifdef WPA_SUPPLICANT_SUPPORT
1239 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1240             if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1241                         {
1242                 union iwreq_data    wrqu;
1243                 //send disassociate event to wpa_supplicant
1244                 memset(&wrqu, 0, sizeof(wrqu));
1245                 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
1246                 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1247             }
1248 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1249 #endif // WPA_SUPPLICANT_SUPPORT //
1250
1251 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1252             {
1253                 union iwreq_data    wrqu;
1254                 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1255                 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1256             }
1257 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1258                 }
1259         }
1260         else
1261         {
1262                 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() sanity check fail\n"));
1263         }
1264
1265 }
1266
1267 /*
1268         ==========================================================================
1269         Description:
1270                 what the state machine will do after assoc timeout
1271         Parameters:
1272                 Elme -
1273
1274         IRQL = DISPATCH_LEVEL
1275
1276         ==========================================================================
1277  */
1278 VOID AssocTimeoutAction(
1279         IN PRTMP_ADAPTER pAd,
1280         IN MLME_QUEUE_ELEM *Elem)
1281 {
1282         USHORT  Status;
1283         DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - AssocTimeoutAction\n"));
1284         pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1285         Status = MLME_REJ_TIMEOUT;
1286         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
1287 }
1288
1289 /*
1290         ==========================================================================
1291         Description:
1292                 what the state machine will do after reassoc timeout
1293
1294         IRQL = DISPATCH_LEVEL
1295
1296         ==========================================================================
1297  */
1298 VOID ReassocTimeoutAction(
1299         IN PRTMP_ADAPTER pAd,
1300         IN MLME_QUEUE_ELEM *Elem)
1301 {
1302         USHORT  Status;
1303         DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - ReassocTimeoutAction\n"));
1304         pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1305         Status = MLME_REJ_TIMEOUT;
1306         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
1307 }
1308
1309 /*
1310         ==========================================================================
1311         Description:
1312                 what the state machine will do after disassoc timeout
1313
1314         IRQL = DISPATCH_LEVEL
1315
1316         ==========================================================================
1317  */
1318 VOID DisassocTimeoutAction(
1319         IN PRTMP_ADAPTER pAd,
1320         IN MLME_QUEUE_ELEM *Elem)
1321 {
1322         USHORT  Status;
1323         DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - DisassocTimeoutAction\n"));
1324         pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1325         Status = MLME_SUCCESS;
1326         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
1327 }
1328
1329 VOID InvalidStateWhenAssoc(
1330         IN PRTMP_ADAPTER pAd,
1331         IN MLME_QUEUE_ELEM *Elem)
1332 {
1333         USHORT  Status;
1334         DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenAssoc(state=%ld), reset ASSOC state machine\n",
1335                 pAd->Mlme.AssocMachine.CurrState));
1336         pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1337         Status = MLME_STATE_MACHINE_REJECT;
1338         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
1339 }
1340
1341 VOID InvalidStateWhenReassoc(
1342         IN PRTMP_ADAPTER pAd,
1343         IN MLME_QUEUE_ELEM *Elem)
1344 {
1345         USHORT Status;
1346         DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenReassoc(state=%ld), reset ASSOC state machine\n",
1347                 pAd->Mlme.AssocMachine.CurrState));
1348         pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1349         Status = MLME_STATE_MACHINE_REJECT;
1350         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
1351 }
1352
1353 VOID InvalidStateWhenDisassociate(
1354         IN PRTMP_ADAPTER pAd,
1355         IN MLME_QUEUE_ELEM *Elem)
1356 {
1357         USHORT Status;
1358         DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenDisassoc(state=%ld), reset ASSOC state machine\n",
1359                 pAd->Mlme.AssocMachine.CurrState));
1360         pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1361         Status = MLME_STATE_MACHINE_REJECT;
1362         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
1363 }
1364
1365 /*
1366         ==========================================================================
1367         Description:
1368                 right part of IEEE 802.11/1999 page 374
1369         Note:
1370                 This event should never cause ASSOC state machine perform state
1371                 transition, and has no relationship with CNTL machine. So we separate
1372                 this routine as a service outside of ASSOC state transition table.
1373
1374         IRQL = DISPATCH_LEVEL
1375
1376         ==========================================================================
1377  */
1378 VOID Cls3errAction(
1379         IN PRTMP_ADAPTER pAd,
1380         IN PUCHAR        pAddr)
1381 {
1382         HEADER_802_11         DisassocHdr;
1383         PHEADER_802_11        pDisassocHdr;
1384         PUCHAR                pOutBuffer = NULL;
1385         ULONG                 FrameLen = 0;
1386         NDIS_STATUS           NStatus;
1387         USHORT                Reason = REASON_CLS3ERR;
1388
1389         NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
1390         if (NStatus != NDIS_STATUS_SUCCESS)
1391                 return;
1392
1393         DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Class 3 Error, Send DISASSOC frame\n"));
1394         MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAddr, pAd->CommonCfg.Bssid);  // patch peap ttls switching issue
1395         MakeOutgoingFrame(pOutBuffer,           &FrameLen,
1396                                           sizeof(HEADER_802_11),&DisassocHdr,
1397                                           2,                    &Reason,
1398                                           END_OF_ARGS);
1399         MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1400
1401         // To patch Instance and Buffalo(N) AP
1402         // Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
1403         // Therefore, we send both of them.
1404         pDisassocHdr = (PHEADER_802_11)pOutBuffer;
1405         pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
1406         MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1407
1408         MlmeFreeMemory(pAd, pOutBuffer);
1409
1410         pAd->StaCfg.DisassocReason = REASON_CLS3ERR;
1411         COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pAddr);
1412 }
1413
1414  /*
1415          ==========================================================================
1416          Description:
1417                  Switch between WEP and CKIP upon new association up.
1418          Parameters:
1419
1420          IRQL = DISPATCH_LEVEL
1421
1422          ==========================================================================
1423   */
1424 VOID SwitchBetweenWepAndCkip(
1425         IN PRTMP_ADAPTER pAd)
1426 {
1427         int            i;
1428         SHAREDKEY_MODE_STRUC  csr1;
1429
1430         // if KP is required. change the CipherAlg in hardware shard key table from WEP
1431         // to CKIP. else remain as WEP
1432         if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10))
1433         {
1434                 // modify hardware key table so that MAC use correct algorithm to decrypt RX
1435                 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
1436                 if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP64)
1437                         csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP64;
1438                 else if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP128)
1439                         csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP128;
1440
1441                 if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP64)
1442                         csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP64;
1443                 else if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP128)
1444                         csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP128;
1445
1446                 if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP64)
1447                         csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP64;
1448                 else if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP128)
1449                         csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP128;
1450
1451                 if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP64)
1452                         csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP64;
1453                 else if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP128)
1454                         csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP128;
1455                 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
1456                 DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
1457
1458                 // modify software key table so that driver can specify correct algorithm in TXD upon TX
1459                 for (i=0; i<SHARE_KEY_NUM; i++)
1460                 {
1461                         if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP64)
1462                                 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP64;
1463                         else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP128)
1464                                 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP128;
1465                 }
1466         }
1467
1468         // else if KP NOT inused. change the CipherAlg in hardware shard key table from CKIP
1469         // to WEP.
1470         else
1471         {
1472                 // modify hardware key table so that MAC use correct algorithm to decrypt RX
1473                 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
1474                 if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP64)
1475                         csr1.field.Bss0Key0CipherAlg = CIPHER_WEP64;
1476                 else if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP128)
1477                         csr1.field.Bss0Key0CipherAlg = CIPHER_WEP128;
1478
1479                 if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP64)
1480                         csr1.field.Bss0Key1CipherAlg = CIPHER_WEP64;
1481                 else if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP128)
1482                         csr1.field.Bss0Key1CipherAlg = CIPHER_WEP128;
1483
1484                 if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP64)
1485                         csr1.field.Bss0Key2CipherAlg = CIPHER_WEP64;
1486                 else if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP128)
1487                         csr1.field.Bss0Key2CipherAlg = CIPHER_WEP128;
1488
1489                 if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP64)
1490                         csr1.field.Bss0Key3CipherAlg = CIPHER_WEP64;
1491                 else if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP128)
1492                         csr1.field.Bss0Key3CipherAlg = CIPHER_WEP128;
1493
1494                 // modify software key table so that driver can specify correct algorithm in TXD upon TX
1495                 for (i=0; i<SHARE_KEY_NUM; i++)
1496                 {
1497                         if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP64)
1498                                 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP64;
1499                         else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP128)
1500                                 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP128;
1501                 }
1502
1503                 //
1504                 // On WPA-NONE, must update CipherAlg.
1505                 // Because the OID_802_11_WEP_STATUS was been set after OID_802_11_ADD_KEY
1506                 // and CipherAlg will be CIPHER_NONE by Windows ZeroConfig.
1507                 // So we need to update CipherAlg after connect.
1508                 //
1509                 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1510                 {
1511                         for (i = 0; i < SHARE_KEY_NUM; i++)
1512                         {
1513                                 if (pAd->SharedKey[BSS0][i].KeyLen != 0)
1514                                 {
1515                                         if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
1516                                         {
1517                                                 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_TKIP;
1518                                         }
1519                                         else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1520                                         {
1521                                                 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_AES;
1522                                         }
1523                                 }
1524                                 else
1525                                 {
1526                                         pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
1527                                 }
1528                         }
1529
1530                         csr1.field.Bss0Key0CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
1531                         csr1.field.Bss0Key1CipherAlg = pAd->SharedKey[BSS0][1].CipherAlg;
1532                         csr1.field.Bss0Key2CipherAlg = pAd->SharedKey[BSS0][2].CipherAlg;
1533                         csr1.field.Bss0Key3CipherAlg = pAd->SharedKey[BSS0][3].CipherAlg;
1534                 }
1535                 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
1536                 DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
1537         }
1538 }
1539
1540 #ifdef WPA_SUPPLICANT_SUPPORT
1541 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1542 VOID    SendAssocIEsToWpaSupplicant(
1543     IN  PRTMP_ADAPTER pAd)
1544 {
1545     union iwreq_data    wrqu;
1546     unsigned char custom[IW_CUSTOM_MAX] = {0};
1547
1548     if ((pAd->StaCfg.ReqVarIELen + 17) <= IW_CUSTOM_MAX)
1549     {
1550         sprintf(custom, "ASSOCINFO_ReqIEs=");
1551             NdisMoveMemory(custom+17, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
1552             memset(&wrqu, 0, sizeof(wrqu));
1553         wrqu.data.length = pAd->StaCfg.ReqVarIELen + 17;
1554         wrqu.data.flags = RT_REQIE_EVENT_FLAG;
1555         wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
1556
1557         memset(&wrqu, 0, sizeof(wrqu));
1558         wrqu.data.flags = RT_ASSOCINFO_EVENT_FLAG;
1559         wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1560     }
1561     else
1562         DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen + 17 > MAX_CUSTOM_LEN\n"));
1563
1564     return;
1565 }
1566 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1567 #endif // WPA_SUPPLICANT_SUPPORT //
1568
1569 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1570 int wext_notify_event_assoc(
1571         IN  RTMP_ADAPTER *pAd)
1572 {
1573     union iwreq_data    wrqu;
1574     char custom[IW_CUSTOM_MAX] = {0};
1575
1576 #if WIRELESS_EXT > 17
1577     if (pAd->StaCfg.ReqVarIELen <= IW_CUSTOM_MAX)
1578     {
1579         wrqu.data.length = pAd->StaCfg.ReqVarIELen;
1580         memcpy(custom, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
1581         wireless_send_event(pAd->net_dev, IWEVASSOCREQIE, &wrqu, custom);
1582     }
1583     else
1584         DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen > MAX_CUSTOM_LEN\n"));
1585 #else
1586     if (((pAd->StaCfg.ReqVarIELen*2) + 17) <= IW_CUSTOM_MAX)
1587     {
1588         UCHAR   idx;
1589         wrqu.data.length = (pAd->StaCfg.ReqVarIELen*2) + 17;
1590         sprintf(custom, "ASSOCINFO(ReqIEs=");
1591         for (idx=0; idx<pAd->StaCfg.ReqVarIELen; idx++)
1592                 sprintf(custom, "%s%02x", custom, pAd->StaCfg.ReqVarIEs[idx]);
1593         wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
1594     }
1595     else
1596         DBGPRINT(RT_DEBUG_TRACE, ("(pAd->StaCfg.ReqVarIELen*2) + 17 > MAX_CUSTOM_LEN\n"));
1597 #endif
1598
1599         return 0;
1600
1601 }
1602 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1603
1604
1605 BOOLEAN StaAddMacTableEntry(
1606         IN  PRTMP_ADAPTER               pAd,
1607         IN  PMAC_TABLE_ENTRY    pEntry,
1608         IN  UCHAR                               MaxSupportedRateIn500Kbps,
1609         IN  HT_CAPABILITY_IE    *pHtCapability,
1610         IN  UCHAR                               HtCapabilityLen,
1611         IN  USHORT                      CapabilityInfo)
1612 {
1613         UCHAR            MaxSupportedRate = RATE_11;
1614
1615         if (ADHOC_ON(pAd))
1616                 CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
1617
1618         switch (MaxSupportedRateIn500Kbps)
1619     {
1620         case 108: MaxSupportedRate = RATE_54;   break;
1621         case 96:  MaxSupportedRate = RATE_48;   break;
1622         case 72:  MaxSupportedRate = RATE_36;   break;
1623         case 48:  MaxSupportedRate = RATE_24;   break;
1624         case 36:  MaxSupportedRate = RATE_18;   break;
1625         case 24:  MaxSupportedRate = RATE_12;   break;
1626         case 18:  MaxSupportedRate = RATE_9;    break;
1627         case 12:  MaxSupportedRate = RATE_6;    break;
1628         case 22:  MaxSupportedRate = RATE_11;   break;
1629         case 11:  MaxSupportedRate = RATE_5_5;  break;
1630         case 4:   MaxSupportedRate = RATE_2;    break;
1631         case 2:   MaxSupportedRate = RATE_1;    break;
1632         default:  MaxSupportedRate = RATE_11;   break;
1633     }
1634
1635     if ((pAd->CommonCfg.PhyMode == PHY_11G) && (MaxSupportedRate < RATE_FIRST_OFDM_RATE))
1636         return FALSE;
1637
1638 #ifdef DOT11_N_SUPPORT
1639         // 11n only
1640         if (((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G))&& (HtCapabilityLen == 0))
1641                 return FALSE;
1642 #endif // DOT11_N_SUPPORT //
1643
1644         if (!pEntry)
1645         return FALSE;
1646
1647         NdisAcquireSpinLock(&pAd->MacTabLock);
1648         if (pEntry)
1649         {
1650                 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1651                 if ((MaxSupportedRate < RATE_FIRST_OFDM_RATE) ||
1652                         (pAd->CommonCfg.PhyMode == PHY_11B))
1653                 {
1654                         pEntry->RateLen = 4;
1655                         if (MaxSupportedRate >= RATE_FIRST_OFDM_RATE)
1656                                 MaxSupportedRate = RATE_11;
1657                 }
1658                 else
1659                         pEntry->RateLen = 12;
1660
1661                 pEntry->MaxHTPhyMode.word = 0;
1662                 pEntry->MinHTPhyMode.word = 0;
1663                 pEntry->HTPhyMode.word = 0;
1664                 pEntry->MaxSupportedRate = MaxSupportedRate;
1665                 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
1666                 {
1667                         pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
1668                         pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
1669                         pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
1670                         pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
1671                         pEntry->HTPhyMode.field.MODE = MODE_CCK;
1672                         pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
1673                 }
1674                 else
1675                 {
1676                         pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
1677                         pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
1678                         pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
1679                         pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
1680                         pEntry->HTPhyMode.field.MODE = MODE_OFDM;
1681                         pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
1682                 }
1683                 pEntry->CapabilityInfo = CapabilityInfo;
1684                 CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
1685                 CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
1686         }
1687
1688 #ifdef DOT11_N_SUPPORT
1689         // If this Entry supports 802.11n, upgrade to HT rate.
1690         if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
1691         {
1692                 UCHAR   j, bitmask; //k,bitmask;
1693                 CHAR    i;
1694
1695                 if (ADHOC_ON(pAd))
1696                         CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
1697                 if ((pHtCapability->HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
1698                 {
1699                         pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
1700                 }
1701                 else
1702                 {
1703                         pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
1704                         pAd->MacTab.fAnyStationNonGF = TRUE;
1705                         pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
1706                 }
1707
1708                 if ((pHtCapability->HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
1709                 {
1710                         pEntry->MaxHTPhyMode.field.BW= BW_40;
1711                         pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(pHtCapability->HtCapInfo.ShortGIfor40));
1712                 }
1713                 else
1714                 {
1715                         pEntry->MaxHTPhyMode.field.BW = BW_20;
1716                         pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(pHtCapability->HtCapInfo.ShortGIfor20));
1717                         pAd->MacTab.fAnyStation20Only = TRUE;
1718                 }
1719
1720                 // 3*3
1721                 if (pAd->MACVersion >= RALINK_2883_VERSION && pAd->MACVersion < RALINK_3070_VERSION)
1722                         pEntry->MaxHTPhyMode.field.TxBF = pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1723
1724                 // find max fixed rate
1725                 for (i=23; i>=0; i--) // 3*3
1726                 {
1727                         j = i/8;
1728                         bitmask = (1<<(i-(j*8)));
1729                         if ((pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j] & bitmask) && (pHtCapability->MCSSet[j] & bitmask))
1730                         {
1731                                 pEntry->MaxHTPhyMode.field.MCS = i;
1732                                 break;
1733                         }
1734                         if (i==0)
1735                                 break;
1736                 }
1737
1738
1739                 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
1740                 {
1741                         if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
1742                         {
1743                                 // Fix MCS as HT Duplicated Mode
1744                                 pEntry->MaxHTPhyMode.field.BW = 1;
1745                                 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
1746                                 pEntry->MaxHTPhyMode.field.STBC = 0;
1747                                 pEntry->MaxHTPhyMode.field.ShortGI = 0;
1748                                 pEntry->MaxHTPhyMode.field.MCS = 32;
1749                         }
1750                         else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
1751                         {
1752                                 // STA supports fixed MCS
1753                                 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1754                         }
1755                 }
1756
1757                 pEntry->MaxHTPhyMode.field.STBC = (pHtCapability->HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
1758                 pEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity;
1759                 pEntry->MaxRAmpduFactor = pHtCapability->HtCapParm.MaxRAmpduFactor;
1760                 pEntry->MmpsMode = (UCHAR)pHtCapability->HtCapInfo.MimoPs;
1761                 pEntry->AMsduSize = (UCHAR)pHtCapability->HtCapInfo.AMsduSize;
1762                 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
1763
1764                 if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE))
1765                         CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED);
1766                 if (pHtCapability->HtCapInfo.ShortGIfor20)
1767                         CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
1768                 if (pHtCapability->HtCapInfo.ShortGIfor40)
1769                         CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
1770                 if (pHtCapability->HtCapInfo.TxSTBC)
1771                         CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
1772                 if (pHtCapability->HtCapInfo.RxSTBC)
1773                         CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
1774                 if (pHtCapability->ExtHtCapInfo.PlusHTC)
1775                         CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
1776                 if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
1777                         CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
1778                 if (pHtCapability->ExtHtCapInfo.MCSFeedback == 0x03)
1779                         CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
1780         }
1781         else
1782         {
1783                 pAd->MacTab.fAnyStationIsLegacy = TRUE;
1784         }
1785
1786         NdisMoveMemory(&pEntry->HTCapability, pHtCapability, sizeof(HT_CAPABILITY_IE));
1787 #endif // DOT11_N_SUPPORT //
1788
1789         pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
1790         pEntry->CurrTxRate = pEntry->MaxSupportedRate;
1791
1792         // Set asic auto fall back
1793         if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
1794         {
1795                 PUCHAR                                  pTable;
1796                 UCHAR                                   TableSize = 0;
1797
1798                 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
1799                 pEntry->bAutoTxRateSwitch = TRUE;
1800         }
1801         else
1802         {
1803                 pEntry->HTPhyMode.field.MODE    = pAd->StaCfg.HTPhyMode.field.MODE;
1804                 pEntry->HTPhyMode.field.MCS     = pAd->StaCfg.HTPhyMode.field.MCS;
1805                 pEntry->bAutoTxRateSwitch = FALSE;
1806
1807                 // If the legacy mode is set, overwrite the transmit setting of this entry.
1808                 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1809         }
1810
1811         pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1812         pEntry->Sst = SST_ASSOC;
1813         pEntry->AuthState = AS_AUTH_OPEN;
1814         pEntry->AuthMode = pAd->StaCfg.AuthMode;
1815         pEntry->WepStatus = pAd->StaCfg.WepStatus;
1816
1817         NdisReleaseSpinLock(&pAd->MacTabLock);
1818
1819 #ifdef WPA_SUPPLICANT_SUPPORT
1820 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1821     if (pAd->StaCfg.WpaSupplicantUP)
1822     {
1823         union iwreq_data    wrqu;
1824
1825         SendAssocIEsToWpaSupplicant(pAd);
1826         memset(&wrqu, 0, sizeof(wrqu));
1827         wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
1828         wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1829     }
1830 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1831 #endif // WPA_SUPPLICANT_SUPPORT //
1832
1833 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1834     {
1835         union iwreq_data    wrqu;
1836         wext_notify_event_assoc(pAd);
1837
1838         memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1839         memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
1840         wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1841
1842     }
1843 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1844         return TRUE;
1845 }
1846
1847