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