MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / net / wireless / rtlink.org / connect.c
blobaa9da30e6e6c8c78e87bb1f3bf6f5d68b33d6424
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 * (c) Copyright 2002, Ralink Technology, Inc.
8 * All rights reserved. Ralink's source code is an unpublished work and the
9 * use of a copyright notice does not imply otherwise. This source code
10 * contains confidential trade secret material of Ralink Tech. Any attemp
11 * or participation in deciphering, decoding, reverse engineering or in any
12 * way altering the source code is stricitly prohibited, unless the prior
13 * written consent of Ralink Technology, Inc. is obtained.
14 ****************************************************************************/
16 #include "rt_config.h"
18 UCHAR CipherSuiteWpaNoneTkip[] = {
19 0x00, 0x50, 0xf2, 0x01, // oui
20 0x01, 0x00, // Version
21 0x00, 0x50, 0xf2, 0x02, // Multicast
22 0x01, 0x00, // Number of unicast
23 0x00, 0x50, 0xf2, 0x00, // unicast
24 0x01, 0x00, // number of authentication method
25 0x00, 0x50, 0xf2, 0x00 // authentication
27 UCHAR CipherSuiteWpaNoneTkipLen = (sizeof(CipherSuiteWpaNoneTkip) / sizeof(UCHAR));
29 UCHAR CipherSuiteWpaNoneAes[] = {
30 0x00, 0x50, 0xf2, 0x01, // oui
31 0x01, 0x00, // Version
32 0x00, 0x50, 0xf2, 0x04, // Multicast
33 0x01, 0x00, // Number of unicast
34 0x00, 0x50, 0xf2, 0x00, // unicast
35 0x01, 0x00, // number of authentication method
36 0x00, 0x50, 0xf2, 0x00 // authentication
38 UCHAR CipherSuiteWpaNoneAesLen = (sizeof(CipherSuiteWpaNoneAes) / sizeof(UCHAR));
41 ==========================================================================
42 Description:
43 ==========================================================================
45 VOID MlmeCntlInit(
46 IN PRTMP_ADAPTER pAd,
47 IN STATE_MACHINE *S,
48 OUT STATE_MACHINE_FUNC Trans[])
50 // Control state machine differs from other state machines, the interface
51 // follows the standard interface
52 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
56 ==========================================================================
57 Description:
58 ==========================================================================
60 VOID MlmeCntlMachinePerformAction(
61 IN PRTMP_ADAPTER pAd,
62 IN STATE_MACHINE *S,
63 IN MLME_QUEUE_ELEM *Elem)
65 switch(pAd->Mlme.CntlMachine.CurrState)
67 case CNTL_IDLE:
68 CntlIdleProc(pAd, Elem);
69 break;
70 case CNTL_WAIT_DISASSOC:
71 CntlWaitDisassocProc(pAd, Elem);
72 break;
73 case CNTL_WAIT_JOIN:
74 CntlWaitJoinProc(pAd, Elem);
75 break;
77 // CNTL_WAIT_REASSOC is the only state in CNTL machine that does
78 // not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)".
79 // Therefore not protected by NDIS's "only one outstanding OID request"
80 // rule. Which means NDIS may SET OID in the middle of ROAMing attempts.
81 // Current approach is to block new SET request at RTMPSetInformation()
82 // when CntlMachine.CurrState is not CNTL_IDLE
83 case CNTL_WAIT_REASSOC:
84 CntlWaitReassocProc(pAd, Elem);
85 break;
87 case CNTL_WAIT_START:
88 CntlWaitStartProc(pAd, Elem);
89 break;
90 case CNTL_WAIT_AUTH:
91 CntlWaitAuthProc(pAd, Elem);
92 break;
93 case CNTL_WAIT_AUTH2:
94 CntlWaitAuthProc2(pAd, Elem);
95 break;
96 case CNTL_WAIT_ASSOC:
97 CntlWaitAssocProc(pAd, Elem);
98 break;
100 case CNTL_WAIT_OID_LIST_SCAN:
101 if(Elem->MsgType == MT2_SCAN_CONF)
103 // Resume TxRing after SCANING complete. We hope the out-of-service time
104 // won't be too long to let upper layer time-out the waiting frames
105 RTMPResumeMsduTransmission(pAd);
106 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
109 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
111 if (pAd->MediaState == NdisMediaStateDisconnected)
113 //DBGPRINT(RT_DEBUG_TRACE, "**MlmeCntlMachinePerformAction**\n");
114 MlmeAutoReconnectLastSSID(pAd);
116 break;
118 case CNTL_WAIT_OID_DISASSOC:
119 if (Elem->MsgType == MT2_DISASSOC_CONF)
121 LinkDown(pAd);
123 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
126 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
128 break;
130 default:
131 DBGPRINT(RT_DEBUG_ERROR, "CNTL - Illegal message type(=%d)", Elem->MsgType);
132 break;
138 ==========================================================================
139 Description:
140 ==========================================================================
142 VOID CntlIdleProc(
143 IN PRTMP_ADAPTER pAd,
144 IN MLME_QUEUE_ELEM *Elem)
146 MLME_DISASSOC_REQ_STRUCT DisassocReq;
148 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
150 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
152 pAd->Mlme.CntlAux.CurrReqIsFromNdis = FALSE;
154 return;
157 switch(Elem->MsgType)
159 case OID_802_11_SSID:
160 CntlOidSsidProc(pAd, Elem);
161 break;
163 case OID_802_11_BSSID:
164 CntlOidRTBssidProc(pAd,Elem);
165 break;
167 case OID_802_11_BSSID_LIST_SCAN:
168 CntlOidScanProc(pAd,Elem);
169 break;
171 case OID_802_11_DISASSOCIATE:
172 DisassocParmFill(pAd, &DisassocReq, &pAd->PortCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
173 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
174 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
175 // Set the control aux SSID to prevent it reconnect to old SSID
176 // Since calling this indicate user don't want to connect to that SSID anymore.
177 pAd->Mlme.CntlAux.SsidLen = 32;
178 NdisZeroMemory(pAd->Mlme.CntlAux.Ssid, pAd->Mlme.CntlAux.SsidLen);
179 break;
181 case MT2_MLME_ROAMING_REQ:
182 CntlMlmeRoamingProc(pAd, Elem);
183 break;
185 default:
186 DBGPRINT(RT_DEBUG_TRACE, "CNTL - Illegal message in CntlIdleProc(MsgType=%d)\n",Elem->MsgType);
187 break;
191 VOID CntlOidScanProc(
192 IN PRTMP_ADAPTER pAd,
193 IN MLME_QUEUE_ELEM *Elem)
195 MLME_SCAN_REQ_STRUCT ScanReq;
196 CHAR BroadSsid[MAX_LEN_OF_SSID];
197 ULONG BssIdx = BSS_NOT_FOUND;
198 BSS_ENTRY CurrBss;
200 DBGPRINT(RT_DEBUG_INFO, "CNTL - SCAN starts\n");
202 // temporarily recover BBP from short-distance-low-sensibility mode during SCAN
203 // for best SCANNING reult;
204 AsicRestoreBbpSensibility(pAd);
206 // record current BSS if network is connected.
207 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
208 if (pAd->MediaState == NdisMediaStateConnected) // if (INFRA_ON(pAd) || ADHOC_ON(pAd))
210 BssIdx = BssTableSearch(&pAd->PortCfg.BssTab, &pAd->PortCfg.Bssid);
211 if (BssIdx != BSS_NOT_FOUND)
213 NdisMoveMemory(&CurrBss, &pAd->PortCfg.BssTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
215 // 2003-2-20 reset this RSSI to a low value but not zero. In normal case, the coming SCAN
216 // should return a correct RSSI to overwrite this. If no BEEACON received after SCAN,
217 // at least we still report a "greater than 0" RSSI since we claim it's CONNECTED.
218 CurrBss.Rssi = 18; // about -82 dB
222 // clean up previous SCAN result, add current BSS back to table if any
223 BssTableInit(&pAd->PortCfg.BssTab);
224 if (BssIdx != BSS_NOT_FOUND)
226 // DDK Note: If the NIC is associated with a particular BSSID and SSID
227 // that are not contained in the list of BSSIDs generated by this scan, the
228 // BSSID description of the currently associated BSSID and SSID should be
229 // appended to the list of BSSIDs in the NIC's database.
230 // To ensure this, we append this BSS as the first entry in SCAN result
231 NdisMoveMemory(&pAd->PortCfg.BssTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
232 pAd->PortCfg.BssTab.BssNr = 1;
235 BroadSsid[0] = '\0';
236 ScanParmFill(pAd, &ScanReq, BroadSsid, 0, BSS_ANY, SCAN_PASSIVE);
237 MlmeEnqueue(&pAd->Mlme.Queue, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
238 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
239 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
243 ==========================================================================
244 Description:
245 ==========================================================================
247 VOID CntlOidSsidProc(
248 IN PRTMP_ADAPTER pAd,
249 IN MLME_QUEUE_ELEM * Elem)
251 NDIS_802_11_SSID *OidSsid = (NDIS_802_11_SSID *)Elem->Msg;
252 MLME_DISASSOC_REQ_STRUCT DisassocReq;
253 ULONG Now;
255 // Step 0.
256 // record the desired SSID and all matching BSSes into CntlAux.SsidBssTab for
257 // later-on iteration. Sort by RSSI order
258 NdisMoveMemory(pAd->Mlme.CntlAux.Ssid, OidSsid->Ssid, OidSsid->SsidLength);
259 pAd->Mlme.CntlAux.SsidLen = (UCHAR)OidSsid->SsidLength;
260 BssTableSsidSort(pAd, &pAd->Mlme.CntlAux.SsidBssTab, pAd->Mlme.CntlAux.Ssid, pAd->Mlme.CntlAux.SsidLen);
261 pAd->Mlme.CntlAux.BssIdx = 0;
262 DBGPRINT(RT_DEBUG_TRACE, "CNTL - %d BSS match the desire SSID %s\n",pAd->Mlme.CntlAux.SsidBssTab.BssNr, pAd->Mlme.CntlAux.Ssid);
263 Now = jiffies;
265 if ((pAd->MediaState == NdisMediaStateConnected) &&
266 MAC_ADDR_EQUAL(&pAd->PortCfg.Bssid, &pAd->Mlme.CntlAux.SsidBssTab.BssEntry[0].Bssid))
268 if (((pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
269 (pAd->PortCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
271 // For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
272 // connection process
273 DBGPRINT(RT_DEBUG_TRACE, "CNTL - disassociate with current AP...\n");
274 DisassocParmFill(pAd, &DisassocReq, &pAd->PortCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
275 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
276 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
277 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
279 else if (pAd->bConfigChanged == TRUE)
281 // Config has changed, we have to reconnect the same AP
282 DBGPRINT(RT_DEBUG_TRACE, "CNTL - disassociate with current AP Because config changed...\n");
283 DisassocParmFill(pAd, &DisassocReq, &pAd->PortCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
284 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
285 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
286 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
288 else
290 // We only check if same to the BSSID with highest RSSI.
291 // If roaming of same SSID required, we still do the reconnection.
292 // same BSSID, go back to idle state directly
293 DBGPRINT(RT_DEBUG_TRACE, "CNTL - already with this BSSID. ignore this SET_SSID request\n");
294 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
297 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
300 else if (INFRA_ON(pAd))
302 // case 1. active association existent
303 // roaming is done within miniport driver, nothing to do with configuration
304 // utility. so upon a new SET(OID_802_11_SSID) is received, we just
305 // disassociate with the current (or previous) associated AP, if any,
306 // then perform a new association with this new SSID, no matter the
307 // new/old SSID are the same or npt.
308 DBGPRINT(RT_DEBUG_TRACE, "CNTL - disassociate with current AP...\n");
309 DisassocParmFill(pAd, &DisassocReq, &pAd->PortCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
310 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
311 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
312 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
314 else
316 if (ADHOC_ON(pAd))
318 DBGPRINT(RT_DEBUG_TRACE, "CNTL - drop current ADHOC\n");
319 LinkDown(pAd);
320 pAd->MediaState = NdisMediaStateDisconnected;
321 DBGPRINT(RT_DEBUG_TRACE, "NDIS_STATUS_MEDIA_DISCONNECT Event C!\n");
324 if ((pAd->Mlme.CntlAux.SsidBssTab.BssNr==0) && (pAd->PortCfg.AutoReconnect == TRUE) && (pAd->PortCfg.BssType == BSS_INFRA))
326 MLME_SCAN_REQ_STRUCT ScanReq;
328 DBGPRINT(RT_DEBUG_TRACE, "CNTL2 - No matching BSS, start a new scan\n");
329 // BroadSsid[0] = '\0';
330 ScanParmFill(pAd, &ScanReq, pAd->Mlme.CntlAux.Ssid, pAd->Mlme.CntlAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
331 MlmeEnqueue(&pAd->Mlme.Queue, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
332 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
333 // Reset Missed scan number
334 pAd->PortCfg.IgnoredScanNumber = 0;
335 pAd->PortCfg.LastScanTime = Now;
337 else
339 IterateOnBssTab(pAd);
345 ==========================================================================
346 Description:
347 ==========================================================================
349 VOID CntlOidRTBssidProc(
350 IN PRTMP_ADAPTER pAd,
351 IN MLME_QUEUE_ELEM * Elem)
353 ULONG BssIdx;
354 MACADDR *pOidBssid = (MACADDR *)Elem->Msg;
355 MLME_DISASSOC_REQ_STRUCT DisassocReq;
356 MLME_JOIN_REQ_STRUCT JoinReq;
358 COPY_MAC_ADDR(&pAd->Mlme.CntlAux.Bssid, pOidBssid);
359 BssIdx = BssTableSearch(&pAd->PortCfg.BssTab, pOidBssid);
361 if (BssIdx == BSS_NOT_FOUND)
363 DBGPRINT(RT_DEBUG_TRACE, "CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n");
364 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
368 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
369 return;
372 // copy the matched BSS entry from PortCfg.BssTab to CntlAux.SsidBssTab
373 pAd->Mlme.CntlAux.BssIdx = 0;
374 pAd->Mlme.CntlAux.SsidBssTab.BssNr = 1;
375 NdisMoveMemory(&pAd->Mlme.CntlAux.SsidBssTab.BssEntry[0], &pAd->PortCfg.BssTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
377 // Add SSID into Mlme.CntlAux for site surey joining hidden SSID
378 pAd->Mlme.CntlAux.SsidLen = pAd->Mlme.CntlAux.SsidBssTab.BssEntry[0].SsidLen;
379 NdisMoveMemory(pAd->Mlme.CntlAux.Ssid, pAd->Mlme.CntlAux.SsidBssTab.BssEntry[0].Ssid, pAd->Mlme.CntlAux.SsidLen);
381 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
382 // we just follow normal procedure. The reason of user doing this may because he/she changed
383 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
384 // Since user knows he's chnged AP channel, he'll re-connect again. By skipping the following
385 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
386 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
387 // connection when setting the same BSSID.
388 if ( (pAd->MediaState == NdisMediaStateConnected) && //(INFRA_ON(pAd) || ADHOC_ON(pAd)) &&
389 MAC_ADDR_EQUAL(&pAd->PortCfg.Bssid, pOidBssid))
391 // same BSSID, go back to idle state directly
392 DBGPRINT(RT_DEBUG_TRACE, "CNTL - already in this BSSID. ignore this SET_BSSID request\n");
393 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
396 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
398 else
400 if (INFRA_ON(pAd))
402 // disassoc from current AP first
403 DBGPRINT(RT_DEBUG_TRACE, "CNTL - disassociate with current AP ...\n");
404 DisassocParmFill(pAd, &DisassocReq, &pAd->PortCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
405 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
406 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
408 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
410 else
412 if (ADHOC_ON(pAd))
414 DBGPRINT(RT_DEBUG_TRACE, "CNTL - drop current ADHOC\n");
415 LinkDown(pAd);
416 pAd->MediaState = NdisMediaStateDisconnected;
417 DBGPRINT(RT_DEBUG_TRACE, "NDIS_STATUS_MEDIA_DISCONNECT Event C!\n");
420 // No active association, join the BSS immediately
421 DBGPRINT(RT_DEBUG_TRACE, "CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
422 pOidBssid->Octet[0],pOidBssid->Octet[1],pOidBssid->Octet[2],
423 pOidBssid->Octet[3],pOidBssid->Octet[4],pOidBssid->Octet[5]);
424 JoinParmFill(pAd, &JoinReq, pAd->Mlme.CntlAux.BssIdx);
425 MlmeEnqueue(&pAd->Mlme.Queue, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
427 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
432 // Roaming is the only external request triggering CNTL state machine
433 // despite of other "SET OID" operation. All "SET OID" related oerations
434 // happen in sequence, because no other SET OID will be sent to this device
435 // until the the previous SET operation is complete (successful o failed).
436 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
437 // or been corrupted by other "SET OID"?
438 VOID CntlMlmeRoamingProc(
439 IN PRTMP_ADAPTER pAd,
440 IN MLME_QUEUE_ELEM *Elem)
442 // TODO:
443 // AP in different channel may show lower RSSI than actual value??
444 // should we add a weighting factor to compensate it?
445 DBGPRINT(RT_DEBUG_TRACE,"CNTL - Roaming in CntlAux.RoamTab...\n");
446 BssTableSortByRssi(&pAd->Mlme.CntlAux.RoamTab);
447 pAd->Mlme.CntlAux.RoamIdx=0;
448 IterateOnBssTab2(pAd);
453 ==========================================================================
454 Description:
455 ==========================================================================
457 VOID CntlWaitDisassocProc(
458 IN PRTMP_ADAPTER pAd,
459 IN MLME_QUEUE_ELEM *Elem)
461 MLME_START_REQ_STRUCT StartReq;
463 if (Elem->MsgType == MT2_DISASSOC_CONF)
465 DBGPRINT(RT_DEBUG_TRACE, "CNTL - Dis-associate successful\n");
466 LinkDown(pAd);
468 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
469 if ((pAd->Mlme.CntlAux.SsidBssTab.BssNr==0) && (pAd->PortCfg.BssType == BSS_INDEP))
471 DBGPRINT(RT_DEBUG_TRACE, "CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->Mlme.CntlAux.Ssid);
472 StartParmFill(pAd, &StartReq, pAd->Mlme.CntlAux.Ssid, pAd->Mlme.CntlAux.SsidLen);
473 MlmeEnqueue(&pAd->Mlme.Queue, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
474 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
476 // case 2. try each matched BSS
477 else
479 IterateOnBssTab(pAd);
485 ==========================================================================
486 Description:
487 ==========================================================================
489 VOID CntlWaitJoinProc(
490 IN PRTMP_ADAPTER pAd,
491 IN MLME_QUEUE_ELEM *Elem)
493 USHORT Reason;
494 MLME_AUTH_REQ_STRUCT AuthReq;
496 if (Elem->MsgType == MT2_JOIN_CONF)
498 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
499 if (Reason == MLME_SUCCESS)
501 // 1. joined an IBSS, we are pretty much done here
502 if (pAd->PortCfg.BssType == BSS_INDEP)
504 LinkUp(pAd, BSS_INDEP);
505 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
508 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
510 // 2. joined a new INFRA network, start from authentication
511 else
513 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
514 if ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeShared) ||
515 (pAd->PortCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
517 AuthParmFill(pAd, &AuthReq, &pAd->PortCfg.Bssid, Ndis802_11AuthModeShared);
519 else
521 AuthParmFill(pAd, &AuthReq, &pAd->PortCfg.Bssid, Ndis802_11AuthModeOpen);
523 MlmeEnqueue(&pAd->Mlme.Queue, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
524 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
526 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
529 else
531 // 3. failed, try next BSS
532 pAd->Mlme.CntlAux.BssIdx++;
533 IterateOnBssTab(pAd);
540 ==========================================================================
541 Description:
542 ==========================================================================
544 VOID CntlWaitStartProc(
545 IN PRTMP_ADAPTER pAd,
546 IN MLME_QUEUE_ELEM *Elem)
548 USHORT Result;
550 if (Elem->MsgType == MT2_START_CONF)
552 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
553 if (Result == MLME_SUCCESS)
555 DBGPRINT(RT_DEBUG_TRACE, "CNTL - We have started a new ADHOC network\n");
556 DBGPRINT(RT_DEBUG_TRACE, "CNTL - BSSID %02x:%02x:%02x:%02x:%02x:%02x ...\n",
557 pAd->PortCfg.Bssid.Octet[0],
558 pAd->PortCfg.Bssid.Octet[1],
559 pAd->PortCfg.Bssid.Octet[2],
560 pAd->PortCfg.Bssid.Octet[3],
561 pAd->PortCfg.Bssid.Octet[4],
562 pAd->PortCfg.Bssid.Octet[5]);
563 LinkUp(pAd, BSS_INDEP);
564 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
567 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
569 else
571 DBGPRINT(RT_DEBUG_TRACE, "CNTL - Start FAIL. BUG!!!!!\n");
572 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
575 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
581 ==========================================================================
582 Description:
583 ==========================================================================
585 VOID CntlWaitAuthProc(
586 IN PRTMP_ADAPTER pAd,
587 IN MLME_QUEUE_ELEM *Elem)
589 USHORT Reason;
590 MLME_ASSOC_REQ_STRUCT AssocReq;
591 MLME_AUTH_REQ_STRUCT AuthReq;
593 if (Elem->MsgType == MT2_AUTH_CONF)
595 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
596 if (Reason == MLME_SUCCESS)
598 DBGPRINT(RT_DEBUG_TRACE, "CNTL - AUTH OK\n");
599 AssocParmFill(pAd, &AssocReq, &pAd->PortCfg.Bssid, pAd->PortCfg.CapabilityInfo,
600 ASSOC_TIMEOUT, pAd->PortCfg.DefaultListenCount);
601 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
602 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
604 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
606 else
608 // This fail may because of the AP already keep us in its MAC table without
609 // ageing-out. The previous authentication attempt must have let it remove us.
610 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
611 DBGPRINT(RT_DEBUG_TRACE, "CNTL - AUTH FAIL, try again...\n");
612 if ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeShared) ||
613 (pAd->PortCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
615 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
616 AuthParmFill(pAd, &AuthReq, &pAd->PortCfg.Bssid, Ndis802_11AuthModeShared);
618 else
620 AuthParmFill(pAd, &AuthReq, &pAd->PortCfg.Bssid, Ndis802_11AuthModeOpen);
623 MlmeEnqueue(&pAd->Mlme.Queue, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
624 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
626 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
632 ==========================================================================
633 Description:
634 ==========================================================================
636 VOID CntlWaitAuthProc2(
637 IN PRTMP_ADAPTER pAd,
638 IN MLME_QUEUE_ELEM *Elem)
640 USHORT Reason;
641 MLME_ASSOC_REQ_STRUCT AssocReq;
642 MLME_AUTH_REQ_STRUCT AuthReq;
644 if (Elem->MsgType == MT2_AUTH_CONF)
646 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
647 if (Reason == MLME_SUCCESS)
649 DBGPRINT(RT_DEBUG_TRACE, "CNTL - AUTH OK\n");
650 AssocParmFill(pAd, &AssocReq, &pAd->PortCfg.Bssid, pAd->PortCfg.CapabilityInfo,
651 ASSOC_TIMEOUT, pAd->PortCfg.DefaultListenCount);
652 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
653 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
655 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
657 else
659 if ((pAd->PortCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
660 (pAd->Mlme.AuthAux.Alg == Ndis802_11AuthModeShared))
662 DBGPRINT(RT_DEBUG_TRACE, "CNTL - AUTH FAIL, try OPEN system...\n");
663 AuthParmFill(pAd, &AuthReq, &pAd->PortCfg.Bssid, Ndis802_11AuthModeOpen);
664 MlmeEnqueue(&pAd->Mlme.Queue, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
665 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
667 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
669 else
671 // not success, try next BSS
672 DBGPRINT(RT_DEBUG_TRACE, "CNTL - AUTH FAIL, give up; try next BSS\n");
673 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
674 pAd->Mlme.CntlAux.BssIdx++;
675 IterateOnBssTab(pAd);
682 ==========================================================================
683 Description:
684 ==========================================================================
686 VOID CntlWaitAssocProc(
687 IN PRTMP_ADAPTER pAd,
688 IN MLME_QUEUE_ELEM *Elem)
690 USHORT Reason;
692 if (Elem->MsgType == MT2_ASSOC_CONF)
694 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
695 if (Reason == MLME_SUCCESS)
697 DBGPRINT(RT_DEBUG_TRACE, "CNTL - Association successful on BSS #%d\n",pAd->Mlme.CntlAux.BssIdx);
698 LinkUp(pAd, BSS_INFRA);
699 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
702 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
704 else
706 // not success, try next BSS
707 DBGPRINT(RT_DEBUG_TRACE, "CNTL - Association fails on BSS #%d\n",pAd->Mlme.CntlAux.BssIdx);
708 pAd->Mlme.CntlAux.BssIdx++;
709 IterateOnBssTab(pAd);
715 ==========================================================================
716 Description:
717 ==========================================================================
719 VOID CntlWaitReassocProc(
720 IN PRTMP_ADAPTER pAd,
721 IN MLME_QUEUE_ELEM *Elem)
723 USHORT Result;
725 if (Elem->MsgType == MT2_REASSOC_CONF)
727 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
728 if (Result == MLME_SUCCESS)
730 BSS_ENTRY *pBss = &pAd->Mlme.CntlAux.RoamTab.BssEntry[pAd->Mlme.CntlAux.RoamIdx];
732 // COPY_MAC_ADDR(&pAd->PortCfg.Bssid, &pBss->Bssid);
733 // AsicSetBssid(pAd, &pAd->PortCfg.Bssid);
735 // The following steps are supposed to be done after JOIN in normal procedure
736 // But since this RE-ASSOC skips the JOIN procedure, we have to do it after
737 // RE-ASSOC succeeds. If RE-ASSOC fails, then stay at original AP without any change
738 pAd->PortCfg.BeaconPeriod = pBss->BeaconPeriod;
739 pAd->PortCfg.Channel = pBss->Channel;
740 // The security setting should always follow upper layer definition, not from frame
741 //pAd->PortCfg.PrivacyInvoked = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
742 pAd->PortCfg.SupportedRatesLen = pBss->RatesLen;
743 NdisMoveMemory(pAd->PortCfg.SupportedRates, pBss->Rates, pBss->RatesLen);
745 // Check for 802.11g information, if 802.11 b /g mixed mode.
746 pAd->PortCfg.CapabilityInfo = pBss->CapabilityInfo;
748 pAd->PortCfg.CfpPeriod = pBss->CfpPeriod;
749 pAd->PortCfg.CfpMaxDuration = pBss->CfpMaxDuration;
750 pAd->PortCfg.CfpDurRemain = pBss->CfpDurRemaining;
751 pAd->PortCfg.CfpCount = pBss->CfpCount;
754 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
756 DBGPRINT(RT_DEBUG_TRACE, "CNTL - Re-assocition successful on BSS #%d\n", pAd->Mlme.CntlAux.RoamIdx);
757 LinkUp(pAd, BSS_INFRA);
758 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
760 else
762 // reassoc failed, try to pick next BSS in the BSS Table
763 DBGPRINT(RT_DEBUG_TRACE, "CNTL - Re-assocition fails on BSS #%d\n", pAd->Mlme.CntlAux.RoamIdx);
764 pAd->Mlme.CntlAux.RoamIdx++;
765 IterateOnBssTab2(pAd);
771 ==========================================================================
772 Description:
773 ==========================================================================
775 VOID LinkUp(
776 IN PRTMP_ADAPTER pAd,
777 IN UCHAR BssType)
779 ULONG Now;
781 DBGPRINT(RT_DEBUG_TRACE, "CNTL - !!! LINK UP !!!\n");
782 MlmeUpdateTxRates(pAd, TRUE);
783 NdisMoveMemory(&pAd->Mlme.PrevWlanCounters, &pAd->WlanCounters, sizeof(COUNTER_802_11));
784 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
786 Now = jiffies;
787 pAd->PortCfg.LastBeaconRxTime = Now; // last RX timestamp
789 if ((pAd->PortCfg.WindowsTxPreamble != Rt802_11PreambleLong) &&
790 CAP_IS_SHORT_PREAMBLE_ON(pAd->PortCfg.CapabilityInfo))
792 DBGPRINT(RT_DEBUG_TRACE, "CNTL - !!! Set to short preamble!!!\n");
793 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
796 pAd->PortCfg.BssType = BssType;
797 if (BssType == BSS_INDEP)
799 pAd->PortCfg.Mibss = TRUE;
800 pAd->PortCfg.Massoc = FALSE;
801 MakeIbssBeacon(pAd);
802 AsicEnableIbssSync(pAd);
804 #ifdef SINGLE_ADHOC_LINKUP
805 // Although this did not follow microsoft's recommendation.
806 //Change based on customer's request
807 pAd->MediaState = NdisMediaStateConnected;
808 #endif
810 // Clear Key information when driver change to WPA-None mode
811 // which did not have any key set
812 #if 0
813 if (pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPANone)
815 INT i;
817 for (i = 0; i < PAIRWISE_KEY_NO; i++)
819 pAd->PortCfg.PairwiseKey[i].KeyLen = 0;
822 for (i = 0; i < GROUP_KEY_NO; i++)
824 pAd->PortCfg.GroupKey[i].KeyLen = 0;
827 #endif
829 else // BSS_INFRA
831 pAd->PortCfg.Massoc = TRUE;
832 pAd->PortCfg.Mibss = FALSE;
834 // NOTE:
835 // the decision of using "short slot time" or not may change dynamically due to
836 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
838 // NOTE:
839 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
840 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
842 ComposePsPoll(pAd);
843 ComposeNullFrame(pAd);
844 AsicEnableBssSync(pAd);
846 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
847 // should wait until at least 2 active nodes in this BSSID.
848 pAd->MediaState = NdisMediaStateConnected;
851 DBGPRINT(RT_DEBUG_TRACE, "NDIS_STATUS_MEDIA_CONNECT Event B!\n");
853 if (pAd->PortCfg.LedMode != LED_MODE_SINGLE)
855 ASIC_LED_ACT_ON(pAd);
858 AsicSetSlotTime(pAd, FALSE);
859 pAd->Mlme.PeriodicRound = 0;
860 // Reset config flag
861 pAd->bConfigChanged = FALSE;
865 ==========================================================================
866 Description:
867 ==========================================================================
869 VOID LinkDown(
870 IN PRTMP_ADAPTER pAd)
872 DBGPRINT(RT_DEBUG_TRACE, "CNTL - !!! LINK DOWN !!!\n");
874 if (ADHOC_ON(pAd)) // Adhoc mode link down
876 pAd->PortCfg.Mibss = FALSE;
878 #ifdef SINGLE_ADHOC_LINKUP
879 pAd->MediaState = NdisMediaStateDisconnected;
880 // clean up previous SCAN result, add current BSS back to table if any
881 BssTableDeleteEntry(&pAd->PortCfg.BssTab, &(pAd->PortCfg.Bssid));
882 #else
883 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
885 pAd->MediaState = NdisMediaStateDisconnected;
886 // clean up previous SCAN result, add current BSS back to table if any
887 BssTableDeleteEntry(&pAd->PortCfg.BssTab, &(pAd->PortCfg.Bssid));
889 #endif
891 else// Infra structure mode
893 pAd->PortCfg.Massoc = FALSE;
894 pAd->MediaState = NdisMediaStateDisconnected;
895 DBGPRINT(RT_DEBUG_TRACE, "NDIS_STATUS_MEDIA_DISCONNECT Event A!\n");
896 BssTableDeleteEntry(&pAd->PortCfg.BssTab, &(pAd->PortCfg.Bssid));
898 // restore back to -
899 // 1. long slot (20 us) or short slot (9 us) time
900 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
901 // 3. short preamble
902 if (pAd->PortCfg.BGProtectionInUsed == TRUE)
904 pAd->PortCfg.BGProtectionInUsed = FALSE;
905 DBGPRINT(RT_DEBUG_TRACE, "Link down - turn off B/G protection\n");
910 AsicSetSlotTime(pAd, FALSE);
911 AsicRestoreBbpSensibility(pAd);
913 if (pAd->PortCfg.WindowsTxPreamble == Rt802_11PreambleShort)
914 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
915 else
916 MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
918 if ((pAd->PortCfg.LedMode != LED_MODE_SINGLE) && (pAd->PortCfg.LedMode != LED_MODE_ASUS))
920 ASIC_LED_ACT_OFF(pAd);
922 else if ((pAd->PortCfg.LedMode == LED_MODE_ASUS) && (pAd->PortCfg.bRadio == TRUE))
924 RTMP_IO_WRITE32(pAd, LEDCSR, 0x0002461E);
926 AsicDisableSync(pAd);
927 pAd->Mlme.PeriodicRound = 0;
929 // Remove PortCfg Information after link down
930 NdisZeroMemory(&(pAd->PortCfg.Bssid), MAC_ADDR_LEN);
931 NdisZeroMemory(pAd->PortCfg.Ssid, MAX_LEN_OF_SSID);
932 pAd->PortCfg.SsidLen = 0;
934 // Reset WPA-PSK state. Only reset when supplicant enabled
935 if (pAd->PortCfg.WpaState != SS_NOTUSE)
937 pAd->PortCfg.WpaState = SS_START;
938 // Clear Replay counter
939 NdisZeroMemory(pAd->PortCfg.ReplayCounter, 8);
942 // Remove all WPA keys after link down
943 RTMPWPARemoveAllKeys(pAd);
944 // 802.1x port control
945 pAd->PortCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
946 pAd->PortCfg.MicErrCnt = 0;
950 ==========================================================================
951 Description:
952 ==========================================================================
954 VOID MlmeCntlConfirm(
955 IN PRTMP_ADAPTER pAd,
956 IN ULONG MsgType,
957 IN USHORT Msg)
959 MlmeEnqueue(&pAd->Mlme.Queue, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg);
963 ==========================================================================
964 Description:
965 ==========================================================================
967 VOID IterateOnBssTab(
968 IN PRTMP_ADAPTER pAd)
970 MLME_START_REQ_STRUCT StartReq;
971 MLME_JOIN_REQ_STRUCT JoinReq;
972 ULONG BssIdx;
974 BssIdx = pAd->Mlme.CntlAux.BssIdx;
975 if (BssIdx < pAd->Mlme.CntlAux.SsidBssTab.BssNr)
977 DBGPRINT(RT_DEBUG_TRACE, "CNTL - Trying BSSID %02x:%02x:%02x:%02x:%02x:%02x ...\n",
978 pAd->Mlme.CntlAux.SsidBssTab.BssEntry[BssIdx].Bssid.Octet[0],
979 pAd->Mlme.CntlAux.SsidBssTab.BssEntry[BssIdx].Bssid.Octet[1],
980 pAd->Mlme.CntlAux.SsidBssTab.BssEntry[BssIdx].Bssid.Octet[2],
981 pAd->Mlme.CntlAux.SsidBssTab.BssEntry[BssIdx].Bssid.Octet[3],
982 pAd->Mlme.CntlAux.SsidBssTab.BssEntry[BssIdx].Bssid.Octet[4],
983 pAd->Mlme.CntlAux.SsidBssTab.BssEntry[BssIdx].Bssid.Octet[5]);
984 JoinParmFill(pAd, &JoinReq, BssIdx);
985 MlmeEnqueue(&pAd->Mlme.Queue, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
986 &JoinReq);
987 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
989 else if (pAd->PortCfg.BssType == BSS_INDEP)
991 DBGPRINT(RT_DEBUG_TRACE, "CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->Mlme.CntlAux.Ssid);
992 StartParmFill(pAd, &StartReq, pAd->Mlme.CntlAux.Ssid, (UCHAR)pAd->Mlme.CntlAux.SsidLen);
993 MlmeEnqueue(&pAd->Mlme.Queue, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
994 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
996 else // no more BSS
998 if (pAd->Mlme.CntlAux.CurrReqIsFromNdis)
1000 DBGPRINT(RT_DEBUG_TRACE, "CNTL - All BSS fail; reply NDIS_STATUS_NOT_ACCEPTED\n");
1002 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1006 // for re-association only
1007 VOID IterateOnBssTab2(
1008 IN PRTMP_ADAPTER pAd)
1010 MLME_REASSOC_REQ_STRUCT ReassocReq;
1011 ULONG BssIdx;
1012 BSS_ENTRY *pBss;
1014 BssIdx = pAd->Mlme.CntlAux.RoamIdx;
1015 pBss = &pAd->Mlme.CntlAux.RoamTab.BssEntry[BssIdx];
1017 if (BssIdx < pAd->Mlme.CntlAux.RoamTab.BssNr)
1019 DBGPRINT(RT_DEBUG_TRACE, "CNTL - try BSS #%d %02x:%02x:%02x:%02x:%02x:%02x ...\n",
1020 BssIdx, pBss->Bssid.Octet[0],pBss->Bssid.Octet[1],pBss->Bssid.Octet[2],
1021 pBss->Bssid.Octet[3],pBss->Bssid.Octet[4],pBss->Bssid.Octet[5]);
1023 AsicSwitchChannel(pAd, pBss->Channel);
1024 AsicLockChannel(pAd, pBss->Channel);
1026 // reassociate message has the same structure as associate message
1027 AssocParmFill(pAd, &ReassocReq, &pBss->Bssid, pBss->CapabilityInfo,
1028 ASSOC_TIMEOUT, pAd->PortCfg.DefaultListenCount);
1029 MlmeEnqueue(&pAd->Mlme.Queue, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
1030 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
1032 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
1034 else // no more BSS
1036 DBGPRINT(RT_DEBUG_TRACE, "CNTL - All roaming failed, stay with original AP\n");
1037 AsicSwitchChannel(pAd, pAd->PortCfg.Channel);
1038 AsicLockChannel(pAd, pAd->PortCfg.Channel);
1039 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1044 ==========================================================================
1045 Description:
1046 ==========================================================================
1048 VOID JoinParmFill(
1049 IN PRTMP_ADAPTER pAd,
1050 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
1051 IN ULONG BssIdx)
1053 JoinReq->BssIdx = BssIdx;
1057 ==========================================================================
1058 Description:
1059 ==========================================================================
1061 VOID AssocParmFill(
1062 IN PRTMP_ADAPTER pAd,
1063 IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
1064 IN MACADDR *Addr,
1065 IN USHORT CapabilityInfo,
1066 IN ULONG Timeout,
1067 IN USHORT ListenIntv)
1069 COPY_MAC_ADDR(&AssocReq->Addr, Addr);
1070 // Add mask to support 802.11b mode only
1071 AssocReq->CapabilityInfo = CapabilityInfo & 0xfff3; // not cf-pollable, not cf-poll-request
1072 AssocReq->Timeout = Timeout;
1073 AssocReq->ListenIntv = ListenIntv;
1077 ==========================================================================
1078 Description:
1079 ==========================================================================
1081 VOID ScanParmFill(
1082 IN PRTMP_ADAPTER pAd,
1083 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
1084 IN CHAR Ssid[],
1085 IN UCHAR SsidLen,
1086 IN UCHAR BssType,
1087 IN UCHAR ScanType)
1089 ScanReq->SsidLen = SsidLen;
1090 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
1091 ScanReq->BssType = BssType;
1092 ScanReq->ScanType = ScanType;
1096 ==========================================================================
1097 Description:
1098 ==========================================================================
1100 VOID DisassocParmFill(
1101 IN PRTMP_ADAPTER pAd,
1102 IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
1103 IN MACADDR *Addr,
1104 IN USHORT Reason)
1106 COPY_MAC_ADDR(&DisassocReq->Addr, Addr);
1107 DisassocReq->Reason = Reason;
1111 ==========================================================================
1112 Description:
1113 ==========================================================================
1115 VOID StartParmFill(
1116 IN PRTMP_ADAPTER pAd,
1117 IN OUT MLME_START_REQ_STRUCT *StartReq,
1118 IN CHAR Ssid[],
1119 IN UCHAR SsidLen)
1121 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
1122 StartReq->SsidLen = SsidLen;
1126 ==========================================================================
1127 Description:
1128 ==========================================================================
1130 VOID AuthParmFill(
1131 IN PRTMP_ADAPTER pAd,
1132 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
1133 IN MACADDR *Addr,
1134 IN USHORT Alg)
1136 COPY_MAC_ADDR(&AuthReq->Addr, Addr);
1137 AuthReq->Alg = Alg;
1138 AuthReq->Timeout = AUTH_TIMEOUT;
1142 ==========================================================================
1143 Description:
1144 ==========================================================================
1146 VOID ComposePsPoll(
1147 IN PRTMP_ADAPTER pAd)
1149 NdisZeroMemory(&pAd->Mlme.PsFr, sizeof(PSPOLL_FRAME));
1150 pAd->Mlme.PsFr.Type = BTYPE_CNTL;
1151 pAd->Mlme.PsFr.SubType = SUBTYPE_PS_POLL;
1152 pAd->Mlme.PsFr.Aid = pAd->PortCfg.Aid | 0xC000;
1153 COPY_MAC_ADDR(&(pAd->Mlme.PsFr.Bssid), &pAd->PortCfg.Bssid);
1154 COPY_MAC_ADDR(&(pAd->Mlme.PsFr.Ta), &(pAd->CurrentAddress));
1157 VOID ComposeNullFrame(
1158 IN PRTMP_ADAPTER pAd)
1160 MgtMacHeaderInit(pAd, &pAd->Mlme.NullFr, SUBTYPE_NULL_FUNC, 1, &pAd->PortCfg.Bssid, &pAd->PortCfg.Bssid);
1161 pAd->Mlme.NullFr.Duration = 0;
1162 pAd->Mlme.NullFr.Type = BTYPE_DATA;
1166 ==========================================================================
1167 Description:
1168 Pre-build a BEACON frame in the shared memory
1169 ==========================================================================
1171 ULONG MakeIbssBeacon(
1172 IN PRTMP_ADAPTER pAd)
1174 UCHAR SsidIe = IE_SSID, DsIe = IE_DS_PARM, IbssIe = IE_IBSS_PARM, SuppIe = IE_SUPP_RATES,
1175 DsLen = 1, IbssLen = 2;
1176 UCHAR ExtRateIe = IE_EXT_SUPP_RATES, ExtRatesLen;
1177 UCHAR ErpIe[3] = {IE_ERP, 1, 0x04};
1178 MACHDR BcnHdr;
1179 USHORT CapabilityInfo;
1180 LARGE_INTEGER FakeTimestamp;
1181 ULONG FrameLen;
1182 PTXD_STRUC pTxD = (PTXD_STRUC)pAd->BeaconRing.va_addr;
1183 CHAR *pBeaconFrame = (CHAR *)pAd->BeaconRing.va_data_addr;
1184 UCHAR SupportedRatesLen;
1185 UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
1186 BOOLEAN Privacy;
1188 // 2003-12-10 802.11g WIFI spec disallow OFDM rates in 802.11g ADHOC mode
1189 // make sure 1,2,5.5,11 are the firt 4 rates in PortCfg.SupportedRates[] array
1190 if ((pAd->PortCfg.PhyMode == PHY_11BG_MIXED) && (pAd->PortCfg.AdhocMode == 0))
1192 int i;
1193 SupportedRatesLen=0;
1194 for (i=0;i<pAd->PortCfg.SupportedRatesLen;i++)
1196 switch (pAd->PortCfg.SupportedRates[i] & 0x7f)
1198 case 2:
1199 case 4:
1200 case 11:
1201 case 22:
1202 SupportedRates[SupportedRatesLen] = pAd->PortCfg.SupportedRates[i];
1203 SupportedRatesLen ++;
1204 break;
1205 default:
1206 break;
1209 // error handling - should never happen
1210 if (SupportedRatesLen != 4)
1212 SupportedRatesLen = 4;
1213 SupportedRates[0] = 0x82;
1214 SupportedRates[1] = 0x84;
1215 SupportedRates[2] = 0x8b;
1216 SupportedRates[3] = 0x96;
1219 else
1221 SupportedRatesLen = pAd->PortCfg.SupportedRatesLen;
1222 NdisMoveMemory(SupportedRates, pAd->PortCfg.SupportedRates, SupportedRatesLen);
1225 pAd->PortCfg.AtimWin = 0; // ??????
1227 // compose IBSS beacon frame
1228 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, &pAd->PortCfg.Broadcast, &pAd->PortCfg.Bssid);
1229 Privacy = (pAd->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
1230 (pAd->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
1231 (pAd->PortCfg.WepStatus == Ndis802_11Encryption3Enabled);
1232 CapabilityInfo = CAP_GENERATE(0, 1, 0, 0, Privacy, (pAd->PortCfg.WindowsTxPreamble == Rt802_11PreambleShort));
1233 if (SupportedRatesLen <= 8)
1235 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
1236 MAC_HDR_LEN, &BcnHdr,
1237 TIMESTAMP_LEN, &FakeTimestamp,
1238 2, &pAd->PortCfg.BeaconPeriod,
1239 2, &CapabilityInfo,
1240 1, &SsidIe,
1241 1, &pAd->PortCfg.SsidLen,
1242 pAd->PortCfg.SsidLen, pAd->PortCfg.Ssid,
1243 1, &SuppIe,
1244 1, &SupportedRatesLen,
1245 SupportedRatesLen, SupportedRates,
1246 1, &DsIe,
1247 1, &DsLen,
1248 1, &pAd->PortCfg.Channel,
1249 1, &IbssIe,
1250 1, &IbssLen,
1251 2, &pAd->PortCfg.AtimWin,
1252 END_OF_ARGS);
1254 else
1256 ExtRatesLen = SupportedRatesLen - 8;
1257 SupportedRatesLen = 8;
1258 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
1259 MAC_HDR_LEN, &BcnHdr,
1260 TIMESTAMP_LEN, &FakeTimestamp,
1261 2, &pAd->PortCfg.BeaconPeriod,
1262 2, &CapabilityInfo,
1263 1, &SsidIe,
1264 1, &pAd->PortCfg.SsidLen,
1265 pAd->PortCfg.SsidLen, pAd->PortCfg.Ssid,
1266 1, &SuppIe,
1267 1, &SupportedRatesLen,
1268 SupportedRatesLen, SupportedRates,
1269 1, &DsIe,
1270 1, &DsLen,
1271 1, &pAd->PortCfg.Channel,
1272 1, &IbssIe,
1273 1, &IbssLen,
1274 2, &pAd->PortCfg.AtimWin,
1275 3, ErpIe,
1276 1, &ExtRateIe,
1277 1, &ExtRatesLen,
1278 ExtRatesLen, &SupportedRates[SupportedRatesLen],
1279 END_OF_ARGS);
1281 // If adhoc secruity is set for WPA-None, append the cipher suite IE
1282 if (pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPANone)
1284 ULONG tmp;
1285 UCHAR WpaIe = IE_WPA;
1287 if (pAd->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) // Tkip
1289 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
1290 1, &WpaIe,
1291 1, &CipherSuiteWpaNoneTkipLen,
1292 CipherSuiteWpaNoneTkipLen, &CipherSuiteWpaNoneTkip[0],
1293 END_OF_ARGS);
1294 FrameLen += tmp;
1296 else if (pAd->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) // Aes
1298 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
1299 1, &WpaIe,
1300 1, &CipherSuiteWpaNoneAesLen,
1301 CipherSuiteWpaNoneAesLen, &CipherSuiteWpaNoneAes[0],
1302 END_OF_ARGS);
1303 FrameLen += tmp;
1306 #ifdef BIG_ENDIAN
1307 RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
1308 #endif
1310 RTMPWriteTxDescriptor(pTxD, FALSE, CIPHER_NONE, FALSE, FALSE, TRUE, SHORT_RETRY, IFS_NEW_BACKOFF,
1311 pAd->PortCfg.MlmeRate, 4, FrameLen, pAd->PortCfg.TxPreambleInUsed, 0);
1313 DBGPRINT(RT_DEBUG_TRACE, "MakeIbssBeacon (len=%d)\n", FrameLen);
1314 return FrameLen;