Staging: add rt2860 wireless driver
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / rt2860 / sta / sync.c
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 sync.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John Chang 2004-09-01 modified for rt2561/2661
36 Jan Lee 2006-08-01 modified for rt2860 for 802.11n
37 */
38 #include "../rt_config.h"
39
40 #define AC0_DEF_TXOP 0
41 #define AC1_DEF_TXOP 0
42 #define AC2_DEF_TXOP 94
43 #define AC3_DEF_TXOP 47
44
45 VOID AdhocTurnOnQos(
46 IN PRTMP_ADAPTER pAd)
47 {
48 // Turn on QOs if use HT rate.
49 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
50 {
51 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
52 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
53 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
54 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
55 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
56
57 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
58 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
59 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
60 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
61
62 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
63 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
64 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
65 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
66
67 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
68 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
69 pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
70 pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
71 }
72 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
73 }
74
75 /*
76 ==========================================================================
77 Description:
78 The sync state machine,
79 Parameters:
80 Sm - pointer to the state machine
81 Note:
82 the state machine looks like the following
83
84 ==========================================================================
85 */
86 VOID SyncStateMachineInit(
87 IN PRTMP_ADAPTER pAd,
88 IN STATE_MACHINE *Sm,
89 OUT STATE_MACHINE_FUNC Trans[])
90 {
91 StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG, (STATE_MACHINE_FUNC)Drop, SYNC_IDLE, SYNC_MACHINE_BASE);
92
93 // column 1
94 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)MlmeScanReqAction);
95 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)MlmeJoinReqAction);
96 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)MlmeStartReqAction);
97 StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeacon);
98 StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ, (STATE_MACHINE_FUNC)PeerProbeReqAction);
99
100 //column 2
101 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
102 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
103 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
104 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtJoinAction);
105 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT, (STATE_MACHINE_FUNC)BeaconTimeoutAtJoinAction);
106
107 // column 3
108 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
109 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
110 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
111 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
112 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
113 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT, (STATE_MACHINE_FUNC)ScanTimeoutAction);
114
115 // timer init
116 RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer, GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE);
117 RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer, GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE);
118 }
119
120 /*
121 ==========================================================================
122 Description:
123 Beacon timeout handler, executed in timer thread
124
125 IRQL = DISPATCH_LEVEL
126
127 ==========================================================================
128 */
129 VOID BeaconTimeout(
130 IN PVOID SystemSpecific1,
131 IN PVOID FunctionContext,
132 IN PVOID SystemSpecific2,
133 IN PVOID SystemSpecific3)
134 {
135 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
136
137 DBGPRINT(RT_DEBUG_TRACE,("SYNC - BeaconTimeout\n"));
138
139 // Do nothing if the driver is starting halt state.
140 // This might happen when timer already been fired before cancel timer with mlmehalt
141 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
142 return;
143
144 #ifdef DOT11_N_SUPPORT
145 if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
146 )
147 {
148 UCHAR BBPValue = 0;
149 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
150 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
151 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
152 BBPValue &= (~0x18);
153 BBPValue |= 0x10;
154 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
155 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
156 }
157 #endif // DOT11_N_SUPPORT //
158
159 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL);
160 RT28XX_MLME_HANDLER(pAd);
161 }
162
163 /*
164 ==========================================================================
165 Description:
166 Scan timeout handler, executed in timer thread
167
168 IRQL = DISPATCH_LEVEL
169
170 ==========================================================================
171 */
172 VOID ScanTimeout(
173 IN PVOID SystemSpecific1,
174 IN PVOID FunctionContext,
175 IN PVOID SystemSpecific2,
176 IN PVOID SystemSpecific3)
177 {
178 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
179
180
181 // Do nothing if the driver is starting halt state.
182 // This might happen when timer already been fired before cancel timer with mlmehalt
183 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
184 return;
185
186 if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL))
187 {
188 RT28XX_MLME_HANDLER(pAd);
189 }
190 else
191 {
192 // To prevent SyncMachine.CurrState is SCAN_LISTEN forever.
193 pAd->MlmeAux.Channel = 0;
194 ScanNextChannel(pAd);
195 if (pAd->CommonCfg.bWirelessEvent)
196 {
197 RTMPSendWirelessEvent(pAd, IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
198 }
199 }
200 }
201
202 /*
203 ==========================================================================
204 Description:
205 MLME SCAN req state machine procedure
206 ==========================================================================
207 */
208 VOID MlmeScanReqAction(
209 IN PRTMP_ADAPTER pAd,
210 IN MLME_QUEUE_ELEM *Elem)
211 {
212 UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0;
213 BOOLEAN TimerCancelled;
214 ULONG Now;
215 USHORT Status;
216 PHEADER_802_11 pHdr80211;
217 PUCHAR pOutBuffer = NULL;
218 NDIS_STATUS NStatus;
219
220 // Check the total scan tries for one single OID command
221 // If this is the CCX 2.0 Case, skip that!
222 if ( !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
223 {
224 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeScanReqAction before Startup\n"));
225 return;
226 }
227
228 // Increase the scan retry counters.
229 pAd->StaCfg.ScanCnt++;
230
231 #ifdef RT2860
232 if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
233 (IDLE_ON(pAd)) &&
234 (pAd->StaCfg.bRadio == TRUE) &&
235 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
236 {
237 RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
238 }
239 #endif // RT2860 //
240
241 // first check the parameter sanity
242 if (MlmeScanReqSanity(pAd,
243 Elem->Msg,
244 Elem->MsgLen,
245 &BssType,
246 Ssid,
247 &SsidLen,
248 &ScanType))
249 {
250
251 // Check for channel load and noise hist request
252 // Suspend MSDU only at scan request, not the last two mentioned
253 if ((ScanType == SCAN_CISCO_NOISE) || (ScanType == SCAN_CISCO_CHANNEL_LOAD))
254 {
255 if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
256 RTMPSuspendMsduTransmission(pAd); // Suspend MSDU transmission here
257 }
258 else
259 {
260 // Suspend MSDU transmission here
261 RTMPSuspendMsduTransmission(pAd);
262 }
263
264 //
265 // To prevent data lost.
266 // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
267 // And should send an NULL data with turned PSM bit off to AP, when scan progress done
268 //
269 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
270 {
271 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
272 if (NStatus == NDIS_STATUS_SUCCESS)
273 {
274 pHdr80211 = (PHEADER_802_11) pOutBuffer;
275 MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
276 pHdr80211->Duration = 0;
277 pHdr80211->FC.Type = BTYPE_DATA;
278 pHdr80211->FC.PwrMgmt = PWR_SAVE;
279
280 // Send using priority queue
281 MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
282 DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
283 MlmeFreeMemory(pAd, pOutBuffer);
284 RTMPusecDelay(5000);
285 }
286 }
287
288 NdisGetSystemUpTime(&Now);
289 pAd->StaCfg.LastScanTime = Now;
290 // reset all the timers
291 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
292 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
293
294 // record desired BSS parameters
295 pAd->MlmeAux.BssType = BssType;
296 pAd->MlmeAux.ScanType = ScanType;
297 pAd->MlmeAux.SsidLen = SsidLen;
298 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
299 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
300
301 // start from the first channel
302 pAd->MlmeAux.Channel = FirstChannel(pAd);
303
304 // Change the scan channel when dealing with CCX beacon report
305 if ((ScanType == SCAN_CISCO_PASSIVE) || (ScanType == SCAN_CISCO_ACTIVE) ||
306 (ScanType == SCAN_CISCO_CHANNEL_LOAD) || (ScanType == SCAN_CISCO_NOISE))
307 pAd->MlmeAux.Channel = pAd->StaCfg.CCXScanChannel;
308
309 // Let BBP register at 20MHz to do scan
310 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
311 BBPValue &= (~0x18);
312 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
313 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
314 ScanNextChannel(pAd);
315 }
316 else
317 {
318 DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n"));
319 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
320 Status = MLME_INVALID_FORMAT;
321 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
322 }
323 }
324
325 /*
326 ==========================================================================
327 Description:
328 MLME JOIN req state machine procedure
329 ==========================================================================
330 */
331 VOID MlmeJoinReqAction(
332 IN PRTMP_ADAPTER pAd,
333 IN MLME_QUEUE_ELEM *Elem)
334 {
335 UCHAR BBPValue = 0;
336 BSS_ENTRY *pBss;
337 BOOLEAN TimerCancelled;
338 HEADER_802_11 Hdr80211;
339 NDIS_STATUS NStatus;
340 ULONG FrameLen = 0;
341 PUCHAR pOutBuffer = NULL;
342 PUCHAR pSupRate = NULL;
343 UCHAR SupRateLen;
344 PUCHAR pExtRate = NULL;
345 UCHAR ExtRateLen;
346 UCHAR ASupRate[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C};
347 UCHAR ASupRateLen = sizeof(ASupRate)/sizeof(UCHAR);
348 MLME_JOIN_REQ_STRUCT *pInfo = (MLME_JOIN_REQ_STRUCT *)(Elem->Msg);
349
350 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
351
352 #ifdef RT2860
353 if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
354 (IDLE_ON(pAd)) &&
355 (pAd->StaCfg.bRadio == TRUE) &&
356 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
357 {
358 RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
359 }
360 #endif // RT2860 //
361
362 // reset all the timers
363 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
364 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
365
366 pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx];
367
368 // record the desired SSID & BSSID we're waiting for
369 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid);
370
371 // If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again.
372 if (pBss->Hidden == 0)
373 {
374 NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen);
375 pAd->MlmeAux.SsidLen = pBss->SsidLen;
376 }
377
378 pAd->MlmeAux.BssType = pBss->BssType;
379 pAd->MlmeAux.Channel = pBss->Channel;
380 pAd->MlmeAux.CentralChannel = pBss->CentralChannel;
381
382 #ifdef EXT_BUILD_CHANNEL_LIST
383 // Country IE of the AP will be evaluated and will be used.
384 if ((pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None) &&
385 (pBss->bHasCountryIE == TRUE))
386 {
387 NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pBss->CountryString[0], 2);
388 if (pBss->CountryString[2] == 'I')
389 pAd->CommonCfg.Geography = IDOR;
390 else if (pBss->CountryString[2] == 'O')
391 pAd->CommonCfg.Geography = ODOR;
392 else
393 pAd->CommonCfg.Geography = BOTH;
394 BuildChannelListEx(pAd);
395 }
396 #endif // EXT_BUILD_CHANNEL_LIST //
397
398 // Let BBP register at 20MHz to do scan
399 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
400 BBPValue &= (~0x18);
401 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
402 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
403
404 // switch channel and waiting for beacon timer
405 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
406 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
407 RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT);
408
409 do
410 {
411 if (((pAd->CommonCfg.bIEEE80211H == 1) &&
412 (pAd->MlmeAux.Channel > 14) &&
413 RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
414 #ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
415 || (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
416 #endif // CARRIER_DETECTION_SUPPORT //
417 )
418 {
419 //
420 // We can't send any Probe request frame to meet 802.11h.
421 //
422 if (pBss->Hidden == 0)
423 break;
424 }
425
426 //
427 // send probe request
428 //
429 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
430 if (NStatus == NDIS_STATUS_SUCCESS)
431 {
432 if (pAd->MlmeAux.Channel <= 14)
433 {
434 pSupRate = pAd->CommonCfg.SupRate;
435 SupRateLen = pAd->CommonCfg.SupRateLen;
436 pExtRate = pAd->CommonCfg.ExtRate;
437 ExtRateLen = pAd->CommonCfg.ExtRateLen;
438 }
439 else
440 {
441 //
442 // Overwrite Support Rate, CCK rate are not allowed
443 //
444 pSupRate = ASupRate;
445 SupRateLen = ASupRateLen;
446 ExtRateLen = 0;
447 }
448
449 if (pAd->MlmeAux.BssType == BSS_INFRA)
450 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, pAd->MlmeAux.Bssid, pAd->MlmeAux.Bssid);
451 else
452 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
453
454 MakeOutgoingFrame(pOutBuffer, &FrameLen,
455 sizeof(HEADER_802_11), &Hdr80211,
456 1, &SsidIe,
457 1, &pAd->MlmeAux.SsidLen,
458 pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
459 1, &SupRateIe,
460 1, &SupRateLen,
461 SupRateLen, pSupRate,
462 END_OF_ARGS);
463
464 if (ExtRateLen)
465 {
466 ULONG Tmp;
467 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
468 1, &ExtRateIe,
469 1, &ExtRateLen,
470 ExtRateLen, pExtRate,
471 END_OF_ARGS);
472 FrameLen += Tmp;
473 }
474
475
476 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
477 MlmeFreeMemory(pAd, pOutBuffer);
478 }
479 } while (FALSE);
480
481 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n",
482 pBss->Channel, pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2], pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
483
484 pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON;
485 }
486
487 /*
488 ==========================================================================
489 Description:
490 MLME START Request state machine procedure, starting an IBSS
491 ==========================================================================
492 */
493 VOID MlmeStartReqAction(
494 IN PRTMP_ADAPTER pAd,
495 IN MLME_QUEUE_ELEM *Elem)
496 {
497 UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen;
498 BOOLEAN TimerCancelled;
499
500 // New for WPA security suites
501 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
502 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
503 LARGE_INTEGER TimeStamp;
504 BOOLEAN Privacy;
505 USHORT Status;
506
507 // Init Variable IE structure
508 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
509 pVIE->Length = 0;
510 TimeStamp.u.LowPart = 0;
511 TimeStamp.u.HighPart = 0;
512
513 if (MlmeStartReqSanity(pAd, Elem->Msg, Elem->MsgLen, Ssid, &SsidLen))
514 {
515 // reset all the timers
516 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
517 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
518
519 //
520 // Start a new IBSS. All IBSS parameters are decided now....
521 //
522 DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
523 pAd->MlmeAux.BssType = BSS_ADHOC;
524 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
525 pAd->MlmeAux.SsidLen = SsidLen;
526
527 // generate a radom number as BSSID
528 MacAddrRandomBssid(pAd, pAd->MlmeAux.Bssid);
529 DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - generate a radom number as BSSID \n"));
530
531 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
532 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
533 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
534 pAd->MlmeAux.CapabilityInfo = CAP_GENERATE(0,1,Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 1, 0);
535 pAd->MlmeAux.BeaconPeriod = pAd->CommonCfg.BeaconPeriod;
536 pAd->MlmeAux.AtimWin = pAd->StaCfg.AtimWin;
537 pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
538
539 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
540 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.CentralChannel;
541
542 pAd->MlmeAux.SupRateLen= pAd->CommonCfg.SupRateLen;
543 NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
544 RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
545 pAd->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen;
546 NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
547 RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
548 #ifdef DOT11_N_SUPPORT
549 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
550 {
551 RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy, &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0], &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo);
552 pAd->MlmeAux.HtCapabilityLen = sizeof(HT_CAPABILITY_IE);
553 // Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here.
554 DBGPRINT(RT_DEBUG_TRACE, ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
555 }
556 else
557 #endif // DOT11_N_SUPPORT //
558 {
559 pAd->MlmeAux.HtCapabilityLen = 0;
560 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
561 }
562 // temporarily not support QOS in IBSS
563 NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
564 NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
565 NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
566
567 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
568 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
569
570 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
571 pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
572
573 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
574 Status = MLME_SUCCESS;
575 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
576 }
577 else
578 {
579 DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n"));
580 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
581 Status = MLME_INVALID_FORMAT;
582 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
583 }
584 }
585
586 /*
587 ==========================================================================
588 Description:
589 peer sends beacon back when scanning
590 ==========================================================================
591 */
592 VOID PeerBeaconAtScanAction(
593 IN PRTMP_ADAPTER pAd,
594 IN MLME_QUEUE_ELEM *Elem)
595 {
596 UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
597 UCHAR Ssid[MAX_LEN_OF_SSID], BssType, Channel, NewChannel,
598 SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe;
599 CF_PARM CfParm;
600 USHORT BeaconPeriod, AtimWin, CapabilityInfo;
601 PFRAME_802_11 pFrame;
602 LARGE_INTEGER TimeStamp;
603 UCHAR Erp;
604 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
605 UCHAR SupRateLen, ExtRateLen;
606 USHORT LenVIE;
607 UCHAR CkipFlag;
608 UCHAR AironetCellPowerLimit;
609 EDCA_PARM EdcaParm;
610 QBSS_LOAD_PARM QbssLoad;
611 QOS_CAPABILITY_PARM QosCapability;
612 ULONG RalinkIe;
613 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
614 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
615 HT_CAPABILITY_IE HtCapability;
616 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
617 UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
618 UCHAR AddHtInfoLen;
619 UCHAR NewExtChannelOffset = 0xff;
620
621 pFrame = (PFRAME_802_11) Elem->Msg;
622 // Init Variable IE structure
623 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
624 pVIE->Length = 0;
625 #ifdef DOT11_N_SUPPORT
626 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
627 RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
628 #endif // DOT11_N_SUPPORT //
629
630 if (PeerBeaconAndProbeRspSanity(pAd,
631 Elem->Msg,
632 Elem->MsgLen,
633 Elem->Channel,
634 Addr2,
635 Bssid,
636 Ssid,
637 &SsidLen,
638 &BssType,
639 &BeaconPeriod,
640 &Channel,
641 &NewChannel,
642 &TimeStamp,
643 &CfParm,
644 &AtimWin,
645 &CapabilityInfo,
646 &Erp,
647 &DtimCount,
648 &DtimPeriod,
649 &BcastFlag,
650 &MessageToMe,
651 SupRate,
652 &SupRateLen,
653 ExtRate,
654 &ExtRateLen,
655 &CkipFlag,
656 &AironetCellPowerLimit,
657 &EdcaParm,
658 &QbssLoad,
659 &QosCapability,
660 &RalinkIe,
661 &HtCapabilityLen,
662 &PreNHtCapabilityLen,
663 &HtCapability,
664 &AddHtInfoLen,
665 &AddHtInfo,
666 &NewExtChannelOffset,
667 &LenVIE,
668 pVIE))
669 {
670 ULONG Idx;
671 CHAR Rssi = 0;
672
673 Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
674 if (Idx != BSS_NOT_FOUND)
675 Rssi = pAd->ScanTab.BssEntry[Idx].Rssi;
676
677 Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
678
679
680 #ifdef DOT11_N_SUPPORT
681 if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
682 HtCapabilityLen = SIZE_HT_CAP_IE;
683 #endif // DOT11_N_SUPPORT //
684 if ((pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) && (Channel == pAd->StaCfg.CCXScanChannel))
685 {
686 Idx = BssTableSetEntry(pAd, &pAd->StaCfg.CCXBssTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
687 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen,ExtRate, ExtRateLen, &HtCapability,
688 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
689 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
690 if (Idx != BSS_NOT_FOUND)
691 {
692 NdisMoveMemory(pAd->StaCfg.CCXBssTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
693 NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
694 NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
695 if (pAd->StaCfg.CCXReqType == MSRN_TYPE_BEACON_REQ)
696 AironetAddBeaconReport(pAd, Idx, Elem);
697 }
698 }
699 else
700 {
701 Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
702 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
703 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
704 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
705 #ifdef DOT11_N_SUPPORT
706 #ifdef DOT11N_DRAFT3
707 if (pAd->ChannelList[pAd->CommonCfg.ChannelListIdx].bEffectedChannel == TRUE)
708 {
709 UCHAR RegClass;
710 PeerBeaconAndProbeRspSanity2(pAd, Elem->Msg, Elem->MsgLen, &RegClass);
711 TriEventTableSetEntry(pAd, &pAd->CommonCfg.TriggerEventTab, Bssid, &HtCapability, HtCapabilityLen, RegClass, Channel);
712 }
713 #endif // DOT11N_DRAFT3 //
714 #endif // DOT11_N_SUPPORT //
715 if (Idx != BSS_NOT_FOUND)
716 {
717 NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
718 NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
719 NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
720 }
721 }
722 }
723 // sanity check fail, ignored
724 }
725
726 /*
727 ==========================================================================
728 Description:
729 When waiting joining the (I)BSS, beacon received from external
730 ==========================================================================
731 */
732 VOID PeerBeaconAtJoinAction(
733 IN PRTMP_ADAPTER pAd,
734 IN MLME_QUEUE_ELEM *Elem)
735 {
736 UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
737 UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe,
738 DtimCount, DtimPeriod, BcastFlag, NewChannel;
739 LARGE_INTEGER TimeStamp;
740 USHORT BeaconPeriod, AtimWin, CapabilityInfo;
741 CF_PARM Cf;
742 BOOLEAN TimerCancelled;
743 UCHAR Erp;
744 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
745 UCHAR SupRateLen, ExtRateLen;
746 UCHAR CkipFlag;
747 USHORT LenVIE;
748 UCHAR AironetCellPowerLimit;
749 EDCA_PARM EdcaParm;
750 QBSS_LOAD_PARM QbssLoad;
751 QOS_CAPABILITY_PARM QosCapability;
752 USHORT Status;
753 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
754 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
755 ULONG RalinkIe;
756 ULONG Idx;
757 HT_CAPABILITY_IE HtCapability;
758 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
759 UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
760 UCHAR AddHtInfoLen;
761 UCHAR NewExtChannelOffset = 0xff;
762 #ifdef DOT11_N_SUPPORT
763 UCHAR CentralChannel;
764 #endif // DOT11_N_SUPPORT //
765
766 // Init Variable IE structure
767 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
768 pVIE->Length = 0;
769 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
770 RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
771
772
773 if (PeerBeaconAndProbeRspSanity(pAd,
774 Elem->Msg,
775 Elem->MsgLen,
776 Elem->Channel,
777 Addr2,
778 Bssid,
779 Ssid,
780 &SsidLen,
781 &BssType,
782 &BeaconPeriod,
783 &Channel,
784 &NewChannel,
785 &TimeStamp,
786 &Cf,
787 &AtimWin,
788 &CapabilityInfo,
789 &Erp,
790 &DtimCount,
791 &DtimPeriod,
792 &BcastFlag,
793 &MessageToMe,
794 SupRate,
795 &SupRateLen,
796 ExtRate,
797 &ExtRateLen,
798 &CkipFlag,
799 &AironetCellPowerLimit,
800 &EdcaParm,
801 &QbssLoad,
802 &QosCapability,
803 &RalinkIe,
804 &HtCapabilityLen,
805 &PreNHtCapabilityLen,
806 &HtCapability,
807 &AddHtInfoLen,
808 &AddHtInfo,
809 &NewExtChannelOffset,
810 &LenVIE,
811 pVIE))
812 {
813 // Disqualify 11b only adhoc when we are in 11g only adhoc mode
814 if ((BssType == BSS_ADHOC) && (pAd->CommonCfg.PhyMode == PHY_11G) && ((SupRateLen+ExtRateLen)< 12))
815 return;
816
817 // BEACON from desired BSS/IBSS found. We should be able to decide most
818 // BSS parameters here.
819 // Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION?
820 // Do we need to receover back all parameters belonging to previous BSS?
821 // A. Should be not. There's no back-door recover to previous AP. It still need
822 // a new JOIN-AUTH-ASSOC sequence.
823 if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid))
824 {
825 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel));
826 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
827
828 // Update RSSI to prevent No signal display when cards first initialized
829 pAd->StaCfg.RssiSample.LastRssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0);
830 pAd->StaCfg.RssiSample.LastRssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1);
831 pAd->StaCfg.RssiSample.LastRssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2);
832 pAd->StaCfg.RssiSample.AvgRssi0 = pAd->StaCfg.RssiSample.LastRssi0;
833 pAd->StaCfg.RssiSample.AvgRssi0X8 = pAd->StaCfg.RssiSample.AvgRssi0 << 3;
834 pAd->StaCfg.RssiSample.AvgRssi1 = pAd->StaCfg.RssiSample.LastRssi1;
835 pAd->StaCfg.RssiSample.AvgRssi1X8 = pAd->StaCfg.RssiSample.AvgRssi1 << 3;
836 pAd->StaCfg.RssiSample.AvgRssi2 = pAd->StaCfg.RssiSample.LastRssi2;
837 pAd->StaCfg.RssiSample.AvgRssi2X8 = pAd->StaCfg.RssiSample.AvgRssi2 << 3;
838
839 //
840 // We need to check if SSID only set to any, then we can record the current SSID.
841 // Otherwise will cause hidden SSID association failed.
842 //
843 if (pAd->MlmeAux.SsidLen == 0)
844 {
845 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
846 pAd->MlmeAux.SsidLen = SsidLen;
847 }
848 else
849 {
850 Idx = BssSsidTableSearch(&pAd->ScanTab, Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Channel);
851
852 if (Idx != BSS_NOT_FOUND)
853 {
854 //
855 // Multiple SSID case, used correct CapabilityInfo
856 //
857 CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo;
858 }
859 }
860 NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN);
861 pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
862 pAd->MlmeAux.BssType = BssType;
863 pAd->MlmeAux.BeaconPeriod = BeaconPeriod;
864 pAd->MlmeAux.Channel = Channel;
865 pAd->MlmeAux.AtimWin = AtimWin;
866 pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod;
867 pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration;
868 pAd->MlmeAux.APRalinkIe = RalinkIe;
869
870 // Copy AP's supported rate to MlmeAux for creating assoication request
871 // Also filter out not supported rate
872 pAd->MlmeAux.SupRateLen = SupRateLen;
873 NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
874 RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
875 pAd->MlmeAux.ExtRateLen = ExtRateLen;
876 NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
877 RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
878
879 NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16);
880 #ifdef DOT11_N_SUPPORT
881 pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
882 pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen;
883
884 // filter out un-supported ht rates
885 if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
886 {
887 RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
888 RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, SIZE_ADD_HT_INFO_IE);
889
890 // StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability
891 NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16);
892 pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
893 pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE;
894 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
895 if (PreNHtCapabilityLen > 0)
896 pAd->StaActive.SupportedPhyInfo.bPreNHt = TRUE;
897 RTMPCheckHt(pAd, BSSID_WCID, &HtCapability, &AddHtInfo);
898 // Copy AP Parameter to StaActive. This is also in LinkUp.
899 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
900 pAd->StaActive.SupportedHtPhy.MpduDensity, pAd->StaActive.SupportedHtPhy.MaxRAmpduFactor, HtCapability.HtCapInfo.ChannelWidth));
901
902 if (AddHtInfoLen > 0)
903 {
904 CentralChannel = AddHtInfo.ControlChan;
905 // Check again the Bandwidth capability of this AP.
906 if ((AddHtInfo.ControlChan > 2)&& (AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
907 {
908 CentralChannel = AddHtInfo.ControlChan - 2;
909 }
910 else if ((AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
911 {
912 CentralChannel = AddHtInfo.ControlChan + 2;
913 }
914
915 // Check Error .
916 if (pAd->MlmeAux.CentralChannel != CentralChannel)
917 DBGPRINT(RT_DEBUG_ERROR, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel, AddHtInfo.ControlChan, pAd->MlmeAux.CentralChannel));
918
919 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel, AddHtInfo.ControlChan));
920
921 }
922
923 }
924 else
925 #endif // DOT11_N_SUPPORT //
926 {
927 // To prevent error, let legacy AP must have same CentralChannel and Channel.
928 if ((HtCapabilityLen == 0) && (PreNHtCapabilityLen == 0))
929 pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel;
930
931 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
932 RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
933 RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
934 }
935
936 RTMPUpdateMlmeRate(pAd);
937
938 // copy QOS related information
939 if ((pAd->CommonCfg.bWmmCapable)
940 #ifdef DOT11_N_SUPPORT
941 || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
942 #endif // DOT11_N_SUPPORT //
943 )
944 {
945 NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, &EdcaParm, sizeof(EDCA_PARM));
946 NdisMoveMemory(&pAd->MlmeAux.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
947 NdisMoveMemory(&pAd->MlmeAux.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
948 }
949 else
950 {
951 NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
952 NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
953 NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
954 }
955
956 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
957 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
958
959 #ifdef LEAP_SUPPORT
960 // Update CkipFlag
961 pAd->StaCfg.CkipFlag = CkipFlag;
962
963 // Keep TimeStamp for Re-Association used.
964 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
965 pAd->StaCfg.CCKMBeaconAtJoinTimeStamp = TimeStamp;
966 #endif // LEAP_SUPPORT //
967
968 if (AironetCellPowerLimit != 0xFF)
969 {
970 //We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power
971 ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
972 }
973 else //Used the default TX Power Percentage.
974 pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
975
976 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
977 Status = MLME_SUCCESS;
978 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
979 }
980 // not to me BEACON, ignored
981 }
982 // sanity check fail, ignore this frame
983 }
984
985 /*
986 ==========================================================================
987 Description:
988 receive BEACON from peer
989
990 IRQL = DISPATCH_LEVEL
991
992 ==========================================================================
993 */
994 VOID PeerBeacon(
995 IN PRTMP_ADAPTER pAd,
996 IN MLME_QUEUE_ELEM *Elem)
997 {
998 UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
999 CHAR Ssid[MAX_LEN_OF_SSID];
1000 CF_PARM CfParm;
1001 UCHAR SsidLen, MessageToMe=0, BssType, Channel, NewChannel, index=0;
1002 UCHAR DtimCount=0, DtimPeriod=0, BcastFlag=0;
1003 USHORT CapabilityInfo, AtimWin, BeaconPeriod;
1004 LARGE_INTEGER TimeStamp;
1005 USHORT TbttNumToNextWakeUp;
1006 UCHAR Erp;
1007 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
1008 UCHAR SupRateLen, ExtRateLen;
1009 UCHAR CkipFlag;
1010 USHORT LenVIE;
1011 UCHAR AironetCellPowerLimit;
1012 EDCA_PARM EdcaParm;
1013 QBSS_LOAD_PARM QbssLoad;
1014 QOS_CAPABILITY_PARM QosCapability;
1015 ULONG RalinkIe;
1016 // New for WPA security suites
1017 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
1018 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
1019 HT_CAPABILITY_IE HtCapability;
1020 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
1021 UCHAR HtCapabilityLen, PreNHtCapabilityLen;
1022 UCHAR AddHtInfoLen;
1023 UCHAR NewExtChannelOffset = 0xff;
1024
1025
1026 #ifdef RALINK_ATE
1027 if (ATE_ON(pAd))
1028 {
1029 return;
1030 }
1031 #endif // RALINK_ATE //
1032
1033 if (!(INFRA_ON(pAd) || ADHOC_ON(pAd)
1034 ))
1035 return;
1036
1037 // Init Variable IE structure
1038 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
1039 pVIE->Length = 0;
1040 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
1041 RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
1042
1043 if (PeerBeaconAndProbeRspSanity(pAd,
1044 Elem->Msg,
1045 Elem->MsgLen,
1046 Elem->Channel,
1047 Addr2,
1048 Bssid,
1049 Ssid,
1050 &SsidLen,
1051 &BssType,
1052 &BeaconPeriod,
1053 &Channel,
1054 &NewChannel,
1055 &TimeStamp,
1056 &CfParm,
1057 &AtimWin,
1058 &CapabilityInfo,
1059 &Erp,
1060 &DtimCount,
1061 &DtimPeriod,
1062 &BcastFlag,
1063 &MessageToMe,
1064 SupRate,
1065 &SupRateLen,
1066 ExtRate,
1067 &ExtRateLen,
1068 &CkipFlag,
1069 &AironetCellPowerLimit,
1070 &EdcaParm,
1071 &QbssLoad,
1072 &QosCapability,
1073 &RalinkIe,
1074 &HtCapabilityLen,
1075 &PreNHtCapabilityLen,
1076 &HtCapability,
1077 &AddHtInfoLen,
1078 &AddHtInfo,
1079 &NewExtChannelOffset,
1080 &LenVIE,
1081 pVIE))
1082 {
1083 BOOLEAN is_my_bssid, is_my_ssid;
1084 ULONG Bssidx, Now;
1085 BSS_ENTRY *pBss;
1086 CHAR RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
1087
1088 is_my_bssid = MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid)? TRUE : FALSE;
1089 is_my_ssid = SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)? TRUE:FALSE;
1090
1091
1092 // ignore BEACON not for my SSID
1093 if ((! is_my_ssid) && (! is_my_bssid))
1094 return;
1095
1096 // It means STA waits disassoc completely from this AP, ignores this beacon.
1097 if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC)
1098 return;
1099
1100 #ifdef DOT11_N_SUPPORT
1101 // Copy Control channel for this BSSID.
1102 if (AddHtInfoLen != 0)
1103 Channel = AddHtInfo.ControlChan;
1104
1105 if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
1106 HtCapabilityLen = SIZE_HT_CAP_IE;
1107 #endif // DOT11_N_SUPPORT //
1108
1109 //
1110 // Housekeeping "SsidBssTab" table for later-on ROAMing usage.
1111 //
1112 Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
1113 if (Bssidx == BSS_NOT_FOUND)
1114 {
1115 // discover new AP of this network, create BSS entry
1116 Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
1117 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,
1118 &HtCapability, &AddHtInfo,HtCapabilityLen,AddHtInfoLen,NewExtChannelOffset, Channel,
1119 RealRssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability,
1120 &QbssLoad, LenVIE, pVIE);
1121 if (Bssidx == BSS_NOT_FOUND) // return if BSS table full
1122 return;
1123
1124 NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4);
1125 NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
1126 NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
1127
1128
1129
1130 }
1131
1132 if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
1133 {
1134 // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
1135 // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
1136 AsicSwitchChannel(pAd, 1, FALSE);
1137 AsicLockChannel(pAd, 1);
1138 LinkDown(pAd, FALSE);
1139 MlmeQueueInit(&pAd->Mlme.Queue);
1140 BssTableInit(&pAd->ScanTab);
1141 RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
1142
1143 // channel sanity check
1144 for (index = 0 ; index < pAd->ChannelListNum; index++)
1145 {
1146 if (pAd->ChannelList[index].Channel == NewChannel)
1147 {
1148 pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
1149 pAd->CommonCfg.Channel = NewChannel;
1150 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1151 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1152 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
1153 break;
1154 }
1155 }
1156
1157 if (index >= pAd->ChannelListNum)
1158 {
1159 DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
1160 }
1161 }
1162
1163 // if the ssid matched & bssid unmatched, we should select the bssid with large value.
1164 // This might happened when two STA start at the same time
1165 if ((! is_my_bssid) && ADHOC_ON(pAd))
1166 {
1167 INT i;
1168
1169 // Add the safeguard against the mismatch of adhoc wep status
1170 if (pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus)
1171 {
1172 return;
1173 }
1174
1175 // collapse into the ADHOC network which has bigger BSSID value.
1176 for (i = 0; i < 6; i++)
1177 {
1178 if (Bssid[i] > pAd->CommonCfg.Bssid[i])
1179 {
1180 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
1181 Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
1182 AsicDisableSync(pAd);
1183 COPY_MAC_ADDR(pAd->CommonCfg.Bssid, Bssid);
1184 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1185 MakeIbssBeacon(pAd); // re-build BEACON frame
1186 AsicEnableIbssSync(pAd); // copy BEACON frame to on-chip memory
1187 is_my_bssid = TRUE;
1188 break;
1189 }
1190 else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
1191 break;
1192 }
1193 }
1194
1195
1196 NdisGetSystemUpTime(&Now);
1197 pBss = &pAd->ScanTab.BssEntry[Bssidx];
1198 pBss->Rssi = RealRssi; // lastest RSSI
1199 pBss->LastBeaconRxTime = Now; // last RX timestamp
1200
1201 //
1202 // BEACON from my BSSID - either IBSS or INFRA network
1203 //
1204 if (is_my_bssid)
1205 {
1206 RXWI_STRUC RxWI;
1207
1208 pAd->StaCfg.DtimCount = DtimCount;
1209 pAd->StaCfg.DtimPeriod = DtimPeriod;
1210 pAd->StaCfg.LastBeaconRxTime = Now;
1211
1212
1213 RxWI.RSSI0 = Elem->Rssi0;
1214 RxWI.RSSI1 = Elem->Rssi1;
1215 RxWI.RSSI2 = Elem->Rssi2;
1216
1217 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI);
1218 if (AironetCellPowerLimit != 0xFF)
1219 {
1220 //
1221 // We get the Cisco (ccx) "TxPower Limit" required
1222 // Changed to appropriate TxPower Limit for Ciso Compatible Extensions
1223 //
1224 ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
1225 }
1226 else
1227 {
1228 //
1229 // AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist.
1230 // Used the default TX Power Percentage, that set from UI.
1231 //
1232 pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
1233 }
1234
1235 // at least one 11b peer joined. downgrade the MaxTxRate to 11Mbps
1236 // after last 11b peer left for several seconds, we'll auto switch back to 11G rate
1237 // in MlmePeriodicExec()
1238 if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo)))
1239 {
1240 BOOLEAN bRestart;
1241 BOOLEAN bnRestart;
1242
1243 bRestart = FALSE;
1244 bnRestart = FALSE;
1245
1246 do
1247 {
1248 if ((SupRateLen+ExtRateLen <= 4) && (pAd->CommonCfg.MaxTxRate > RATE_11))
1249 {
1250 if (pAd->StaCfg.AdhocBOnlyJoined == FALSE)
1251 {
1252 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - 11b peer joined. down-grade to 11b TX rates \n"));
1253 bRestart = TRUE;
1254 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
1255 pAd->StaActive.SupRateLen = SupRateLen;
1256 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
1257 pAd->StaActive.ExtRateLen = ExtRateLen;
1258 pAd->StaCfg.AdhocBOnlyJoined = TRUE;
1259 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
1260 AsicSetEdcaParm(pAd, NULL);
1261 }
1262
1263 // this timestamp is for MlmePeriodicExec() to check if all 11B peers have left
1264 pAd->StaCfg.Last11bBeaconRxTime = Now;
1265 break;
1266 }
1267 #ifdef DOT11_N_SUPPORT
1268 // Update Ht Phy.
1269 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
1270 {
1271 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
1272 !pAd->StaCfg.AdhocBGJoined &&
1273 !pAd->StaCfg.AdhocBOnlyJoined)
1274 AdhocTurnOnQos(pAd);
1275
1276 // Handle rate switch issue when Adhoc mode
1277 if ((SupRateLen+ExtRateLen >= 8) && (HtCapability.MCSSet[0] == 0) && (HtCapability.MCSSet[1] == 0))
1278 {
1279 if (pAd->StaCfg.AdhocBGJoined == FALSE)
1280 {
1281 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - 11g peer joined. down-grade to 11g TX rates \n"));
1282 bRestart = TRUE;
1283 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
1284 pAd->StaActive.SupRateLen = SupRateLen;
1285 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
1286 pAd->StaActive.ExtRateLen = ExtRateLen;
1287 pAd->StaCfg.AdhocBGJoined = TRUE;
1288 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
1289 AsicSetEdcaParm(pAd, NULL);
1290 }
1291
1292 // this timestamp is for MlmePeriodicExec() to check if all 11g peers have left
1293 pAd->StaCfg.Last11gBeaconRxTime = Now;
1294 break;
1295 }
1296 else if (!pAd->StaCfg.AdhocBGJoined &&
1297 !pAd->StaCfg.AdhocBOnlyJoined &&
1298 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) &&
1299 (HtCapability.HtCapInfo.ChannelWidth == BW_20))
1300 {
1301 if (pAd->StaCfg.Adhoc20NJoined == FALSE)
1302 {
1303 UCHAR ByteValue = 0;
1304
1305 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1306
1307 pAd->StaCfg.Adhoc20NJoined = TRUE;
1308 NdisMoveMemory(&pAd->MlmeAux.HtCapability, &HtCapability, SIZE_HT_CAP_IE);
1309 if (AddHtInfoLen != 0)
1310 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, AddHtInfoLen);
1311 NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16);
1312
1313 RTMPCheckHt(pAd, Elem->Wcid, &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo);
1314 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1315 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
1316 bRestart = TRUE;
1317 bnRestart = TRUE;
1318 }
1319 // this timestamp is for MlmePeriodicExec() to check if all 20MHz N peers have left
1320 pAd->StaCfg.Last20NBeaconRxTime = Now;
1321 }
1322
1323 }
1324 else
1325 #endif // DOT11_N_SUPPORT //
1326 {
1327 RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
1328 RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
1329 }
1330 }while (FALSE);
1331
1332 // If peer Adhoc is legacy mode, I don't need to call MlmeUpdateHtTxRates no matter I support HT or not
1333 if ((bRestart == TRUE) && (bnRestart == FALSE))
1334 {
1335 MlmeUpdateTxRates(pAd, FALSE, 0);
1336 MakeIbssBeacon(pAd); // re-build BEACON frame
1337 AsicEnableIbssSync(pAd); // copy to on-chip memory
1338 }
1339 #ifdef DOT11_N_SUPPORT
1340 else if ((bRestart == TRUE) && (bnRestart == TRUE))
1341 {
1342 MlmeUpdateTxRates(pAd, FALSE, BSS0);
1343 MlmeUpdateHtTxRates(pAd, BSS0);
1344 MakeIbssBeacon(pAd); // re-build BEACON frame
1345 AsicEnableIbssSync(pAd); // copy to on-chip memory
1346 }
1347 #endif // DOT11_N_SUPPORT //
1348
1349 // At least another peer in this IBSS, declare MediaState as CONNECTED
1350 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1351 {
1352 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1353
1354 pAd->IndicateMediaState = NdisMediaStateConnected;
1355 RTMP_IndicateMediaState(pAd);
1356 pAd->ExtraInfo = GENERAL_LINK_UP;
1357 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1358
1359 // 2003/03/12 - john
1360 // Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
1361 // "site survey" result should always include the current connected network.
1362 //
1363 Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
1364 if (Bssidx == BSS_NOT_FOUND)
1365 {
1366 Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
1367 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
1368 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0,
1369 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
1370 }
1371 DBGPRINT(RT_DEBUG_TRACE, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
1372 }
1373
1374 // Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
1375 // To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
1376 if (ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID))
1377 {
1378 UCHAR idx;
1379 MAC_TABLE_ENTRY *pEntry;
1380
1381 // look up the existing table
1382 pEntry = MacTableLookup(pAd, Addr2);
1383 if (pEntry == NULL)
1384 {
1385 // Another adhoc joining, add to our MAC table.
1386 pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE);
1387 if (pEntry)
1388 {
1389 pEntry->Sst = SST_ASSOC;
1390 idx = pAd->StaCfg.DefaultKeyId;
1391 // After InsertEntry, Write to ASIC on-chip table.
1392 RT28XX_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry);
1393 DBGPRINT(RT_DEBUG_TRACE, ("ADHOC %x:%x:%x:%x:%x:%x join in.Entry=%d\n", Addr2[0],Addr2[1],Addr2[2],Addr2[3],Addr2[4],Addr2[5], pEntry->Aid));
1394
1395 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1396 if (HtCapabilityLen <= 0)
1397 {
1398 pEntry->HTPhyMode.field.STBC = 0;
1399 pEntry->HTPhyMode.field.BW = 0;
1400 pEntry->HTPhyMode.field.ShortGI = 0;
1401 if ((SupRateLen+ExtRateLen <= 4) && (pAd->CommonCfg.Channel <= 14))
1402 {
1403 pEntry->HTPhyMode.field.MODE = MODE_CCK;
1404 }
1405 else
1406 {
1407 pEntry->HTPhyMode.field.MODE = MODE_OFDM;
1408 }
1409 MlmeUpdateTxRates(pAd, FALSE, 0);
1410 }
1411 #ifdef DOT11_N_SUPPORT
1412 else
1413 {
1414 MlmeUpdateTxRates(pAd, FALSE, 0);
1415 MlmeUpdateHtTxRates(pAd, BSS0);
1416 }
1417 #endif // DOT11_N_SUPPORT //
1418
1419 #ifdef WPA_SUPPLICANT_SUPPORT
1420 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1421 if (pAd->StaCfg.WpaSupplicantUP)
1422 {
1423 union iwreq_data wrqu;
1424
1425 SendAssocIEsToWpaSupplicant(pAd);
1426 memset(&wrqu, 0, sizeof(wrqu));
1427 wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
1428 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1429 }
1430 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1431 #endif // WPA_SUPPLICANT_SUPPORT //
1432
1433 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1434 {
1435 union iwreq_data wrqu;
1436 wext_notify_event_assoc(pAd);
1437
1438 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1439 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
1440 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1441
1442 }
1443 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1444 }
1445 }
1446 }
1447 }
1448
1449 if (INFRA_ON(pAd))
1450 {
1451 BOOLEAN bUseShortSlot, bUseBGProtection;
1452
1453 // decide to use/change to -
1454 // 1. long slot (20 us) or short slot (9 us) time
1455 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1456 // 3. short preamble
1457
1458 //bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo);
1459 bUseShortSlot = CAP_IS_SHORT_SLOT(CapabilityInfo);
1460 if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
1461 AsicSetSlotTime(pAd, bUseShortSlot);
1462
1463 bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || // always use
1464 ((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(Erp));
1465
1466 if (pAd->CommonCfg.Channel > 14) // always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP
1467 bUseBGProtection = FALSE;
1468
1469 if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
1470 {
1471 if (bUseBGProtection)
1472 {
1473 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1474 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),FALSE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
1475 }
1476 else
1477 {
1478 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1479 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),TRUE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
1480 }
1481
1482 DBGPRINT(RT_DEBUG_WARN, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection));
1483 }
1484
1485 #ifdef DOT11_N_SUPPORT
1486 // check Ht protection mode. and adhere to the Non-GF device indication by AP.
1487 if ((AddHtInfoLen != 0) &&
1488 ((AddHtInfo.AddHtInfo2.OperaionMode != pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode) ||
1489 (AddHtInfo.AddHtInfo2.NonGfPresent != pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent)))
1490 {
1491 pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent = AddHtInfo.AddHtInfo2.NonGfPresent;
1492 pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode = AddHtInfo.AddHtInfo2.OperaionMode;
1493 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1494 {
1495 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1496 }
1497 else
1498 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1499
1500 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP changed N OperaionMode to %d\n", pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode));
1501 }
1502 #endif // DOT11_N_SUPPORT //
1503
1504 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) &&
1505 ERP_IS_USE_BARKER_PREAMBLE(Erp))
1506 {
1507 MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
1508 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP forced to use LONG preamble\n"));
1509 }
1510
1511 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
1512 (EdcaParm.bValid == TRUE) &&
1513 (EdcaParm.EdcaUpdateCount != pAd->CommonCfg.APEdcaParm.EdcaUpdateCount))
1514 {
1515 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP change EDCA parameters(from %d to %d)\n",
1516 pAd->CommonCfg.APEdcaParm.EdcaUpdateCount,
1517 EdcaParm.EdcaUpdateCount));
1518 AsicSetEdcaParm(pAd, &EdcaParm);
1519 }
1520
1521 // copy QOS related information
1522 NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
1523 NdisMoveMemory(&pAd->CommonCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
1524 }
1525
1526 // only INFRASTRUCTURE mode support power-saving feature
1527 if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE)) || (pAd->CommonCfg.bAPSDForcePowerSave))
1528 {
1529 UCHAR FreeNumber;
1530 // 1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL
1531 // 2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE
1532 // 3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE
1533 // 4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE
1534 // 5. otherwise, put PHY back to sleep to save battery.
1535 if (MessageToMe)
1536 {
1537 #ifdef RT2860
1538 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1539 {
1540 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
1541 // Turn clk to 80Mhz.
1542 }
1543 #endif // RT2860 //
1544 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable &&
1545 pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO)
1546 {
1547 pAd->CommonCfg.bNeedSendTriggerFrame = TRUE;
1548 }
1549 else
1550 RT28XX_PS_POLL_ENQUEUE(pAd);
1551 }
1552 else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
1553 {
1554 #ifdef RT2860
1555 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1556 {
1557 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
1558 }
1559 #endif // RT2860 //
1560 }
1561 else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) ||
1562 (pAd->TxSwQueue[QID_AC_BE].Number != 0) ||
1563 (pAd->TxSwQueue[QID_AC_VI].Number != 0) ||
1564 (pAd->TxSwQueue[QID_AC_VO].Number != 0) ||
1565 (RTMPFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1566 (RTMPFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1567 (RTMPFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1568 (RTMPFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1569 (RTMPFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS))
1570 {
1571 // TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
1572 // can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
1573 #ifdef RT2860
1574 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1575 {
1576 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
1577 }
1578 #endif // RT2860 //
1579 }
1580 else
1581 {
1582 USHORT NextDtim = DtimCount;
1583
1584 if (NextDtim == 0)
1585 NextDtim = DtimPeriod;
1586
1587 TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
1588 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
1589 TbttNumToNextWakeUp = NextDtim;
1590
1591 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1592 {
1593 AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
1594 }
1595 }
1596 }
1597 }
1598 // not my BSSID, ignore it
1599 }
1600 // sanity check fail, ignore this frame
1601 }
1602
1603 /*
1604 ==========================================================================
1605 Description:
1606 Receive PROBE REQ from remote peer when operating in IBSS mode
1607 ==========================================================================
1608 */
1609 VOID PeerProbeReqAction(
1610 IN PRTMP_ADAPTER pAd,
1611 IN MLME_QUEUE_ELEM *Elem)
1612 {
1613 UCHAR Addr2[MAC_ADDR_LEN];
1614 CHAR Ssid[MAX_LEN_OF_SSID];
1615 UCHAR SsidLen;
1616 #ifdef DOT11_N_SUPPORT
1617 UCHAR HtLen, AddHtLen, NewExtLen;
1618 #endif // DOT11_N_SUPPORT //
1619 HEADER_802_11 ProbeRspHdr;
1620 NDIS_STATUS NStatus;
1621 PUCHAR pOutBuffer = NULL;
1622 ULONG FrameLen = 0;
1623 LARGE_INTEGER FakeTimestamp;
1624 UCHAR DsLen = 1, IbssLen = 2;
1625 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0};
1626 BOOLEAN Privacy;
1627 USHORT CapabilityInfo;
1628 UCHAR RSNIe = IE_WPA;
1629
1630 if (! ADHOC_ON(pAd))
1631 return;
1632
1633 if (PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen))
1634 {
1635 if ((SsidLen == 0) || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
1636 {
1637 // allocate and send out ProbeRsp frame
1638 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1639 if (NStatus != NDIS_STATUS_SUCCESS)
1640 return;
1641
1642 //pAd->StaCfg.AtimWin = 0; // ??????
1643
1644 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
1645 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
1646 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
1647 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
1648
1649 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1650 sizeof(HEADER_802_11), &ProbeRspHdr,
1651 TIMESTAMP_LEN, &FakeTimestamp,
1652 2, &pAd->CommonCfg.BeaconPeriod,
1653 2, &CapabilityInfo,
1654 1, &SsidIe,
1655 1, &pAd->CommonCfg.SsidLen,
1656 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
1657 1, &SupRateIe,
1658 1, &pAd->StaActive.SupRateLen,
1659 pAd->StaActive.SupRateLen, pAd->StaActive.SupRate,
1660 1, &DsIe,
1661 1, &DsLen,
1662 1, &pAd->CommonCfg.Channel,
1663 1, &IbssIe,
1664 1, &IbssLen,
1665 2, &pAd->StaActive.AtimWin,
1666 END_OF_ARGS);
1667
1668 if (pAd->StaActive.ExtRateLen)
1669 {
1670 ULONG tmp;
1671 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1672 3, LocalErpIe,
1673 1, &ExtRateIe,
1674 1, &pAd->StaActive.ExtRateLen,
1675 pAd->StaActive.ExtRateLen, &pAd->StaActive.ExtRate,
1676 END_OF_ARGS);
1677 FrameLen += tmp;
1678 }
1679
1680 // If adhoc secruity is set for WPA-None, append the cipher suite IE
1681 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1682 {
1683 ULONG tmp;
1684 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1685 1, &RSNIe,
1686 1, &pAd->StaCfg.RSNIE_Len,
1687 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
1688 END_OF_ARGS);
1689 FrameLen += tmp;
1690 }
1691 #ifdef DOT11_N_SUPPORT
1692 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1693 {
1694 ULONG TmpLen;
1695 UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
1696 HtLen = sizeof(pAd->CommonCfg.HtCapability);
1697 AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);
1698 NewExtLen = 1;
1699 //New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame
1700 if (pAd->bBroadComHT == TRUE)
1701 {
1702 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
1703 1, &WpaIe,
1704 4, &BROADCOM[0],
1705 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
1706 END_OF_ARGS);
1707 }
1708 else
1709 {
1710 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
1711 1, &HtCapIe,
1712 1, &HtLen,
1713 sizeof(HT_CAPABILITY_IE), &pAd->CommonCfg.HtCapability,
1714 1, &AddHtInfoIe,
1715 1, &AddHtLen,
1716 sizeof(ADD_HT_INFO_IE), &pAd->CommonCfg.AddHTInfo,
1717 1, &NewExtChanIe,
1718 1, &NewExtLen,
1719 sizeof(NEW_EXT_CHAN_IE), &pAd->CommonCfg.NewExtChanOffset,
1720 END_OF_ARGS);
1721 }
1722 FrameLen += TmpLen;
1723 }
1724 #endif // DOT11_N_SUPPORT //
1725 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1726 MlmeFreeMemory(pAd, pOutBuffer);
1727 }
1728 }
1729 }
1730
1731 VOID BeaconTimeoutAtJoinAction(
1732 IN PRTMP_ADAPTER pAd,
1733 IN MLME_QUEUE_ELEM *Elem)
1734 {
1735 USHORT Status;
1736 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n"));
1737 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1738 Status = MLME_REJ_TIMEOUT;
1739 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1740 }
1741
1742 /*
1743 ==========================================================================
1744 Description:
1745 Scan timeout procedure. basically add channel index by 1 and rescan
1746 ==========================================================================
1747 */
1748 VOID ScanTimeoutAction(
1749 IN PRTMP_ADAPTER pAd,
1750 IN MLME_QUEUE_ELEM *Elem)
1751 {
1752 pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
1753
1754 // Only one channel scanned for CISCO beacon request
1755 if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) ||
1756 (pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) ||
1757 (pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) ||
1758 (pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD))
1759 pAd->MlmeAux.Channel = 0;
1760
1761 // this routine will stop if pAd->MlmeAux.Channel == 0
1762 ScanNextChannel(pAd);
1763 }
1764
1765 /*
1766 ==========================================================================
1767 Description:
1768 ==========================================================================
1769 */
1770 VOID InvalidStateWhenScan(
1771 IN PRTMP_ADAPTER pAd,
1772 IN MLME_QUEUE_ELEM *Elem)
1773 {
1774 USHORT Status;
1775 DBGPRINT(RT_DEBUG_TRACE, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1776 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1777 Status = MLME_STATE_MACHINE_REJECT;
1778 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
1779 }
1780
1781 /*
1782 ==========================================================================
1783 Description:
1784 ==========================================================================
1785 */
1786 VOID InvalidStateWhenJoin(
1787 IN PRTMP_ADAPTER pAd,
1788 IN MLME_QUEUE_ELEM *Elem)
1789 {
1790 USHORT Status;
1791 DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1792 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1793 Status = MLME_STATE_MACHINE_REJECT;
1794 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1795 }
1796
1797 /*
1798 ==========================================================================
1799 Description:
1800 ==========================================================================
1801 */
1802 VOID InvalidStateWhenStart(
1803 IN PRTMP_ADAPTER pAd,
1804 IN MLME_QUEUE_ELEM *Elem)
1805 {
1806 USHORT Status;
1807 DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1808 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1809 Status = MLME_STATE_MACHINE_REJECT;
1810 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
1811 }
1812
1813 /*
1814 ==========================================================================
1815 Description:
1816
1817 IRQL = DISPATCH_LEVEL
1818
1819 ==========================================================================
1820 */
1821 VOID EnqueuePsPoll(
1822 IN PRTMP_ADAPTER pAd)
1823 {
1824 #ifdef RALINK_ATE
1825 if (ATE_ON(pAd))
1826 {
1827 return;
1828 }
1829 #endif // RALINK_ATE //
1830
1831
1832 if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP)
1833 pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE;
1834 MiniportMMRequest(pAd, 0, (PUCHAR)&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
1835 }
1836
1837
1838 /*
1839 ==========================================================================
1840 Description:
1841 ==========================================================================
1842 */
1843 VOID EnqueueProbeRequest(
1844 IN PRTMP_ADAPTER pAd)
1845 {
1846 NDIS_STATUS NState;
1847 PUCHAR pOutBuffer;
1848 ULONG FrameLen = 0;
1849 HEADER_802_11 Hdr80211;
1850
1851 DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
1852
1853 NState = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1854 if (NState == NDIS_STATUS_SUCCESS)
1855 {
1856 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
1857
1858 // this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse
1859 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1860 sizeof(HEADER_802_11), &Hdr80211,
1861 1, &SsidIe,
1862 1, &pAd->CommonCfg.SsidLen,
1863 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
1864 1, &SupRateIe,
1865 1, &pAd->StaActive.SupRateLen,
1866 pAd->StaActive.SupRateLen, pAd->StaActive.SupRate,
1867 END_OF_ARGS);
1868 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1869 MlmeFreeMemory(pAd, pOutBuffer);
1870 }
1871
1872 }
1873
1874 #ifdef DOT11_N_SUPPORT
1875 #ifdef DOT11N_DRAFT3
1876 VOID BuildEffectedChannelList(
1877 IN PRTMP_ADAPTER pAd)
1878 {
1879 UCHAR EChannel[11];
1880 UCHAR i, j, k;
1881 UCHAR UpperChannel = 0, LowerChannel = 0;
1882
1883 RTMPZeroMemory(EChannel, 11);
1884 i = 0;
1885 // Find upper channel and lower channel.
1886 if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
1887 {
1888 UpperChannel = pAd->CommonCfg.Channel;
1889 LowerChannel = pAd->CommonCfg.CentralChannel;
1890 }
1891 else if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
1892 {
1893 UpperChannel = pAd->CommonCfg.CentralChannel;
1894 LowerChannel = pAd->CommonCfg.Channel;
1895 }
1896 else
1897 {
1898 return;
1899 }
1900
1901 // Record channels that is below lower channel..
1902 if (LowerChannel > 1)
1903 {
1904 EChannel[0] = LowerChannel - 1;
1905 i = 1;
1906 if (LowerChannel > 2)
1907 {
1908 EChannel[1] = LowerChannel - 2;
1909 i = 2;
1910 if (LowerChannel > 3)
1911 {
1912 EChannel[2] = LowerChannel - 3;
1913 i = 3;
1914 }
1915 }
1916 }
1917 // Record channels that is between lower channel and upper channel.
1918 for (k = LowerChannel;k < UpperChannel;k++)
1919 {
1920 EChannel[i] = k;
1921 i++;
1922 }
1923 // Record channels that is above upper channel..
1924 if (LowerChannel < 11)
1925 {
1926 EChannel[i] = UpperChannel + 1;
1927 i++;
1928 if (LowerChannel < 10)
1929 {
1930 EChannel[i] = LowerChannel + 2;
1931 i++;
1932 if (LowerChannel < 9)
1933 {
1934 EChannel[i] = LowerChannel + 3;
1935 i++;
1936 }
1937 }
1938 }
1939 //
1940 for (j = 0;j < i;j++)
1941 {
1942 for (k = 0;k < pAd->ChannelListNum;k++)
1943 {
1944 if (pAd->ChannelList[k].Channel == EChannel[j])
1945 {
1946 pAd->ChannelList[k].bEffectedChannel = TRUE;
1947 DBGPRINT(RT_DEBUG_TRACE,(" EffectedChannel( =%d)\n", EChannel[j]));
1948 break;
1949 }
1950 }
1951 }
1952 }
1953 #endif // DOT11N_DRAFT3 //
1954 #endif // DOT11_N_SUPPORT //
1955
1956 BOOLEAN ScanRunning(
1957 IN PRTMP_ADAPTER pAd)
1958 {
1959 return (pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE;
1960 }
1961