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