Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.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 %02x:%02x:%02x:%02x:%02x:%02x\n",
428                   pBss->Channel, pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2],
429                   pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
430
431         pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON;
432 }
433
434 /*
435         ==========================================================================
436         Description:
437                 MLME START Request state machine procedure, starting an IBSS
438         ==========================================================================
439  */
440 void MlmeStartReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
441 {
442         u8 Ssid[MAX_LEN_OF_SSID], SsidLen;
443         BOOLEAN TimerCancelled;
444
445         /* New for WPA security suites */
446         u8 VarIE[MAX_VIE_LEN];  /* Total VIE length = MAX_VIE_LEN - -5 */
447         struct rt_ndis_802_11_variable_ies *pVIE = NULL;
448         LARGE_INTEGER TimeStamp;
449         BOOLEAN Privacy;
450         u16 Status;
451
452         /* Init Variable IE structure */
453         pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
454         pVIE->Length = 0;
455         TimeStamp.u.LowPart = 0;
456         TimeStamp.u.HighPart = 0;
457
458         if (MlmeStartReqSanity
459             (pAd, Elem->Msg, Elem->MsgLen, (char *)Ssid, &SsidLen)) {
460                 /* reset all the timers */
461                 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
462                 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
463
464                 /* */
465                 /* Start a new IBSS. All IBSS parameters are decided now.... */
466                 /* */
467                 DBGPRINT(RT_DEBUG_TRACE,
468                          ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
469                 pAd->MlmeAux.BssType = BSS_ADHOC;
470                 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
471                 pAd->MlmeAux.SsidLen = SsidLen;
472
473                 /* generate a radom number as BSSID */
474                 MacAddrRandomBssid(pAd, pAd->MlmeAux.Bssid);
475                 DBGPRINT(RT_DEBUG_TRACE,
476                          ("MlmeStartReqAction - generate a radom number as BSSID \n"));
477
478                 Privacy =
479                     (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
480                     || (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
481                     || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
482                 pAd->MlmeAux.CapabilityInfo =
483                     CAP_GENERATE(0, 1, Privacy,
484                                  (pAd->CommonCfg.TxPreamble ==
485                                   Rt802_11PreambleShort), 1, 0);
486                 pAd->MlmeAux.BeaconPeriod = pAd->CommonCfg.BeaconPeriod;
487                 pAd->MlmeAux.AtimWin = pAd->StaCfg.AtimWin;
488                 pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
489
490                 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
491                 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.CentralChannel;
492
493                 pAd->MlmeAux.SupRateLen = pAd->CommonCfg.SupRateLen;
494                 NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate,
495                                MAX_LEN_OF_SUPPORTED_RATES);
496                 RTMPCheckRates(pAd, pAd->MlmeAux.SupRate,
497                                &pAd->MlmeAux.SupRateLen);
498                 pAd->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen;
499                 NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate,
500                                MAX_LEN_OF_SUPPORTED_RATES);
501                 RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate,
502                                &pAd->MlmeAux.ExtRateLen);
503
504                 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
505                         RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy,
506                                        &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0],
507                                        &pAd->MlmeAux.HtCapability,
508                                        &pAd->MlmeAux.AddHtInfo);
509                         pAd->MlmeAux.HtCapabilityLen = sizeof(struct rt_ht_capability_ie);
510                         /* Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here. */
511                         DBGPRINT(RT_DEBUG_TRACE,
512                                  ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
513                 } else {
514                         pAd->MlmeAux.HtCapabilityLen = 0;
515                         pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
516                         NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.
517                                        MCSSet[0], 16);
518                 }
519                 /* temporarily not support QOS in IBSS */
520                 NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(struct rt_edca_parm));
521                 NdisZeroMemory(&pAd->MlmeAux.APQbssLoad,
522                                sizeof(struct rt_qbss_load_parm));
523                 NdisZeroMemory(&pAd->MlmeAux.APQosCapability,
524                                sizeof(struct rt_qos_capability_parm));
525
526                 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
527                 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
528
529                 DBGPRINT(RT_DEBUG_TRACE,
530                          ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
531                           pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen,
532                           pAd->MlmeAux.ExtRateLen));
533
534                 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
535                 Status = MLME_SUCCESS;
536                 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2,
537                             &Status);
538         } else {
539                 DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n"));
540                 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
541                 Status = MLME_INVALID_FORMAT;
542                 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2,
543                             &Status);
544         }
545 }
546
547 /*
548         ==========================================================================
549         Description:
550                 peer sends beacon back when scanning
551         ==========================================================================
552  */
553 void PeerBeaconAtScanAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
554 {
555         u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
556         u8 Ssid[MAX_LEN_OF_SSID], BssType, Channel, NewChannel,
557             SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe;
558         struct rt_cf_parm CfParm;
559         u16 BeaconPeriod, AtimWin, CapabilityInfo;
560         struct rt_frame_802_11 * pFrame;
561         LARGE_INTEGER TimeStamp;
562         u8 Erp;
563         u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
564             ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
565         u8 SupRateLen, ExtRateLen;
566         u16 LenVIE;
567         u8 CkipFlag;
568         u8 AironetCellPowerLimit;
569         struct rt_edca_parm EdcaParm;
570         struct rt_qbss_load_parm QbssLoad;
571         struct rt_qos_capability_parm QosCapability;
572         unsigned long RalinkIe;
573         u8 VarIE[MAX_VIE_LEN];  /* Total VIE length = MAX_VIE_LEN - -5 */
574         struct rt_ndis_802_11_variable_ies *pVIE = NULL;
575         struct rt_ht_capability_ie HtCapability;
576         struct rt_add_ht_info_ie AddHtInfo;     /* AP might use this additional ht info IE */
577         u8 HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
578         u8 AddHtInfoLen;
579         u8 NewExtChannelOffset = 0xff;
580
581         /* NdisFillMemory(Ssid, MAX_LEN_OF_SSID, 0x00); */
582         pFrame = (struct rt_frame_802_11 *) Elem->Msg;
583         /* Init Variable IE structure */
584         pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
585         pVIE->Length = 0;
586
587         RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
588         RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
589
590         if (PeerBeaconAndProbeRspSanity(pAd,
591                                         Elem->Msg,
592                                         Elem->MsgLen,
593                                         Elem->Channel,
594                                         Addr2,
595                                         Bssid,
596                                         (char *)Ssid,
597                                         &SsidLen,
598                                         &BssType,
599                                         &BeaconPeriod,
600                                         &Channel,
601                                         &NewChannel,
602                                         &TimeStamp,
603                                         &CfParm,
604                                         &AtimWin,
605                                         &CapabilityInfo,
606                                         &Erp,
607                                         &DtimCount,
608                                         &DtimPeriod,
609                                         &BcastFlag,
610                                         &MessageToMe,
611                                         SupRate,
612                                         &SupRateLen,
613                                         ExtRate,
614                                         &ExtRateLen,
615                                         &CkipFlag,
616                                         &AironetCellPowerLimit,
617                                         &EdcaParm,
618                                         &QbssLoad,
619                                         &QosCapability,
620                                         &RalinkIe,
621                                         &HtCapabilityLen,
622                                         &PreNHtCapabilityLen,
623                                         &HtCapability,
624                                         &AddHtInfoLen,
625                                         &AddHtInfo,
626                                         &NewExtChannelOffset, &LenVIE, pVIE)) {
627                 unsigned long Idx;
628                 char Rssi = 0;
629
630                 Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
631                 if (Idx != BSS_NOT_FOUND)
632                         Rssi = pAd->ScanTab.BssEntry[Idx].Rssi;
633
634                 Rssi =
635                     RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
636                                 ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
637                                 ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
638
639                 if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
640                         HtCapabilityLen = SIZE_HT_CAP_IE;
641
642                 Idx =
643                     BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (char *)Ssid,
644                                      SsidLen, BssType, BeaconPeriod, &CfParm,
645                                      AtimWin, CapabilityInfo, SupRate,
646                                      SupRateLen, ExtRate, ExtRateLen,
647                                      &HtCapability, &AddHtInfo, HtCapabilityLen,
648                                      AddHtInfoLen, NewExtChannelOffset, Channel,
649                                      Rssi, TimeStamp, CkipFlag, &EdcaParm,
650                                      &QosCapability, &QbssLoad, LenVIE, pVIE);
651
652                 if (Idx != BSS_NOT_FOUND) {
653                         NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF,
654                                        &Elem->Msg[24], 4);
655                         NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0],
656                                        &Elem->TimeStamp.u.LowPart, 4);
657                         NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4],
658                                        &Elem->TimeStamp.u.LowPart, 4);
659                 }
660
661         }
662         /* sanity check fail, ignored */
663 }
664
665 /*
666         ==========================================================================
667         Description:
668                 When waiting joining the (I)BSS, beacon received from external
669         ==========================================================================
670  */
671 void PeerBeaconAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
672 {
673         u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
674         u8 Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe,
675             DtimCount, DtimPeriod, BcastFlag, NewChannel;
676         LARGE_INTEGER TimeStamp;
677         u16 BeaconPeriod, AtimWin, CapabilityInfo;
678         struct rt_cf_parm Cf;
679         BOOLEAN TimerCancelled;
680         u8 Erp;
681         u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
682             ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
683         u8 SupRateLen, ExtRateLen;
684         u8 CkipFlag;
685         u16 LenVIE;
686         u8 AironetCellPowerLimit;
687         struct rt_edca_parm EdcaParm;
688         struct rt_qbss_load_parm QbssLoad;
689         struct rt_qos_capability_parm QosCapability;
690         u16 Status;
691         u8 VarIE[MAX_VIE_LEN];  /* Total VIE length = MAX_VIE_LEN - -5 */
692         struct rt_ndis_802_11_variable_ies *pVIE = NULL;
693         unsigned long RalinkIe;
694         unsigned long Idx;
695         struct rt_ht_capability_ie HtCapability;
696         struct rt_add_ht_info_ie AddHtInfo;     /* AP might use this additional ht info IE */
697         u8 HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
698         u8 AddHtInfoLen;
699         u8 NewExtChannelOffset = 0xff;
700         u8 CentralChannel;
701         BOOLEAN bAllowNrate = FALSE;
702
703         /* Init Variable IE structure */
704         pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
705         pVIE->Length = 0;
706         RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
707         RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
708
709         if (PeerBeaconAndProbeRspSanity(pAd,
710                                         Elem->Msg,
711                                         Elem->MsgLen,
712                                         Elem->Channel,
713                                         Addr2,
714                                         Bssid,
715                                         (char *)Ssid,
716                                         &SsidLen,
717                                         &BssType,
718                                         &BeaconPeriod,
719                                         &Channel,
720                                         &NewChannel,
721                                         &TimeStamp,
722                                         &Cf,
723                                         &AtimWin,
724                                         &CapabilityInfo,
725                                         &Erp,
726                                         &DtimCount,
727                                         &DtimPeriod,
728                                         &BcastFlag,
729                                         &MessageToMe,
730                                         SupRate,
731                                         &SupRateLen,
732                                         ExtRate,
733                                         &ExtRateLen,
734                                         &CkipFlag,
735                                         &AironetCellPowerLimit,
736                                         &EdcaParm,
737                                         &QbssLoad,
738                                         &QosCapability,
739                                         &RalinkIe,
740                                         &HtCapabilityLen,
741                                         &PreNHtCapabilityLen,
742                                         &HtCapability,
743                                         &AddHtInfoLen,
744                                         &AddHtInfo,
745                                         &NewExtChannelOffset, &LenVIE, pVIE)) {
746                 /* Disqualify 11b only adhoc when we are in 11g only adhoc mode */
747                 if ((BssType == BSS_ADHOC)
748                     && (pAd->CommonCfg.PhyMode == PHY_11G)
749                     && ((SupRateLen + ExtRateLen) < 12))
750                         return;
751
752                 /* BEACON from desired BSS/IBSS found. We should be able to decide most */
753                 /* BSS parameters here. */
754                 /* Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION? */
755                 /*    Do we need to receover back all parameters belonging to previous BSS? */
756                 /* A. Should be not. There's no back-door recover to previous AP. It still need */
757                 /*    a new JOIN-AUTH-ASSOC sequence. */
758                 if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid)) {
759                         DBGPRINT(RT_DEBUG_TRACE,
760                                  ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n",
761                                   Channel));
762                         RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,
763                                         &TimerCancelled);
764
765                         /* Update RSSI to prevent No signal display when cards first initialized */
766                         pAd->StaCfg.RssiSample.LastRssi0 =
767                             ConvertToRssi(pAd, Elem->Rssi0, RSSI_0);
768                         pAd->StaCfg.RssiSample.LastRssi1 =
769                             ConvertToRssi(pAd, Elem->Rssi1, RSSI_1);
770                         pAd->StaCfg.RssiSample.LastRssi2 =
771                             ConvertToRssi(pAd, Elem->Rssi2, RSSI_2);
772                         pAd->StaCfg.RssiSample.AvgRssi0 =
773                             pAd->StaCfg.RssiSample.LastRssi0;
774                         pAd->StaCfg.RssiSample.AvgRssi0X8 =
775                             pAd->StaCfg.RssiSample.AvgRssi0 << 3;
776                         pAd->StaCfg.RssiSample.AvgRssi1 =
777                             pAd->StaCfg.RssiSample.LastRssi1;
778                         pAd->StaCfg.RssiSample.AvgRssi1X8 =
779                             pAd->StaCfg.RssiSample.AvgRssi1 << 3;
780                         pAd->StaCfg.RssiSample.AvgRssi2 =
781                             pAd->StaCfg.RssiSample.LastRssi2;
782                         pAd->StaCfg.RssiSample.AvgRssi2X8 =
783                             pAd->StaCfg.RssiSample.AvgRssi2 << 3;
784
785                         /* */
786                         /* We need to check if SSID only set to any, then we can record the current SSID. */
787                         /* Otherwise will cause hidden SSID association failed. */
788                         /* */
789                         if (pAd->MlmeAux.SsidLen == 0) {
790                                 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid,
791                                                SsidLen);
792                                 pAd->MlmeAux.SsidLen = SsidLen;
793                         } else {
794                                 Idx =
795                                     BssSsidTableSearch(&pAd->ScanTab, Bssid,
796                                                        pAd->MlmeAux.Ssid,
797                                                        pAd->MlmeAux.SsidLen,
798                                                        Channel);
799
800                                 if (Idx == BSS_NOT_FOUND) {
801                                         char Rssi = 0;
802                                         Rssi =
803                                             RTMPMaxRssi(pAd,
804                                                         ConvertToRssi(pAd,
805                                                                       Elem->
806                                                                       Rssi0,
807                                                                       RSSI_0),
808                                                         ConvertToRssi(pAd,
809                                                                       Elem->
810                                                                       Rssi1,
811                                                                       RSSI_1),
812                                                         ConvertToRssi(pAd,
813                                                                       Elem->
814                                                                       Rssi2,
815                                                                       RSSI_2));
816                                         Idx =
817                                             BssTableSetEntry(pAd, &pAd->ScanTab,
818                                                              Bssid,
819                                                              (char *) Ssid,
820                                                              SsidLen, BssType,
821                                                              BeaconPeriod, &Cf,
822                                                              AtimWin,
823                                                              CapabilityInfo,
824                                                              SupRate,
825                                                              SupRateLen,
826                                                              ExtRate,
827                                                              ExtRateLen,
828                                                              &HtCapability,
829                                                              &AddHtInfo,
830                                                              HtCapabilityLen,
831                                                              AddHtInfoLen,
832                                                              NewExtChannelOffset,
833                                                              Channel, Rssi,
834                                                              TimeStamp,
835                                                              CkipFlag,
836                                                              &EdcaParm,
837                                                              &QosCapability,
838                                                              &QbssLoad, LenVIE,
839                                                              pVIE);
840                                         if (Idx != BSS_NOT_FOUND) {
841                                                 NdisMoveMemory(pAd->ScanTab.
842                                                                BssEntry[Idx].
843                                                                PTSF,
844                                                                &Elem->Msg[24],
845                                                                4);
846                                                 NdisMoveMemory(&pAd->ScanTab.
847                                                                BssEntry[Idx].
848                                                                TTSF[0],
849                                                                &Elem->TimeStamp.
850                                                                u.LowPart, 4);
851                                                 NdisMoveMemory(&pAd->ScanTab.
852                                                                BssEntry[Idx].
853                                                                TTSF[4],
854                                                                &Elem->TimeStamp.
855                                                                u.LowPart, 4);
856                                                 CapabilityInfo =
857                                                     pAd->ScanTab.BssEntry[Idx].
858                                                     CapabilityInfo;
859                                         }
860                                 } else {
861                                         /* */
862                                         /* Multiple SSID case, used correct CapabilityInfo */
863                                         /* */
864                                         CapabilityInfo =
865                                             pAd->ScanTab.BssEntry[Idx].
866                                             CapabilityInfo;
867                                 }
868                         }
869                         NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN);
870                         pAd->MlmeAux.CapabilityInfo =
871                             CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
872                         pAd->MlmeAux.BssType = BssType;
873                         pAd->MlmeAux.BeaconPeriod = BeaconPeriod;
874                         pAd->MlmeAux.Channel = Channel;
875                         pAd->MlmeAux.AtimWin = AtimWin;
876                         pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod;
877                         pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration;
878                         pAd->MlmeAux.APRalinkIe = RalinkIe;
879
880                         /* Copy AP's supported rate to MlmeAux for creating assoication request */
881                         /* Also filter out not supported rate */
882                         pAd->MlmeAux.SupRateLen = SupRateLen;
883                         NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate,
884                                        SupRateLen);
885                         RTMPCheckRates(pAd, pAd->MlmeAux.SupRate,
886                                        &pAd->MlmeAux.SupRateLen);
887                         pAd->MlmeAux.ExtRateLen = ExtRateLen;
888                         NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate,
889                                        ExtRateLen);
890                         RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate,
891                                        &pAd->MlmeAux.ExtRateLen);
892
893                         NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet,
894                                        16);
895
896                         if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled)
897                              && (pAd->StaCfg.WepStatus !=
898                                  Ndis802_11Encryption2Enabled))
899                             || (pAd->CommonCfg.HT_DisallowTKIP == FALSE)) {
900                                 bAllowNrate = TRUE;
901                         }
902
903                         pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
904                         pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen;
905
906                         RTMPZeroMemory(&pAd->MlmeAux.HtCapability,
907                                        SIZE_HT_CAP_IE);
908                         /* filter out un-supported ht rates */
909                         if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
910                             && ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
911                                 && (bAllowNrate))) {
912                                 RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo,
913                                                &AddHtInfo, SIZE_ADD_HT_INFO_IE);
914
915                                 /* StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability */
916                                 NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.
917                                                MCSSet, HtCapability.MCSSet, 16);
918                                 pAd->MlmeAux.NewExtChannelOffset =
919                                     NewExtChannelOffset;
920                                 pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE;
921                                 pAd->StaActive.SupportedPhyInfo.bHtEnable =
922                                     TRUE;
923                                 if (PreNHtCapabilityLen > 0)
924                                         pAd->StaActive.SupportedPhyInfo.
925                                             bPreNHt = TRUE;
926                                 RTMPCheckHt(pAd, BSSID_WCID, &HtCapability,
927                                             &AddHtInfo);
928                                 /* Copy AP Parameter to StaActive.  This is also in LinkUp. */
929                                 DBGPRINT(RT_DEBUG_TRACE,
930                                          ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
931                                           pAd->StaActive.SupportedHtPhy.
932                                           MpduDensity,
933                                           pAd->StaActive.SupportedHtPhy.
934                                           MaxRAmpduFactor,
935                                           HtCapability.HtCapInfo.ChannelWidth));
936
937                                 if (AddHtInfoLen > 0) {
938                                         CentralChannel = AddHtInfo.ControlChan;
939                                         /* Check again the Bandwidth capability of this AP. */
940                                         if ((AddHtInfo.ControlChan > 2)
941                                             && (AddHtInfo.AddHtInfo.
942                                                 ExtChanOffset == EXTCHA_BELOW)
943                                             && (HtCapability.HtCapInfo.
944                                                 ChannelWidth == BW_40)) {
945                                                 CentralChannel =
946                                                     AddHtInfo.ControlChan - 2;
947                                         } else
948                                             if ((AddHtInfo.AddHtInfo.
949                                                  ExtChanOffset == EXTCHA_ABOVE)
950                                                 && (HtCapability.HtCapInfo.
951                                                     ChannelWidth == BW_40)) {
952                                                 CentralChannel =
953                                                     AddHtInfo.ControlChan + 2;
954                                         }
955                                         /* Check Error . */
956                                         if (pAd->MlmeAux.CentralChannel !=
957                                             CentralChannel)
958                                                 DBGPRINT(RT_DEBUG_ERROR,
959                                                          ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n",
960                                                           CentralChannel,
961                                                           AddHtInfo.ControlChan,
962                                                           pAd->MlmeAux.
963                                                           CentralChannel));
964
965                                         DBGPRINT(RT_DEBUG_TRACE,
966                                                  ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d,  .\n",
967                                                   CentralChannel,
968                                                   AddHtInfo.ControlChan));
969
970                                 }
971
972                         } else {
973                                 /* To prevent error, let legacy AP must have same CentralChannel and Channel. */
974                                 if ((HtCapabilityLen == 0)
975                                     && (PreNHtCapabilityLen == 0))
976                                         pAd->MlmeAux.CentralChannel =
977                                             pAd->MlmeAux.Channel;
978
979                                 pAd->StaActive.SupportedPhyInfo.bHtEnable =
980                                     FALSE;
981                                 pAd->MlmeAux.NewExtChannelOffset = 0xff;
982                                 RTMPZeroMemory(&pAd->MlmeAux.HtCapability,
983                                                SIZE_HT_CAP_IE);
984                                 pAd->MlmeAux.HtCapabilityLen = 0;
985                                 RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo,
986                                                SIZE_ADD_HT_INFO_IE);
987                         }
988
989                         RTMPUpdateMlmeRate(pAd);
990
991                         /* copy QOS related information */
992                         if ((pAd->CommonCfg.bWmmCapable)
993                             || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
994                             ) {
995                                 NdisMoveMemory(&pAd->MlmeAux.APEdcaParm,
996                                                &EdcaParm, sizeof(struct rt_edca_parm));
997                                 NdisMoveMemory(&pAd->MlmeAux.APQbssLoad,
998                                                &QbssLoad,
999                                                sizeof(struct rt_qbss_load_parm));
1000                                 NdisMoveMemory(&pAd->MlmeAux.APQosCapability,
1001                                                &QosCapability,
1002                                                sizeof(struct rt_qos_capability_parm));
1003                         } else {
1004                                 NdisZeroMemory(&pAd->MlmeAux.APEdcaParm,
1005                                                sizeof(struct rt_edca_parm));
1006                                 NdisZeroMemory(&pAd->MlmeAux.APQbssLoad,
1007                                                sizeof(struct rt_qbss_load_parm));
1008                                 NdisZeroMemory(&pAd->MlmeAux.APQosCapability,
1009                                                sizeof(struct rt_qos_capability_parm));
1010                         }
1011
1012                         DBGPRINT(RT_DEBUG_TRACE,
1013                                  ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
1014                                   pAd->MlmeAux.SupRateLen,
1015                                   pAd->MlmeAux.ExtRateLen));
1016
1017                         if (AironetCellPowerLimit != 0xFF) {
1018                                 /*We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */
1019                                 ChangeToCellPowerLimit(pAd,
1020                                                        AironetCellPowerLimit);
1021                         } else  /*Used the default TX Power Percentage. */
1022                                 pAd->CommonCfg.TxPowerPercentage =
1023                                     pAd->CommonCfg.TxPowerDefault;
1024
1025                         pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1026                         Status = MLME_SUCCESS;
1027                         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF,
1028                                     2, &Status);
1029                 }
1030                 /* not to me BEACON, ignored */
1031         }
1032         /* sanity check fail, ignore this frame */
1033 }
1034
1035 /*
1036         ==========================================================================
1037         Description:
1038                 receive BEACON from peer
1039
1040         IRQL = DISPATCH_LEVEL
1041
1042         ==========================================================================
1043  */
1044 void PeerBeacon(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1045 {
1046         u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
1047         char Ssid[MAX_LEN_OF_SSID];
1048         struct rt_cf_parm CfParm;
1049         u8 SsidLen, MessageToMe = 0, BssType, Channel, NewChannel, index = 0;
1050         u8 DtimCount = 0, DtimPeriod = 0, BcastFlag = 0;
1051         u16 CapabilityInfo, AtimWin, BeaconPeriod;
1052         LARGE_INTEGER TimeStamp;
1053         u16 TbttNumToNextWakeUp;
1054         u8 Erp;
1055         u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
1056             ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
1057         u8 SupRateLen, ExtRateLen;
1058         u8 CkipFlag;
1059         u16 LenVIE;
1060         u8 AironetCellPowerLimit;
1061         struct rt_edca_parm EdcaParm;
1062         struct rt_qbss_load_parm QbssLoad;
1063         struct rt_qos_capability_parm QosCapability;
1064         unsigned long RalinkIe;
1065         /* New for WPA security suites */
1066         u8 VarIE[MAX_VIE_LEN];  /* Total VIE length = MAX_VIE_LEN - -5 */
1067         struct rt_ndis_802_11_variable_ies *pVIE = NULL;
1068         struct rt_ht_capability_ie HtCapability;
1069         struct rt_add_ht_info_ie AddHtInfo;     /* AP might use this additional ht info IE */
1070         u8 HtCapabilityLen, PreNHtCapabilityLen;
1071         u8 AddHtInfoLen;
1072         u8 NewExtChannelOffset = 0xff;
1073
1074         if (!(INFRA_ON(pAd) || ADHOC_ON(pAd)
1075             ))
1076                 return;
1077
1078         /* Init Variable IE structure */
1079         pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
1080         pVIE->Length = 0;
1081         RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
1082         RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
1083
1084         if (PeerBeaconAndProbeRspSanity(pAd,
1085                                         Elem->Msg,
1086                                         Elem->MsgLen,
1087                                         Elem->Channel,
1088                                         Addr2,
1089                                         Bssid,
1090                                         Ssid,
1091                                         &SsidLen,
1092                                         &BssType,
1093                                         &BeaconPeriod,
1094                                         &Channel,
1095                                         &NewChannel,
1096                                         &TimeStamp,
1097                                         &CfParm,
1098                                         &AtimWin,
1099                                         &CapabilityInfo,
1100                                         &Erp,
1101                                         &DtimCount,
1102                                         &DtimPeriod,
1103                                         &BcastFlag,
1104                                         &MessageToMe,
1105                                         SupRate,
1106                                         &SupRateLen,
1107                                         ExtRate,
1108                                         &ExtRateLen,
1109                                         &CkipFlag,
1110                                         &AironetCellPowerLimit,
1111                                         &EdcaParm,
1112                                         &QbssLoad,
1113                                         &QosCapability,
1114                                         &RalinkIe,
1115                                         &HtCapabilityLen,
1116                                         &PreNHtCapabilityLen,
1117                                         &HtCapability,
1118                                         &AddHtInfoLen,
1119                                         &AddHtInfo,
1120                                         &NewExtChannelOffset, &LenVIE, pVIE)) {
1121                 BOOLEAN is_my_bssid, is_my_ssid;
1122                 unsigned long Bssidx, Now;
1123                 struct rt_bss_entry *pBss;
1124                 char RealRssi =
1125                     RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
1126                                 ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
1127                                 ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
1128
1129                 is_my_bssid =
1130                     MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid) ? TRUE : FALSE;
1131                 is_my_ssid =
1132                     SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid,
1133                                pAd->CommonCfg.SsidLen) ? TRUE : FALSE;
1134
1135                 /* ignore BEACON not for my SSID */
1136                 if ((!is_my_ssid) && (!is_my_bssid))
1137                         return;
1138
1139                 /* It means STA waits disassoc completely from this AP, ignores this beacon. */
1140                 if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC)
1141                         return;
1142
1143                 /* Copy Control channel for this BSSID. */
1144                 if (AddHtInfoLen != 0)
1145                         Channel = AddHtInfo.ControlChan;
1146
1147                 if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
1148                         HtCapabilityLen = SIZE_HT_CAP_IE;
1149
1150                 /* */
1151                 /* Housekeeping "SsidBssTab" table for later-on ROAMing usage. */
1152                 /* */
1153                 Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
1154                 if (Bssidx == BSS_NOT_FOUND) {
1155                         /* discover new AP of this network, create BSS entry */
1156                         Bssidx =
1157                             BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid,
1158                                              SsidLen, BssType, BeaconPeriod,
1159                                              &CfParm, AtimWin, CapabilityInfo,
1160                                              SupRate, SupRateLen, ExtRate,
1161                                              ExtRateLen, &HtCapability,
1162                                              &AddHtInfo, HtCapabilityLen,
1163                                              AddHtInfoLen, NewExtChannelOffset,
1164                                              Channel, RealRssi, TimeStamp,
1165                                              CkipFlag, &EdcaParm,
1166                                              &QosCapability, &QbssLoad, LenVIE,
1167                                              pVIE);
1168                         if (Bssidx == BSS_NOT_FOUND)    /* return if BSS table full */
1169                                 return;
1170
1171                         NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF,
1172                                        &Elem->Msg[24], 4);
1173                         NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0],
1174                                        &Elem->TimeStamp.u.LowPart, 4);
1175                         NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4],
1176                                        &Elem->TimeStamp.u.LowPart, 4);
1177
1178                 }
1179
1180                 if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0)
1181                     && (Channel != NewChannel)) {
1182                         /* Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection). */
1183                         /* In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results. */
1184                         AsicSwitchChannel(pAd, 1, FALSE);
1185                         AsicLockChannel(pAd, 1);
1186                         LinkDown(pAd, FALSE);
1187                         MlmeQueueInit(&pAd->Mlme.Queue);
1188                         BssTableInit(&pAd->ScanTab);
1189                         RTMPusecDelay(1000000); /* use delay to prevent STA do reassoc */
1190
1191                         /* channel sanity check */
1192                         for (index = 0; index < pAd->ChannelListNum; index++) {
1193                                 if (pAd->ChannelList[index].Channel ==
1194                                     NewChannel) {
1195                                         pAd->ScanTab.BssEntry[Bssidx].Channel =
1196                                             NewChannel;
1197                                         pAd->CommonCfg.Channel = NewChannel;
1198                                         AsicSwitchChannel(pAd,
1199                                                           pAd->CommonCfg.
1200                                                           Channel, FALSE);
1201                                         AsicLockChannel(pAd,
1202                                                         pAd->CommonCfg.Channel);
1203                                         DBGPRINT(RT_DEBUG_TRACE,
1204                                                  ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n",
1205                                                   NewChannel));
1206                                         break;
1207                                 }
1208                         }
1209
1210                         if (index >= pAd->ChannelListNum) {
1211                                 DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
1212                         }
1213                 }
1214                 /* if the ssid matched & bssid unmatched, we should select the bssid with large value. */
1215                 /* This might happened when two STA start at the same time */
1216                 if ((!is_my_bssid) && ADHOC_ON(pAd)) {
1217                         int i;
1218
1219                         /* Add the safeguard against the mismatch of adhoc wep status */
1220                         if (pAd->StaCfg.WepStatus !=
1221                             pAd->ScanTab.BssEntry[Bssidx].WepStatus) {
1222                                 return;
1223                         }
1224                         /* collapse into the ADHOC network which has bigger BSSID value. */
1225                         for (i = 0; i < 6; i++) {
1226                                 if (Bssid[i] > pAd->CommonCfg.Bssid[i]) {
1227                                         DBGPRINT(RT_DEBUG_TRACE,
1228                                                  ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
1229                                                   Bssid[0], Bssid[1], Bssid[2],
1230                                                   Bssid[3], Bssid[4],
1231                                                   Bssid[5]));
1232                                         AsicDisableSync(pAd);
1233                                         COPY_MAC_ADDR(pAd->CommonCfg.Bssid,
1234                                                       Bssid);
1235                                         AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1236                                         MakeIbssBeacon(pAd);    /* re-build BEACON frame */
1237                                         AsicEnableIbssSync(pAd);        /* copy BEACON frame to on-chip memory */
1238                                         is_my_bssid = TRUE;
1239                                         break;
1240                                 } else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
1241                                         break;
1242                         }
1243                 }
1244
1245                 NdisGetSystemUpTime(&Now);
1246                 pBss = &pAd->ScanTab.BssEntry[Bssidx];
1247                 pBss->Rssi = RealRssi;  /* lastest RSSI */
1248                 pBss->LastBeaconRxTime = Now;   /* last RX timestamp */
1249
1250                 /* */
1251                 /* BEACON from my BSSID - either IBSS or INFRA network */
1252                 /* */
1253                 if (is_my_bssid) {
1254                         struct rt_rxwi RxWI;
1255
1256                         pAd->StaCfg.DtimCount = DtimCount;
1257                         pAd->StaCfg.DtimPeriod = DtimPeriod;
1258                         pAd->StaCfg.LastBeaconRxTime = Now;
1259
1260                         RxWI.RSSI0 = Elem->Rssi0;
1261                         RxWI.RSSI1 = Elem->Rssi1;
1262                         RxWI.RSSI2 = Elem->Rssi2;
1263
1264                         Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI);
1265                         if (AironetCellPowerLimit != 0xFF) {
1266                                 /* */
1267                                 /* We get the Cisco (ccx) "TxPower Limit" required */
1268                                 /* Changed to appropriate TxPower Limit for Ciso Compatible Extensions */
1269                                 /* */
1270                                 ChangeToCellPowerLimit(pAd,
1271                                                        AironetCellPowerLimit);
1272                         } else {
1273                                 /* */
1274                                 /* AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist. */
1275                                 /* Used the default TX Power Percentage, that set from UI. */
1276                                 /* */
1277                                 pAd->CommonCfg.TxPowerPercentage =
1278                                     pAd->CommonCfg.TxPowerDefault;
1279                         }
1280
1281                         if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo))) {
1282                                 u8 MaxSupportedRateIn500Kbps = 0;
1283                                 u8 idx;
1284                                 struct rt_mac_table_entry *pEntry;
1285
1286                                 /* supported rates array may not be sorted. sort it and find the maximum rate */
1287                                 for (idx = 0; idx < SupRateLen; idx++) {
1288                                         if (MaxSupportedRateIn500Kbps <
1289                                             (SupRate[idx] & 0x7f))
1290                                                 MaxSupportedRateIn500Kbps =
1291                                                     SupRate[idx] & 0x7f;
1292                                 }
1293
1294                                 for (idx = 0; idx < ExtRateLen; idx++) {
1295                                         if (MaxSupportedRateIn500Kbps <
1296                                             (ExtRate[idx] & 0x7f))
1297                                                 MaxSupportedRateIn500Kbps =
1298                                                     ExtRate[idx] & 0x7f;
1299                                 }
1300
1301                                 /* look up the existing table */
1302                                 pEntry = MacTableLookup(pAd, Addr2);
1303
1304                                 /* Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon. */
1305                                 /* To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station. */
1306                                 if ((ADHOC_ON(pAd)
1307                                      && (Elem->Wcid == RESERVED_WCID))
1308                                     || (pEntry
1309                                         &&
1310                                         ((pEntry->LastBeaconRxTime +
1311                                           ADHOC_ENTRY_BEACON_LOST_TIME) <
1312                                          Now))) {
1313                                         if (pEntry == NULL)
1314                                                 /* Another adhoc joining, add to our MAC table. */
1315                                                 pEntry =
1316                                                     MacTableInsertEntry(pAd,
1317                                                                         Addr2,
1318                                                                         BSS0,
1319                                                                         FALSE);
1320
1321                                         if (StaAddMacTableEntry(pAd,
1322                                                                 pEntry,
1323                                                                 MaxSupportedRateIn500Kbps,
1324                                                                 &HtCapability,
1325                                                                 HtCapabilityLen,
1326                                                                 &AddHtInfo,
1327                                                                 AddHtInfoLen,
1328                                                                 CapabilityInfo)
1329                                             == FALSE) {
1330                                                 DBGPRINT(RT_DEBUG_TRACE,
1331                                                          ("ADHOC - Add Entry failed.\n"));
1332                                                 return;
1333                                         }
1334
1335                                         if (pEntry &&
1336                                             (Elem->Wcid == RESERVED_WCID)) {
1337                                                 idx = pAd->StaCfg.DefaultKeyId;
1338                                                 RTMP_STA_SECURITY_INFO_ADD(pAd,
1339                                                                            BSS0,
1340                                                                            idx,
1341                                                                            pEntry);
1342                                         }
1343                                 }
1344
1345                                 if (pEntry && pEntry->ValidAsCLI)
1346                                         pEntry->LastBeaconRxTime = Now;
1347
1348                                 /* At least another peer in this IBSS, declare MediaState as CONNECTED */
1349                                 if (!OPSTATUS_TEST_FLAG
1350                                     (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
1351                                         OPSTATUS_SET_FLAG(pAd,
1352                                                           fOP_STATUS_MEDIA_STATE_CONNECTED);
1353
1354                                         pAd->IndicateMediaState =
1355                                             NdisMediaStateConnected;
1356                                         RTMP_IndicateMediaState(pAd);
1357                                         pAd->ExtraInfo = GENERAL_LINK_UP;
1358                                         AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1359
1360                                         /* 2003/03/12 - john */
1361                                         /* Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that */
1362                                         /* "site survey" result should always include the current connected network. */
1363                                         /* */
1364                                         Bssidx =
1365                                             BssTableSearch(&pAd->ScanTab, Bssid,
1366                                                            Channel);
1367                                         if (Bssidx == BSS_NOT_FOUND) {
1368                                                 Bssidx =
1369                                                     BssTableSetEntry(pAd,
1370                                                                      &pAd->
1371                                                                      ScanTab,
1372                                                                      Bssid,
1373                                                                      Ssid,
1374                                                                      SsidLen,
1375                                                                      BssType,
1376                                                                      BeaconPeriod,
1377                                                                      &CfParm,
1378                                                                      AtimWin,
1379                                                                      CapabilityInfo,
1380                                                                      SupRate,
1381                                                                      SupRateLen,
1382                                                                      ExtRate,
1383                                                                      ExtRateLen,
1384                                                                      &HtCapability,
1385                                                                      &AddHtInfo,
1386                                                                      HtCapabilityLen,
1387                                                                      AddHtInfoLen,
1388                                                                      NewExtChannelOffset,
1389                                                                      Channel,
1390                                                                      RealRssi,
1391                                                                      TimeStamp,
1392                                                                      0,
1393                                                                      &EdcaParm,
1394                                                                      &QosCapability,
1395                                                                      &QbssLoad,
1396                                                                      LenVIE,
1397                                                                      pVIE);
1398                                         }
1399                                         DBGPRINT(RT_DEBUG_TRACE,
1400                                                  ("ADHOC  fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
1401                                 }
1402                         }
1403
1404                         if (INFRA_ON(pAd)) {
1405                                 BOOLEAN bUseShortSlot, bUseBGProtection;
1406
1407                                 /* decide to use/change to - */
1408                                 /*      1. long slot (20 us) or short slot (9 us) time */
1409                                 /*      2. turn on/off RTS/CTS and/or CTS-to-self protection */
1410                                 /*      3. short preamble */
1411
1412                                 /*bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo); */
1413                                 bUseShortSlot =
1414                                     CAP_IS_SHORT_SLOT(CapabilityInfo);
1415                                 if (bUseShortSlot !=
1416                                     OPSTATUS_TEST_FLAG(pAd,
1417                                                        fOP_STATUS_SHORT_SLOT_INUSED))
1418                                         AsicSetSlotTime(pAd, bUseShortSlot);
1419
1420                                 bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) ||     /* always use */
1421                                     ((pAd->CommonCfg.UseBGProtection == 0)
1422                                      && ERP_IS_USE_PROTECTION(Erp));
1423
1424                                 if (pAd->CommonCfg.Channel > 14)        /* always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP */
1425                                         bUseBGProtection = FALSE;
1426
1427                                 if (bUseBGProtection !=
1428                                     OPSTATUS_TEST_FLAG(pAd,
1429                                                        fOP_STATUS_BG_PROTECTION_INUSED))
1430                                 {
1431                                         if (bUseBGProtection) {
1432                                                 OPSTATUS_SET_FLAG(pAd,
1433                                                                   fOP_STATUS_BG_PROTECTION_INUSED);
1434                                                 AsicUpdateProtect(pAd,
1435                                                                   pAd->MlmeAux.
1436                                                                   AddHtInfo.
1437                                                                   AddHtInfo2.
1438                                                                   OperaionMode,
1439                                                                   (OFDMSETPROTECT
1440                                                                    |
1441                                                                    CCKSETPROTECT
1442                                                                    |
1443                                                                    ALLN_SETPROTECT),
1444                                                                   FALSE,
1445                                                                   (pAd->MlmeAux.
1446                                                                    AddHtInfo.
1447                                                                    AddHtInfo2.
1448                                                                    NonGfPresent
1449                                                                    == 1));
1450                                         } else {
1451                                                 OPSTATUS_CLEAR_FLAG(pAd,
1452                                                                     fOP_STATUS_BG_PROTECTION_INUSED);
1453                                                 AsicUpdateProtect(pAd,
1454                                                                   pAd->MlmeAux.
1455                                                                   AddHtInfo.
1456                                                                   AddHtInfo2.
1457                                                                   OperaionMode,
1458                                                                   (OFDMSETPROTECT
1459                                                                    |
1460                                                                    CCKSETPROTECT
1461                                                                    |
1462                                                                    ALLN_SETPROTECT),
1463                                                                   TRUE,
1464                                                                   (pAd->MlmeAux.
1465                                                                    AddHtInfo.
1466                                                                    AddHtInfo2.
1467                                                                    NonGfPresent
1468                                                                    == 1));
1469                                         }
1470
1471                                         DBGPRINT(RT_DEBUG_WARN,
1472                                                  ("SYNC - AP changed B/G protection to %d\n",
1473                                                   bUseBGProtection));
1474                                 }
1475                                 /* check Ht protection mode. and adhere to the Non-GF device indication by AP. */
1476                                 if ((AddHtInfoLen != 0) &&
1477                                     ((AddHtInfo.AddHtInfo2.OperaionMode !=
1478                                       pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1479                                       OperaionMode)
1480                                      || (AddHtInfo.AddHtInfo2.NonGfPresent !=
1481                                          pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1482                                          NonGfPresent))) {
1483                                         pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1484                                             NonGfPresent =
1485                                             AddHtInfo.AddHtInfo2.NonGfPresent;
1486                                         pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1487                                             OperaionMode =
1488                                             AddHtInfo.AddHtInfo2.OperaionMode;
1489                                         if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1490                                             NonGfPresent == 1) {
1491                                                 AsicUpdateProtect(pAd,
1492                                                                   pAd->MlmeAux.
1493                                                                   AddHtInfo.
1494                                                                   AddHtInfo2.
1495                                                                   OperaionMode,
1496                                                                   ALLN_SETPROTECT,
1497                                                                   FALSE, TRUE);
1498                                         } else
1499                                                 AsicUpdateProtect(pAd,
1500                                                                   pAd->MlmeAux.
1501                                                                   AddHtInfo.
1502                                                                   AddHtInfo2.
1503                                                                   OperaionMode,
1504                                                                   ALLN_SETPROTECT,
1505                                                                   FALSE, FALSE);
1506
1507                                         DBGPRINT(RT_DEBUG_TRACE,
1508                                                  ("SYNC - AP changed N OperaionMode to %d\n",
1509                                                   pAd->MlmeAux.AddHtInfo.
1510                                                   AddHtInfo2.OperaionMode));
1511                                 }
1512
1513                                 if (OPSTATUS_TEST_FLAG
1514                                     (pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED)
1515                                     && ERP_IS_USE_BARKER_PREAMBLE(Erp)) {
1516                                         MlmeSetTxPreamble(pAd,
1517                                                           Rt802_11PreambleLong);
1518                                         DBGPRINT(RT_DEBUG_TRACE,
1519                                                  ("SYNC - AP forced to use long preamble\n"));
1520                                 }
1521
1522                                 if (OPSTATUS_TEST_FLAG
1523                                     (pAd, fOP_STATUS_WMM_INUSED)
1524                                     && (EdcaParm.bValid == TRUE)
1525                                     && (EdcaParm.EdcaUpdateCount !=
1526                                         pAd->CommonCfg.APEdcaParm.
1527                                         EdcaUpdateCount)) {
1528                                         DBGPRINT(RT_DEBUG_TRACE,
1529                                                  ("SYNC - AP change EDCA parameters(from %d to %d)\n",
1530                                                   pAd->CommonCfg.APEdcaParm.
1531                                                   EdcaUpdateCount,
1532                                                   EdcaParm.EdcaUpdateCount));
1533                                         AsicSetEdcaParm(pAd, &EdcaParm);
1534                                 }
1535                                 /* copy QOS related information */
1536                                 NdisMoveMemory(&pAd->CommonCfg.APQbssLoad,
1537                                                &QbssLoad,
1538                                                sizeof(struct rt_qbss_load_parm));
1539                                 NdisMoveMemory(&pAd->CommonCfg.APQosCapability,
1540                                                &QosCapability,
1541                                                sizeof(struct rt_qos_capability_parm));
1542                         }
1543                         /* only INFRASTRUCTURE mode support power-saving feature */
1544                         if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE))
1545                             || (pAd->CommonCfg.bAPSDForcePowerSave)) {
1546                                 u8 FreeNumber;
1547                                 /*  1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL */
1548                                 /*  2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE */
1549                                 /*  3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE */
1550                                 /*  4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE */
1551                                 /*  5. otherwise, put PHY back to sleep to save battery. */
1552                                 if (MessageToMe) {
1553 #ifdef RTMP_MAC_PCI
1554                                         if (OPSTATUS_TEST_FLAG
1555                                             (pAd, fOP_STATUS_PCIE_DEVICE)) {
1556                                                 /* Restore to correct BBP R3 value */
1557                                                 if (pAd->Antenna.field.RxPath >
1558                                                     1)
1559                                                         RTMP_BBP_IO_WRITE8_BY_REG_ID
1560                                                             (pAd, BBP_R3,
1561                                                              pAd->StaCfg.BBPR3);
1562                                                 /* Turn clk to 80Mhz. */
1563                                         }
1564 #endif /* RTMP_MAC_PCI // */
1565                                         if (pAd->CommonCfg.bAPSDCapable
1566                                             && pAd->CommonCfg.APEdcaParm.
1567                                             bAPSDCapable
1568                                             && pAd->CommonCfg.bAPSDAC_BE
1569                                             && pAd->CommonCfg.bAPSDAC_BK
1570                                             && pAd->CommonCfg.bAPSDAC_VI
1571                                             && pAd->CommonCfg.bAPSDAC_VO) {
1572                                                 pAd->CommonCfg.
1573                                                     bNeedSendTriggerFrame =
1574                                                     TRUE;
1575                                         } else
1576                                                 RTMP_PS_POLL_ENQUEUE(pAd);
1577                                 } else if (BcastFlag && (DtimCount == 0)
1578                                            && OPSTATUS_TEST_FLAG(pAd,
1579                                                                  fOP_STATUS_RECEIVE_DTIM))
1580                                 {
1581 #ifdef RTMP_MAC_PCI
1582                                         if (OPSTATUS_TEST_FLAG
1583                                             (pAd, fOP_STATUS_PCIE_DEVICE)) {
1584                                                 if (pAd->Antenna.field.RxPath >
1585                                                     1)
1586                                                         RTMP_BBP_IO_WRITE8_BY_REG_ID
1587                                                             (pAd, BBP_R3,
1588                                                              pAd->StaCfg.BBPR3);
1589                                         }
1590 #endif /* RTMP_MAC_PCI // */
1591                                 } else
1592                                     if ((pAd->TxSwQueue[QID_AC_BK].Number != 0)
1593                                         || (pAd->TxSwQueue[QID_AC_BE].Number !=
1594                                             0)
1595                                         || (pAd->TxSwQueue[QID_AC_VI].Number !=
1596                                             0)
1597                                         || (pAd->TxSwQueue[QID_AC_VO].Number !=
1598                                             0)
1599                                         ||
1600                                         (RTMPFreeTXDRequest
1601                                          (pAd, QID_AC_BK, TX_RING_SIZE - 1,
1602                                           &FreeNumber) != NDIS_STATUS_SUCCESS)
1603                                         ||
1604                                         (RTMPFreeTXDRequest
1605                                          (pAd, QID_AC_BE, TX_RING_SIZE - 1,
1606                                           &FreeNumber) != NDIS_STATUS_SUCCESS)
1607                                         ||
1608                                         (RTMPFreeTXDRequest
1609                                          (pAd, QID_AC_VI, TX_RING_SIZE - 1,
1610                                           &FreeNumber) != NDIS_STATUS_SUCCESS)
1611                                         ||
1612                                         (RTMPFreeTXDRequest
1613                                          (pAd, QID_AC_VO, TX_RING_SIZE - 1,
1614                                           &FreeNumber) != NDIS_STATUS_SUCCESS)
1615                                         ||
1616                                         (RTMPFreeTXDRequest
1617                                          (pAd, QID_MGMT, MGMT_RING_SIZE - 1,
1618                                           &FreeNumber) !=
1619                                          NDIS_STATUS_SUCCESS)) {
1620                                         /* TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme */
1621                                         /* can we cheat here (i.e. just check MGMT & AC_BE) for better performance? */
1622 #ifdef RTMP_MAC_PCI
1623                                         if (OPSTATUS_TEST_FLAG
1624                                             (pAd, fOP_STATUS_PCIE_DEVICE)) {
1625                                                 if (pAd->Antenna.field.RxPath >
1626                                                     1)
1627                                                         RTMP_BBP_IO_WRITE8_BY_REG_ID
1628                                                             (pAd, BBP_R3,
1629                                                              pAd->StaCfg.BBPR3);
1630                                         }
1631 #endif /* RTMP_MAC_PCI // */
1632                                 } else {
1633                                         if ((pAd->CommonCfg.
1634                                              bACMAPSDTr[QID_AC_VO])
1635                                             || (pAd->CommonCfg.
1636                                                 bACMAPSDTr[QID_AC_VI])
1637                                             || (pAd->CommonCfg.
1638                                                 bACMAPSDTr[QID_AC_BK])
1639                                             || (pAd->CommonCfg.
1640                                                 bACMAPSDTr[QID_AC_BE])) {
1641                                                 /*
1642                                                    WMM Spec v1.0 3.6.2.4,
1643                                                    The WMM STA shall remain awake until it receives a
1644                                                    QoS Data or Null frame addressed to it, with the
1645                                                    EOSP subfield in QoS Control field set to 1.
1646
1647                                                    So we can not sleep here or we will suffer a case:
1648
1649                                                    PS Management Frame -->
1650                                                    Trigger frame -->
1651                                                    Beacon (TIM=0) (Beacon is closer to Trig frame) -->
1652                                                    Station goes to sleep -->
1653                                                    AP delivery queued UAPSD packets -->
1654                                                    Station can NOT receive the reply
1655
1656                                                    Maybe we need a timeout timer to avoid that we do
1657                                                    NOT receive the EOSP frame.
1658
1659                                                    We can not use More Data to check if SP is ended
1660                                                    due to MaxSPLength.
1661                                                  */
1662                                         } else {
1663                                                 u16 NextDtim = DtimCount;
1664
1665                                                 if (NextDtim == 0)
1666                                                         NextDtim = DtimPeriod;
1667
1668                                                 TbttNumToNextWakeUp =
1669                                                     pAd->StaCfg.
1670                                                     DefaultListenCount;
1671                                                 if (OPSTATUS_TEST_FLAG
1672                                                     (pAd,
1673                                                      fOP_STATUS_RECEIVE_DTIM)
1674                                                     && (TbttNumToNextWakeUp >
1675                                                         NextDtim))
1676                                                         TbttNumToNextWakeUp =
1677                                                             NextDtim;
1678
1679                                                 if (!OPSTATUS_TEST_FLAG
1680                                                     (pAd, fOP_STATUS_DOZE)) {
1681                                                         /* Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode. */
1682                                                         pAd->
1683                                                             ThisTbttNumToNextWakeUp
1684                                                             =
1685                                                             TbttNumToNextWakeUp;
1686                                                         AsicSleepThenAutoWakeup
1687                                                             (pAd,
1688                                                              pAd->
1689                                                              ThisTbttNumToNextWakeUp);
1690                                                 }
1691                                         }
1692                                 }
1693                         }
1694                 }
1695                 /* not my BSSID, ignore it */
1696         }
1697         /* sanity check fail, ignore this frame */
1698 }
1699
1700 /*
1701         ==========================================================================
1702         Description:
1703                 Receive PROBE REQ from remote peer when operating in IBSS mode
1704         ==========================================================================
1705  */
1706 void PeerProbeReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1707 {
1708         u8 Addr2[MAC_ADDR_LEN];
1709         char Ssid[MAX_LEN_OF_SSID];
1710         u8 SsidLen;
1711         u8 HtLen, AddHtLen, NewExtLen;
1712         struct rt_header_802_11 ProbeRspHdr;
1713         int NStatus;
1714         u8 *pOutBuffer = NULL;
1715         unsigned long FrameLen = 0;
1716         LARGE_INTEGER FakeTimestamp;
1717         u8 DsLen = 1, IbssLen = 2;
1718         u8 LocalErpIe[3] = { IE_ERP, 1, 0 };
1719         BOOLEAN Privacy;
1720         u16 CapabilityInfo;
1721         u8 RSNIe = IE_WPA;
1722
1723         if (!ADHOC_ON(pAd))
1724                 return;
1725
1726         if (PeerProbeReqSanity
1727             (pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen)) {
1728                 if ((SsidLen == 0)
1729                     || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid,
1730                                   pAd->CommonCfg.SsidLen)) {
1731                         /* allocate and send out ProbeRsp frame */
1732                         NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
1733                         if (NStatus != NDIS_STATUS_SUCCESS)
1734                                 return;
1735
1736                         /*pAd->StaCfg.AtimWin = 0;  // ?????? */
1737
1738                         Privacy =
1739                             (pAd->StaCfg.WepStatus ==
1740                              Ndis802_11Encryption1Enabled)
1741                             || (pAd->StaCfg.WepStatus ==
1742                                 Ndis802_11Encryption2Enabled)
1743                             || (pAd->StaCfg.WepStatus ==
1744                                 Ndis802_11Encryption3Enabled);
1745                         CapabilityInfo =
1746                             CAP_GENERATE(0, 1, Privacy,
1747                                          (pAd->CommonCfg.TxPreamble ==
1748                                           Rt802_11PreambleShort), 0, 0);
1749
1750                         MakeOutgoingFrame(pOutBuffer, &FrameLen,
1751                                           sizeof(struct rt_header_802_11), &ProbeRspHdr,
1752                                           TIMESTAMP_LEN, &FakeTimestamp,
1753                                           2, &pAd->CommonCfg.BeaconPeriod,
1754                                           2, &CapabilityInfo,
1755                                           1, &SsidIe,
1756                                           1, &pAd->CommonCfg.SsidLen,
1757                                           pAd->CommonCfg.SsidLen,
1758                                           pAd->CommonCfg.Ssid, 1, &SupRateIe, 1,
1759                                           &pAd->StaActive.SupRateLen,
1760                                           pAd->StaActive.SupRateLen,
1761                                           pAd->StaActive.SupRate, 1, &DsIe, 1,
1762                                           &DsLen, 1, &pAd->CommonCfg.Channel, 1,
1763                                           &IbssIe, 1, &IbssLen, 2,
1764                                           &pAd->StaActive.AtimWin, END_OF_ARGS);
1765
1766                         if (pAd->StaActive.ExtRateLen) {
1767                                 unsigned long tmp;
1768                                 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1769                                                   3, LocalErpIe,
1770                                                   1, &ExtRateIe,
1771                                                   1, &pAd->StaActive.ExtRateLen,
1772                                                   pAd->StaActive.ExtRateLen,
1773                                                   &pAd->StaActive.ExtRate,
1774                                                   END_OF_ARGS);
1775                                 FrameLen += tmp;
1776                         }
1777                         /* If adhoc secruity is set for WPA-None, append the cipher suite IE */
1778                         if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
1779                                 unsigned long tmp;
1780                                 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1781                                                   1, &RSNIe,
1782                                                   1, &pAd->StaCfg.RSNIE_Len,
1783                                                   pAd->StaCfg.RSNIE_Len,
1784                                                   pAd->StaCfg.RSN_IE,
1785                                                   END_OF_ARGS);
1786                                 FrameLen += tmp;
1787                         }
1788
1789                         if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
1790                                 unsigned long TmpLen;
1791                                 u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 };
1792                                 HtLen = sizeof(pAd->CommonCfg.HtCapability);
1793                                 AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);
1794                                 NewExtLen = 1;
1795                                 /*New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame */
1796                                 if (pAd->bBroadComHT == TRUE) {
1797                                         MakeOutgoingFrame(pOutBuffer + FrameLen,
1798                                                           &TmpLen, 1, &WpaIe, 4,
1799                                                           &BROADCOM[0],
1800                                                           pAd->MlmeAux.
1801                                                           HtCapabilityLen,
1802                                                           &pAd->MlmeAux.
1803                                                           HtCapability,
1804                                                           END_OF_ARGS);
1805                                 } else {
1806                                         MakeOutgoingFrame(pOutBuffer + FrameLen,
1807                                                           &TmpLen, 1, &HtCapIe,
1808                                                           1, &HtLen,
1809                                                           sizeof
1810                                                           (struct rt_ht_capability_ie),
1811                                                           &pAd->CommonCfg.
1812                                                           HtCapability, 1,
1813                                                           &AddHtInfoIe, 1,
1814                                                           &AddHtLen,
1815                                                           sizeof
1816                                                           (struct rt_add_ht_info_ie),
1817                                                           &pAd->CommonCfg.
1818                                                           AddHTInfo, 1,
1819                                                           &NewExtChanIe, 1,
1820                                                           &NewExtLen,
1821                                                           sizeof
1822                                                           (struct rt_new_ext_chan_ie),
1823                                                           &pAd->CommonCfg.
1824                                                           NewExtChanOffset,
1825                                                           END_OF_ARGS);
1826                                 }
1827                                 FrameLen += TmpLen;
1828                         }
1829
1830                         MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1831                         MlmeFreeMemory(pAd, pOutBuffer);
1832                 }
1833         }
1834 }
1835
1836 void BeaconTimeoutAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1837 {
1838         u16 Status;
1839         DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n"));
1840         pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1841         Status = MLME_REJ_TIMEOUT;
1842         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1843 }
1844
1845 /*
1846         ==========================================================================
1847         Description:
1848                 Scan timeout procedure. basically add channel index by 1 and rescan
1849         ==========================================================================
1850  */
1851 void ScanTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1852 {
1853         pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
1854
1855         /* Only one channel scanned for CISCO beacon request */
1856         if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) ||
1857             (pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) ||
1858             (pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) ||
1859             (pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD))
1860                 pAd->MlmeAux.Channel = 0;
1861
1862         /* this routine will stop if pAd->MlmeAux.Channel == 0 */
1863         ScanNextChannel(pAd);
1864 }
1865
1866 /*
1867         ==========================================================================
1868         Description:
1869         ==========================================================================
1870  */
1871 void InvalidStateWhenScan(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1872 {
1873         u16 Status;
1874         DBGPRINT(RT_DEBUG_TRACE,
1875                  ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n",
1876                   pAd->Mlme.SyncMachine.CurrState));
1877         pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1878         Status = MLME_STATE_MACHINE_REJECT;
1879         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
1880 }
1881
1882 /*
1883         ==========================================================================
1884         Description:
1885         ==========================================================================
1886  */
1887 void InvalidStateWhenJoin(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1888 {
1889         u16 Status;
1890         DBGPRINT(RT_DEBUG_TRACE,
1891                  ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n",
1892                   pAd->Mlme.SyncMachine.CurrState));
1893         pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1894         Status = MLME_STATE_MACHINE_REJECT;
1895         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1896 }
1897
1898 /*
1899         ==========================================================================
1900         Description:
1901         ==========================================================================
1902  */
1903 void InvalidStateWhenStart(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1904 {
1905         u16 Status;
1906         DBGPRINT(RT_DEBUG_TRACE,
1907                  ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n",
1908                   pAd->Mlme.SyncMachine.CurrState));
1909         pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1910         Status = MLME_STATE_MACHINE_REJECT;
1911         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
1912 }
1913
1914 /*
1915         ==========================================================================
1916         Description:
1917
1918         IRQL = DISPATCH_LEVEL
1919
1920         ==========================================================================
1921  */
1922 void EnqueuePsPoll(struct rt_rtmp_adapter *pAd)
1923 {
1924
1925         if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP)
1926                 pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE;
1927         MiniportMMRequest(pAd, 0, (u8 *)& pAd->PsPollFrame,
1928                           sizeof(struct rt_pspoll_frame));
1929 }
1930
1931 /*
1932         ==========================================================================
1933         Description:
1934         ==========================================================================
1935  */
1936 void EnqueueProbeRequest(struct rt_rtmp_adapter *pAd)
1937 {
1938         int NState;
1939         u8 *pOutBuffer;
1940         unsigned long FrameLen = 0;
1941         struct rt_header_802_11 Hdr80211;
1942
1943         DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
1944
1945         NState = MlmeAllocateMemory(pAd, &pOutBuffer);  /*Get an unused nonpaged memory */
1946         if (NState == NDIS_STATUS_SUCCESS) {
1947                 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
1948                                  BROADCAST_ADDR, BROADCAST_ADDR);
1949
1950                 /* this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse */
1951                 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1952                                   sizeof(struct rt_header_802_11), &Hdr80211,
1953                                   1, &SsidIe,
1954                                   1, &pAd->CommonCfg.SsidLen,
1955                                   pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
1956                                   1, &SupRateIe,
1957                                   1, &pAd->StaActive.SupRateLen,
1958                                   pAd->StaActive.SupRateLen,
1959                                   pAd->StaActive.SupRate, END_OF_ARGS);
1960                 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1961                 MlmeFreeMemory(pAd, pOutBuffer);
1962         }
1963
1964 }
1965
1966 BOOLEAN ScanRunning(struct rt_rtmp_adapter *pAd)
1967 {
1968         return (pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE;
1969 }