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