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 */
MlmeCntlInit(struct rt_rtmp_adapter * pAd,struct rt_state_machine * S,OUT STATE_MACHINE_FUNC Trans[])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 */
MlmeCntlMachinePerformAction(struct rt_rtmp_adapter * pAd,struct rt_state_machine * S,struct rt_mlme_queue_elem * Elem)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 */
CntlIdleProc(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)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 
CntlOidScanProc(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)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 */
CntlOidSsidProc(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)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 */
CntlOidRTBssidProc(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)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 */
CntlMlmeRoamingProc(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)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 */
CntlWaitDisassocProc(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)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 */
CntlWaitJoinProc(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)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 */
CntlWaitStartProc(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)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 */
CntlWaitAuthProc(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)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 */
CntlWaitAuthProc2(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)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 */
CntlWaitAssocProc(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)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 */
CntlWaitReassocProc(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)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 
AdhocTurnOnQos(struct rt_rtmp_adapter * pAd)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 */
LinkUp(struct rt_rtmp_adapter * pAd,u8 BssType)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 */
LinkDown(struct rt_rtmp_adapter * pAd,IN BOOLEAN IsReqFromAP)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 */
IterateOnBssTab(struct rt_rtmp_adapter * pAd)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 */
IterateOnBssTab2(struct rt_rtmp_adapter * pAd)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 */
JoinParmFill(struct rt_rtmp_adapter * pAd,struct rt_mlme_join_req * JoinReq,unsigned long BssIdx)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 */
ScanParmFill(struct rt_rtmp_adapter * pAd,struct rt_mlme_scan_req * ScanReq,char Ssid[],u8 SsidLen,u8 BssType,u8 ScanType)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 */
StartParmFill(struct rt_rtmp_adapter * pAd,struct rt_mlme_start_req * StartReq,char Ssid[],u8 SsidLen)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 */
AuthParmFill(struct rt_rtmp_adapter * pAd,struct rt_mlme_auth_req * AuthReq,u8 * pAddr,u16 Alg)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
ComposePsPoll(struct rt_rtmp_adapter * pAd)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 */
ComposeNullFrame(struct rt_rtmp_adapter * pAd)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
MlmeCntlConfirm(struct rt_rtmp_adapter * pAd,unsigned long MsgType,u16 Msg)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 
ComposePsPoll(struct rt_rtmp_adapter * pAd)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 */
ComposeNullFrame(struct rt_rtmp_adapter * pAd)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 */
MakeIbssBeacon(struct rt_rtmp_adapter * pAd)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 }
2614