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