Staging: rt2860: remove DOT11_N_SUPPORT ifdefs
[linux-2.6] / drivers / staging / rt2860 / sta / connect.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         connect.c
29
30         Abstract:
31
32         Revision History:
33         Who                     When                    What
34         --------        ----------              ----------------------------------------------
35         John                    2004-08-08                      Major modification from RT2560
36 */
37 #include "../rt_config.h"
38
39 UCHAR   CipherSuiteWpaNoneTkip[] = {
40                 0x00, 0x50, 0xf2, 0x01, // oui
41                 0x01, 0x00,                             // Version
42                 0x00, 0x50, 0xf2, 0x02, // Multicast
43                 0x01, 0x00,                             // Number of unicast
44                 0x00, 0x50, 0xf2, 0x02, // unicast
45                 0x01, 0x00,                             // number of authentication method
46                 0x00, 0x50, 0xf2, 0x00  // authentication
47                 };
48 UCHAR   CipherSuiteWpaNoneTkipLen = (sizeof(CipherSuiteWpaNoneTkip) / sizeof(UCHAR));
49
50 UCHAR   CipherSuiteWpaNoneAes[] = {
51                 0x00, 0x50, 0xf2, 0x01, // oui
52                 0x01, 0x00,                             // Version
53                 0x00, 0x50, 0xf2, 0x04, // Multicast
54                 0x01, 0x00,                             // Number of unicast
55                 0x00, 0x50, 0xf2, 0x04, // unicast
56                 0x01, 0x00,                             // number of authentication method
57                 0x00, 0x50, 0xf2, 0x00  // authentication
58                 };
59 UCHAR   CipherSuiteWpaNoneAesLen = (sizeof(CipherSuiteWpaNoneAes) / sizeof(UCHAR));
60
61 // The following MACRO is called after 1. starting an new IBSS, 2. succesfully JOIN an IBSS,
62 // or 3. succesfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS
63 // All settings successfuly negotiated furing MLME state machines become final settings
64 // and are copied to pAd->StaActive
65 #define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd)                                 \
66 {                                                                                       \
67         (_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen;                                \
68         NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \
69         COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid);                      \
70         (_pAd)->CommonCfg.Channel = (_pAd)->MlmeAux.Channel;                                \
71         (_pAd)->CommonCfg.CentralChannel = (_pAd)->MlmeAux.CentralChannel;                  \
72         (_pAd)->StaActive.Aid = (_pAd)->MlmeAux.Aid;                                        \
73         (_pAd)->StaActive.AtimWin = (_pAd)->MlmeAux.AtimWin;                                \
74         (_pAd)->StaActive.CapabilityInfo = (_pAd)->MlmeAux.CapabilityInfo;                  \
75         (_pAd)->CommonCfg.BeaconPeriod = (_pAd)->MlmeAux.BeaconPeriod;                      \
76         (_pAd)->StaActive.CfpMaxDuration = (_pAd)->MlmeAux.CfpMaxDuration;                  \
77         (_pAd)->StaActive.CfpPeriod = (_pAd)->MlmeAux.CfpPeriod;                            \
78         (_pAd)->StaActive.SupRateLen = (_pAd)->MlmeAux.SupRateLen;                          \
79         NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\
80         (_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen;                          \
81         NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\
82         NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));\
83         NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));\
84         NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));\
85         COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid);      \
86         (_pAd)->MacTab.Content[BSSID_WCID].Aid = (_pAd)->MlmeAux.Aid;                       \
87         (_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\
88         COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.BssId, (_pAd)->MlmeAux.Bssid);\
89         (_pAd)->MacTab.Content[BSSID_WCID].RateLen = (_pAd)->StaActive.SupRateLen + (_pAd)->StaActive.ExtRateLen;\
90 }
91
92 /*
93         ==========================================================================
94         Description:
95
96         IRQL = PASSIVE_LEVEL
97
98         ==========================================================================
99 */
100 VOID MlmeCntlInit(
101         IN PRTMP_ADAPTER pAd,
102         IN STATE_MACHINE *S,
103         OUT STATE_MACHINE_FUNC Trans[])
104 {
105         // Control state machine differs from other state machines, the interface
106         // follows the standard interface
107         pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
108 }
109
110 /*
111         ==========================================================================
112         Description:
113
114         IRQL = DISPATCH_LEVEL
115
116         ==========================================================================
117 */
118 VOID MlmeCntlMachinePerformAction(
119         IN PRTMP_ADAPTER pAd,
120         IN STATE_MACHINE *S,
121         IN MLME_QUEUE_ELEM *Elem)
122 {
123         switch(pAd->Mlme.CntlMachine.CurrState)
124         {
125                 case CNTL_IDLE:
126                         {
127                                 CntlIdleProc(pAd, Elem);
128                         }
129                         break;
130                 case CNTL_WAIT_DISASSOC:
131                         CntlWaitDisassocProc(pAd, Elem);
132                         break;
133                 case CNTL_WAIT_JOIN:
134                         CntlWaitJoinProc(pAd, Elem);
135                         break;
136
137                 // CNTL_WAIT_REASSOC is the only state in CNTL machine that does
138                 // not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)".
139                 // Therefore not protected by NDIS's "only one outstanding OID request"
140                 // rule. Which means NDIS may SET OID in the middle of ROAMing attempts.
141                 // Current approach is to block new SET request at RTMPSetInformation()
142                 // when CntlMachine.CurrState is not CNTL_IDLE
143                 case CNTL_WAIT_REASSOC:
144                         CntlWaitReassocProc(pAd, Elem);
145                         break;
146
147                 case CNTL_WAIT_START:
148                         CntlWaitStartProc(pAd, Elem);
149                         break;
150                 case CNTL_WAIT_AUTH:
151                         CntlWaitAuthProc(pAd, Elem);
152                         break;
153                 case CNTL_WAIT_AUTH2:
154                         CntlWaitAuthProc2(pAd, Elem);
155                         break;
156                 case CNTL_WAIT_ASSOC:
157                         CntlWaitAssocProc(pAd, Elem);
158                         break;
159
160                 case CNTL_WAIT_OID_LIST_SCAN:
161                         if(Elem->MsgType == MT2_SCAN_CONF)
162                         {
163                                 // Resume TxRing after SCANING complete. We hope the out-of-service time
164                                 // won't be too long to let upper layer time-out the waiting frames
165                                 RTMPResumeMsduTransmission(pAd);
166                                 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
167                                 {
168                                         // Cisco scan request is finished, prepare beacon report
169                                         MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
170                                 }
171                                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
172
173                 //
174                                 // Set LED status to previous status.
175                                 //
176                                 if (pAd->bLedOnScanning)
177                                 {
178                                         pAd->bLedOnScanning = FALSE;
179                                         RTMPSetLED(pAd, pAd->LedStatus);
180                                 }
181                         }
182                         break;
183
184                 case CNTL_WAIT_OID_DISASSOC:
185                         if (Elem->MsgType == MT2_DISASSOC_CONF)
186                         {
187                                 LinkDown(pAd, FALSE);
188                                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
189                         }
190                         break;
191                 default:
192                         DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
193                         break;
194         }
195 }
196
197
198 /*
199         ==========================================================================
200         Description:
201
202         IRQL = DISPATCH_LEVEL
203
204         ==========================================================================
205 */
206 VOID CntlIdleProc(
207         IN PRTMP_ADAPTER pAd,
208         IN MLME_QUEUE_ELEM *Elem)
209 {
210         MLME_DISASSOC_REQ_STRUCT   DisassocReq;
211
212         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
213                 return;
214
215         switch(Elem->MsgType)
216         {
217                 case OID_802_11_SSID:
218                         CntlOidSsidProc(pAd, Elem);
219                         break;
220
221                 case OID_802_11_BSSID:
222                         CntlOidRTBssidProc(pAd,Elem);
223                         break;
224
225                 case OID_802_11_BSSID_LIST_SCAN:
226                         CntlOidScanProc(pAd,Elem);
227                         break;
228
229                 case OID_802_11_DISASSOCIATE:
230                         DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
231                         MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
232                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
233
234             if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
235             {
236                         // Set the AutoReconnectSsid to prevent it reconnect to old SSID
237                         // Since calling this indicate user don't want to connect to that SSID anymore.
238                         pAd->MlmeAux.AutoReconnectSsidLen= 32;
239                         NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
240             }
241                         break;
242
243                 case MT2_MLME_ROAMING_REQ:
244                         CntlMlmeRoamingProc(pAd, Elem);
245                         break;
246
247         case OID_802_11_MIC_FAILURE_REPORT_FRAME:
248             WpaMicFailureReportFrame(pAd, Elem);
249             break;
250
251                 default:
252                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
253                         break;
254         }
255 }
256
257 VOID CntlOidScanProc(
258         IN PRTMP_ADAPTER pAd,
259         IN MLME_QUEUE_ELEM *Elem)
260 {
261         MLME_SCAN_REQ_STRUCT       ScanReq;
262         ULONG                      BssIdx = BSS_NOT_FOUND;
263         BSS_ENTRY                  CurrBss;
264
265         // record current BSS if network is connected.
266         // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
267         if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
268         {
269                 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
270                 if (BssIdx != BSS_NOT_FOUND)
271                 {
272                         NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
273                 }
274         }
275
276         // clean up previous SCAN result, add current BSS back to table if any
277         BssTableInit(&pAd->ScanTab);
278         if (BssIdx != BSS_NOT_FOUND)
279         {
280                 // DDK Note: If the NIC is associated with a particular BSSID and SSID
281                 //    that are not contained in the list of BSSIDs generated by this scan, the
282                 //    BSSID description of the currently associated BSSID and SSID should be
283                 //    appended to the list of BSSIDs in the NIC's database.
284                 // To ensure this, we append this BSS as the first entry in SCAN result
285                 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
286                 pAd->ScanTab.BssNr = 1;
287         }
288
289         ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
290         MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
291                 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
292         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
293 }
294
295 /*
296         ==========================================================================
297         Description:
298                 Before calling this routine, user desired SSID should already been
299                 recorded in CommonCfg.Ssid[]
300         IRQL = DISPATCH_LEVEL
301
302         ==========================================================================
303 */
304 VOID CntlOidSsidProc(
305         IN PRTMP_ADAPTER pAd,
306         IN MLME_QUEUE_ELEM * Elem)
307 {
308         PNDIS_802_11_SSID          pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
309         MLME_DISASSOC_REQ_STRUCT   DisassocReq;
310         ULONG                                      Now;
311
312         // BBP and RF are not accessible in PS mode, we has to wake them up first
313         if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
314                 AsicForceWakeup(pAd, RTMP_HALT);
315
316         // Step 1. record the desired user settings to MlmeAux
317         NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
318         NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
319         pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
320         NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
321         pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
322
323
324         //
325         // Update Reconnect Ssid, that user desired to connect.
326         //
327         NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
328         NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
329         pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
330
331         // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
332         //    & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
333         BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
334
335         DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
336                         pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
337         NdisGetSystemUpTime(&Now);
338
339         if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
340                 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
341                 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
342                 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
343         {
344                 // Case 1. already connected with an AP who has the desired SSID
345                 //         with highest RSSI
346
347                 // Add checking Mode "LEAP" for CCX 1.0
348                 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
349                          (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
350                          (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
351                          (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
352                          ) &&
353                         (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
354                 {
355                         // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
356                         //          connection process
357                         DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
358                         DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
359                         MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
360                                                 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
361                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
362                 }
363                 else if (pAd->bConfigChanged == TRUE)
364                 {
365                         // case 1.2 Important Config has changed, we have to reconnect to the same AP
366                         DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
367                         DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
368                         MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
369                                                 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
370                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
371                 }
372                 else
373                 {
374                         // case 1.3. already connected to the SSID with highest RSSI.
375                         DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
376                         //
377                         // (HCT 12.1) 1c_wlan_mediaevents required
378                         // media connect events are indicated when associating with the same AP
379                         //
380                         if (INFRA_ON(pAd))
381                         {
382                                 //
383                                 // Since MediaState already is NdisMediaStateConnected
384                                 // We just indicate the connect event again to meet the WHQL required.
385                                 //
386                                 pAd->IndicateMediaState = NdisMediaStateConnected;
387                                 RTMP_IndicateMediaState(pAd);
388                 pAd->ExtraInfo = GENERAL_LINK_UP;   // Update extra information to link is up
389                         }
390
391                         pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
392
393             {
394                 union iwreq_data    wrqu;
395
396                 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
397                 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
398                 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
399
400             }
401                 }
402         }
403         else if (INFRA_ON(pAd))
404         {
405                 //
406                 // For RT61
407                 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
408                 // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
409                 // But media status is connected, so the SSID not report correctly.
410                 //
411                 if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
412                 {
413                         //
414                         // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
415                         //
416                         pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
417                 }
418                 // case 2. active INFRA association existent
419                 //    roaming is done within miniport driver, nothing to do with configuration
420                 //    utility. so upon a new SET(OID_802_11_SSID) is received, we just
421                 //    disassociate with the current associated AP,
422                 //    then perform a new association with this new SSID, no matter the
423                 //    new/old SSID are the same or not.
424                 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
425                 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
426                 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
427                                         sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
428                 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
429         }
430         else
431         {
432                 if (ADHOC_ON(pAd))
433                 {
434                         DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
435                         LinkDown(pAd, FALSE);
436                         OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
437                         pAd->IndicateMediaState = NdisMediaStateDisconnected;
438                         RTMP_IndicateMediaState(pAd);
439             pAd->ExtraInfo = GENERAL_LINK_DOWN;
440                         DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
441                 }
442
443                 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
444                         (pAd->StaCfg.bAutoReconnect == TRUE) &&
445                         (pAd->MlmeAux.BssType == BSS_INFRA) &&
446                         (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
447                         )
448                 {
449                         MLME_SCAN_REQ_STRUCT       ScanReq;
450
451                         DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
452                         ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
453                         MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
454                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
455                         // Reset Missed scan number
456                         pAd->StaCfg.LastScanTime = Now;
457                 }
458                 else
459                 {
460                         pAd->MlmeAux.BssIdx = 0;
461                         IterateOnBssTab(pAd);
462                 }
463         }
464 }
465
466
467 /*
468         ==========================================================================
469         Description:
470
471         IRQL = DISPATCH_LEVEL
472
473         ==========================================================================
474 */
475 VOID CntlOidRTBssidProc(
476         IN PRTMP_ADAPTER pAd,
477         IN MLME_QUEUE_ELEM * Elem)
478 {
479         ULONG       BssIdx;
480         PUCHAR      pOidBssid = (PUCHAR)Elem->Msg;
481         MLME_DISASSOC_REQ_STRUCT    DisassocReq;
482         MLME_JOIN_REQ_STRUCT        JoinReq;
483
484         // record user desired settings
485         COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
486         pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
487
488         //
489         // Update Reconnect Ssid, that user desired to connect.
490         //
491         NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
492         pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
493         NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
494
495         // find the desired BSS in the latest SCAN result table
496         BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
497         if (BssIdx == BSS_NOT_FOUND)
498         {
499                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
500                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
501                 return;
502         }
503
504         // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
505         // Because we need this entry to become the JOIN target in later on SYNC state machine
506         pAd->MlmeAux.BssIdx = 0;
507         pAd->MlmeAux.SsidBssTab.BssNr = 1;
508         NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
509
510         // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
511         //   we just follow normal procedure. The reason of user doing this may because he/she changed
512         //   AP to another channel, but we still received BEACON from it thus don't claim Link Down.
513         //   Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
514         //   checking, we'll disassociate then re-do normal association with this AP at the new channel.
515         // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
516         //   connection when setting the same BSSID.
517         if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
518                 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
519         {
520                 // already connected to the same BSSID, go back to idle state directly
521                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
522                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
523
524             {
525                 union iwreq_data    wrqu;
526
527                 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
528                 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
529                 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
530
531             }
532         }
533         else
534         {
535                 if (INFRA_ON(pAd))
536                 {
537                         // disassoc from current AP first
538                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
539                         DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
540                         MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
541                                                 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
542
543                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
544                 }
545                 else
546                 {
547                         if (ADHOC_ON(pAd))
548                         {
549                                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
550                                 LinkDown(pAd, FALSE);
551                                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
552                                 pAd->IndicateMediaState = NdisMediaStateDisconnected;
553                                 RTMP_IndicateMediaState(pAd);
554                 pAd->ExtraInfo = GENERAL_LINK_DOWN;
555                                 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
556                         }
557
558                         // Change the wepstatus to original wepstatus
559                         pAd->StaCfg.WepStatus   = pAd->StaCfg.OrigWepStatus;
560                         pAd->StaCfg.PairCipher  = pAd->StaCfg.OrigWepStatus;
561                         pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
562
563                         // Check cipher suite, AP must have more secured cipher than station setting
564                         // Set the Pairwise and Group cipher to match the intended AP setting
565                         // We can only connect to AP with less secured cipher setting
566                         if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
567                         {
568                                 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
569
570                                 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
571                                         pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
572                                 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
573                                         pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
574                                 else    // There is no PairCipher Aux, downgrade our capability to TKIP
575                                         pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
576                         }
577                         else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
578                         {
579                                 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
580
581                                 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
582                                         pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
583                                 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
584                                         pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
585                                 else    // There is no PairCipher Aux, downgrade our capability to TKIP
586                                         pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
587
588                                 // RSN capability
589                                 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
590                         }
591
592                         // Set Mix cipher flag
593                         pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
594                         if (pAd->StaCfg.bMixCipher == TRUE)
595                         {
596                                 // If mix cipher, re-build RSNIE
597                                 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
598                         }
599                         // No active association, join the BSS immediately
600                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
601                                 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
602
603                         JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
604                         MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
605
606                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
607                 }
608         }
609 }
610
611 // Roaming is the only external request triggering CNTL state machine
612 // despite of other "SET OID" operation. All "SET OID" related oerations
613 // happen in sequence, because no other SET OID will be sent to this device
614 // until the the previous SET operation is complete (successful o failed).
615 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
616 // or been corrupted by other "SET OID"?
617 //
618 // IRQL = DISPATCH_LEVEL
619 VOID CntlMlmeRoamingProc(
620         IN PRTMP_ADAPTER pAd,
621         IN MLME_QUEUE_ELEM *Elem)
622 {
623         // TODO:
624         // AP in different channel may show lower RSSI than actual value??
625         // should we add a weighting factor to compensate it?
626         DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
627
628         NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
629         pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
630
631         BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
632         pAd->MlmeAux.BssIdx = 0;
633         IterateOnBssTab(pAd);
634 }
635
636 /*
637         ==========================================================================
638         Description:
639
640         IRQL = DISPATCH_LEVEL
641
642         ==========================================================================
643 */
644 VOID CntlWaitDisassocProc(
645         IN PRTMP_ADAPTER pAd,
646         IN MLME_QUEUE_ELEM *Elem)
647 {
648         MLME_START_REQ_STRUCT     StartReq;
649
650         if (Elem->MsgType == MT2_DISASSOC_CONF)
651         {
652                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
653
654             if (pAd->CommonCfg.bWirelessEvent)
655                 {
656                         RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
657                 }
658
659                 LinkDown(pAd, FALSE);
660
661                 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
662                 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
663                 {
664                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
665                         StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
666                         MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
667                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
668                 }
669                 // case 2. try each matched BSS
670                 else
671                 {
672                         pAd->MlmeAux.BssIdx = 0;
673
674                         IterateOnBssTab(pAd);
675                 }
676         }
677 }
678
679 /*
680         ==========================================================================
681         Description:
682
683         IRQL = DISPATCH_LEVEL
684
685         ==========================================================================
686 */
687 VOID CntlWaitJoinProc(
688         IN PRTMP_ADAPTER pAd,
689         IN MLME_QUEUE_ELEM *Elem)
690 {
691         USHORT                      Reason;
692         MLME_AUTH_REQ_STRUCT        AuthReq;
693
694         if (Elem->MsgType == MT2_JOIN_CONF)
695         {
696                 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
697                 if (Reason == MLME_SUCCESS)
698                 {
699                         // 1. joined an IBSS, we are pretty much done here
700                         if (pAd->MlmeAux.BssType == BSS_ADHOC)
701                         {
702                             //
703                                 // 5G bands rules of Japan:
704                                 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
705                                 //
706                                 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
707                       RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
708                                    )
709                                 {
710                                         pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
711                                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
712                                         return;
713                                 }
714
715                                 LinkUp(pAd, BSS_ADHOC);
716                                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
717                                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
718                                 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
719                                 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
720
721                 pAd->IndicateMediaState = NdisMediaStateConnected;
722                 pAd->ExtraInfo = GENERAL_LINK_UP;
723                         }
724                         // 2. joined a new INFRA network, start from authentication
725                         else
726                         {
727                                 {
728                                         // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
729                                         if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
730                                                 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
731                                         {
732                                                 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
733                                         }
734                                         else
735                                         {
736                                                 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
737                                         }
738                                 }
739                                 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
740                                                         sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
741
742                                 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
743                         }
744                 }
745                 else
746                 {
747                         // 3. failed, try next BSS
748                         pAd->MlmeAux.BssIdx++;
749                         IterateOnBssTab(pAd);
750                 }
751         }
752 }
753
754
755 /*
756         ==========================================================================
757         Description:
758
759         IRQL = DISPATCH_LEVEL
760
761         ==========================================================================
762 */
763 VOID CntlWaitStartProc(
764         IN PRTMP_ADAPTER pAd,
765         IN MLME_QUEUE_ELEM *Elem)
766 {
767         USHORT      Result;
768
769         if (Elem->MsgType == MT2_START_CONF)
770         {
771                 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
772                 if (Result == MLME_SUCCESS)
773                 {
774                     //
775                         // 5G bands rules of Japan:
776                         // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
777                         //
778                         if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
779                   RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
780                            )
781                         {
782                                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
783                                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
784                                 return;
785                         }
786
787                         if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
788                         {
789                                 N_ChannelCheck(pAd);
790                                 SetCommonHT(pAd);
791                                 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
792                                 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
793                                 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
794                                 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
795                                 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
796                                 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
797
798                                 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth  == BW_40) &&
799                                         (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
800                                 {
801                                         pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
802                                 }
803                                 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth  == BW_40) &&
804                                                  (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
805                                 {
806                                         pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
807                                 }
808                         }
809                         else
810                         {
811                                 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
812                         }
813                         LinkUp(pAd, BSS_ADHOC);
814                         pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
815                         // Before send beacon, driver need do radar detection
816                         if ((pAd->CommonCfg.Channel > 14 )
817                                 && (pAd->CommonCfg.bIEEE80211H == 1)
818                                 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
819                         {
820                                 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
821                                 pAd->CommonCfg.RadarDetect.RDCount = 0;
822                         }
823
824                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
825                                 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
826                                 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
827                 }
828                 else
829                 {
830                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
831                         pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
832                 }
833         }
834 }
835
836 /*
837         ==========================================================================
838         Description:
839
840         IRQL = DISPATCH_LEVEL
841
842         ==========================================================================
843 */
844 VOID CntlWaitAuthProc(
845         IN PRTMP_ADAPTER pAd,
846         IN MLME_QUEUE_ELEM *Elem)
847 {
848         USHORT                       Reason;
849         MLME_ASSOC_REQ_STRUCT        AssocReq;
850         MLME_AUTH_REQ_STRUCT         AuthReq;
851
852         if (Elem->MsgType == MT2_AUTH_CONF)
853         {
854                 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
855                 if (Reason == MLME_SUCCESS)
856                 {
857                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
858                         AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
859                                                   ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
860
861                         {
862                                 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
863                                                         sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
864
865                                 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
866                         }
867                 }
868                 else
869                 {
870                         // This fail may because of the AP already keep us in its MAC table without
871                         // ageing-out. The previous authentication attempt must have let it remove us.
872                         // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
873                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
874
875                         {
876                                 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
877                                         (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
878                                 {
879                                         // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
880                                         AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
881                                 }
882                                 else
883                                 {
884                                         AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
885                                 }
886                         }
887                         MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
888                                                 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
889
890                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
891                 }
892         }
893 }
894
895 /*
896         ==========================================================================
897         Description:
898
899         IRQL = DISPATCH_LEVEL
900
901         ==========================================================================
902 */
903 VOID CntlWaitAuthProc2(
904         IN PRTMP_ADAPTER pAd,
905         IN MLME_QUEUE_ELEM *Elem)
906 {
907         USHORT                       Reason;
908         MLME_ASSOC_REQ_STRUCT        AssocReq;
909         MLME_AUTH_REQ_STRUCT         AuthReq;
910
911         if (Elem->MsgType == MT2_AUTH_CONF)
912         {
913                 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
914                 if (Reason == MLME_SUCCESS)
915                 {
916                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
917                         AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
918                                                   ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
919                         MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
920                                                 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
921
922                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
923                 }
924                 else
925                 {
926                         if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
927                                  (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
928                         {
929                                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
930                                 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
931                                 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
932                                                         sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
933
934                                 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
935                         }
936                         else
937                         {
938                                 // not success, try next BSS
939                                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
940                                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
941                                 pAd->MlmeAux.BssIdx++;
942                                 IterateOnBssTab(pAd);
943                         }
944                 }
945         }
946 }
947
948 /*
949         ==========================================================================
950         Description:
951
952         IRQL = DISPATCH_LEVEL
953
954         ==========================================================================
955 */
956 VOID CntlWaitAssocProc(
957         IN PRTMP_ADAPTER pAd,
958         IN MLME_QUEUE_ELEM *Elem)
959 {
960         USHORT      Reason;
961
962         if (Elem->MsgType == MT2_ASSOC_CONF)
963         {
964                 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
965                 if (Reason == MLME_SUCCESS)
966                 {
967                         LinkUp(pAd, BSS_INFRA);
968                         pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
969                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
970
971                         if (pAd->CommonCfg.bWirelessEvent)
972                         {
973                                 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
974                         }
975                 }
976                 else
977                 {
978                         // not success, try next BSS
979                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
980                         pAd->MlmeAux.BssIdx++;
981                         IterateOnBssTab(pAd);
982                 }
983         }
984 }
985
986 /*
987         ==========================================================================
988         Description:
989
990         IRQL = DISPATCH_LEVEL
991
992         ==========================================================================
993 */
994 VOID CntlWaitReassocProc(
995         IN PRTMP_ADAPTER pAd,
996         IN MLME_QUEUE_ELEM *Elem)
997 {
998         USHORT      Result;
999
1000         if (Elem->MsgType == MT2_REASSOC_CONF)
1001         {
1002                 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1003                 if (Result == MLME_SUCCESS)
1004                 {
1005                         //
1006                         // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1007                         //
1008                         LinkUp(pAd, BSS_INFRA);
1009
1010                         // send wireless event - for association
1011                         if (pAd->CommonCfg.bWirelessEvent)
1012                                 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1013
1014                         pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1015                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1016                 }
1017                 else
1018                 {
1019                         // reassoc failed, try to pick next BSS in the BSS Table
1020                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1021                         pAd->MlmeAux.RoamIdx++;
1022                         IterateOnBssTab2(pAd);
1023                 }
1024         }
1025 }
1026
1027 /*
1028         ==========================================================================
1029         Description:
1030
1031         IRQL = DISPATCH_LEVEL
1032
1033         ==========================================================================
1034 */
1035 VOID LinkUp(
1036         IN PRTMP_ADAPTER pAd,
1037         IN UCHAR BssType)
1038 {
1039         ULONG   Now;
1040         UINT32  Data;
1041         BOOLEAN Cancelled;
1042         UCHAR   Value = 0, idx;
1043         MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1044
1045         if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
1046         {
1047                 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
1048                 RTMPusecDelay(6000);
1049                 pAd->bPCIclkOff = FALSE;
1050         }
1051
1052         pEntry = &pAd->MacTab.Content[BSSID_WCID];
1053
1054         //
1055         // ASSOC - DisassocTimeoutAction
1056         // CNTL - Dis-associate successful
1057         // !!! LINK DOWN !!!
1058         // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1059         //
1060         // To prevent DisassocTimeoutAction to call Link down after we link up,
1061         // cancel the DisassocTimer no matter what it start or not.
1062         //
1063         RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer,  &Cancelled);
1064
1065         COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1066
1067         COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1068
1069         // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1070         // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1071         // to examine if cipher algorithm switching is required.
1072         //rt2860b. Don't know why need this
1073         SwitchBetweenWepAndCkip(pAd);
1074
1075         // Before power save before link up function, We will force use 1R.
1076         // So after link up, check Rx antenna # again.
1077         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1078         if(pAd->Antenna.field.RxPath == 3)
1079         {
1080                 Value |= (0x10);
1081         }
1082         else if(pAd->Antenna.field.RxPath == 2)
1083         {
1084                 Value |= (0x8);
1085         }
1086         else if(pAd->Antenna.field.RxPath == 1)
1087         {
1088                 Value |= (0x0);
1089         }
1090         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1091         pAd->StaCfg.BBPR3 = Value;
1092
1093         if (BssType == BSS_ADHOC)
1094         {
1095                 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1096                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1097
1098                 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1099         }
1100         else
1101         {
1102                 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1103                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1104
1105                 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1106         }
1107
1108         // 3*3
1109         // reset Tx beamforming bit
1110         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1111         Value &= (~0x01);
1112         Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1113         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1114
1115         // Change to AP channel
1116     if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1117         {
1118                 // Must using 40MHz.
1119                 pAd->CommonCfg.BBPCurrentBW = BW_40;
1120                 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1121                 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1122
1123                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1124                 Value &= (~0x18);
1125                 Value |= 0x10;
1126                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1127
1128                 //  RX : control channel at lower
1129                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1130                 Value &= (~0x20);
1131                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1132         pAd->StaCfg.BBPR3 = Value;
1133
1134                 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1135                 Data &= 0xfffffffe;
1136                 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1137
1138                 if (pAd->MACVersion == 0x28600100)
1139                 {
1140                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1141                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1142                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1143             DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1144                 }
1145
1146                 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1147         }
1148         else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1149     {
1150             // Must using 40MHz.
1151                 pAd->CommonCfg.BBPCurrentBW = BW_40;
1152                 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1153             AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1154
1155                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1156                 Value &= (~0x18);
1157                 Value |= 0x10;
1158                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1159
1160                 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1161                 Data |= 0x1;
1162                 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1163
1164                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1165             Value |= (0x20);
1166                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1167         pAd->StaCfg.BBPR3 = Value;
1168
1169                 if (pAd->MACVersion == 0x28600100)
1170                 {
1171                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1172                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1173                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1174                             DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1175                 }
1176
1177             DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1178     }
1179     else
1180     {
1181             pAd->CommonCfg.BBPCurrentBW = BW_20;
1182                 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1183                 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1184                 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1185
1186                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1187                 Value &= (~0x18);
1188                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1189
1190                 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1191                 Data &= 0xfffffffe;
1192                 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1193
1194                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1195                 Value &= (~0x20);
1196                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1197         pAd->StaCfg.BBPR3 = Value;
1198
1199                 if (pAd->MACVersion == 0x28600100)
1200                 {
1201                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1202                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1203                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1204             DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1205                 }
1206
1207             DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1208     }
1209
1210         RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1211         //
1212         // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1213         //
1214         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1215
1216         DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1217                 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1218
1219         DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1220
1221                 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1222
1223         AsicSetSlotTime(pAd, TRUE);
1224         AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1225
1226         // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1227         AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1228
1229         if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1230         {
1231                 // Update HT protectionfor based on AP's operating mode.
1232         if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1233         {
1234                 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode,  ALLN_SETPROTECT, FALSE, TRUE);
1235         }
1236         else
1237                         AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode,  ALLN_SETPROTECT, FALSE, FALSE);
1238         }
1239
1240         NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1241
1242         NdisGetSystemUpTime(&Now);
1243         pAd->StaCfg.LastBeaconRxTime = Now;   // last RX timestamp
1244
1245         if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1246                 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1247         {
1248                 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1249         }
1250
1251         OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1252
1253         if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1254         {
1255         }
1256         pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1257
1258         if (BssType == BSS_ADHOC)
1259         {
1260                 MakeIbssBeacon(pAd);
1261                 if ((pAd->CommonCfg.Channel > 14)
1262                         && (pAd->CommonCfg.bIEEE80211H == 1)
1263                         && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1264                 {
1265                         ; //Do nothing
1266                 }
1267                 else
1268                 {
1269                         AsicEnableIbssSync(pAd);
1270                 }
1271
1272                 // In ad hoc mode, use MAC table from index 1.
1273                 // p.s ASIC use all 0xff as termination of WCID table search.To prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here.
1274                 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1275                 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1276
1277                 // If WEP is enabled, add key material and cipherAlg into Asic
1278                 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1279
1280                 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1281                 {
1282                         PUCHAR  Key;
1283                         UCHAR   CipherAlg;
1284
1285                         for (idx=0; idx < SHARE_KEY_NUM; idx++)
1286                 {
1287                                 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1288                         Key = pAd->SharedKey[BSS0][idx].Key;
1289
1290                                 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1291                                 {
1292                                         // Set key material and cipherAlg to Asic
1293                                 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1294
1295                     if (idx == pAd->StaCfg.DefaultKeyId)
1296                                         {
1297                                                 // Update WCID attribute table and IVEIV table for this group key table
1298                                                 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1299                                         }
1300                                 }
1301
1302
1303                         }
1304                 }
1305                 // If WPANone is enabled, add key material and cipherAlg into Asic
1306                 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1307                 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1308                 {
1309                         pAd->StaCfg.DefaultKeyId = 0;   // always be zero
1310
1311             NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1312                                                         pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1313                         NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1314
1315             if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1316             {
1317                         NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1318                         NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1319             }
1320
1321                         // Decide its ChiperAlg
1322                         if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1323                                 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1324                         else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1325                                 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1326                         else
1327             {
1328                 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1329                                 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1330             }
1331
1332                         // Set key material and cipherAlg to Asic
1333                         AsicAddSharedKeyEntry(pAd,
1334                                                                   BSS0,
1335                                                                   0,
1336                                                                   pAd->SharedKey[BSS0][0].CipherAlg,
1337                                                                   pAd->SharedKey[BSS0][0].Key,
1338                                                                   pAd->SharedKey[BSS0][0].TxMic,
1339                                                                   pAd->SharedKey[BSS0][0].RxMic);
1340
1341             // Update WCID attribute table and IVEIV table for this group key table
1342                         RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1343
1344                 }
1345
1346         }
1347         else // BSS_INFRA
1348         {
1349                 // Check the new SSID with last SSID
1350                 while (Cancelled == TRUE)
1351                 {
1352                         if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1353                         {
1354                                 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1355                                 {
1356                                         // Link to the old one no linkdown is required.
1357                                         break;
1358                                 }
1359                         }
1360                         // Send link down event before set to link up
1361                         pAd->IndicateMediaState = NdisMediaStateDisconnected;
1362                         RTMP_IndicateMediaState(pAd);
1363             pAd->ExtraInfo = GENERAL_LINK_DOWN;
1364                         DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1365                         break;
1366                 }
1367
1368                 //
1369                 // On WPA mode, Remove All Keys if not connect to the last BSSID
1370                 // Key will be set after 4-way handshake.
1371                 //
1372                 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1373                 {
1374                         ULONG           IV;
1375
1376                         // Remove all WPA keys
1377                         RTMPWPARemoveAllKeys(pAd);
1378                         pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1379                         pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1380
1381                         // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1382                         // If IV related values are too large in GroupMsg2, AP would ignore this message.
1383                         IV = 0;
1384                         IV |= (pAd->StaCfg.DefaultKeyId << 30);
1385                         AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1386
1387                         RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1388                 }
1389                 // NOTE:
1390                 // the decision of using "short slot time" or not may change dynamically due to
1391                 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1392
1393                 // NOTE:
1394                 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1395                 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1396
1397                 ComposePsPoll(pAd);
1398                 ComposeNullFrame(pAd);
1399
1400                         AsicEnableBssSync(pAd);
1401
1402                 // Add BSSID to WCID search table
1403                 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1404
1405                 NdisAcquireSpinLock(&pAd->MacTabLock);
1406                 // add this BSSID entry into HASH table
1407                 {
1408                         UCHAR HashIdx;
1409
1410                         //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1411                         HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1412                         if (pAd->MacTab.Hash[HashIdx] == NULL)
1413                         {
1414                                 pAd->MacTab.Hash[HashIdx] = pEntry;
1415                         }
1416                         else
1417                         {
1418                                 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1419                                 while (pCurrEntry->pNext != NULL)
1420                                         pCurrEntry = pCurrEntry->pNext;
1421                                 pCurrEntry->pNext = pEntry;
1422                         }
1423                 }
1424                 NdisReleaseSpinLock(&pAd->MacTabLock);
1425
1426
1427                 // If WEP is enabled, add paiewise and shared key
1428         if (((pAd->StaCfg.WpaSupplicantUP)&&
1429              (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1430              (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1431             ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1432               (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1433                 {
1434                         PUCHAR  Key;
1435                         UCHAR   CipherAlg;
1436
1437                         for (idx=0; idx < SHARE_KEY_NUM; idx++)
1438                 {
1439                                 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1440                         Key = pAd->SharedKey[BSS0][idx].Key;
1441
1442                                 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1443                                 {
1444                                         // Set key material and cipherAlg to Asic
1445                                 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1446
1447                                         if (idx == pAd->StaCfg.DefaultKeyId)
1448                                         {
1449                                                 // Assign group key info
1450                                                 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1451
1452                                                 // Assign pairwise key info
1453                                                 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1454                                         }
1455                                 }
1456                         }
1457                 }
1458
1459                 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1460                 // should wait until at least 2 active nodes in this BSSID.
1461                 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1462
1463         // For GUI ++
1464                 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1465                 {
1466                         pAd->IndicateMediaState = NdisMediaStateConnected;
1467                         pAd->ExtraInfo = GENERAL_LINK_UP;
1468                 }
1469         // --
1470                 RTMP_IndicateMediaState(pAd);
1471
1472                 // Add BSSID in my MAC Table.
1473         NdisAcquireSpinLock(&pAd->MacTabLock);
1474                 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1475                 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1476                 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1477                 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE;      //Although this is bssid..still set ValidAsCl
1478                 pAd->MacTab.Size = 1;   // infra mode always set MACtab size =1.
1479                 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1480                 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1481                 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1482         NdisReleaseSpinLock(&pAd->MacTabLock);
1483
1484                 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!!  ClientStatusFlags=%lx)\n",
1485                         pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1486
1487                 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1488                 MlmeUpdateHtTxRates(pAd, BSS0);
1489                 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1490
1491                 if (pAd->CommonCfg.bAggregationCapable)
1492                 {
1493                         if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1494                         {
1495
1496                                 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1497                                 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1498                 RTMPSetPiggyBack(pAd, TRUE);
1499                                 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1500                         }
1501                         else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1502                         {
1503                                 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1504                         }
1505                 }
1506
1507                 if (pAd->MlmeAux.APRalinkIe != 0x0)
1508                 {
1509                         if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1510                         {
1511                                 AsicEnableRDG(pAd);
1512                         }
1513
1514                         OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1515                         CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1516                 }
1517                 else
1518                 {
1519                         OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1520                         CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1521                 }
1522         }
1523
1524         DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_CONNECT Event B!.BACapability = %x. ClientStatusFlags = %lx\n", pAd->CommonCfg.BACapability.word, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1525
1526         // Set LED
1527         RTMPSetLED(pAd, LED_LINK_UP);
1528
1529         pAd->Mlme.PeriodicRound = 0;
1530         pAd->Mlme.OneSecPeriodicRound = 0;
1531         pAd->bConfigChanged = FALSE;        // Reset config flag
1532         pAd->ExtraInfo = GENERAL_LINK_UP;   // Update extra information to link is up
1533
1534         // Set asic auto fall back
1535         {
1536                 PUCHAR                                  pTable;
1537                 UCHAR                                   TableSize = 0;
1538
1539                 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1540                 AsicUpdateAutoFallBackTable(pAd, pTable);
1541         }
1542
1543         NdisAcquireSpinLock(&pAd->MacTabLock);
1544     pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1545     pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1546         if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1547         {
1548                 pEntry->bAutoTxRateSwitch = FALSE;
1549
1550                 if (pEntry->HTPhyMode.field.MCS == 32)
1551                         pEntry->HTPhyMode.field.ShortGI = GI_800;
1552
1553                 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1554                         pEntry->HTPhyMode.field.STBC = STBC_NONE;
1555
1556                 // If the legacy mode is set, overwrite the transmit setting of this entry.
1557                 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1558                         RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1559         }
1560         else
1561                 pEntry->bAutoTxRateSwitch = TRUE;
1562         NdisReleaseSpinLock(&pAd->MacTabLock);
1563
1564         //  Let Link Status Page display first initial rate.
1565         pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1566         // Select DAC according to HT or Legacy
1567         if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1568         {
1569                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1570                 Value &= (~0x18);
1571                 if (pAd->Antenna.field.TxPath == 2)
1572                 {
1573                     Value |= 0x10;
1574                 }
1575                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1576         }
1577         else
1578         {
1579                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1580                 Value &= (~0x18);
1581                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1582         }
1583
1584         if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1585         {
1586         }
1587         else if (pEntry->MaxRAmpduFactor == 0)
1588         {
1589             // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1590             // Because our Init value is 1 at MACRegTable.
1591                 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1592         }
1593
1594         // Patch for Marvel AP to gain high throughput
1595         // Need to set as following,
1596         // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1597         // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1598         // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1599         // 4. kick per two packets when dequeue
1600         //
1601         // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1602         //
1603         // if 1. Legacy AP WMM on,  or 2. 11n AP, AMPDU disable.  Force turn off burst no matter what bEnableTxBurst is.
1604         if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1605                 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))
1606         {
1607                 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1608                 Data  &= 0xFFFFFF00;
1609                 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1610
1611                 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1612                 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1613         }
1614         else
1615         if (pAd->CommonCfg.bEnableTxBurst)
1616         {
1617                 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1618                 Data  &= 0xFFFFFF00;
1619                 Data  |= 0x60;
1620                 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1621                 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1622
1623                 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1624                 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1625         }
1626         else
1627         {
1628                 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1629                 Data  &= 0xFFFFFF00;
1630                 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1631
1632                 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1633                 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1634         }
1635
1636         // Re-check to turn on TX burst or not.
1637         if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1638         {
1639                 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1640                 if (pAd->CommonCfg.bEnableTxBurst)
1641                 {
1642                     UINT32 MACValue = 0;
1643                         // Force disable  TXOP value in this case. The same action in MLMEUpdateProtect too.
1644                         // I didn't change PBF_MAX_PCNT setting.
1645                         RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1646                         MACValue  &= 0xFFFFFF00;
1647                         RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1648                         pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1649                 }
1650         }
1651         else
1652         {
1653                 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1654         }
1655
1656         pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1657         COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1658         DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1659         // BSSID add in one MAC entry too.  Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1660         // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1661         // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1662
1663     if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1664     {
1665         pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1666                 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1667         }
1668
1669         NdisAcquireSpinLock(&pAd->MacTabLock);
1670         pEntry->PortSecured = pAd->StaCfg.PortSecured;
1671         NdisReleaseSpinLock(&pAd->MacTabLock);
1672
1673     //
1674         // Patch Atheros AP TX will breakdown issue.
1675         // AP Model: DLink DWL-8200AP
1676         //
1677         if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1678         {
1679                 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1680         }
1681         else
1682         {
1683                 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1684         }
1685
1686         RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1687         RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1688 }
1689
1690 /*
1691         ==========================================================================
1692
1693         Routine Description:
1694                 Disconnect current BSSID
1695
1696         Arguments:
1697                 pAd                             - Pointer to our adapter
1698                 IsReqFromAP             - Request from AP
1699
1700         Return Value:
1701                 None
1702
1703         IRQL = DISPATCH_LEVEL
1704
1705         Note:
1706                 We need more information to know it's this requst from AP.
1707                 If yes! we need to do extra handling, for example, remove the WPA key.
1708                 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1709                 remove while auto reconnect.
1710                 Disconnect request from AP, it means we will start afresh 4-way handshaking
1711                 on WPA mode.
1712
1713         ==========================================================================
1714 */
1715 VOID LinkDown(
1716         IN PRTMP_ADAPTER pAd,
1717         IN  BOOLEAN      IsReqFromAP)
1718 {
1719         UCHAR                       i, ByteValue = 0;
1720         BOOLEAN         Cancelled;
1721
1722         // Do nothing if monitor mode is on
1723         if (MONITOR_ON(pAd))
1724                 return;
1725
1726         RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1727         RTMPCancelTimer(&pAd->Mlme.PsPollTimer,         &Cancelled);
1728
1729         // Not allow go to sleep within linkdown function.
1730         RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1731
1732     if (pAd->CommonCfg.bWirelessEvent)
1733         {
1734                 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1735         }
1736
1737         DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
1738         OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1739
1740     if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1741     {
1742             BOOLEAN Cancelled;
1743         pAd->Mlme.bPsPollTimerRunning = FALSE;
1744         RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1745     }
1746
1747     if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
1748                 RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
1749                 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
1750     {
1751                 AsicForceWakeup(pAd, RTMP_HALT);
1752         OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
1753     }
1754
1755     pAd->bPCIclkOff = FALSE;
1756         if (ADHOC_ON(pAd))              // Adhoc mode link down
1757         {
1758                 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
1759
1760                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1761                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1762                 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1763                 RTMP_IndicateMediaState(pAd);
1764         pAd->ExtraInfo = GENERAL_LINK_DOWN;
1765                 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1766                 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
1767         }
1768         else                                    // Infra structure mode
1769         {
1770                 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
1771
1772                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1773                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1774
1775                 // Saved last SSID for linkup comparison
1776                 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
1777                 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
1778                 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1779                 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
1780                 {
1781                         pAd->IndicateMediaState = NdisMediaStateDisconnected;
1782                         RTMP_IndicateMediaState(pAd);
1783             pAd->ExtraInfo = GENERAL_LINK_DOWN;
1784                         DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
1785                         pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
1786                 }
1787                 else
1788                 {
1789             //
1790                         // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
1791                         // Otherwise lost beacon or receive De-Authentication from AP,
1792                         // then we should delete BSSID from BssTable.
1793                         // If we don't delete from entry, roaming will fail.
1794                         //
1795                         BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1796                 }
1797
1798                 // restore back to -
1799                 //      1. long slot (20 us) or short slot (9 us) time
1800                 //      2. turn on/off RTS/CTS and/or CTS-to-self protection
1801                 //      3. short preamble
1802                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1803
1804                 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
1805                 {
1806                         //
1807                         // Record current AP's information.
1808                         // for later used reporting Adjacent AP report.
1809                         //
1810                         pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
1811                         pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
1812                         NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
1813                         COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
1814                 }
1815         }
1816
1817         for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
1818         {
1819                 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
1820                         MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
1821         }
1822
1823         pAd->StaCfg.CCXQosECWMin        = 4;
1824         pAd->StaCfg.CCXQosECWMax        = 10;
1825
1826         AsicSetSlotTime(pAd, TRUE); //FALSE);
1827         AsicSetEdcaParm(pAd, NULL);
1828
1829         // Set LED
1830         RTMPSetLED(pAd, LED_LINK_DOWN);
1831     pAd->LedIndicatorStregth = 0xF0;
1832     RTMPSetSignalLED(pAd, -100);        // Force signal strength Led to be turned off, firmware is not done it.
1833
1834                 AsicDisableSync(pAd);
1835
1836         pAd->Mlme.PeriodicRound = 0;
1837         pAd->Mlme.OneSecPeriodicRound = 0;
1838
1839         if (pAd->StaCfg.BssType == BSS_INFRA)
1840         {
1841                 // Remove StaCfg Information after link down
1842                 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1843                 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
1844                 pAd->CommonCfg.SsidLen = 0;
1845         }
1846
1847         NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
1848         NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
1849         pAd->MlmeAux.HtCapabilityLen = 0;
1850         pAd->MlmeAux.NewExtChannelOffset = 0xff;
1851
1852         // Reset WPA-PSK state. Only reset when supplicant enabled
1853         if (pAd->StaCfg.WpaState != SS_NOTUSE)
1854         {
1855                 pAd->StaCfg.WpaState = SS_START;
1856                 // Clear Replay counter
1857                 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
1858         }
1859
1860
1861         //
1862         // if link down come from AP, we need to remove all WPA keys on WPA mode.
1863         // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
1864         //
1865         if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1866         {
1867                 // Remove all WPA keys
1868                 RTMPWPARemoveAllKeys(pAd);
1869         }
1870
1871         // 802.1x port control
1872
1873         // Prevent clear PortSecured here with static WEP
1874         // NetworkManger set security policy first then set SSID to connect AP.
1875         if (pAd->StaCfg.WpaSupplicantUP &&
1876                 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1877                 (pAd->StaCfg.IEEE8021X == FALSE))
1878         {
1879                 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1880         }
1881         else
1882         {
1883                 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1884                 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1885         }
1886
1887         NdisAcquireSpinLock(&pAd->MacTabLock);
1888         pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
1889         NdisReleaseSpinLock(&pAd->MacTabLock);
1890
1891         pAd->StaCfg.MicErrCnt = 0;
1892
1893         // Turn off Ckip control flag
1894         pAd->StaCfg.bCkipOn = FALSE;
1895         pAd->StaCfg.CCXEnable = FALSE;
1896
1897     pAd->IndicateMediaState = NdisMediaStateDisconnected;
1898         // Update extra information to link is up
1899         pAd->ExtraInfo = GENERAL_LINK_DOWN;
1900
1901     pAd->StaCfg.AdhocBOnlyJoined = FALSE;
1902         pAd->StaCfg.AdhocBGJoined = FALSE;
1903         pAd->StaCfg.Adhoc20NJoined = FALSE;
1904     pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
1905
1906         // Reset the Current AP's IP address
1907         NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
1908
1909         // Clean association information
1910         NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
1911         pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
1912         pAd->StaCfg.ReqVarIELen = 0;
1913         pAd->StaCfg.ResVarIELen = 0;
1914
1915         //
1916         // Reset RSSI value after link down
1917         //
1918         pAd->StaCfg.RssiSample.AvgRssi0 = 0;
1919         pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
1920         pAd->StaCfg.RssiSample.AvgRssi1 = 0;
1921         pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
1922         pAd->StaCfg.RssiSample.AvgRssi2 = 0;
1923         pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
1924
1925         // Restore MlmeRate
1926         pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
1927         pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
1928
1929         //
1930         // After Link down, reset piggy-back setting in ASIC. Disable RDG.
1931         //
1932         if (pAd->CommonCfg.BBPCurrentBW == BW_40)
1933         {
1934                 pAd->CommonCfg.BBPCurrentBW = BW_20;
1935                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
1936                 ByteValue &= (~0x18);
1937                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
1938         }
1939
1940         // Reset DAC
1941         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
1942         ByteValue &= (~0x18);
1943         if (pAd->Antenna.field.TxPath == 2)
1944         {
1945                 ByteValue |= 0x10;
1946         }
1947         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
1948
1949         RTMPSetPiggyBack(pAd,FALSE);
1950         OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1951
1952         pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
1953
1954         // Restore all settings in the following.
1955         AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
1956         AsicDisableRDG(pAd);
1957         pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
1958         pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1959
1960         RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
1961         RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1962
1963         // Allow go to sleep after linkdown steps.
1964         RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1965
1966         {
1967                 union iwreq_data    wrqu;
1968                 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1969                 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1970         }
1971 }
1972
1973 /*
1974         ==========================================================================
1975         Description:
1976
1977         IRQL = DISPATCH_LEVEL
1978
1979         ==========================================================================
1980 */
1981 VOID IterateOnBssTab(
1982         IN PRTMP_ADAPTER pAd)
1983 {
1984         MLME_START_REQ_STRUCT   StartReq;
1985         MLME_JOIN_REQ_STRUCT    JoinReq;
1986         ULONG                   BssIdx;
1987
1988         // Change the wepstatus to original wepstatus
1989         pAd->StaCfg.WepStatus   = pAd->StaCfg.OrigWepStatus;
1990         pAd->StaCfg.PairCipher  = pAd->StaCfg.OrigWepStatus;
1991         pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
1992
1993         BssIdx = pAd->MlmeAux.BssIdx;
1994         if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
1995         {
1996                 // Check cipher suite, AP must have more secured cipher than station setting
1997                 // Set the Pairwise and Group cipher to match the intended AP setting
1998                 // We can only connect to AP with less secured cipher setting
1999                 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2000                 {
2001                         pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2002
2003                         if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2004                                 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2005                         else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2006                                 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2007                         else    // There is no PairCipher Aux, downgrade our capability to TKIP
2008                                 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2009                 }
2010                 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2011                 {
2012                         pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2013
2014                         if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2015                                 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2016                         else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2017                                 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2018                         else    // There is no PairCipher Aux, downgrade our capability to TKIP
2019                                 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2020
2021                         // RSN capability
2022                         pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2023                 }
2024
2025                 // Set Mix cipher flag
2026                 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2027                 if (pAd->StaCfg.bMixCipher == TRUE)
2028                 {
2029                         // If mix cipher, re-build RSNIE
2030                         RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2031                 }
2032
2033                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2034                 JoinParmFill(pAd, &JoinReq, BssIdx);
2035                 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2036                                         &JoinReq);
2037                 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2038         }
2039         else if (pAd->StaCfg.BssType == BSS_ADHOC)
2040         {
2041                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2042                 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2043                 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2044                 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2045         }
2046         else // no more BSS
2047         {
2048                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2049                 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2050                 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2051                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2052         }
2053 }
2054
2055 // for re-association only
2056 // IRQL = DISPATCH_LEVEL
2057 VOID IterateOnBssTab2(
2058         IN PRTMP_ADAPTER pAd)
2059 {
2060         MLME_REASSOC_REQ_STRUCT ReassocReq;
2061         ULONG                   BssIdx;
2062         BSS_ENTRY               *pBss;
2063
2064         BssIdx = pAd->MlmeAux.RoamIdx;
2065         pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2066
2067         if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2068         {
2069                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2070
2071                 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2072                 AsicLockChannel(pAd, pBss->Channel);
2073
2074                 // reassociate message has the same structure as associate message
2075                 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2076                                           ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2077                 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2078                                         sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2079
2080                 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2081         }
2082         else // no more BSS
2083         {
2084                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2085                 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2086                 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2087                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2088         }
2089 }
2090
2091 /*
2092         ==========================================================================
2093         Description:
2094
2095         IRQL = DISPATCH_LEVEL
2096
2097         ==========================================================================
2098 */
2099 VOID JoinParmFill(
2100         IN PRTMP_ADAPTER pAd,
2101         IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2102         IN ULONG BssIdx)
2103 {
2104         JoinReq->BssIdx = BssIdx;
2105 }
2106
2107 /*
2108         ==========================================================================
2109         Description:
2110
2111         IRQL = DISPATCH_LEVEL
2112
2113         ==========================================================================
2114 */
2115 VOID ScanParmFill(
2116         IN PRTMP_ADAPTER pAd,
2117         IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2118         IN CHAR Ssid[],
2119         IN UCHAR SsidLen,
2120         IN UCHAR BssType,
2121         IN UCHAR ScanType)
2122 {
2123     NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2124         ScanReq->SsidLen = SsidLen;
2125         NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2126         ScanReq->BssType = BssType;
2127         ScanReq->ScanType = ScanType;
2128 }
2129
2130 /*
2131         ==========================================================================
2132         Description:
2133
2134         IRQL = DISPATCH_LEVEL
2135
2136         ==========================================================================
2137 */
2138 VOID StartParmFill(
2139         IN PRTMP_ADAPTER pAd,
2140         IN OUT MLME_START_REQ_STRUCT *StartReq,
2141         IN CHAR Ssid[],
2142         IN UCHAR SsidLen)
2143 {
2144         ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2145         NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2146         StartReq->SsidLen = SsidLen;
2147 }
2148
2149 /*
2150         ==========================================================================
2151         Description:
2152
2153         IRQL = DISPATCH_LEVEL
2154
2155         ==========================================================================
2156 */
2157 VOID AuthParmFill(
2158         IN PRTMP_ADAPTER pAd,
2159         IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2160         IN PUCHAR pAddr,
2161         IN USHORT Alg)
2162 {
2163         COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2164         AuthReq->Alg = Alg;
2165         AuthReq->Timeout = AUTH_TIMEOUT;
2166 }
2167
2168 /*
2169         ==========================================================================
2170         Description:
2171
2172         IRQL = DISPATCH_LEVEL
2173
2174         ==========================================================================
2175  */
2176 VOID ComposePsPoll(
2177         IN PRTMP_ADAPTER pAd)
2178 {
2179         NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2180         pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2181         pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2182         pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2183         COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2184         COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2185 }
2186
2187 // IRQL = DISPATCH_LEVEL
2188 VOID ComposeNullFrame(
2189         IN PRTMP_ADAPTER pAd)
2190 {
2191         NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2192         pAd->NullFrame.FC.Type = BTYPE_DATA;
2193         pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2194         pAd->NullFrame.FC.ToDs = 1;
2195         COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2196         COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2197         COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2198 }
2199
2200
2201
2202
2203 /*
2204         ==========================================================================
2205         Description:
2206                 Pre-build a BEACON frame in the shared memory
2207
2208         IRQL = PASSIVE_LEVEL
2209         IRQL = DISPATCH_LEVEL
2210
2211         ==========================================================================
2212 */
2213 ULONG MakeIbssBeacon(
2214         IN PRTMP_ADAPTER pAd)
2215 {
2216         UCHAR         DsLen = 1, IbssLen = 2;
2217         UCHAR         LocalErpIe[3] = {IE_ERP, 1, 0x04};
2218         HEADER_802_11 BcnHdr;
2219         USHORT        CapabilityInfo;
2220         LARGE_INTEGER FakeTimestamp;
2221         ULONG         FrameLen = 0;
2222         PTXWI_STRUC       pTxWI = &pAd->BeaconTxWI;
2223         CHAR         *pBeaconFrame = pAd->BeaconBuf;
2224         BOOLEAN       Privacy;
2225         UCHAR         SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2226         UCHAR         SupRateLen = 0;
2227         UCHAR         ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2228         UCHAR         ExtRateLen = 0;
2229         UCHAR         RSNIe = IE_WPA;
2230
2231         if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2232         {
2233                 SupRate[0] = 0x82; // 1 mbps
2234                 SupRate[1] = 0x84; // 2 mbps
2235                 SupRate[2] = 0x8b; // 5.5 mbps
2236                 SupRate[3] = 0x96; // 11 mbps
2237                 SupRateLen = 4;
2238                 ExtRateLen = 0;
2239         }
2240         else if (pAd->CommonCfg.Channel > 14)
2241         {
2242                 SupRate[0]  = 0x8C;    // 6 mbps, in units of 0.5 Mbps, basic rate
2243                 SupRate[1]  = 0x12;    // 9 mbps, in units of 0.5 Mbps
2244                 SupRate[2]  = 0x98;    // 12 mbps, in units of 0.5 Mbps, basic rate
2245                 SupRate[3]  = 0x24;    // 18 mbps, in units of 0.5 Mbps
2246                 SupRate[4]  = 0xb0;    // 24 mbps, in units of 0.5 Mbps, basic rate
2247                 SupRate[5]  = 0x48;    // 36 mbps, in units of 0.5 Mbps
2248                 SupRate[6]  = 0x60;    // 48 mbps, in units of 0.5 Mbps
2249                 SupRate[7]  = 0x6c;    // 54 mbps, in units of 0.5 Mbps
2250                 SupRateLen  = 8;
2251                 ExtRateLen  = 0;
2252
2253                 //
2254                 // Also Update MlmeRate & RtsRate for G only & A only
2255                 //
2256                 pAd->CommonCfg.MlmeRate = RATE_6;
2257                 pAd->CommonCfg.RtsRate = RATE_6;
2258                 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2259                 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2260                 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2261                 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2262         }
2263         else
2264         {
2265                 SupRate[0] = 0x82; // 1 mbps
2266                 SupRate[1] = 0x84; // 2 mbps
2267                 SupRate[2] = 0x8b; // 5.5 mbps
2268                 SupRate[3] = 0x96; // 11 mbps
2269                 SupRateLen = 4;
2270
2271                 ExtRate[0]  = 0x0C;    // 6 mbps, in units of 0.5 Mbps,
2272                 ExtRate[1]  = 0x12;    // 9 mbps, in units of 0.5 Mbps
2273                 ExtRate[2]  = 0x18;    // 12 mbps, in units of 0.5 Mbps,
2274                 ExtRate[3]  = 0x24;    // 18 mbps, in units of 0.5 Mbps
2275                 ExtRate[4]  = 0x30;    // 24 mbps, in units of 0.5 Mbps,
2276                 ExtRate[5]  = 0x48;    // 36 mbps, in units of 0.5 Mbps
2277                 ExtRate[6]  = 0x60;    // 48 mbps, in units of 0.5 Mbps
2278                 ExtRate[7]  = 0x6c;    // 54 mbps, in units of 0.5 Mbps
2279                 ExtRateLen  = 8;
2280         }
2281
2282         pAd->StaActive.SupRateLen = SupRateLen;
2283         NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2284         pAd->StaActive.ExtRateLen = ExtRateLen;
2285         NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2286
2287         // compose IBSS beacon frame
2288         MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2289         Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2290                           (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2291                           (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2292         CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2293
2294         MakeOutgoingFrame(pBeaconFrame,                &FrameLen,
2295                                           sizeof(HEADER_802_11),           &BcnHdr,
2296                                           TIMESTAMP_LEN,                   &FakeTimestamp,
2297                                           2,                               &pAd->CommonCfg.BeaconPeriod,
2298                                           2,                               &CapabilityInfo,
2299                                           1,                               &SsidIe,
2300                                           1,                               &pAd->CommonCfg.SsidLen,
2301                                           pAd->CommonCfg.SsidLen,          pAd->CommonCfg.Ssid,
2302                                           1,                               &SupRateIe,
2303                                           1,                               &SupRateLen,
2304                                           SupRateLen,                      SupRate,
2305                                           1,                               &DsIe,
2306                                           1,                               &DsLen,
2307                                           1,                               &pAd->CommonCfg.Channel,
2308                                           1,                               &IbssIe,
2309                                           1,                               &IbssLen,
2310                                           2,                               &pAd->StaActive.AtimWin,
2311                                           END_OF_ARGS);
2312
2313         // add ERP_IE and EXT_RAE IE of in 802.11g
2314         if (ExtRateLen)
2315         {
2316                 ULONG   tmp;
2317
2318                 MakeOutgoingFrame(pBeaconFrame + FrameLen,         &tmp,
2319                                                   3,                               LocalErpIe,
2320                                                   1,                               &ExtRateIe,
2321                                                   1,                               &ExtRateLen,
2322                                                   ExtRateLen,                      ExtRate,
2323                                                   END_OF_ARGS);
2324                 FrameLen += tmp;
2325         }
2326
2327         // If adhoc secruity is set for WPA-None, append the cipher suite IE
2328         if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2329         {
2330                 ULONG tmp;
2331         RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2332
2333                 MakeOutgoingFrame(pBeaconFrame + FrameLen,              &tmp,
2334                                                   1,                                    &RSNIe,
2335                                                   1,                                    &pAd->StaCfg.RSNIE_Len,
2336                                                   pAd->StaCfg.RSNIE_Len,                pAd->StaCfg.RSN_IE,
2337                                                   END_OF_ARGS);
2338                 FrameLen += tmp;
2339         }
2340
2341         if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2342         {
2343                 ULONG TmpLen;
2344                 UCHAR HtLen, HtLen1;
2345
2346                 // add HT Capability IE
2347                 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2348                 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2349
2350                 MakeOutgoingFrame(pBeaconFrame+FrameLen,        &TmpLen,
2351                                                   1,                                            &HtCapIe,
2352                                                   1,                                            &HtLen,
2353                                                   HtLen,                                        &pAd->CommonCfg.HtCapability,
2354                                                   1,                                            &AddHtInfoIe,
2355                                                   1,                                            &HtLen1,
2356                                                   HtLen1,                                       &pAd->CommonCfg.AddHTInfo,
2357                                                   END_OF_ARGS);
2358
2359                 FrameLen += TmpLen;
2360         }
2361
2362         //beacon use reserved WCID 0xff
2363     if (pAd->CommonCfg.Channel > 14)
2364     {
2365         RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE,  TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2366                 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2367     }
2368     else
2369     {
2370         // Set to use 1Mbps for Adhoc beacon.
2371                 HTTRANSMIT_SETTING Transmit;
2372         Transmit.word = 0;
2373         RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE,  TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2374                 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2375     }
2376
2377     DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2378                                         FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));
2379         return FrameLen;
2380 }
2381
2382