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