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