]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/rt3090/sta/dls.c
Staging: rt2860: add RT3090 chipset support
[net-next-2.6.git] / drivers / staging / rt3090 / sta / dls.c
CommitLineData
36c7928c
BZ
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 dls.c
29
30 Abstract:
31 Handle WMM-DLS state machine
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Rory Chen 02-14-2006
37 Arvin Tai 06-03-2008 Modified for RT28xx
38 */
39
40#include "../rt_config.h"
41
42
43/*
44 ==========================================================================
45 Description:
46 dls state machine init, including state transition and timer init
47 Parameters:
48 Sm - pointer to the dls state machine
49 Note:
50 The state machine looks like this
51
52 DLS_IDLE
53 MT2_MLME_DLS_REQUEST MlmeDlsReqAction
54 MT2_PEER_DLS_REQUEST PeerDlsReqAction
55 MT2_PEER_DLS_RESPONSE PeerDlsRspAction
56 MT2_MLME_DLS_TEARDOWN MlmeTearDownAction
57 MT2_PEER_DLS_TEARDOWN PeerTearDownAction
58
59 IRQL = PASSIVE_LEVEL
60
61 ==========================================================================
62 */
63void DlsStateMachineInit(
64 IN PRTMP_ADAPTER pAd,
65 IN STATE_MACHINE *Sm,
66 OUT STATE_MACHINE_FUNC Trans[])
67{
68 UCHAR i;
69
70 StateMachineInit(Sm, (STATE_MACHINE_FUNC*)Trans, MAX_DLS_STATE, MAX_DLS_MSG, (STATE_MACHINE_FUNC)Drop, DLS_IDLE, DLS_MACHINE_BASE);
71
72 // the first column
73 StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_REQ, (STATE_MACHINE_FUNC)MlmeDlsReqAction);
74 StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_REQ, (STATE_MACHINE_FUNC)PeerDlsReqAction);
75 StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_RSP, (STATE_MACHINE_FUNC)PeerDlsRspAction);
76 StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)MlmeDlsTearDownAction);
77 StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)PeerDlsTearDownAction);
78
79 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
80 {
81 pAd->StaCfg.DLSEntry[i].pAd = pAd;
82 RTMPInitTimer(pAd, &pAd->StaCfg.DLSEntry[i].Timer, GET_TIMER_FUNCTION(DlsTimeoutAction), pAd, FALSE);
83 }
84}
85
86/*
87 ==========================================================================
88 Description:
89
90 IRQL = DISPATCH_LEVEL
91
92 ==========================================================================
93 */
94VOID MlmeDlsReqAction(
95 IN PRTMP_ADAPTER pAd,
96 IN MLME_QUEUE_ELEM *Elem)
97{
98 PUCHAR pOutBuffer = NULL;
99 NDIS_STATUS NStatus;
100 ULONG FrameLen = 0;
101 HEADER_802_11 DlsReqHdr;
102 PRT_802_11_DLS pDLS = NULL;
103 UCHAR Category = CATEGORY_DLS;
104 UCHAR Action = ACTION_DLS_REQUEST;
105 ULONG tmp;
106 USHORT reason;
107 ULONG Timeout;
108 BOOLEAN TimerCancelled;
109
110 if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &reason))
111 return;
112
113 DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsReqAction() \n"));
114
115 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
116 if (NStatus != NDIS_STATUS_SUCCESS)
117 {
118 DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsReqAction() allocate memory failed \n"));
119 return;
120 }
121
122 ActHeaderInit(pAd, &DlsReqHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
123
124 // Build basic frame first
125 MakeOutgoingFrame(pOutBuffer, &FrameLen,
126 sizeof(HEADER_802_11), &DlsReqHdr,
127 1, &Category,
128 1, &Action,
129 6, &pDLS->MacAddr,
130 6, pAd->CurrentAddress,
131 2, &pAd->StaActive.CapabilityInfo,
132 2, &pDLS->TimeOut,
133 1, &SupRateIe,
134 1, &pAd->MlmeAux.SupRateLen,
135 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
136 END_OF_ARGS);
137
138 if (pAd->MlmeAux.ExtRateLen != 0)
139 {
140 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
141 1, &ExtRateIe,
142 1, &pAd->MlmeAux.ExtRateLen,
143 pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
144 END_OF_ARGS);
145 FrameLen += tmp;
146 }
147
148#ifdef DOT11_N_SUPPORT
149 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
150 {
151 UCHAR HtLen;
152
153#ifdef RT_BIG_ENDIAN
154 HT_CAPABILITY_IE HtCapabilityTmp;
155#endif
156
157 // add HT Capability IE
158 HtLen = sizeof(HT_CAPABILITY_IE);
159#ifndef RT_BIG_ENDIAN
160 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
161 1, &HtCapIe,
162 1, &HtLen,
163 HtLen, &pAd->CommonCfg.HtCapability,
164 END_OF_ARGS);
165#else
166 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
167 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
168 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
169
170 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
171 1, &HtCapIe,
172 1, &HtLen,
173 HtLen, &HtCapabilityTmp,
174 END_OF_ARGS);
175#endif
176 FrameLen = FrameLen + tmp;
177 }
178#endif // DOT11_N_SUPPORT //
179
180 RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
181 Timeout = DLS_TIMEOUT;
182 RTMPSetTimer(&pDLS->Timer, Timeout);
183
184 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
185 MlmeFreeMemory(pAd, pOutBuffer);
186}
187
188/*
189 ==========================================================================
190 Description:
191
192 IRQL = DISPATCH_LEVEL
193
194 ==========================================================================
195 */
196VOID PeerDlsReqAction(
197 IN PRTMP_ADAPTER pAd,
198 IN MLME_QUEUE_ELEM *Elem)
199{
200 PUCHAR pOutBuffer = NULL;
201 NDIS_STATUS NStatus;
202 ULONG FrameLen = 0;
203 USHORT StatusCode = MLME_SUCCESS;
204 HEADER_802_11 DlsRspHdr;
205 UCHAR Category = CATEGORY_DLS;
206 UCHAR Action = ACTION_DLS_RESPONSE;
207 ULONG tmp;
208 USHORT CapabilityInfo;
209 UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
210 USHORT DLSTimeOut;
211 SHORT i;
212 ULONG Timeout;
213 BOOLEAN TimerCancelled;
214 PRT_802_11_DLS pDLS = NULL;
215 UCHAR MaxSupportedRateIn500Kbps = 0;
216 UCHAR SupportedRatesLen;
217 UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
218 UCHAR HtCapabilityLen;
219 HT_CAPABILITY_IE HtCapability;
220
221 if (!PeerDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &DLSTimeOut,
222 &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
223 return;
224
225 // supported rates array may not be sorted. sort it and find the maximum rate
226 for (i = 0; i < SupportedRatesLen; i++)
227 {
228 if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
229 MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
230 }
231
232 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() from %02x:%02x:%02x:%02x:%02x:%02x\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
233
234 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
235 if (NStatus != NDIS_STATUS_SUCCESS)
236 {
237 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsReqAction() allocate memory failed \n"));
238 return;
239 }
240
241 if (!INFRA_ON(pAd))
242 {
243 StatusCode = MLME_REQUEST_DECLINED;
244 }
245 else if (!pAd->CommonCfg.bWmmCapable)
246 {
247 StatusCode = MLME_DEST_STA_IS_NOT_A_QSTA;
248 }
249 else if (!pAd->CommonCfg.bDLSCapable)
250 {
251 StatusCode = MLME_REQUEST_DECLINED;
252 }
253 else
254 {
255 // find table to update parameters
256 for (i = (MAX_NUM_OF_DLS_ENTRY-1); i >= 0; i--)
257 {
258 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
259 {
260 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
261 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
262 else
263 {
264 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
265 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
266 }
267
268 pAd->StaCfg.DLSEntry[i].Sequence = 0;
269 pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut;
270 pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut;
271 if (HtCapabilityLen != 0)
272 pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
273 else
274 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
275 pDLS = &pAd->StaCfg.DLSEntry[i];
276 break;
277 }
278 }
279
280 // can not find in table, create a new one
281 if (i < 0)
282 {
283 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() can not find same entry \n"));
284 for (i=(MAX_NUM_OF_DLS_ENTRY - 1); i >= MAX_NUM_OF_INIT_DLS_ENTRY; i--)
285 {
286 if (!pAd->StaCfg.DLSEntry[i].Valid)
287 {
288 MAC_TABLE_ENTRY *pEntry;
289 UCHAR MaxSupportedRate = RATE_11;
290
291 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
292 {
293 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
294 }
295 else
296 {
297 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
298 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
299 }
300
301 pAd->StaCfg.DLSEntry[i].Sequence = 0;
302 pAd->StaCfg.DLSEntry[i].Valid = TRUE;
303 pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut;
304 pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut;
305 NdisMoveMemory(pAd->StaCfg.DLSEntry[i].MacAddr, SA, MAC_ADDR_LEN);
306 if (HtCapabilityLen != 0)
307 pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
308 else
309 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
310 pDLS = &pAd->StaCfg.DLSEntry[i];
311 pEntry = MacTableInsertDlsEntry(pAd, SA, i);
312
313 switch (MaxSupportedRateIn500Kbps)
314 {
315 case 108: MaxSupportedRate = RATE_54; break;
316 case 96: MaxSupportedRate = RATE_48; break;
317 case 72: MaxSupportedRate = RATE_36; break;
318 case 48: MaxSupportedRate = RATE_24; break;
319 case 36: MaxSupportedRate = RATE_18; break;
320 case 24: MaxSupportedRate = RATE_12; break;
321 case 18: MaxSupportedRate = RATE_9; break;
322 case 12: MaxSupportedRate = RATE_6; break;
323 case 22: MaxSupportedRate = RATE_11; break;
324 case 11: MaxSupportedRate = RATE_5_5; break;
325 case 4: MaxSupportedRate = RATE_2; break;
326 case 2: MaxSupportedRate = RATE_1; break;
327 default: MaxSupportedRate = RATE_11; break;
328 }
329
330 pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
331
332 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
333 {
334 pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
335 pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
336 pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
337 pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
338 pEntry->HTPhyMode.field.MODE = MODE_CCK;
339 pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
340 }
341 else
342 {
343 pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
344 pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
345 pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
346 pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
347 pEntry->HTPhyMode.field.MODE = MODE_OFDM;
348 pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
349 }
350
351 pEntry->MaxHTPhyMode.field.BW = BW_20;
352 pEntry->MinHTPhyMode.field.BW = BW_20;
353
354#ifdef DOT11_N_SUPPORT
355 pEntry->HTCapability.MCSSet[0] = 0;
356 pEntry->HTCapability.MCSSet[1] = 0;
357
358 // If this Entry supports 802.11n, upgrade to HT rate.
359 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
360 {
361 UCHAR j, bitmask; //k,bitmask;
362 CHAR ii;
363
364 DBGPRINT(RT_DEBUG_TRACE, ("DLS - PeerDlsReqAction() Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
365 SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
366
367 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
368 {
369 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
370 }
371 else
372 {
373 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
374 pAd->MacTab.fAnyStationNonGF = TRUE;
375 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
376 }
377
378 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
379 {
380 pEntry->MaxHTPhyMode.field.BW= BW_40;
381 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
382 }
383 else
384 {
385 pEntry->MaxHTPhyMode.field.BW = BW_20;
386 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
387 pAd->MacTab.fAnyStation20Only = TRUE;
388 }
389
390 // find max fixed rate
391 for (ii=15; ii>=0; ii--)
392 {
393 j = ii/8;
394 bitmask = (1<<(ii-(j*8)));
395 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
396 {
397 pEntry->MaxHTPhyMode.field.MCS = ii;
398 break;
399 }
400 if (ii==0)
401 break;
402 }
403
404
405 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
406 {
407
408 DBGPRINT(RT_DEBUG_OFF, ("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
409 pAd->StaCfg.DesiredTransmitSetting.field.MCS));
410 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
411 {
412 // Fix MCS as HT Duplicated Mode
413 pEntry->MaxHTPhyMode.field.BW = 1;
414 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
415 pEntry->MaxHTPhyMode.field.STBC = 0;
416 pEntry->MaxHTPhyMode.field.ShortGI = 0;
417 pEntry->MaxHTPhyMode.field.MCS = 32;
418 }
419 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
420 {
421 // STA supports fixed MCS
422 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
423 }
424 }
425
426 pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
427 pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
428 pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
429 pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
430 pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
431 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
432
433 if (HtCapability.HtCapInfo.ShortGIfor20)
434 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
435 if (HtCapability.HtCapInfo.ShortGIfor40)
436 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
437 if (HtCapability.HtCapInfo.TxSTBC)
438 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
439 if (HtCapability.HtCapInfo.RxSTBC)
440 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
441 if (HtCapability.ExtHtCapInfo.PlusHTC)
442 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
443 if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
444 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
445 if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
446 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
447
448 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
449 }
450#endif // DOT11_N_SUPPORT //
451
452 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
453 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
454 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
455
456 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
457 {
458 PUCHAR pTable;
459 UCHAR TableSize = 0;
460
461 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
462 pEntry->bAutoTxRateSwitch = TRUE;
463 }
464 else
465 {
466 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
467 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
468 pEntry->bAutoTxRateSwitch = FALSE;
469
470 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
471 }
472 pEntry->RateLen = SupportedRatesLen;
473
474 break;
475 }
476 }
477 }
478 StatusCode = MLME_SUCCESS;
479
480 // can not find in table, create a new one
481 if (i < 0)
482 {
483 StatusCode = MLME_QOS_UNSPECIFY;
484 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsReqAction() DLSEntry table full(only can support %d DLS session) \n", MAX_NUM_OF_DLS_ENTRY - MAX_NUM_OF_INIT_DLS_ENTRY));
485 }
486 else
487 {
488 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() use entry(%d) %02x:%02x:%02x:%02x:%02x:%02x\n",
489 i, SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
490 }
491 }
492
493 ActHeaderInit(pAd, &DlsRspHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
494
495 // Build basic frame first
496 if (StatusCode == MLME_SUCCESS)
497 {
498 MakeOutgoingFrame(pOutBuffer, &FrameLen,
499 sizeof(HEADER_802_11), &DlsRspHdr,
500 1, &Category,
501 1, &Action,
502 2, &StatusCode,
503 6, SA,
504 6, pAd->CurrentAddress,
505 2, &pAd->StaActive.CapabilityInfo,
506 1, &SupRateIe,
507 1, &pAd->MlmeAux.SupRateLen,
508 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
509 END_OF_ARGS);
510
511 if (pAd->MlmeAux.ExtRateLen != 0)
512 {
513 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
514 1, &ExtRateIe,
515 1, &pAd->MlmeAux.ExtRateLen,
516 pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
517 END_OF_ARGS);
518 FrameLen += tmp;
519 }
520
521#ifdef DOT11_N_SUPPORT
522 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
523 {
524 UCHAR HtLen;
525
526#ifdef RT_BIG_ENDIAN
527 HT_CAPABILITY_IE HtCapabilityTmp;
528#endif
529
530 // add HT Capability IE
531 HtLen = sizeof(HT_CAPABILITY_IE);
532#ifndef RT_BIG_ENDIAN
533 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
534 1, &HtCapIe,
535 1, &HtLen,
536 HtLen, &pAd->CommonCfg.HtCapability,
537 END_OF_ARGS);
538#else
539 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
540 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
541 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
542
543 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
544 1, &HtCapIe,
545 1, &HtLen,
546 HtLen, &HtCapabilityTmp,
547 END_OF_ARGS);
548#endif
549 FrameLen = FrameLen + tmp;
550 }
551#endif // DOT11_N_SUPPORT //
552
553 if (pDLS && (pDLS->Status != DLS_FINISH))
554 {
555 RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
556 Timeout = DLS_TIMEOUT;
557 RTMPSetTimer(&pDLS->Timer, Timeout);
558 }
559 }
560 else
561 {
562 MakeOutgoingFrame(pOutBuffer, &FrameLen,
563 sizeof(HEADER_802_11), &DlsRspHdr,
564 1, &Category,
565 1, &Action,
566 2, &StatusCode,
567 6, SA,
568 6, pAd->CurrentAddress,
569 END_OF_ARGS);
570 }
571
572 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
573 MlmeFreeMemory(pAd, pOutBuffer);
574}
575
576/*
577 ==========================================================================
578 Description:
579
580 IRQL = DISPATCH_LEVEL
581
582 ==========================================================================
583 */
584VOID PeerDlsRspAction(
585 IN PRTMP_ADAPTER pAd,
586 IN MLME_QUEUE_ELEM *Elem)
587{
588 USHORT CapabilityInfo;
589 UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
590 USHORT StatusCode;
591 SHORT i;
592 BOOLEAN TimerCancelled;
593 UCHAR MaxSupportedRateIn500Kbps = 0;
594 UCHAR SupportedRatesLen;
595 UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
596 UCHAR HtCapabilityLen;
597 HT_CAPABILITY_IE HtCapability;
598
599 if (!pAd->CommonCfg.bDLSCapable)
600 return;
601
602 if (!INFRA_ON(pAd))
603 return;
604
605 if (!PeerDlsRspSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &StatusCode,
606 &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
607 return;
608
609 // supported rates array may not be sorted. sort it and find the maximum rate
610 for (i=0; i<SupportedRatesLen; i++)
611 {
612 if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
613 MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
614 }
615
616 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x with StatusCode=%d, CapabilityInfo=0x%x\n",
617 SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], StatusCode, CapabilityInfo));
618
619 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
620 {
621 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
622 {
623 if (StatusCode == MLME_SUCCESS)
624 {
625 MAC_TABLE_ENTRY *pEntry;
626 UCHAR MaxSupportedRate = RATE_11;
627
628 pEntry = MacTableInsertDlsEntry(pAd, SA, i);
629
630 switch (MaxSupportedRateIn500Kbps)
631 {
632 case 108: MaxSupportedRate = RATE_54; break;
633 case 96: MaxSupportedRate = RATE_48; break;
634 case 72: MaxSupportedRate = RATE_36; break;
635 case 48: MaxSupportedRate = RATE_24; break;
636 case 36: MaxSupportedRate = RATE_18; break;
637 case 24: MaxSupportedRate = RATE_12; break;
638 case 18: MaxSupportedRate = RATE_9; break;
639 case 12: MaxSupportedRate = RATE_6; break;
640 case 22: MaxSupportedRate = RATE_11; break;
641 case 11: MaxSupportedRate = RATE_5_5; break;
642 case 4: MaxSupportedRate = RATE_2; break;
643 case 2: MaxSupportedRate = RATE_1; break;
644 default: MaxSupportedRate = RATE_11; break;
645 }
646
647 pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
648
649 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
650 {
651 pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
652 pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
653 pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
654 pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
655 pEntry->HTPhyMode.field.MODE = MODE_CCK;
656 pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
657 }
658 else
659 {
660 pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
661 pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
662 pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
663 pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
664 pEntry->HTPhyMode.field.MODE = MODE_OFDM;
665 pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
666 }
667
668 pEntry->MaxHTPhyMode.field.BW = BW_20;
669 pEntry->MinHTPhyMode.field.BW = BW_20;
670
671#ifdef DOT11_N_SUPPORT
672 pEntry->HTCapability.MCSSet[0] = 0;
673 pEntry->HTCapability.MCSSet[1] = 0;
674
675 // If this Entry supports 802.11n, upgrade to HT rate.
676 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
677 {
678 UCHAR j, bitmask; //k,bitmask;
679 CHAR ii;
680
681 DBGPRINT(RT_DEBUG_OFF, ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
682 SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
683
684 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
685 {
686 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
687 }
688 else
689 {
690 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
691 pAd->MacTab.fAnyStationNonGF = TRUE;
692 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
693 }
694
695 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
696 {
697 pEntry->MaxHTPhyMode.field.BW= BW_40;
698 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
699 }
700 else
701 {
702 pEntry->MaxHTPhyMode.field.BW = BW_20;
703 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
704 pAd->MacTab.fAnyStation20Only = TRUE;
705 }
706
707 // find max fixed rate
708 for (ii=15; ii>=0; ii--)
709 {
710 j = ii/8;
711 bitmask = (1<<(ii-(j*8)));
712 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
713 {
714 pEntry->MaxHTPhyMode.field.MCS = ii;
715 break;
716 }
717 if (ii==0)
718 break;
719 }
720
721 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
722 {
723 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
724 {
725 // Fix MCS as HT Duplicated Mode
726 pEntry->MaxHTPhyMode.field.BW = 1;
727 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
728 pEntry->MaxHTPhyMode.field.STBC = 0;
729 pEntry->MaxHTPhyMode.field.ShortGI = 0;
730 pEntry->MaxHTPhyMode.field.MCS = 32;
731 }
732 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
733 {
734 // STA supports fixed MCS
735 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
736 }
737 }
738
739 pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
740 pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
741 pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
742 pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
743 pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
744 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
745
746 if (HtCapability.HtCapInfo.ShortGIfor20)
747 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
748 if (HtCapability.HtCapInfo.ShortGIfor40)
749 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
750 if (HtCapability.HtCapInfo.TxSTBC)
751 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
752 if (HtCapability.HtCapInfo.RxSTBC)
753 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
754 if (HtCapability.ExtHtCapInfo.PlusHTC)
755 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
756 if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
757 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
758 if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
759 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
760
761 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
762 }
763#endif // DOT11_N_SUPPORT //
764 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
765 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
766 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
767
768 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
769 {
770 PUCHAR pTable;
771 UCHAR TableSize = 0;
772
773 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
774 pEntry->bAutoTxRateSwitch = TRUE;
775 }
776 else
777 {
778 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
779 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
780 pEntry->bAutoTxRateSwitch = FALSE;
781
782 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
783 }
784 pEntry->RateLen = SupportedRatesLen;
785
786 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
787 {
788 // If support WPA or WPA2, start STAKey hand shake,
789 // If failed hand shake, just tear down peer DLS
790 if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
791 {
792 MLME_DLS_REQ_STRUCT MlmeDlsReq;
793 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
794
795 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
796 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
797 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
798 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
799 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
800 }
801 else
802 {
803 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
804 DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
805 }
806 }
807 else
808 {
809 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
810 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
811 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x Succeed with WEP or no security\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
812 }
813
814 //initialize seq no for DLS frames.
815 pAd->StaCfg.DLSEntry[i].Sequence = 0;
816 if (HtCapabilityLen != 0)
817 pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
818 else
819 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
820 }
821 else
822 {
823 // DLS setup procedure failed.
824 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
825 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
826 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
827 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
828 }
829 }
830 }
831
832 if (i >= MAX_NUM_OF_INIT_DLS_ENTRY)
833 {
834 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() update timeout value \n"));
835 for (i=(MAX_NUM_OF_DLS_ENTRY-1); i>=MAX_NUM_OF_INIT_DLS_ENTRY; i--)
836 {
837 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
838 {
839 if (StatusCode == MLME_SUCCESS)
840 {
841 MAC_TABLE_ENTRY *pEntry;
842 UCHAR MaxSupportedRate = RATE_11;
843
844 pEntry = MacTableInsertDlsEntry(pAd, SA, i);
845
846 switch (MaxSupportedRateIn500Kbps)
847 {
848 case 108: MaxSupportedRate = RATE_54; break;
849 case 96: MaxSupportedRate = RATE_48; break;
850 case 72: MaxSupportedRate = RATE_36; break;
851 case 48: MaxSupportedRate = RATE_24; break;
852 case 36: MaxSupportedRate = RATE_18; break;
853 case 24: MaxSupportedRate = RATE_12; break;
854 case 18: MaxSupportedRate = RATE_9; break;
855 case 12: MaxSupportedRate = RATE_6; break;
856 case 22: MaxSupportedRate = RATE_11; break;
857 case 11: MaxSupportedRate = RATE_5_5; break;
858 case 4: MaxSupportedRate = RATE_2; break;
859 case 2: MaxSupportedRate = RATE_1; break;
860 default: MaxSupportedRate = RATE_11; break;
861 }
862
863 pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
864
865 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
866 {
867 pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
868 pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
869 pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
870 pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
871 pEntry->HTPhyMode.field.MODE = MODE_CCK;
872 pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
873 }
874 else
875 {
876 pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
877 pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
878 pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
879 pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
880 pEntry->HTPhyMode.field.MODE = MODE_OFDM;
881 pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
882 }
883
884 pEntry->MaxHTPhyMode.field.BW = BW_20;
885 pEntry->MinHTPhyMode.field.BW = BW_20;
886
887#ifdef DOT11_N_SUPPORT
888 pEntry->HTCapability.MCSSet[0] = 0;
889 pEntry->HTCapability.MCSSet[1] = 0;
890
891 // If this Entry supports 802.11n, upgrade to HT rate.
892 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
893 {
894 UCHAR j, bitmask; //k,bitmask;
895 CHAR ii;
896
897 DBGPRINT(RT_DEBUG_TRACE, ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
898 SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
899
900 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
901 {
902 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
903 }
904 else
905 {
906 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
907 pAd->MacTab.fAnyStationNonGF = TRUE;
908 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
909 }
910
911 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
912 {
913 pEntry->MaxHTPhyMode.field.BW= BW_40;
914 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
915 }
916 else
917 {
918 pEntry->MaxHTPhyMode.field.BW = BW_20;
919 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
920 pAd->MacTab.fAnyStation20Only = TRUE;
921 }
922
923 // find max fixed rate
924 for (ii=15; ii>=0; ii--)
925 {
926 j = ii/8;
927 bitmask = (1<<(ii-(j*8)));
928 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
929 {
930 pEntry->MaxHTPhyMode.field.MCS = ii;
931 break;
932 }
933 if (ii==0)
934 break;
935 }
936
937 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
938 {
939 DBGPRINT(RT_DEBUG_OFF, ("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
940 pAd->StaCfg.DesiredTransmitSetting.field.MCS));
941 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
942 {
943 // Fix MCS as HT Duplicated Mode
944 pEntry->MaxHTPhyMode.field.BW = 1;
945 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
946 pEntry->MaxHTPhyMode.field.STBC = 0;
947 pEntry->MaxHTPhyMode.field.ShortGI = 0;
948 pEntry->MaxHTPhyMode.field.MCS = 32;
949 }
950 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
951 {
952 // STA supports fixed MCS
953 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
954 }
955 }
956
957 pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
958 pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
959 pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
960 pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
961 pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
962 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
963
964 if (HtCapability.HtCapInfo.ShortGIfor20)
965 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
966 if (HtCapability.HtCapInfo.ShortGIfor40)
967 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
968 if (HtCapability.HtCapInfo.TxSTBC)
969 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
970 if (HtCapability.HtCapInfo.RxSTBC)
971 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
972 if (HtCapability.ExtHtCapInfo.PlusHTC)
973 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
974 if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
975 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
976 if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
977 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
978
979 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
980 }
981#endif // DOT11_N_SUPPORT //
982
983 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
984 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
985 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
986
987 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
988 {
989 PUCHAR pTable;
990 UCHAR TableSize = 0;
991
992 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
993 pEntry->bAutoTxRateSwitch = TRUE;
994 }
995 else
996 {
997 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
998 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
999 pEntry->bAutoTxRateSwitch = FALSE;
1000
1001 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1002 }
1003 pEntry->RateLen = SupportedRatesLen;
1004
1005 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
1006 {
1007 // If support WPA or WPA2, start STAKey hand shake,
1008 // If failed hand shake, just tear down peer DLS
1009 if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
1010 {
1011 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1012 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
1013
1014 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1015 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1016 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1017 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1018 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
1019 }
1020 else
1021 {
1022 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
1023 DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
1024 }
1025 }
1026 else
1027 {
1028 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1029 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1030 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x Succeed with WEP or no security\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
1031 }
1032 pAd->StaCfg.DLSEntry[i].Sequence = 0;
1033 if (HtCapabilityLen != 0)
1034 pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
1035 else
1036 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
1037 }
1038 else
1039 {
1040 // DLS setup procedure failed.
1041 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1042 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1043 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1044 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
1045 }
1046 }
1047 }
1048 }
1049}
1050
1051/*
1052 ==========================================================================
1053 Description:
1054
1055 IRQL = DISPATCH_LEVEL
1056
1057 ==========================================================================
1058 */
1059VOID MlmeDlsTearDownAction(
1060 IN PRTMP_ADAPTER pAd,
1061 IN MLME_QUEUE_ELEM *Elem)
1062{
1063 PUCHAR pOutBuffer = NULL;
1064 NDIS_STATUS NStatus;
1065 ULONG FrameLen = 0;
1066 UCHAR Category = CATEGORY_DLS;
1067 UCHAR Action = ACTION_DLS_TEARDOWN;
1068 USHORT ReasonCode = REASON_QOS_UNSPECIFY;
1069 HEADER_802_11 DlsTearDownHdr;
1070 PRT_802_11_DLS pDLS;
1071 BOOLEAN TimerCancelled;
1072 UCHAR i;
1073
1074 if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &ReasonCode))
1075 return;
1076
1077 DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsTearDownAction() with ReasonCode=%d \n", ReasonCode));
1078
1079 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1080 if (NStatus != NDIS_STATUS_SUCCESS)
1081 {
1082 DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsTearDownAction() allocate memory failed \n"));
1083 return;
1084 }
1085
1086 ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1087
1088 // Build basic frame first
1089 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1090 sizeof(HEADER_802_11), &DlsTearDownHdr,
1091 1, &Category,
1092 1, &Action,
1093 6, &pDLS->MacAddr,
1094 6, pAd->CurrentAddress,
1095 2, &ReasonCode,
1096 END_OF_ARGS);
1097
1098 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1099 MlmeFreeMemory(pAd, pOutBuffer);
1100 RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
1101
1102 // Remove key in local dls table entry
1103 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1104 {
1105 if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1106 {
1107 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1108 }
1109 }
1110
1111 // clear peer dls table entry
1112 for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; i++)
1113 {
1114 if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1115 {
1116 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1117 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1118 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1119 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1120 }
1121 }
1122}
1123
1124/*
1125 ==========================================================================
1126 Description:
1127
1128 IRQL = DISPATCH_LEVEL
1129
1130 ==========================================================================
1131 */
1132VOID PeerDlsTearDownAction(
1133 IN PRTMP_ADAPTER pAd,
1134 IN MLME_QUEUE_ELEM *Elem)
1135{
1136 UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
1137 USHORT ReasonCode;
1138 UINT i;
1139 BOOLEAN TimerCancelled;
1140
1141 if (!pAd->CommonCfg.bDLSCapable)
1142 return;
1143
1144 if (!INFRA_ON(pAd))
1145 return;
1146
1147 if (!PeerDlsTearDownSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &ReasonCode))
1148 return;
1149
1150 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsTearDownAction() from %02x:%02x:%02x:%02x:%02x:%02x with ReasonCode=%d\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], ReasonCode));
1151
1152 // clear local dls table entry
1153 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1154 {
1155 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
1156 {
1157 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1158 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1159 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1160 //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1161 //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1162 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1163 }
1164 }
1165
1166 // clear peer dls table entry
1167 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1168 {
1169 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
1170 {
1171 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1172 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1173 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1174 //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1175 //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1176 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1177 }
1178 }
1179}
1180
1181/*
1182 ==========================================================================
1183 Description:
1184
1185 IRQL = DISPATCH_LEVEL
1186
1187 ==========================================================================
1188 */
1189VOID RTMPCheckDLSTimeOut(
1190 IN PRTMP_ADAPTER pAd)
1191{
1192 ULONG i;
1193 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1194 USHORT reason = REASON_QOS_UNSPECIFY;
1195
1196 if (! pAd->CommonCfg.bDLSCapable)
1197 return;
1198
1199 if (! INFRA_ON(pAd))
1200 return;
1201
1202 // If timeout value is equaled to zero, it means always not be timeout.
1203
1204 // update local dls table entry
1205 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1206 {
1207 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1208 && (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
1209 {
1210 pAd->StaCfg.DLSEntry[i].CountDownTimer --;
1211
1212 if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
1213 {
1214 reason = REASON_QOS_REQUEST_TIMEOUT;
1215 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1216 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1217 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1218 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1219 }
1220 }
1221 }
1222
1223 // update peer dls table entry
1224 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1225 {
1226 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1227 && (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
1228 {
1229 pAd->StaCfg.DLSEntry[i].CountDownTimer --;
1230
1231 if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
1232 {
1233 reason = REASON_QOS_REQUEST_TIMEOUT;
1234 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1235 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1236 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1237 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1238 }
1239 }
1240 }
1241}
1242
1243/*
1244 ==========================================================================
1245 Description:
1246
1247 IRQL = DISPATCH_LEVEL
1248
1249 ==========================================================================
1250 */
1251BOOLEAN RTMPRcvFrameDLSCheck(
1252 IN PRTMP_ADAPTER pAd,
1253 IN PHEADER_802_11 pHeader,
1254 IN ULONG Len,
1255 IN PRT28XX_RXD_STRUC pRxD)
1256{
1257 ULONG i;
1258 BOOLEAN bFindEntry = FALSE;
1259 BOOLEAN bSTAKeyFrame = FALSE;
1260 PEAPOL_PACKET pEap;
1261 PUCHAR pProto, pAddr = NULL;
1262 PUCHAR pSTAKey = NULL;
1263 UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
1264 UCHAR Mic[16], OldMic[16];
1265 UCHAR digest[80];
1266 UCHAR DlsPTK[80];
1267 UCHAR temp[64];
1268 BOOLEAN TimerCancelled;
1269 CIPHER_KEY PairwiseKey;
1270
1271
1272 if (! pAd->CommonCfg.bDLSCapable)
1273 return bSTAKeyFrame;
1274
1275 if (! INFRA_ON(pAd))
1276 return bSTAKeyFrame;
1277
1278 if (Len < LENGTH_802_11 + 6 + 2) /* LENGTH_802_11 + LLC + EAPOL protocol type */
1279 return bSTAKeyFrame;
1280
1281 pProto = (PUCHAR)pHeader + LENGTH_802_11;
1282
1283 if ((pHeader->FC.SubType & 0x08))
1284 pProto += 2; /* QOS Control field */
1285
1286 /* Skip 4-bytes for HTC */
1287 if (pHeader->FC.Order && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
1288 {
1289 pProto += 4;
1290 }
1291
1292 /* L2PAD bit on will pad 2 bytes at LLC */
1293 if (pRxD->L2PAD)
1294 {
1295 pProto += 2;
1296 }
1297
1298 pProto += 6; /* 0xAA 0xAA 0xAA 0x00 0x00 0x00 */
1299
1300 if ((!(pHeader->FC.SubType & 0x08)) && (!RTMPEqualMemory(EAPOL, pProto, 2)))
1301 return bSTAKeyFrame;
1302
1303 pAddr = pHeader->Addr2;
1304
1305 if (RTMPEqualMemory(EAPOL, pProto, 2) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1306 {
1307 pEap = (PEAPOL_PACKET) (pProto + 2);
1308
1309 DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff Len=%ld, DataLen=%d, KeyMic=%d, Install=%d, KeyAck=%d, Secure=%d, EKD_DL=%d, Error=%d, Request=%d\n", Len,
1310 (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16),
1311 pEap->KeyDesc.KeyInfo.KeyMic,
1312 pEap->KeyDesc.KeyInfo.Install,
1313 pEap->KeyDesc.KeyInfo.KeyAck,
1314 pEap->KeyDesc.KeyInfo.Secure,
1315 pEap->KeyDesc.KeyInfo.EKD_DL,
1316 pEap->KeyDesc.KeyInfo.Error,
1317 pEap->KeyDesc.KeyInfo.Request));
1318
1319 if ((Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16)) && pEap->KeyDesc.KeyInfo.KeyMic
1320 && pEap->KeyDesc.KeyInfo.Install && pEap->KeyDesc.KeyInfo.KeyAck && pEap->KeyDesc.KeyInfo.Secure
1321 && pEap->KeyDesc.KeyInfo.EKD_DL && !pEap->KeyDesc.KeyInfo.Error && !pEap->KeyDesc.KeyInfo.Request)
1322 {
1323 // First validate replay counter, only accept message with larger replay counter
1324 // Let equal pass, some AP start with all zero replay counter
1325 NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
1326 if ((RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) &&
1327 (RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
1328 return bSTAKeyFrame;
1329
1330 //RTMPMoveMemory(pAd->StaCfg.ReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1331 RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1332 DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter (%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
1333 pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
1334 pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4], pAd->StaCfg.ReplayCounter[5],
1335 pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
1336
1337 // put these code segment to get the replay counter
1338 if (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)
1339 return bSTAKeyFrame;
1340
1341 // Check MIC value
1342 // Save the MIC and replace with zero
1343 // use proprietary PTK
1344 NdisZeroMemory(temp, 64);
1345 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1346 WpaDerivePTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1347
1348 NdisMoveMemory(OldMic, pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1349 NdisZeroMemory(pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1350 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1351 {
1352 // AES
1353 HMAC_SHA1(DlsPTK, LEN_EAP_MICK, (PUCHAR) pEap, pEap->Body_Len[1] + 4, digest, SHA1_DIGEST_SIZE);
1354 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
1355 }
1356 else
1357 {
1358 HMAC_MD5(DlsPTK, LEN_EAP_MICK, (PUCHAR) pEap, pEap->Body_Len[1] + 4, Mic, MD5_DIGEST_SIZE);
1359 }
1360
1361 if (!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
1362 {
1363 DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in Msg1 of STAKey handshake! \n"));
1364 return bSTAKeyFrame;
1365 }
1366 else
1367 DBGPRINT(RT_DEBUG_TRACE, ("MIC VALID in Msg1 of STAKey handshake! \n"));
1368 if ((pEap->KeyDesc.KeyData[0] == 0xDD) && (pEap->KeyDesc.KeyData[2] == 0x00) && (pEap->KeyDesc.KeyData[3] == 0x0C)
1369 && (pEap->KeyDesc.KeyData[4] == 0x43) && (pEap->KeyDesc.KeyData[5] == 0x02))
1370 {
1371 pAddr = pEap->KeyDesc.KeyData + 8; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2)
1372 pSTAKey = pEap->KeyDesc.KeyData + 14; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6)
1373
1374 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%ld, KeyDataLen=%d\n",
1375 pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], Len, pEap->KeyDesc.KeyData[1]));
1376
1377 bSTAKeyFrame = TRUE;
1378 }
1379
1380 }
1381 else if (Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE))
1382 {
1383 RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1384 DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter 2(%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
1385 pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
1386 pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4], pAd->StaCfg.ReplayCounter[5],
1387 pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
1388 }
1389 }
1390
1391 // If timeout value is equaled to zero, it means always not be timeout.
1392 // update local dls table entry
1393 for (i= 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1394 {
1395 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1396 {
1397 if (bSTAKeyFrame)
1398 {
1399 PMAC_TABLE_ENTRY pEntry;
1400
1401 // STAKey frame, add pairwise key table
1402 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1403 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1404
1405 PairwiseKey.KeyLen = LEN_TKIP_EK;
1406 NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
1407 NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
1408 NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
1409
1410 //PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
1411 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1412 PairwiseKey.CipherAlg = CIPHER_TKIP;
1413 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1414 PairwiseKey.CipherAlg = CIPHER_AES;
1415
1416 pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1417 //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
1418 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1419 // Add Pair-wise key to Asic
1420#ifdef RTMP_MAC_PCI
1421 AsicAddPairwiseKeyEntry(pAd,
1422 pAd->StaCfg.DLSEntry[i].MacAddr,
1423 (UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
1424 &PairwiseKey);
1425
1426 RTMPAddWcidAttributeEntry(pAd,
1427 BSS0,
1428 0,
1429 PairwiseKey.CipherAlg,
1430 pEntry);
1431
1432#endif // RTMP_MAC_PCI //
1433 NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
1434 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n"));
1435
1436 RTMPSendSTAKeyHandShake(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
1437
1438 DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Initiator side)\n"));
1439 }
1440 else
1441 {
1442 // Data frame, update timeout value
1443 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1444 {
1445 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1446 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1447 }
1448 }
1449
1450 bFindEntry = TRUE;
1451 }
1452 }
1453
1454 // update peer dls table entry
1455 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1456 {
1457 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1458 {
1459 if (bSTAKeyFrame)
1460 {
1461 PMAC_TABLE_ENTRY pEntry = NULL;
1462
1463 // STAKey frame, add pairwise key table, and send STAkey Msg-2
1464 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1465 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1466
1467 PairwiseKey.KeyLen = LEN_TKIP_EK;
1468 NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
1469 NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
1470 NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
1471
1472 //PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
1473 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1474 PairwiseKey.CipherAlg = CIPHER_TKIP;
1475 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1476 PairwiseKey.CipherAlg = CIPHER_AES;
1477
1478 pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1479 //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
1480 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1481 // Add Pair-wise key to Asic
1482#ifdef RTMP_MAC_PCI
1483 AsicAddPairwiseKeyEntry(pAd,
1484 pAd->StaCfg.DLSEntry[i].MacAddr,
1485 (UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
1486 &PairwiseKey);
1487
1488 RTMPAddWcidAttributeEntry(pAd,
1489 BSS0,
1490 0,
1491 PairwiseKey.CipherAlg,
1492 pEntry);
1493#endif // RTMP_MAC_PCI //
1494 NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
1495 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n"));
1496
1497 // If support WPA or WPA2, start STAKey hand shake,
1498 // If failed hand shake, just tear down peer DLS
1499 if (RTMPSendSTAKeyHandShake(pAd, pAddr) != NDIS_STATUS_SUCCESS)
1500 {
1501 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1502 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
1503
1504 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1505 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1506 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1507 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1508 }
1509 else
1510 {
1511 DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Peer side)\n"));
1512 }
1513 }
1514 else
1515 {
1516 // Data frame, update timeout value
1517 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1518 {
1519 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1520 }
1521 }
1522
1523 bFindEntry = TRUE;
1524 }
1525 }
1526
1527
1528 return bSTAKeyFrame;
1529}
1530
1531/*
1532 ========================================================================
1533
1534 Routine Description:
1535 Check if the frame can be sent through DLS direct link interface
1536
1537 Arguments:
1538 pAd Pointer to adapter
1539
1540 Return Value:
1541 DLS entry index
1542
1543 Note:
1544
1545 ========================================================================
1546*/
1547INT RTMPCheckDLSFrame(
1548 IN PRTMP_ADAPTER pAd,
1549 IN PUCHAR pDA)
1550{
1551 INT rval = -1;
1552 INT i;
1553
1554 if (!pAd->CommonCfg.bDLSCapable)
1555 return rval;
1556
1557 if (!INFRA_ON(pAd))
1558 return rval;
1559
1560 do{
1561 // check local dls table entry
1562 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1563 {
1564 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1565 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1566 {
1567 rval = i;
1568 break;
1569 }
1570 }
1571
1572 // check peer dls table entry
1573 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1574 {
1575 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1576 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1577 {
1578 rval = i;
1579 break;
1580 }
1581 }
1582 } while (FALSE);
1583
1584 return rval;
1585}
1586
1587/*
1588 ==========================================================================
1589 Description:
1590
1591 IRQL = DISPATCH_LEVEL
1592
1593 ==========================================================================
1594 */
1595VOID RTMPSendDLSTearDownFrame(
1596 IN PRTMP_ADAPTER pAd,
1597 IN PUCHAR pDA)
1598{
1599 PUCHAR pOutBuffer = NULL;
1600 NDIS_STATUS NStatus;
1601 HEADER_802_11 DlsTearDownHdr;
1602 ULONG FrameLen = 0;
1603 USHORT Reason = REASON_QOS_QSTA_LEAVING_QBSS;
1604 UCHAR Category = CATEGORY_DLS;
1605 UCHAR Action = ACTION_DLS_TEARDOWN;
1606 UCHAR i = 0;
1607
1608 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
1609 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
1610 return;
1611
1612 DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame \n"));
1613
1614 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1615 if (NStatus != NDIS_STATUS_SUCCESS)
1616 {
1617 DBGPRINT(RT_DEBUG_ERROR,("ASSOC - RTMPSendDLSTearDownFrame() allocate memory failed \n"));
1618 return;
1619 }
1620
1621 ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1622 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1623 sizeof(HEADER_802_11), &DlsTearDownHdr,
1624 1, &Category,
1625 1, &Action,
1626 6, pDA,
1627 6, pAd->CurrentAddress,
1628 2, &Reason,
1629 END_OF_ARGS);
1630
1631 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1632 MlmeFreeMemory(pAd, pOutBuffer);
1633
1634 // Remove key in local dls table entry
1635 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1636 {
1637 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1638 && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1639 {
1640 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1641 }
1642 }
1643
1644 // Remove key in peer dls table entry
1645 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1646 {
1647 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1648 && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1649 {
1650 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1651 }
1652 }
1653
1654 DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame and remove key in (i=%d) \n", i));
1655}
1656
1657/*
1658 ==========================================================================
1659 Description:
1660
1661 IRQL = DISPATCH_LEVEL
1662
1663 ==========================================================================
1664 */
1665NDIS_STATUS RTMPSendSTAKeyRequest(
1666 IN PRTMP_ADAPTER pAd,
1667 IN PUCHAR pDA)
1668{
1669 UCHAR Header802_3[14];
1670 NDIS_STATUS NStatus;
1671 ULONG FrameLen = 0;
1672 EAPOL_PACKET Packet;
1673 UCHAR Mic[16];
1674 UCHAR digest[80];
1675 PUCHAR pOutBuffer = NULL;
1676 PNDIS_PACKET pNdisPacket;
1677 UCHAR temp[64];
1678 UCHAR DlsPTK[80];
1679
1680 DBGPRINT(RT_DEBUG_TRACE,("DLS - RTMPSendSTAKeyRequest() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5]));
1681
1682 pAd->Sequence ++;
1683 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1684
1685 // Zero message body
1686 NdisZeroMemory(&Packet, sizeof(Packet));
1687 Packet.ProVer = EAPOL_VER;
1688 Packet.ProType = EAPOLKey;
1689 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE andPeer MAC address
1690
1691 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1692 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1693 {
1694 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1695 }
1696 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1697 {
1698 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1699 }
1700
1701 // Key descriptor version
1702 Packet.KeyDesc.KeyInfo.KeyDescVer =
1703 (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1704
1705 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1706 Packet.KeyDesc.KeyInfo.Secure = 1;
1707 Packet.KeyDesc.KeyInfo.Request = 1;
1708
1709 Packet.KeyDesc.KeyDataLen[1] = 12;
1710
1711 // use our own OUI to distinguish proprietary with standard.
1712 Packet.KeyDesc.KeyData[0] = 0xDD;
1713 Packet.KeyDesc.KeyData[1] = 0x0A;
1714 Packet.KeyDesc.KeyData[2] = 0x00;
1715 Packet.KeyDesc.KeyData[3] = 0x0C;
1716 Packet.KeyDesc.KeyData[4] = 0x43;
1717 Packet.KeyDesc.KeyData[5] = 0x03;
1718 NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
1719
1720 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1721
1722 // Allocate buffer for transmitting message
1723 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1724 if (NStatus != NDIS_STATUS_SUCCESS)
1725 return NStatus;
1726
1727 // Prepare EAPOL frame for MIC calculation
1728 // Be careful, only EAPOL frame is counted for MIC calculation
1729 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1730 Packet.Body_Len[1] + 4, &Packet,
1731 END_OF_ARGS);
1732
1733 // use proprietary PTK
1734 NdisZeroMemory(temp, 64);
1735 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1736 WpaDerivePTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1737
1738 // calculate MIC
1739 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1740 {
1741 // AES
1742 NdisZeroMemory(digest, sizeof(digest));
1743 HMAC_SHA1(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE);
1744 NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
1745 }
1746 else
1747 {
1748 NdisZeroMemory(Mic, sizeof(Mic));
1749 HMAC_MD5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic, MD5_DIGEST_SIZE);
1750 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1751 }
1752
1753 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1754 sizeof(Header802_3), Header802_3,
1755 Packet.Body_Len[1] + 4, &Packet,
1756 END_OF_ARGS);
1757
1758 NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1759 if (NStatus == NDIS_STATUS_SUCCESS)
1760 {
1761 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1762 STASendPacket(pAd, pNdisPacket);
1763 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1764 }
1765
1766 MlmeFreeMemory(pAd, pOutBuffer);
1767
1768 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyRequest- Send STAKey request (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1769
1770 return NStatus;
1771}
1772
1773/*
1774 ==========================================================================
1775 Description:
1776
1777 IRQL = DISPATCH_LEVEL
1778
1779 ==========================================================================
1780 */
1781NDIS_STATUS RTMPSendSTAKeyHandShake(
1782 IN PRTMP_ADAPTER pAd,
1783 IN PUCHAR pDA)
1784{
1785 UCHAR Header802_3[14];
1786 NDIS_STATUS NStatus;
1787 ULONG FrameLen = 0;
1788 EAPOL_PACKET Packet;
1789 UCHAR Mic[16];
1790 UCHAR digest[80];
1791 PUCHAR pOutBuffer = NULL;
1792 PNDIS_PACKET pNdisPacket;
1793 UCHAR temp[64];
1794 UCHAR DlsPTK[80]; // Due to dirver can not get PTK, use proprietary PTK
1795
1796 DBGPRINT(RT_DEBUG_TRACE,("DLS - RTMPSendSTAKeyHandShake() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5]));
1797
1798 pAd->Sequence ++;
1799 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1800
1801 // Zero message body
1802 NdisZeroMemory(&Packet, sizeof(Packet));
1803 Packet.ProVer = EAPOL_VER;
1804 Packet.ProType = EAPOLKey;
1805 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE and Peer MAC address
1806
1807 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1808 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1809 {
1810 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1811 }
1812 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1813 {
1814 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1815 }
1816
1817 // Key descriptor version
1818 Packet.KeyDesc.KeyInfo.KeyDescVer =
1819 (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1820
1821 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1822 Packet.KeyDesc.KeyInfo.Secure = 1;
1823
1824 Packet.KeyDesc.KeyDataLen[1] = 12;
1825
1826 // use our own OUI to distinguish proprietary with standard.
1827 Packet.KeyDesc.KeyData[0] = 0xDD;
1828 Packet.KeyDesc.KeyData[1] = 0x0A;
1829 Packet.KeyDesc.KeyData[2] = 0x00;
1830 Packet.KeyDesc.KeyData[3] = 0x0C;
1831 Packet.KeyDesc.KeyData[4] = 0x43;
1832 Packet.KeyDesc.KeyData[5] = 0x03;
1833 NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
1834
1835 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1836
1837 // Allocate buffer for transmitting message
1838 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1839 if (NStatus != NDIS_STATUS_SUCCESS)
1840 return NStatus;
1841
1842 // Prepare EAPOL frame for MIC calculation
1843 // Be careful, only EAPOL frame is counted for MIC calculation
1844 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1845 Packet.Body_Len[1] + 4, &Packet,
1846 END_OF_ARGS);
1847
1848 // use proprietary PTK
1849 NdisZeroMemory(temp, 64);
1850 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1851 WpaDerivePTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1852
1853 // calculate MIC
1854 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1855 {
1856 // AES
1857 NdisZeroMemory(digest, sizeof(digest));
1858 HMAC_SHA1(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE);
1859 NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
1860 }
1861 else
1862 {
1863 NdisZeroMemory(Mic, sizeof(Mic));
1864 HMAC_MD5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic, MD5_DIGEST_SIZE);
1865 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1866 }
1867
1868 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1869 sizeof(Header802_3), Header802_3,
1870 Packet.Body_Len[1] + 4, &Packet,
1871 END_OF_ARGS);
1872
1873 NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1874 if (NStatus == NDIS_STATUS_SUCCESS)
1875 {
1876 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1877 STASendPacket(pAd, pNdisPacket);
1878 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1879 }
1880
1881 MlmeFreeMemory(pAd, pOutBuffer);
1882
1883 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyHandShake- Send STAKey Message-2 (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1884
1885 return NStatus;
1886}
1887
1888VOID DlsTimeoutAction(
1889 IN PVOID SystemSpecific1,
1890 IN PVOID FunctionContext,
1891 IN PVOID SystemSpecific2,
1892 IN PVOID SystemSpecific3)
1893{
1894 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1895 USHORT reason;
1896 PRT_802_11_DLS pDLS = (PRT_802_11_DLS)FunctionContext;
1897 PRTMP_ADAPTER pAd = pDLS->pAd;
1898
1899 DBGPRINT(RT_DEBUG_TRACE, ("DlsTimeout - Tear down DLS links (%02x:%02x:%02x:%02x:%02x:%02x)\n",
1900 pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5]));
1901
1902 if ((pDLS) && (pDLS->Valid))
1903 {
1904 reason = REASON_QOS_REQUEST_TIMEOUT;
1905 pDLS->Valid = FALSE;
1906 pDLS->Status = DLS_NONE;
1907 DlsParmFill(pAd, &MlmeDlsReq, pDLS, reason);
1908 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1909 RTMP_MLME_HANDLER(pAd);
1910 }
1911}
1912
1913/*
1914================================================================
1915Description : because DLS and CLI share the same WCID table in ASIC.
1916Mesh entry also insert to pAd->MacTab.content[]. Such is marked as ValidAsDls = TRUE.
1917Also fills the pairwise key.
1918Because front MAX_AID_BA entries have direct mapping to BAEntry, which is only used as CLI. So we insert Dls
1919from index MAX_AID_BA.
1920================================================================
1921*/
1922MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
1923 IN PRTMP_ADAPTER pAd,
1924 IN PUCHAR pAddr,
1925 IN UINT DlsEntryIdx)
1926{
1927 PMAC_TABLE_ENTRY pEntry = NULL;
1928
1929 DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableInsertDlsEntry\n"));
1930 // if FULL, return
1931 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
1932 return NULL;
1933
1934 do
1935 {
1936 if((pEntry = DlsEntryTableLookup(pAd, pAddr, TRUE)) != NULL)
1937 break;
1938
1939 // allocate one MAC entry
1940 pEntry = MacTableInsertEntry(pAd, pAddr, DlsEntryIdx + MIN_NET_DEVICE_FOR_DLS, TRUE);
1941 if (pEntry)
1942 {
1943 pAd->StaCfg.DLSEntry[DlsEntryIdx].MacTabMatchWCID = pEntry->Aid;
1944 pEntry->MatchDlsEntryIdx = DlsEntryIdx;
1945 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1946 pEntry->WepStatus = pAd->StaCfg.WepStatus;
1947 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1948
1949 DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertDlsEntry - allocate entry #%d, Total= %d\n",pEntry->Aid, pAd->MacTab.Size));
1950
1951 // If legacy WEP is used, set pair-wise cipherAlg into WCID attribute table for this entry
1952 if ((pEntry->ValidAsDls) && (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled))
1953 {
1954 UCHAR KeyIdx = 0;
1955 UCHAR CipherAlg = 0;
1956
1957 KeyIdx = pAd->StaCfg.DefaultKeyId;
1958
1959 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1960
1961 RTMPAddWcidAttributeEntry(pAd,
1962 BSS0,
1963 pAd->StaCfg.DefaultKeyId,
1964 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1965 pEntry);
1966 }
1967
1968 break;
1969 }
1970 } while(FALSE);
1971
1972 DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableInsertDlsEntry\n"));
1973
1974 return pEntry;
1975}
1976
1977
1978/*
1979 ==========================================================================
1980 Description:
1981 Delete all Mesh Entry in pAd->MacTab
1982 ==========================================================================
1983 */
1984BOOLEAN MacTableDeleteDlsEntry(
1985 IN PRTMP_ADAPTER pAd,
1986 IN USHORT wcid,
1987 IN PUCHAR pAddr)
1988{
1989 DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableDeleteDlsEntry\n"));
1990
1991 if (!VALID_WCID(wcid))
1992 return FALSE;
1993
1994 MacTableDeleteEntry(pAd, wcid, pAddr);
1995
1996 DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableDeleteDlsEntry\n"));
1997
1998 return TRUE;
1999}
2000
2001MAC_TABLE_ENTRY *DlsEntryTableLookup(
2002 IN PRTMP_ADAPTER pAd,
2003 IN PUCHAR pAddr,
2004 IN BOOLEAN bResetIdelCount)
2005{
2006 ULONG HashIdx;
2007 MAC_TABLE_ENTRY *pEntry = NULL;
2008
2009 RTMP_SEM_LOCK(&pAd->MacTabLock);
2010 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2011 pEntry = pAd->MacTab.Hash[HashIdx];
2012
2013 while (pEntry)
2014 {
2015 if ((pEntry->ValidAsDls == TRUE)
2016 && MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2017 {
2018 if(bResetIdelCount)
2019 pEntry->NoDataIdleCount = 0;
2020 break;
2021 }
2022 else
2023 pEntry = pEntry->pNext;
2024 }
2025
2026 RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2027 return pEntry;
2028}
2029
2030MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
2031 IN PRTMP_ADAPTER pAd,
2032 IN UCHAR wcid,
2033 IN PUCHAR pAddr,
2034 IN BOOLEAN bResetIdelCount)
2035{
2036 ULONG DLsIndex;
2037 PMAC_TABLE_ENTRY pCurEntry = NULL;
2038 PMAC_TABLE_ENTRY pEntry = NULL;
2039
2040 if (!VALID_WCID(wcid))
2041 return NULL;
2042
2043 RTMP_SEM_LOCK(&pAd->MacTabLock);
2044
2045 do
2046 {
2047 pCurEntry = &pAd->MacTab.Content[wcid];
2048
2049 DLsIndex = 0xff;
2050 if ((pCurEntry) && (pCurEntry->ValidAsDls== TRUE))
2051 {
2052 DLsIndex = pCurEntry->MatchDlsEntryIdx;
2053 }
2054
2055 if (DLsIndex == 0xff)
2056 break;
2057
2058 if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr))
2059 {
2060 if(bResetIdelCount)
2061 pCurEntry->NoDataIdleCount = 0;
2062 pEntry = pCurEntry;
2063 break;
2064 }
2065 } while(FALSE);
2066
2067 RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2068
2069 return pEntry;
2070}
2071
2072INT Set_DlsEntryInfo_Display_Proc(
2073 IN PRTMP_ADAPTER pAd,
2074 IN PUCHAR arg)
2075{
2076 INT i;
2077
2078 DBGPRINT(RT_DEBUG_OFF, ("\n%-19s%-8s\n", "MAC", "TIMEOUT\n"));
2079 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
2080 {
2081 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2082 {
2083 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[pAd->StaCfg.DLSEntry[i].MacTabMatchWCID];
2084
2085 DBGPRINT(RT_DEBUG_OFF, ("%02x:%02x:%02x:%02x:%02x:%02x ",
2086 pAd->StaCfg.DLSEntry[i].MacAddr[0], pAd->StaCfg.DLSEntry[i].MacAddr[1], pAd->StaCfg.DLSEntry[i].MacAddr[2],
2087 pAd->StaCfg.DLSEntry[i].MacAddr[3], pAd->StaCfg.DLSEntry[i].MacAddr[4], pAd->StaCfg.DLSEntry[i].MacAddr[5]));
2088 DBGPRINT(RT_DEBUG_OFF, ("%-8d\n", pAd->StaCfg.DLSEntry[i].TimeOut));
2089
2090 DBGPRINT(RT_DEBUG_OFF, ("\n"));
2091 DBGPRINT(RT_DEBUG_OFF, ("\n%-19s%-4s%-4s%-4s%-4s%-7s%-7s%-7s","MAC", "AID", "BSS", "PSM", "WMM", "RSSI0", "RSSI1", "RSSI2"));
2092#ifdef DOT11_N_SUPPORT
2093 DBGPRINT(RT_DEBUG_OFF, ("%-8s%-10s%-6s%-6s%-6s%-6s", "MIMOPS", "PhMd", "BW", "MCS", "SGI", "STBC"));
2094#endif // DOT11_N_SUPPORT //
2095 DBGPRINT(RT_DEBUG_OFF, ("\n%02X:%02X:%02X:%02X:%02X:%02X ",
2096 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
2097 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]));
2098 DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->Aid));
2099 DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->apidx));
2100 DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->PsMode));
2101 DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE)));
2102 DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi0));
2103 DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi1));
2104 DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi2));
2105#ifdef DOT11_N_SUPPORT
2106 DBGPRINT(RT_DEBUG_OFF, ("%-8d", (int)pEntry->MmpsMode));
2107 DBGPRINT(RT_DEBUG_OFF, ("%-10s", GetPhyMode(pEntry->HTPhyMode.field.MODE)));
2108 DBGPRINT(RT_DEBUG_OFF, ("%-6s", GetBW(pEntry->HTPhyMode.field.BW)));
2109 DBGPRINT(RT_DEBUG_OFF, ("%-6d", pEntry->HTPhyMode.field.MCS));
2110 DBGPRINT(RT_DEBUG_OFF, ("%-6d", pEntry->HTPhyMode.field.ShortGI));
2111 DBGPRINT(RT_DEBUG_OFF, ("%-6d", pEntry->HTPhyMode.field.STBC));
2112#endif // DOT11_N_SUPPORT //
2113 DBGPRINT(RT_DEBUG_OFF, ("%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount,
2114 (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0));
2115 DBGPRINT(RT_DEBUG_OFF, ("\n"));
2116
2117 }
2118 }
2119
2120 return TRUE;
2121}
2122
2123INT Set_DlsAddEntry_Proc(
2124 IN PRTMP_ADAPTER pAd,
2125 IN PSTRING arg)
2126{
2127 UCHAR mac[MAC_ADDR_LEN];
2128 USHORT Timeout;
2129 PSTRING token;
2130 STRING sepValue[] = ":", DASH = '-';
2131 INT i;
2132 RT_802_11_DLS Dls;
2133
2134 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and timeout value in decimal format.
2135 return FALSE;
2136
2137 token = strchr(arg, DASH);
2138 if ((token != NULL) && (strlen(token)>1))
2139 {
2140 Timeout = (USHORT) simple_strtol((token+1), 0, 10);
2141
2142 *token = '\0';
2143 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2144 {
2145 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2146 return FALSE;
2147 AtoH(token, (&mac[i]), 1);
2148 }
2149 if(i != 6)
2150 return FALSE;
2151
2152 DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%d", mac[0], mac[1],
2153 mac[2], mac[3], mac[4], mac[5], (int)Timeout));
2154
2155 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2156 Dls.TimeOut = Timeout;
2157 COPY_MAC_ADDR(Dls.MacAddr, mac);
2158 Dls.Valid = 1;
2159
2160 MlmeEnqueue(pAd,
2161 MLME_CNTL_STATE_MACHINE,
2162 RT_OID_802_11_SET_DLS_PARAM,
2163 sizeof(RT_802_11_DLS),
2164 &Dls);
2165
2166 return TRUE;
2167 }
2168
2169 return FALSE;
2170
2171}
2172
2173INT Set_DlsTearDownEntry_Proc(
2174 IN PRTMP_ADAPTER pAd,
2175 IN PSTRING arg)
2176{
2177 UCHAR macAddr[MAC_ADDR_LEN];
2178 PSTRING value;
2179 INT i;
2180 RT_802_11_DLS Dls;
2181
2182 if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
2183 return FALSE;
2184
2185 for (i=0, value = rstrtok(arg,":"); value; value = rstrtok(NULL,":"))
2186 {
2187 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
2188 return FALSE; //Invalid
2189
2190 AtoH(value, &macAddr[i++], 2);
2191 }
2192
2193 DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x", macAddr[0], macAddr[1],
2194 macAddr[2], macAddr[3], macAddr[4], macAddr[5]));
2195
2196 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2197 COPY_MAC_ADDR(Dls.MacAddr, macAddr);
2198 Dls.Valid = 0;
2199
2200 MlmeEnqueue(pAd,
2201 MLME_CNTL_STATE_MACHINE,
2202 RT_OID_802_11_SET_DLS_PARAM,
2203 sizeof(RT_802_11_DLS),
2204 &Dls);
2205
2206 return TRUE;
2207}