MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / net / wireless / rtlink / connect.c
blob7b2204e0951cb4f60dc3e2f539ac239f8aab603e
1 /*************************************************************************
2 * Ralink Tech Inc. *
3 * 4F, No. 2 Technology 5th Rd. *
4 * Science-based Industrial Park *
5 * Hsin-chu, Taiwan, R.O.C. *
6 * *
7 * (c) Copyright 2002, Ralink Technology, Inc. *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the *
21 * Free Software Foundation, Inc., *
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
23 * *
24 ************************************************************************/
26 #include "rt_config.h"
28 UCHAR CipherSuiteWpaNoneTkip[] = {
29 0x00, 0x50, 0xf2, 0x01, // oui
30 0x01, 0x00, // Version
31 0x00, 0x50, 0xf2, 0x02, // Multicast
32 0x01, 0x00, // Number of unicast
33 0x00, 0x50, 0xf2, 0x00, // unicast
34 0x01, 0x00, // number of authentication method
35 0x00, 0x50, 0xf2, 0x00 // authentication
37 UCHAR CipherSuiteWpaNoneTkipLen = (sizeof(CipherSuiteWpaNoneTkip) / sizeof(UCHAR));
39 UCHAR CipherSuiteWpaNoneAes[] = {
40 0x00, 0x50, 0xf2, 0x01, // oui
41 0x01, 0x00, // Version
42 0x00, 0x50, 0xf2, 0x04, // Multicast
43 0x01, 0x00, // Number of unicast
44 0x00, 0x50, 0xf2, 0x00, // unicast
45 0x01, 0x00, // number of authentication method
46 0x00, 0x50, 0xf2, 0x00 // authentication
48 UCHAR CipherSuiteWpaNoneAesLen = (sizeof(CipherSuiteWpaNoneAes) / sizeof(UCHAR));
51 ==========================================================================
52 Description:
53 ==========================================================================
55 VOID MlmeCntlInit(
56 IN PRTMP_ADAPTER pAd,
57 IN STATE_MACHINE *S,
58 OUT STATE_MACHINE_FUNC Trans[])
60 // Control state machine differs from other state machines, the interface
61 // follows the standard interface
62 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
66 ==========================================================================
67 Description:
68 ==========================================================================
70 VOID MlmeCntlMachinePerformAction(
71 IN PRTMP_ADAPTER pAd,
72 IN STATE_MACHINE *S,
73 IN MLME_QUEUE_ELEM *Elem)
75 switch(pAd->Mlme.CntlMachine.CurrState)
77 case CNTL_IDLE:
78 CntlIdleProc(pAd, Elem);
79 break;
80 case CNTL_WAIT_DISASSOC:
81 CntlWaitDisassocProc(pAd, Elem);
82 break;
83 case CNTL_WAIT_JOIN:
84 CntlWaitJoinProc(pAd, Elem);
85 break;
87 // CNTL_WAIT_REASSOC is the only state in CNTL machine that does
88 // not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)".
89 // Therefore not protected by NDIS's "only one outstanding OID request"
90 // rule. Which means NDIS may SET OID in the middle of ROAMing attempts.
91 // Current approach is to block new SET request at RTMPSetInformation()
92 // when CntlMachine.CurrState is not CNTL_IDLE
93 case CNTL_WAIT_REASSOC:
94 CntlWaitReassocProc(pAd, Elem);
95 break;
97 case CNTL_WAIT_START:
98 CntlWaitStartProc(pAd, Elem);
99 break;
100 case CNTL_WAIT_AUTH:
101 CntlWaitAuthProc(pAd, Elem);
102 break;
103 case CNTL_WAIT_AUTH2:
104 CntlWaitAuthProc2(pAd, Elem);
105 break;
106 case CNTL_WAIT_ASSOC:
107 CntlWaitAssocProc(pAd, Elem);
108 break;
110 case CNTL_WAIT_OID_LIST_SCAN:
111 if(Elem->MsgType == MT2_SCAN_CONF)
113 // Resume TxRing after SCANING complete. We hope the out-of-service time
114 // won't be too long to let upper layer time-out the waiting frames
115 RTMPResumeMsduTransmission(pAd);
116 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
119 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
121 if (pAd->MediaState == NdisMediaStateDisconnected)
122 MlmeAutoReconnectLastSSID(pAd);
123 break;
125 case CNTL_WAIT_OID_DISASSOC:
126 if (Elem->MsgType == MT2_DISASSOC_CONF)
128 LinkDown(pAd);
130 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
133 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
135 break;
137 default:
138 DBGPRINT(RT_DEBUG_ERROR, "CNTL - Illegal message type(=%d)", Elem->MsgType);
139 break;
145 ==========================================================================
146 Description:
147 ==========================================================================
149 VOID CntlIdleProc(
150 IN PRTMP_ADAPTER pAd,
151 IN MLME_QUEUE_ELEM *Elem)
153 MLME_DISASSOC_REQ_STRUCT DisassocReq;
155 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
157 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
159 pAd->Mlme.CntlAux.CurrReqIsFromNdis = FALSE;
161 return;
164 switch(Elem->MsgType)
166 case OID_802_11_SSID:
167 CntlOidSsidProc(pAd, Elem);
168 break;
170 case OID_802_11_BSSID:
171 CntlOidRTBssidProc(pAd,Elem);
172 break;
174 case OID_802_11_BSSID_LIST_SCAN:
175 CntlOidScanProc(pAd,Elem);
176 break;
178 case OID_802_11_DISASSOCIATE:
179 DisassocParmFill(pAd, &DisassocReq, &pAd->PortCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
180 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
181 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
182 // Set the control aux SSID to prevent it reconnect to old SSID
183 // Since calling this indicate user don't want to connect to that SSID anymore.
184 pAd->Mlme.CntlAux.SsidLen = 32;
185 NdisZeroMemory(pAd->Mlme.CntlAux.Ssid, pAd->Mlme.CntlAux.SsidLen);
186 break;
188 case MT2_MLME_ROAMING_REQ:
189 CntlMlmeRoamingProc(pAd, Elem);
190 break;
192 default:
193 DBGPRINT(RT_DEBUG_TRACE, "CNTL - Illegal message in CntlIdleProc(MsgType=%d)\n",Elem->MsgType);
194 break;
198 VOID CntlOidScanProc(
199 IN PRTMP_ADAPTER pAd,
200 IN MLME_QUEUE_ELEM *Elem)
202 MLME_SCAN_REQ_STRUCT ScanReq;
203 CHAR BroadSsid[MAX_LEN_OF_SSID];
204 ULONG BssIdx = BSS_NOT_FOUND;
205 BSS_ENTRY CurrBss;
207 DBGPRINT(RT_DEBUG_INFO, "CNTL - SCAN starts\n");
209 // temporarily recover BBP from short-distance-low-sensibility mode during SCAN
210 // for best SCANNING reult;
211 AsicRestoreBbpSensibility(pAd);
213 // record current BSS if network is connected.
214 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
215 if (pAd->MediaState == NdisMediaStateConnected) // if (INFRA_ON(pAd) || ADHOC_ON(pAd))
217 BssIdx = BssTableSearch(&pAd->PortCfg.BssTab, &pAd->PortCfg.Bssid);
218 if (BssIdx != BSS_NOT_FOUND)
220 NdisMoveMemory(&CurrBss, &pAd->PortCfg.BssTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
222 // 2003-2-20 reset this RSSI to a low value but not zero. In normal case, the coming SCAN
223 // should return a correct RSSI to overwrite this. If no BEEACON received after SCAN,
224 // at least we still report a "greater than 0" RSSI since we claim it's CONNECTED.
225 CurrBss.Rssi = 18; // about -82 dB
229 // clean up previous SCAN result, add current BSS back to table if any
230 BssTableInit(&pAd->PortCfg.BssTab);
231 if (BssIdx != BSS_NOT_FOUND)
233 // DDK Note: If the NIC is associated with a particular BSSID and SSID
234 // that are not contained in the list of BSSIDs generated by this scan, the
235 // BSSID description of the currently associated BSSID and SSID should be
236 // appended to the list of BSSIDs in the NIC's database.
237 // To ensure this, we append this BSS as the first entry in SCAN result
238 NdisMoveMemory(&pAd->PortCfg.BssTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
239 pAd->PortCfg.BssTab.BssNr = 1;
242 BroadSsid[0] = '\0';
243 ScanParmFill(pAd, &ScanReq, BroadSsid, 0, BSS_ANY, SCAN_PASSIVE);
244 MlmeEnqueue(&pAd->Mlme.Queue, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
245 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
246 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
250 ==========================================================================
251 Description:
252 ==========================================================================
254 VOID CntlOidSsidProc(
255 IN PRTMP_ADAPTER pAd,
256 IN MLME_QUEUE_ELEM * Elem)
258 NDIS_802_11_SSID *OidSsid = (NDIS_802_11_SSID *)Elem->Msg;
259 MLME_DISASSOC_REQ_STRUCT DisassocReq;
260 ULONG Now;
262 // Step 0.
263 // record the desired SSID and all matching BSSes into CntlAux.SsidBssTab for
264 // later-on iteration. Sort by RSSI order
265 NdisMoveMemory(pAd->Mlme.CntlAux.Ssid, OidSsid->Ssid, OidSsid->SsidLength);
266 pAd->Mlme.CntlAux.SsidLen = (UCHAR)OidSsid->SsidLength;
267 BssTableSsidSort(pAd, &pAd->Mlme.CntlAux.SsidBssTab, pAd->Mlme.CntlAux.Ssid, pAd->Mlme.CntlAux.SsidLen);
268 pAd->Mlme.CntlAux.BssIdx = 0;
269 DBGPRINT(RT_DEBUG_INFO, "CNTL - %d BSS match the desire SSID %s\n",pAd->Mlme.CntlAux.SsidBssTab.BssNr, pAd->Mlme.CntlAux.Ssid);
270 Now = jiffies;
272 if ((pAd->MediaState == NdisMediaStateConnected) &&
273 MAC_ADDR_EQUAL(&pAd->PortCfg.Bssid, &pAd->Mlme.CntlAux.SsidBssTab.BssEntry[0].Bssid))
275 if (((pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
276 (pAd->PortCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
278 // For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
279 // connection process
280 DBGPRINT(RT_DEBUG_TRACE, "CNTL - disassociate with current AP...\n");
281 DisassocParmFill(pAd, &DisassocReq, &pAd->PortCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
282 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
283 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
284 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
286 else if (pAd->bConfigChanged == TRUE)
288 // Config has changed, we have to reconnect the same AP
289 DBGPRINT(RT_DEBUG_TRACE, "CNTL - disassociate with current AP Because config changed...\n");
290 DisassocParmFill(pAd, &DisassocReq, &pAd->PortCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
291 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
292 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
293 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
295 else
297 // We only check if same to the BSSID with highest RSSI.
298 // If roaming of same SSID required, we still do the reconnection.
299 // same BSSID, go back to idle state directly
300 DBGPRINT(RT_DEBUG_TRACE, "CNTL - already with this BSSID. ignore this SET_SSID request\n");
301 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
304 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
307 else if (INFRA_ON(pAd))
309 // case 1. active association existent
310 // roaming is done within miniport driver, nothing to do with configuration
311 // utility. so upon a new SET(OID_802_11_SSID) is received, we just
312 // disassociate with the current (or previous) associated AP, if any,
313 // then perform a new association with this new SSID, no matter the
314 // new/old SSID are the same or npt.
315 DBGPRINT(RT_DEBUG_TRACE, "CNTL - disassociate with current AP...\n");
316 DisassocParmFill(pAd, &DisassocReq, &pAd->PortCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
317 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
318 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
319 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
321 else
323 if (ADHOC_ON(pAd))
325 DBGPRINT(RT_DEBUG_TRACE, "CNTL - drop current ADHOC\n");
326 LinkDown(pAd);
327 pAd->MediaState = NdisMediaStateDisconnected;
328 DBGPRINT(RT_DEBUG_TRACE, "NDIS_STATUS_MEDIA_DISCONNECT Event C!\n");
331 if ((pAd->Mlme.CntlAux.SsidBssTab.BssNr==0) && (pAd->PortCfg.AutoReconnect == TRUE) && (pAd->PortCfg.BssType == BSS_INFRA))
333 MLME_SCAN_REQ_STRUCT ScanReq;
335 DBGPRINT(RT_DEBUG_INFO, "CNTL - No matching BSS, start a new scan\n");
336 // BroadSsid[0] = '\0';
337 ScanParmFill(pAd, &ScanReq, pAd->Mlme.CntlAux.Ssid, pAd->Mlme.CntlAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
338 MlmeEnqueue(&pAd->Mlme.Queue, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
339 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
340 // Reset Missed scan number
341 pAd->PortCfg.IgnoredScanNumber = 0;
342 pAd->PortCfg.LastScanTime = Now;
344 else
346 IterateOnBssTab(pAd);
352 ==========================================================================
353 Description:
354 ==========================================================================
356 VOID CntlOidRTBssidProc(
357 IN PRTMP_ADAPTER pAd,
358 IN MLME_QUEUE_ELEM * Elem)
360 ULONG BssIdx;
361 MACADDR *pOidBssid = (MACADDR *)Elem->Msg;
362 MLME_DISASSOC_REQ_STRUCT DisassocReq;
363 MLME_JOIN_REQ_STRUCT JoinReq;
365 COPY_MAC_ADDR(&pAd->Mlme.CntlAux.Bssid, pOidBssid);
366 BssIdx = BssTableSearch(&pAd->PortCfg.BssTab, pOidBssid);
368 if (BssIdx == BSS_NOT_FOUND)
370 DBGPRINT(RT_DEBUG_TRACE, "CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n");
371 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
375 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
376 return;
379 // copy the matched BSS entry from PortCfg.BssTab to CntlAux.SsidBssTab
380 pAd->Mlme.CntlAux.BssIdx = 0;
381 pAd->Mlme.CntlAux.SsidBssTab.BssNr = 1;
382 NdisMoveMemory(&pAd->Mlme.CntlAux.SsidBssTab.BssEntry[0], &pAd->PortCfg.BssTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
384 // Add SSID into Mlme.CntlAux for site surey joining hidden SSID
385 pAd->Mlme.CntlAux.SsidLen = pAd->Mlme.CntlAux.SsidBssTab.BssEntry[0].SsidLen;
386 NdisMoveMemory(pAd->Mlme.CntlAux.Ssid, pAd->Mlme.CntlAux.SsidBssTab.BssEntry[0].Ssid, pAd->Mlme.CntlAux.SsidLen);
388 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
389 // we just follow normal procedure. The reason of user doing this may because he/she changed
390 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
391 // Since user knows he's chnged AP channel, he'll re-connect again. By skipping the following
392 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
393 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
394 // connection when setting the same BSSID.
395 if ( (pAd->MediaState == NdisMediaStateConnected) && //(INFRA_ON(pAd) || ADHOC_ON(pAd)) &&
396 MAC_ADDR_EQUAL(&pAd->PortCfg.Bssid, pOidBssid))
398 // same BSSID, go back to idle state directly
399 DBGPRINT(RT_DEBUG_TRACE, "CNTL - already in this BSSID. ignore this SET_BSSID request\n");
400 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
403 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
405 else
407 if (INFRA_ON(pAd))
409 // disassoc from current AP first
410 DBGPRINT(RT_DEBUG_TRACE, "CNTL - disassociate with current AP ...\n");
411 DisassocParmFill(pAd, &DisassocReq, &pAd->PortCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
412 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
413 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
415 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
417 else
419 if (ADHOC_ON(pAd))
421 DBGPRINT(RT_DEBUG_TRACE, "CNTL - drop current ADHOC\n");
422 LinkDown(pAd);
423 pAd->MediaState = NdisMediaStateDisconnected;
424 DBGPRINT(RT_DEBUG_TRACE, "NDIS_STATUS_MEDIA_DISCONNECT Event C!\n");
427 // No active association, join the BSS immediately
428 DBGPRINT(RT_DEBUG_TRACE, "CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
429 pOidBssid->Octet[0],pOidBssid->Octet[1],pOidBssid->Octet[2],
430 pOidBssid->Octet[3],pOidBssid->Octet[4],pOidBssid->Octet[5]);
431 JoinParmFill(pAd, &JoinReq, pAd->Mlme.CntlAux.BssIdx);
432 MlmeEnqueue(&pAd->Mlme.Queue, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
434 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
439 // Roaming is the only external request triggering CNTL state machine
440 // despite of other "SET OID" operation. All "SET OID" related oerations
441 // happen in sequence, because no other SET OID will be sent to this device
442 // until the the previous SET operation is complete (successful o failed).
443 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
444 // or been corrupted by other "SET OID"?
445 VOID CntlMlmeRoamingProc(
446 IN PRTMP_ADAPTER pAd,
447 IN MLME_QUEUE_ELEM *Elem)
449 // TODO:
450 // AP in different channel may show lower RSSI than actual value??
451 // should we add a weighting factor to compensate it?
452 DBGPRINT(RT_DEBUG_TRACE,"CNTL - Roaming in CntlAux.RoamTab...\n");
453 BssTableSortByRssi(&pAd->Mlme.CntlAux.RoamTab);
454 pAd->Mlme.CntlAux.RoamIdx=0;
455 IterateOnBssTab2(pAd);
460 ==========================================================================
461 Description:
462 ==========================================================================
464 VOID CntlWaitDisassocProc(
465 IN PRTMP_ADAPTER pAd,
466 IN MLME_QUEUE_ELEM *Elem)
468 MLME_START_REQ_STRUCT StartReq;
470 if (Elem->MsgType == MT2_DISASSOC_CONF)
472 DBGPRINT(RT_DEBUG_TRACE, "CNTL - Dis-associate successful\n");
473 LinkDown(pAd);
475 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
476 if ((pAd->Mlme.CntlAux.SsidBssTab.BssNr==0) && (pAd->PortCfg.BssType == BSS_INDEP))
478 DBGPRINT(RT_DEBUG_TRACE, "CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->Mlme.CntlAux.Ssid);
479 StartParmFill(pAd, &StartReq, pAd->Mlme.CntlAux.Ssid, pAd->Mlme.CntlAux.SsidLen);
480 MlmeEnqueue(&pAd->Mlme.Queue, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
481 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
483 // case 2. try each matched BSS
484 else
486 IterateOnBssTab(pAd);
492 ==========================================================================
493 Description:
494 ==========================================================================
496 VOID CntlWaitJoinProc(
497 IN PRTMP_ADAPTER pAd,
498 IN MLME_QUEUE_ELEM *Elem)
500 USHORT Reason;
501 MLME_AUTH_REQ_STRUCT AuthReq;
503 if (Elem->MsgType == MT2_JOIN_CONF)
505 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
506 if (Reason == MLME_SUCCESS)
508 // 1. joined an IBSS, we are pretty much done here
509 if (pAd->PortCfg.BssType == BSS_INDEP)
511 LinkUp(pAd, BSS_INDEP);
512 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
515 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
517 // 2. joined a new INFRA network, start from authentication
518 else
520 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
521 if ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeShared) ||
522 (pAd->PortCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
524 AuthParmFill(pAd, &AuthReq, &pAd->PortCfg.Bssid, Ndis802_11AuthModeShared);
526 else
528 AuthParmFill(pAd, &AuthReq, &pAd->PortCfg.Bssid, Ndis802_11AuthModeOpen);
530 MlmeEnqueue(&pAd->Mlme.Queue, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
531 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
533 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
536 else
538 // 3. failed, try next BSS
539 pAd->Mlme.CntlAux.BssIdx++;
540 IterateOnBssTab(pAd);
547 ==========================================================================
548 Description:
549 ==========================================================================
551 VOID CntlWaitStartProc(
552 IN PRTMP_ADAPTER pAd,
553 IN MLME_QUEUE_ELEM *Elem)
555 USHORT Result;
557 if (Elem->MsgType == MT2_START_CONF)
559 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
560 if (Result == MLME_SUCCESS)
562 DBGPRINT(RT_DEBUG_TRACE, "CNTL - We have started a new ADHOC network\n");
563 DBGPRINT(RT_DEBUG_TRACE, "CNTL - BSSID %02x:%02x:%02x:%02x:%02x:%02x ...\n",
564 pAd->PortCfg.Bssid.Octet[0],
565 pAd->PortCfg.Bssid.Octet[1],
566 pAd->PortCfg.Bssid.Octet[2],
567 pAd->PortCfg.Bssid.Octet[3],
568 pAd->PortCfg.Bssid.Octet[4],
569 pAd->PortCfg.Bssid.Octet[5]);
570 LinkUp(pAd, BSS_INDEP);
571 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
574 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
576 else
578 DBGPRINT(RT_DEBUG_TRACE, "CNTL - Start FAIL. BUG!!!!!\n");
579 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
582 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
588 ==========================================================================
589 Description:
590 ==========================================================================
592 VOID CntlWaitAuthProc(
593 IN PRTMP_ADAPTER pAd,
594 IN MLME_QUEUE_ELEM *Elem)
596 USHORT Reason;
597 MLME_ASSOC_REQ_STRUCT AssocReq;
598 MLME_AUTH_REQ_STRUCT AuthReq;
600 if (Elem->MsgType == MT2_AUTH_CONF)
602 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
603 if (Reason == MLME_SUCCESS)
605 DBGPRINT(RT_DEBUG_TRACE, "CNTL - AUTH OK\n");
606 AssocParmFill(pAd, &AssocReq, &pAd->PortCfg.Bssid, pAd->PortCfg.CapabilityInfo,
607 ASSOC_TIMEOUT, pAd->PortCfg.DefaultListenCount);
608 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
609 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
611 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
613 else
615 // This fail may because of the AP already keep us in its MAC table without
616 // ageing-out. The previous authentication attempt must have let it remove us.
617 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
618 DBGPRINT(RT_DEBUG_TRACE, "CNTL - AUTH FAIL, try again...\n");
619 if ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeShared) ||
620 (pAd->PortCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
622 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
623 AuthParmFill(pAd, &AuthReq, &pAd->PortCfg.Bssid, Ndis802_11AuthModeShared);
625 else
627 AuthParmFill(pAd, &AuthReq, &pAd->PortCfg.Bssid, Ndis802_11AuthModeOpen);
630 MlmeEnqueue(&pAd->Mlme.Queue, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
631 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
633 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
639 ==========================================================================
640 Description:
641 ==========================================================================
643 VOID CntlWaitAuthProc2(
644 IN PRTMP_ADAPTER pAd,
645 IN MLME_QUEUE_ELEM *Elem)
647 USHORT Reason;
648 MLME_ASSOC_REQ_STRUCT AssocReq;
649 MLME_AUTH_REQ_STRUCT AuthReq;
651 if (Elem->MsgType == MT2_AUTH_CONF)
653 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
654 if (Reason == MLME_SUCCESS)
656 DBGPRINT(RT_DEBUG_TRACE, "CNTL - AUTH OK\n");
657 AssocParmFill(pAd, &AssocReq, &pAd->PortCfg.Bssid, pAd->PortCfg.CapabilityInfo,
658 ASSOC_TIMEOUT, pAd->PortCfg.DefaultListenCount);
659 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
660 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
662 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
664 else
666 if ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
667 (pAd->Mlme.AuthAux.Alg == Ndis802_11AuthModeShared))
669 DBGPRINT(RT_DEBUG_TRACE, "CNTL - AUTH FAIL, try OPEN system...\n");
670 AuthParmFill(pAd, &AuthReq, &pAd->PortCfg.Bssid, Ndis802_11AuthModeOpen);
671 MlmeEnqueue(&pAd->Mlme.Queue, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
672 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
674 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
676 else
678 // not success, try next BSS
679 DBGPRINT(RT_DEBUG_TRACE, "CNTL - AUTH FAIL, give up; try next BSS\n");
680 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
681 pAd->Mlme.CntlAux.BssIdx++;
682 IterateOnBssTab(pAd);
689 ==========================================================================
690 Description:
691 ==========================================================================
693 VOID CntlWaitAssocProc(
694 IN PRTMP_ADAPTER pAd,
695 IN MLME_QUEUE_ELEM *Elem)
697 USHORT Reason;
699 if (Elem->MsgType == MT2_ASSOC_CONF)
701 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
702 if (Reason == MLME_SUCCESS)
704 DBGPRINT(RT_DEBUG_TRACE, "CNTL - Association successful on BSS #%d\n",pAd->Mlme.CntlAux.BssIdx);
705 LinkUp(pAd, BSS_INFRA);
706 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
709 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
711 else
713 // not success, try next BSS
714 DBGPRINT(RT_DEBUG_TRACE, "CNTL - Association fails on BSS #%d\n",pAd->Mlme.CntlAux.BssIdx);
715 pAd->Mlme.CntlAux.BssIdx++;
716 IterateOnBssTab(pAd);
722 ==========================================================================
723 Description:
724 ==========================================================================
726 VOID CntlWaitReassocProc(
727 IN PRTMP_ADAPTER pAd,
728 IN MLME_QUEUE_ELEM *Elem)
730 USHORT Result;
732 if (Elem->MsgType == MT2_REASSOC_CONF)
734 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
735 if (Result == MLME_SUCCESS)
737 BSS_ENTRY *pBss = &pAd->Mlme.CntlAux.RoamTab.BssEntry[pAd->Mlme.CntlAux.RoamIdx];
739 // COPY_MAC_ADDR(&pAd->PortCfg.Bssid, &pBss->Bssid);
740 // AsicSetBssid(pAd, &pAd->PortCfg.Bssid);
742 // The following steps are supposed to be done after JOIN in normal procedure
743 // But since this RE-ASSOC skips the JOIN procedure, we have to do it after
744 // RE-ASSOC succeeds. If RE-ASSOC fails, then stay at original AP without any change
745 pAd->PortCfg.BeaconPeriod = pBss->BeaconPeriod;
746 pAd->PortCfg.Channel = pBss->Channel;
747 // The security setting should always follow upper layer definition, not from frame
748 //pAd->PortCfg.PrivacyInvoked = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
749 pAd->PortCfg.SupportedRatesLen = pBss->RatesLen;
750 NdisMoveMemory(pAd->PortCfg.SupportedRates, pBss->Rates, pBss->RatesLen);
752 // Check for 802.11g information, if 802.11 b /g mixed mode.
753 pAd->PortCfg.CapabilityInfo = pBss->CapabilityInfo;
755 pAd->PortCfg.CfpPeriod = pBss->CfpPeriod;
756 pAd->PortCfg.CfpMaxDuration = pBss->CfpMaxDuration;
757 pAd->PortCfg.CfpDurRemain = pBss->CfpDurRemaining;
758 pAd->PortCfg.CfpCount = pBss->CfpCount;
761 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
763 DBGPRINT(RT_DEBUG_TRACE, "CNTL - Re-assocition successful on BSS #%d\n", pAd->Mlme.CntlAux.RoamIdx);
764 LinkUp(pAd, BSS_INFRA);
765 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
767 else
769 // reassoc failed, try to pick next BSS in the BSS Table
770 DBGPRINT(RT_DEBUG_TRACE, "CNTL - Re-assocition fails on BSS #%d\n", pAd->Mlme.CntlAux.RoamIdx);
771 pAd->Mlme.CntlAux.RoamIdx++;
772 IterateOnBssTab2(pAd);
778 ==========================================================================
779 Description:
780 ==========================================================================
782 VOID LinkUp(
783 IN PRTMP_ADAPTER pAd,
784 IN UCHAR BssType)
786 ULONG Now;
788 DBGPRINT(RT_DEBUG_TRACE, "CNTL - !!! LINK UP !!!\n");
789 MlmeUpdateTxRates(pAd, TRUE);
790 NdisMoveMemory(&pAd->Mlme.PrevWlanCounters, &pAd->WlanCounters, sizeof(COUNTER_802_11));
791 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
793 Now = jiffies;
794 pAd->PortCfg.LastBeaconRxTime = Now; // last RX timestamp
796 if ((pAd->PortCfg.WindowsTxPreamble != Rt802_11PreambleLong) &&
797 CAP_IS_SHORT_PREAMBLE_ON(pAd->PortCfg.CapabilityInfo))
799 DBGPRINT(RT_DEBUG_TRACE, "CNTL - !!! Set to short preamble!!!\n");
800 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
803 pAd->PortCfg.BssType = BssType;
804 if (BssType == BSS_INDEP)
806 pAd->PortCfg.Mibss = TRUE;
807 pAd->PortCfg.Massoc = FALSE;
808 MakeIbssBeacon(pAd);
809 AsicEnableIbssSync(pAd);
811 #ifdef SINGLE_ADHOC_LINKUP
812 // Although this did not follow microsoft's recommendation.
813 //Change based on customer's request
814 pAd->MediaState = NdisMediaStateConnected;
815 #endif
817 // Clear Key information when driver change to WPA-None mode
818 // which did not have any key set
819 #if 0
820 if (pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPANone)
822 INT i;
824 for (i = 0; i < PAIRWISE_KEY_NO; i++)
826 pAd->PortCfg.PairwiseKey[i].KeyLen = 0;
829 for (i = 0; i < GROUP_KEY_NO; i++)
831 pAd->PortCfg.GroupKey[i].KeyLen = 0;
834 #endif
836 else // BSS_INFRA
838 pAd->PortCfg.Massoc = TRUE;
839 pAd->PortCfg.Mibss = FALSE;
841 // NOTE:
842 // the decision of using "short slot time" or not may change dynamically due to
843 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
845 // NOTE:
846 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
847 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
849 ComposePsPoll(pAd);
850 ComposeNullFrame(pAd);
851 AsicEnableBssSync(pAd);
853 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
854 // should wait until at least 2 active nodes in this BSSID.
855 pAd->MediaState = NdisMediaStateConnected;
858 DBGPRINT(RT_DEBUG_TRACE, "NDIS_STATUS_MEDIA_CONNECT Event B!\n");
860 if (pAd->PortCfg.LedMode != LED_MODE_SINGLE)
862 ASIC_LED_ACT_ON(pAd);
865 AsicSetSlotTime(pAd, FALSE);
866 pAd->Mlme.PeriodicRound = 0;
867 // Reset config flag
868 pAd->bConfigChanged = FALSE;
872 ==========================================================================
873 Description:
874 ==========================================================================
876 VOID LinkDown(
877 IN PRTMP_ADAPTER pAd)
879 DBGPRINT(RT_DEBUG_TRACE, "CNTL - !!! LINK DOWN !!!\n");
881 if (ADHOC_ON(pAd)) // Adhoc mode link down
883 pAd->PortCfg.Mibss = FALSE;
885 #ifdef SINGLE_ADHOC_LINKUP
886 pAd->MediaState = NdisMediaStateDisconnected;
887 // clean up previous SCAN result, add current BSS back to table if any
888 BssTableDeleteEntry(&pAd->PortCfg.BssTab, &(pAd->PortCfg.Bssid));
889 #else
890 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
892 pAd->MediaState = NdisMediaStateDisconnected;
893 // clean up previous SCAN result, add current BSS back to table if any
894 BssTableDeleteEntry(&pAd->PortCfg.BssTab, &(pAd->PortCfg.Bssid));
896 #endif
898 else// Infra structure mode
900 pAd->PortCfg.Massoc = FALSE;
901 pAd->MediaState = NdisMediaStateDisconnected;
902 DBGPRINT(RT_DEBUG_TRACE, "NDIS_STATUS_MEDIA_DISCONNECT Event A!\n");
903 BssTableDeleteEntry(&pAd->PortCfg.BssTab, &(pAd->PortCfg.Bssid));
905 // restore back to -
906 // 1. long slot (20 us) or short slot (9 us) time
907 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
908 // 3. short preamble
909 if (pAd->PortCfg.BGProtectionInUsed == TRUE)
911 pAd->PortCfg.BGProtectionInUsed = FALSE;
912 DBGPRINT(RT_DEBUG_TRACE, "Link down - turn off B/G protection\n");
917 AsicSetSlotTime(pAd, FALSE);
918 AsicRestoreBbpSensibility(pAd);
920 if (pAd->PortCfg.WindowsTxPreamble == Rt802_11PreambleShort)
921 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
922 else
923 MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
925 if ((pAd->PortCfg.LedMode != LED_MODE_SINGLE) && (pAd->PortCfg.LedMode != LED_MODE_ASUS))
927 ASIC_LED_ACT_OFF(pAd);
929 else if ((pAd->PortCfg.LedMode == LED_MODE_ASUS) && (pAd->PortCfg.bRadio == TRUE))
931 RTMP_IO_WRITE32(pAd, LEDCSR, 0x0002461E);
933 AsicDisableSync(pAd);
934 pAd->Mlme.PeriodicRound = 0;
936 // Remove PortCfg Information after link down
937 NdisZeroMemory(&(pAd->PortCfg.Bssid), MAC_ADDR_LEN);
938 NdisZeroMemory(pAd->PortCfg.Ssid, MAX_LEN_OF_SSID);
939 pAd->PortCfg.SsidLen = 0;
941 // Reset WPA-PSK state. Only reset when supplicant enabled
942 if (pAd->PortCfg.WpaState != SS_NOTUSE)
944 pAd->PortCfg.WpaState = SS_START;
945 // Clear Replay counter
946 NdisZeroMemory(pAd->PortCfg.ReplayCounter, 8);
949 // Remove all WPA keys after link down
950 RTMPWPARemoveAllKeys(pAd);
951 // 802.1x port control
952 pAd->PortCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
953 pAd->PortCfg.MicErrCnt = 0;
957 ==========================================================================
958 Description:
959 ==========================================================================
961 VOID MlmeCntlConfirm(
962 IN PRTMP_ADAPTER pAd,
963 IN ULONG MsgType,
964 IN USHORT Msg)
966 MlmeEnqueue(&pAd->Mlme.Queue, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg);
970 ==========================================================================
971 Description:
972 ==========================================================================
974 VOID IterateOnBssTab(
975 IN PRTMP_ADAPTER pAd)
977 MLME_START_REQ_STRUCT StartReq;
978 MLME_JOIN_REQ_STRUCT JoinReq;
979 ULONG BssIdx;
981 BssIdx = pAd->Mlme.CntlAux.BssIdx;
982 if (BssIdx < pAd->Mlme.CntlAux.SsidBssTab.BssNr)
984 DBGPRINT(RT_DEBUG_TRACE, "CNTL - Trying BSSID %02x:%02x:%02x:%02x:%02x:%02x ...\n",
985 pAd->Mlme.CntlAux.SsidBssTab.BssEntry[BssIdx].Bssid.Octet[0],
986 pAd->Mlme.CntlAux.SsidBssTab.BssEntry[BssIdx].Bssid.Octet[1],
987 pAd->Mlme.CntlAux.SsidBssTab.BssEntry[BssIdx].Bssid.Octet[2],
988 pAd->Mlme.CntlAux.SsidBssTab.BssEntry[BssIdx].Bssid.Octet[3],
989 pAd->Mlme.CntlAux.SsidBssTab.BssEntry[BssIdx].Bssid.Octet[4],
990 pAd->Mlme.CntlAux.SsidBssTab.BssEntry[BssIdx].Bssid.Octet[5]);
991 JoinParmFill(pAd, &JoinReq, BssIdx);
992 MlmeEnqueue(&pAd->Mlme.Queue, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
993 &JoinReq);
994 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
996 else if (pAd->PortCfg.BssType == BSS_INDEP)
998 DBGPRINT(RT_DEBUG_TRACE, "CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->Mlme.CntlAux.Ssid);
999 StartParmFill(pAd, &StartReq, pAd->Mlme.CntlAux.Ssid, (UCHAR)pAd->Mlme.CntlAux.SsidLen);
1000 MlmeEnqueue(&pAd->Mlme.Queue, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
1001 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
1003 else // no more BSS
1005 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
1007 DBGPRINT(RT_DEBUG_TRACE, "CNTL - All BSS fail; reply NDIS_STATUS_NOT_ACCEPTED\n");
1009 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1013 // for re-association only
1014 VOID IterateOnBssTab2(
1015 IN PRTMP_ADAPTER pAd)
1017 MLME_REASSOC_REQ_STRUCT ReassocReq;
1018 ULONG BssIdx;
1019 BSS_ENTRY *pBss;
1021 BssIdx = pAd->Mlme.CntlAux.RoamIdx;
1022 pBss = &pAd->Mlme.CntlAux.RoamTab.BssEntry[BssIdx];
1024 if (BssIdx < pAd->Mlme.CntlAux.RoamTab.BssNr)
1026 DBGPRINT(RT_DEBUG_TRACE, "CNTL - try BSS #%d %02x:%02x:%02x:%02x:%02x:%02x ...\n",
1027 BssIdx, pBss->Bssid.Octet[0],pBss->Bssid.Octet[1],pBss->Bssid.Octet[2],
1028 pBss->Bssid.Octet[3],pBss->Bssid.Octet[4],pBss->Bssid.Octet[5]);
1030 AsicSwitchChannel(pAd, pBss->Channel);
1031 AsicLockChannel(pAd, pBss->Channel);
1033 // reassociate message has the same structure as associate message
1034 AssocParmFill(pAd, &ReassocReq, &pBss->Bssid, pBss->CapabilityInfo,
1035 ASSOC_TIMEOUT, pAd->PortCfg.DefaultListenCount);
1036 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
1037 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
1039 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
1041 else // no more BSS
1043 DBGPRINT(RT_DEBUG_TRACE, "CNTL - All roaming failed, stay with original AP\n");
1044 AsicSwitchChannel(pAd, pAd->PortCfg.Channel);
1045 AsicLockChannel(pAd, pAd->PortCfg.Channel);
1046 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1051 ==========================================================================
1052 Description:
1053 ==========================================================================
1055 VOID JoinParmFill(
1056 IN PRTMP_ADAPTER pAd,
1057 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
1058 IN ULONG BssIdx)
1060 JoinReq->BssIdx = BssIdx;
1064 ==========================================================================
1065 Description:
1066 ==========================================================================
1068 VOID AssocParmFill(
1069 IN PRTMP_ADAPTER pAd,
1070 IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
1071 IN MACADDR *Addr,
1072 IN USHORT CapabilityInfo,
1073 IN ULONG Timeout,
1074 IN USHORT ListenIntv)
1076 COPY_MAC_ADDR(&AssocReq->Addr, Addr);
1077 // Add mask to support 802.11b mode only
1078 AssocReq->CapabilityInfo = CapabilityInfo & 0xfff3; // not cf-pollable, not cf-poll-request
1079 AssocReq->Timeout = Timeout;
1080 AssocReq->ListenIntv = ListenIntv;
1084 ==========================================================================
1085 Description:
1086 ==========================================================================
1088 VOID ScanParmFill(
1089 IN PRTMP_ADAPTER pAd,
1090 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
1091 IN CHAR Ssid[],
1092 IN UCHAR SsidLen,
1093 IN UCHAR BssType,
1094 IN UCHAR ScanType)
1096 ScanReq->SsidLen = SsidLen;
1097 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
1098 ScanReq->BssType = BssType;
1099 ScanReq->ScanType = ScanType;
1103 ==========================================================================
1104 Description:
1105 ==========================================================================
1107 VOID DisassocParmFill(
1108 IN PRTMP_ADAPTER pAd,
1109 IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
1110 IN MACADDR *Addr,
1111 IN USHORT Reason)
1113 COPY_MAC_ADDR(&DisassocReq->Addr, Addr);
1114 DisassocReq->Reason = Reason;
1118 ==========================================================================
1119 Description:
1120 ==========================================================================
1122 VOID StartParmFill(
1123 IN PRTMP_ADAPTER pAd,
1124 IN OUT MLME_START_REQ_STRUCT *StartReq,
1125 IN CHAR Ssid[],
1126 IN UCHAR SsidLen)
1128 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
1129 StartReq->SsidLen = SsidLen;
1133 ==========================================================================
1134 Description:
1135 ==========================================================================
1137 VOID AuthParmFill(
1138 IN PRTMP_ADAPTER pAd,
1139 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
1140 IN MACADDR *Addr,
1141 IN USHORT Alg)
1143 COPY_MAC_ADDR(&AuthReq->Addr, Addr);
1144 AuthReq->Alg = Alg;
1145 AuthReq->Timeout = AUTH_TIMEOUT;
1149 ==========================================================================
1150 Description:
1151 ==========================================================================
1153 VOID ComposePsPoll(
1154 IN PRTMP_ADAPTER pAd)
1156 NdisZeroMemory(&pAd->Mlme.PsFr, sizeof(PSPOLL_FRAME));
1157 pAd->Mlme.PsFr.Type = BTYPE_CNTL;
1158 pAd->Mlme.PsFr.SubType = SUBTYPE_PS_POLL;
1159 pAd->Mlme.PsFr.Aid = pAd->PortCfg.Aid | 0xC000;
1160 COPY_MAC_ADDR(&(pAd->Mlme.PsFr.Bssid), &pAd->PortCfg.Bssid);
1161 COPY_MAC_ADDR(&(pAd->Mlme.PsFr.Ta), &(pAd->CurrentAddress));
1164 VOID ComposeNullFrame(
1165 IN PRTMP_ADAPTER pAd)
1167 MgtMacHeaderInit(pAd, &pAd->Mlme.NullFr, SUBTYPE_NULL_FUNC, 1, &pAd->PortCfg.Bssid, &pAd->PortCfg.Bssid);
1168 pAd->Mlme.NullFr.Duration = 0;
1169 pAd->Mlme.NullFr.Type = BTYPE_DATA;
1173 ==========================================================================
1174 Description:
1175 Pre-build a BEACON frame in the shared memory
1176 ==========================================================================
1178 ULONG MakeIbssBeacon(
1179 IN PRTMP_ADAPTER pAd)
1181 UCHAR SsidIe = IE_SSID, DsIe = IE_DS_PARM, IbssIe = IE_IBSS_PARM, SuppIe = IE_SUPP_RATES,
1182 DsLen = 1, IbssLen = 2;
1183 UCHAR ExtRateIe = IE_EXT_SUPP_RATES, ExtRatesLen;
1184 UCHAR ErpIe[3] = {IE_ERP, 1, 0x04};
1185 MACHDR BcnHdr;
1186 USHORT CapabilityInfo;
1187 LARGE_INTEGER FakeTimestamp;
1188 ULONG FrameLen;
1189 PTXD_STRUC pTxD = (PTXD_STRUC)pAd->BeaconRing.va_addr;
1190 CHAR *pBeaconFrame = (CHAR *)pAd->BeaconRing.va_data_addr;
1191 UCHAR SupportedRatesLen;
1192 UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
1193 BOOLEAN Privacy;
1195 // 2003-12-10 802.11g WIFI spec disallow OFDM rates in 802.11g ADHOC mode
1196 // make sure 1,2,5.5,11 are the firt 4 rates in PortCfg.SupportedRates[] array
1197 if ((pAd->PortCfg.PhyMode == PHY_11BG_MIXED) && (pAd->PortCfg.AdhocMode == 0))
1199 int i;
1200 SupportedRatesLen=0;
1201 for (i=0;i<pAd->PortCfg.SupportedRatesLen;i++)
1203 switch (pAd->PortCfg.SupportedRates[i] & 0x7f)
1205 case 2:
1206 case 4:
1207 case 11:
1208 case 22:
1209 SupportedRates[SupportedRatesLen] = pAd->PortCfg.SupportedRates[i];
1210 SupportedRatesLen ++;
1211 break;
1212 default:
1213 break;
1216 // error handling - should never happen
1217 if (SupportedRatesLen != 4)
1219 SupportedRatesLen = 4;
1220 SupportedRates[0] = 0x82;
1221 SupportedRates[1] = 0x84;
1222 SupportedRates[2] = 0x8b;
1223 SupportedRates[3] = 0x96;
1226 else
1228 SupportedRatesLen = pAd->PortCfg.SupportedRatesLen;
1229 NdisMoveMemory(SupportedRates, pAd->PortCfg.SupportedRates, SupportedRatesLen);
1232 pAd->PortCfg.AtimWin = 0; // ??????
1234 // compose IBSS beacon frame
1235 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, &pAd->PortCfg.Broadcast, &pAd->PortCfg.Bssid);
1236 Privacy = (pAd->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
1237 (pAd->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
1238 (pAd->PortCfg.WepStatus == Ndis802_11Encryption3Enabled);
1239 CapabilityInfo = CAP_GENERATE(0, 1, 0, 0, Privacy, (pAd->PortCfg.WindowsTxPreamble == Rt802_11PreambleShort));
1240 if (SupportedRatesLen <= 8)
1242 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
1243 MAC_HDR_LEN, &BcnHdr,
1244 TIMESTAMP_LEN, &FakeTimestamp,
1245 2, &pAd->PortCfg.BeaconPeriod,
1246 2, &CapabilityInfo,
1247 1, &SsidIe,
1248 1, &pAd->PortCfg.SsidLen,
1249 pAd->PortCfg.SsidLen, pAd->PortCfg.Ssid,
1250 1, &SuppIe,
1251 1, &SupportedRatesLen,
1252 SupportedRatesLen, SupportedRates,
1253 1, &DsIe,
1254 1, &DsLen,
1255 1, &pAd->PortCfg.Channel,
1256 1, &IbssIe,
1257 1, &IbssLen,
1258 2, &pAd->PortCfg.AtimWin,
1259 END_OF_ARGS);
1261 else
1263 ExtRatesLen = SupportedRatesLen - 8;
1264 SupportedRatesLen = 8;
1265 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
1266 MAC_HDR_LEN, &BcnHdr,
1267 TIMESTAMP_LEN, &FakeTimestamp,
1268 2, &pAd->PortCfg.BeaconPeriod,
1269 2, &CapabilityInfo,
1270 1, &SsidIe,
1271 1, &pAd->PortCfg.SsidLen,
1272 pAd->PortCfg.SsidLen, pAd->PortCfg.Ssid,
1273 1, &SuppIe,
1274 1, &SupportedRatesLen,
1275 SupportedRatesLen, SupportedRates,
1276 1, &DsIe,
1277 1, &DsLen,
1278 1, &pAd->PortCfg.Channel,
1279 1, &IbssIe,
1280 1, &IbssLen,
1281 2, &pAd->PortCfg.AtimWin,
1282 3, ErpIe,
1283 1, &ExtRateIe,
1284 1, &ExtRatesLen,
1285 ExtRatesLen, &SupportedRates[SupportedRatesLen],
1286 END_OF_ARGS);
1288 // If adhoc secruity is set for WPA-None, append the cipher suite IE
1289 if (pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPANone)
1291 ULONG tmp;
1292 UCHAR WpaIe = IE_WPA;
1294 if (pAd->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) // Tkip
1296 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
1297 1, &WpaIe,
1298 1, &CipherSuiteWpaNoneTkipLen,
1299 CipherSuiteWpaNoneTkipLen, &CipherSuiteWpaNoneTkip[0],
1300 END_OF_ARGS);
1301 FrameLen += tmp;
1303 else if (pAd->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) // Aes
1305 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
1306 1, &WpaIe,
1307 1, &CipherSuiteWpaNoneAesLen,
1308 CipherSuiteWpaNoneAesLen, &CipherSuiteWpaNoneAes[0],
1309 END_OF_ARGS);
1310 FrameLen += tmp;
1313 #ifdef BIG_ENDIAN
1314 RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
1315 #endif
1317 RTMPWriteTxDescriptor(pTxD, FALSE, CIPHER_NONE, FALSE, FALSE, TRUE, SHORT_RETRY, IFS_NEW_BACKOFF,
1318 pAd->PortCfg.MlmeRate, 4, FrameLen, pAd->PortCfg.TxPreambleInUsed, 0);
1320 DBGPRINT(RT_DEBUG_TRACE, "MakeIbssBeacon (len=%d)\n", FrameLen);
1321 return FrameLen;