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