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