Full support for Ginger Console
[linux-ginger.git] / drivers / staging / rt3090 / sta / dls.c
blob306e16fdeeaeef68775e24df9bb60bb22047f38c
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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 *************************************************************************
27 Module Name:
28 dls.c
30 Abstract:
31 Handle WMM-DLS state machine
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Rory Chen 02-14-2006
37 Arvin Tai 06-03-2008 Modified for RT28xx
40 #include "../rt_config.h"
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
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
59 IRQL = PASSIVE_LEVEL
61 ==========================================================================
63 void DlsStateMachineInit(
64 IN PRTMP_ADAPTER pAd,
65 IN STATE_MACHINE *Sm,
66 OUT STATE_MACHINE_FUNC Trans[])
68 UCHAR i;
70 StateMachineInit(Sm, (STATE_MACHINE_FUNC*)Trans, MAX_DLS_STATE, MAX_DLS_MSG, (STATE_MACHINE_FUNC)Drop, DLS_IDLE, DLS_MACHINE_BASE);
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);
79 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
81 pAd->StaCfg.DLSEntry[i].pAd = pAd;
82 RTMPInitTimer(pAd, &pAd->StaCfg.DLSEntry[i].Timer, GET_TIMER_FUNCTION(DlsTimeoutAction), pAd, FALSE);
87 ==========================================================================
88 Description:
90 IRQL = DISPATCH_LEVEL
92 ==========================================================================
94 VOID MlmeDlsReqAction(
95 IN PRTMP_ADAPTER pAd,
96 IN MLME_QUEUE_ELEM *Elem)
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;
110 if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &reason))
111 return;
113 DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsReqAction() \n"));
115 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
116 if (NStatus != NDIS_STATUS_SUCCESS)
118 DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsReqAction() allocate memory failed \n"));
119 return;
122 ActHeaderInit(pAd, &DlsReqHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
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);
138 if (pAd->MlmeAux.ExtRateLen != 0)
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;
148 #ifdef DOT11_N_SUPPORT
149 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
151 UCHAR HtLen;
153 #ifdef RT_BIG_ENDIAN
154 HT_CAPABILITY_IE HtCapabilityTmp;
155 #endif
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));
170 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
171 1, &HtCapIe,
172 1, &HtLen,
173 HtLen, &HtCapabilityTmp,
174 END_OF_ARGS);
175 #endif
176 FrameLen = FrameLen + tmp;
178 #endif // DOT11_N_SUPPORT //
180 RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
181 Timeout = DLS_TIMEOUT;
182 RTMPSetTimer(&pDLS->Timer, Timeout);
184 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
185 MlmeFreeMemory(pAd, pOutBuffer);
189 ==========================================================================
190 Description:
192 IRQL = DISPATCH_LEVEL
194 ==========================================================================
196 VOID PeerDlsReqAction(
197 IN PRTMP_ADAPTER pAd,
198 IN MLME_QUEUE_ELEM *Elem)
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;
221 if (!PeerDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &DLSTimeOut,
222 &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
223 return;
225 // supported rates array may not be sorted. sort it and find the maximum rate
226 for (i = 0; i < SupportedRatesLen; i++)
228 if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
229 MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
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]));
234 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
235 if (NStatus != NDIS_STATUS_SUCCESS)
237 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsReqAction() allocate memory failed \n"));
238 return;
241 if (!INFRA_ON(pAd))
243 StatusCode = MLME_REQUEST_DECLINED;
245 else if (!pAd->CommonCfg.bWmmCapable)
247 StatusCode = MLME_DEST_STA_IS_NOT_A_QSTA;
249 else if (!pAd->CommonCfg.bDLSCapable)
251 StatusCode = MLME_REQUEST_DECLINED;
253 else
255 // find table to update parameters
256 for (i = (MAX_NUM_OF_DLS_ENTRY-1); i >= 0; i--)
258 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
260 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
261 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
262 else
264 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
265 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
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;
280 // can not find in table, create a new one
281 if (i < 0)
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--)
286 if (!pAd->StaCfg.DLSEntry[i].Valid)
288 MAC_TABLE_ENTRY *pEntry;
289 UCHAR MaxSupportedRate = RATE_11;
291 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
293 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
295 else
297 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
298 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
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);
313 switch (MaxSupportedRateIn500Kbps)
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;
330 pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
332 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
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;
341 else
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];
351 pEntry->MaxHTPhyMode.field.BW = BW_20;
352 pEntry->MinHTPhyMode.field.BW = BW_20;
354 #ifdef DOT11_N_SUPPORT
355 pEntry->HTCapability.MCSSet[0] = 0;
356 pEntry->HTCapability.MCSSet[1] = 0;
358 // If this Entry supports 802.11n, upgrade to HT rate.
359 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
361 UCHAR j, bitmask; //k,bitmask;
362 CHAR ii;
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]));
367 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
369 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
371 else
373 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
374 pAd->MacTab.fAnyStationNonGF = TRUE;
375 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
378 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
380 pEntry->MaxHTPhyMode.field.BW= BW_40;
381 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
383 else
385 pEntry->MaxHTPhyMode.field.BW = BW_20;
386 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
387 pAd->MacTab.fAnyStation20Only = TRUE;
390 // find max fixed rate
391 for (ii=15; ii>=0; ii--)
393 j = ii/8;
394 bitmask = (1<<(ii-(j*8)));
395 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
397 pEntry->MaxHTPhyMode.field.MCS = ii;
398 break;
400 if (ii==0)
401 break;
405 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
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)
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;
419 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
421 // STA supports fixed MCS
422 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
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;
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);
448 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
450 #endif // DOT11_N_SUPPORT //
452 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
453 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
454 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
456 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
458 PUCHAR pTable;
459 UCHAR TableSize = 0;
461 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
462 pEntry->bAutoTxRateSwitch = TRUE;
464 else
466 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
467 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
468 pEntry->bAutoTxRateSwitch = FALSE;
470 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
472 pEntry->RateLen = SupportedRatesLen;
474 break;
478 StatusCode = MLME_SUCCESS;
480 // can not find in table, create a new one
481 if (i < 0)
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));
486 else
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]));
493 ActHeaderInit(pAd, &DlsRspHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
495 // Build basic frame first
496 if (StatusCode == MLME_SUCCESS)
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);
511 if (pAd->MlmeAux.ExtRateLen != 0)
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;
521 #ifdef DOT11_N_SUPPORT
522 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
524 UCHAR HtLen;
526 #ifdef RT_BIG_ENDIAN
527 HT_CAPABILITY_IE HtCapabilityTmp;
528 #endif
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));
543 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
544 1, &HtCapIe,
545 1, &HtLen,
546 HtLen, &HtCapabilityTmp,
547 END_OF_ARGS);
548 #endif
549 FrameLen = FrameLen + tmp;
551 #endif // DOT11_N_SUPPORT //
553 if (pDLS && (pDLS->Status != DLS_FINISH))
555 RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
556 Timeout = DLS_TIMEOUT;
557 RTMPSetTimer(&pDLS->Timer, Timeout);
560 else
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);
572 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
573 MlmeFreeMemory(pAd, pOutBuffer);
577 ==========================================================================
578 Description:
580 IRQL = DISPATCH_LEVEL
582 ==========================================================================
584 VOID PeerDlsRspAction(
585 IN PRTMP_ADAPTER pAd,
586 IN MLME_QUEUE_ELEM *Elem)
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;
599 if (!pAd->CommonCfg.bDLSCapable)
600 return;
602 if (!INFRA_ON(pAd))
603 return;
605 if (!PeerDlsRspSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &StatusCode,
606 &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
607 return;
609 // supported rates array may not be sorted. sort it and find the maximum rate
610 for (i=0; i<SupportedRatesLen; i++)
612 if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
613 MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
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));
619 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
621 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
623 if (StatusCode == MLME_SUCCESS)
625 MAC_TABLE_ENTRY *pEntry;
626 UCHAR MaxSupportedRate = RATE_11;
628 pEntry = MacTableInsertDlsEntry(pAd, SA, i);
630 switch (MaxSupportedRateIn500Kbps)
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;
647 pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
649 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
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;
658 else
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];
668 pEntry->MaxHTPhyMode.field.BW = BW_20;
669 pEntry->MinHTPhyMode.field.BW = BW_20;
671 #ifdef DOT11_N_SUPPORT
672 pEntry->HTCapability.MCSSet[0] = 0;
673 pEntry->HTCapability.MCSSet[1] = 0;
675 // If this Entry supports 802.11n, upgrade to HT rate.
676 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
678 UCHAR j, bitmask; //k,bitmask;
679 CHAR ii;
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]));
684 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
686 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
688 else
690 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
691 pAd->MacTab.fAnyStationNonGF = TRUE;
692 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
695 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
697 pEntry->MaxHTPhyMode.field.BW= BW_40;
698 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
700 else
702 pEntry->MaxHTPhyMode.field.BW = BW_20;
703 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
704 pAd->MacTab.fAnyStation20Only = TRUE;
707 // find max fixed rate
708 for (ii=15; ii>=0; ii--)
710 j = ii/8;
711 bitmask = (1<<(ii-(j*8)));
712 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
714 pEntry->MaxHTPhyMode.field.MCS = ii;
715 break;
717 if (ii==0)
718 break;
721 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
723 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
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;
732 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
734 // STA supports fixed MCS
735 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
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;
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);
761 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
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);
768 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
770 PUCHAR pTable;
771 UCHAR TableSize = 0;
773 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
774 pEntry->bAutoTxRateSwitch = TRUE;
776 else
778 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
779 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
780 pEntry->bAutoTxRateSwitch = FALSE;
782 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
784 pEntry->RateLen = SupportedRatesLen;
786 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
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)
792 MLME_DLS_REQ_STRUCT MlmeDlsReq;
793 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
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"));
801 else
803 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
804 DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
807 else
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]));
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;
821 else
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));
832 if (i >= MAX_NUM_OF_INIT_DLS_ENTRY)
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--)
837 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
839 if (StatusCode == MLME_SUCCESS)
841 MAC_TABLE_ENTRY *pEntry;
842 UCHAR MaxSupportedRate = RATE_11;
844 pEntry = MacTableInsertDlsEntry(pAd, SA, i);
846 switch (MaxSupportedRateIn500Kbps)
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;
863 pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
865 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
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;
874 else
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];
884 pEntry->MaxHTPhyMode.field.BW = BW_20;
885 pEntry->MinHTPhyMode.field.BW = BW_20;
887 #ifdef DOT11_N_SUPPORT
888 pEntry->HTCapability.MCSSet[0] = 0;
889 pEntry->HTCapability.MCSSet[1] = 0;
891 // If this Entry supports 802.11n, upgrade to HT rate.
892 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
894 UCHAR j, bitmask; //k,bitmask;
895 CHAR ii;
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]));
900 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
902 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
904 else
906 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
907 pAd->MacTab.fAnyStationNonGF = TRUE;
908 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
911 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
913 pEntry->MaxHTPhyMode.field.BW= BW_40;
914 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
916 else
918 pEntry->MaxHTPhyMode.field.BW = BW_20;
919 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
920 pAd->MacTab.fAnyStation20Only = TRUE;
923 // find max fixed rate
924 for (ii=15; ii>=0; ii--)
926 j = ii/8;
927 bitmask = (1<<(ii-(j*8)));
928 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
930 pEntry->MaxHTPhyMode.field.MCS = ii;
931 break;
933 if (ii==0)
934 break;
937 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
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)
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;
950 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
952 // STA supports fixed MCS
953 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
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;
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);
979 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
981 #endif // DOT11_N_SUPPORT //
983 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
984 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
985 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
987 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
989 PUCHAR pTable;
990 UCHAR TableSize = 0;
992 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
993 pEntry->bAutoTxRateSwitch = TRUE;
995 else
997 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
998 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
999 pEntry->bAutoTxRateSwitch = FALSE;
1001 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1003 pEntry->RateLen = SupportedRatesLen;
1005 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
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)
1011 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1012 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
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"));
1020 else
1022 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
1023 DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
1026 else
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]));
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;
1038 else
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));
1052 ==========================================================================
1053 Description:
1055 IRQL = DISPATCH_LEVEL
1057 ==========================================================================
1059 VOID MlmeDlsTearDownAction(
1060 IN PRTMP_ADAPTER pAd,
1061 IN MLME_QUEUE_ELEM *Elem)
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;
1074 if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &ReasonCode))
1075 return;
1077 DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsTearDownAction() with ReasonCode=%d \n", ReasonCode));
1079 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1080 if (NStatus != NDIS_STATUS_SUCCESS)
1082 DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsTearDownAction() allocate memory failed \n"));
1083 return;
1086 ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
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);
1098 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1099 MlmeFreeMemory(pAd, pOutBuffer);
1100 RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
1102 // Remove key in local dls table entry
1103 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1105 if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1107 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1111 // clear peer dls table entry
1112 for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; i++)
1114 if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
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);
1125 ==========================================================================
1126 Description:
1128 IRQL = DISPATCH_LEVEL
1130 ==========================================================================
1132 VOID PeerDlsTearDownAction(
1133 IN PRTMP_ADAPTER pAd,
1134 IN MLME_QUEUE_ELEM *Elem)
1136 UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
1137 USHORT ReasonCode;
1138 UINT i;
1139 BOOLEAN TimerCancelled;
1141 if (!pAd->CommonCfg.bDLSCapable)
1142 return;
1144 if (!INFRA_ON(pAd))
1145 return;
1147 if (!PeerDlsTearDownSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &ReasonCode))
1148 return;
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));
1152 // clear local dls table entry
1153 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1155 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
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);
1166 // clear peer dls table entry
1167 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1169 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
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);
1182 ==========================================================================
1183 Description:
1185 IRQL = DISPATCH_LEVEL
1187 ==========================================================================
1189 VOID RTMPCheckDLSTimeOut(
1190 IN PRTMP_ADAPTER pAd)
1192 ULONG i;
1193 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1194 USHORT reason = REASON_QOS_UNSPECIFY;
1196 if (! pAd->CommonCfg.bDLSCapable)
1197 return;
1199 if (! INFRA_ON(pAd))
1200 return;
1202 // If timeout value is equaled to zero, it means always not be timeout.
1204 // update local dls table entry
1205 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1207 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1208 && (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
1210 pAd->StaCfg.DLSEntry[i].CountDownTimer --;
1212 if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
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);
1223 // update peer dls table entry
1224 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1226 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1227 && (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
1229 pAd->StaCfg.DLSEntry[i].CountDownTimer --;
1231 if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
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);
1244 ==========================================================================
1245 Description:
1247 IRQL = DISPATCH_LEVEL
1249 ==========================================================================
1251 BOOLEAN RTMPRcvFrameDLSCheck(
1252 IN PRTMP_ADAPTER pAd,
1253 IN PHEADER_802_11 pHeader,
1254 IN ULONG Len,
1255 IN PRT28XX_RXD_STRUC pRxD)
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;
1272 if (! pAd->CommonCfg.bDLSCapable)
1273 return bSTAKeyFrame;
1275 if (! INFRA_ON(pAd))
1276 return bSTAKeyFrame;
1278 if (Len < LENGTH_802_11 + 6 + 2) /* LENGTH_802_11 + LLC + EAPOL protocol type */
1279 return bSTAKeyFrame;
1281 pProto = (PUCHAR)pHeader + LENGTH_802_11;
1283 if ((pHeader->FC.SubType & 0x08))
1284 pProto += 2; /* QOS Control field */
1286 /* Skip 4-bytes for HTC */
1287 if (pHeader->FC.Order && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
1289 pProto += 4;
1292 /* L2PAD bit on will pad 2 bytes at LLC */
1293 if (pRxD->L2PAD)
1295 pProto += 2;
1298 pProto += 6; /* 0xAA 0xAA 0xAA 0x00 0x00 0x00 */
1300 if ((!(pHeader->FC.SubType & 0x08)) && (!RTMPEqualMemory(EAPOL, pProto, 2)))
1301 return bSTAKeyFrame;
1303 pAddr = pHeader->Addr2;
1305 if (RTMPEqualMemory(EAPOL, pProto, 2) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1307 pEap = (PEAPOL_PACKET) (pProto + 2);
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));
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)
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;
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]));
1337 // put these code segment to get the replay counter
1338 if (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)
1339 return bSTAKeyFrame;
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);
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)
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);
1356 else
1358 HMAC_MD5(DlsPTK, LEN_EAP_MICK, (PUCHAR) pEap, pEap->Body_Len[1] + 4, Mic, MD5_DIGEST_SIZE);
1361 if (!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
1363 DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in Msg1 of STAKey handshake! \n"));
1364 return bSTAKeyFrame;
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))
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)
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]));
1377 bSTAKeyFrame = TRUE;
1381 else if (Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE))
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]));
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++)
1395 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1397 if (bSTAKeyFrame)
1399 PMAC_TABLE_ENTRY pEntry;
1401 // STAKey frame, add pairwise key table
1402 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1403 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
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);
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;
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);
1426 RTMPAddWcidAttributeEntry(pAd,
1427 BSS0,
1429 PairwiseKey.CipherAlg,
1430 pEntry);
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"));
1436 RTMPSendSTAKeyHandShake(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
1438 DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Initiator side)\n"));
1440 else
1442 // Data frame, update timeout value
1443 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1445 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1446 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1450 bFindEntry = TRUE;
1454 // update peer dls table entry
1455 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1457 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1459 if (bSTAKeyFrame)
1461 PMAC_TABLE_ENTRY pEntry = NULL;
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);
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);
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;
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);
1488 RTMPAddWcidAttributeEntry(pAd,
1489 BSS0,
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"));
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)
1501 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1502 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
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);
1509 else
1511 DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Peer side)\n"));
1514 else
1516 // Data frame, update timeout value
1517 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1519 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1523 bFindEntry = TRUE;
1528 return bSTAKeyFrame;
1532 ========================================================================
1534 Routine Description:
1535 Check if the frame can be sent through DLS direct link interface
1537 Arguments:
1538 pAd Pointer to adapter
1540 Return Value:
1541 DLS entry index
1543 Note:
1545 ========================================================================
1547 INT RTMPCheckDLSFrame(
1548 IN PRTMP_ADAPTER pAd,
1549 IN PUCHAR pDA)
1551 INT rval = -1;
1552 INT i;
1554 if (!pAd->CommonCfg.bDLSCapable)
1555 return rval;
1557 if (!INFRA_ON(pAd))
1558 return rval;
1561 // check local dls table entry
1562 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1564 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1565 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1567 rval = i;
1568 break;
1572 // check peer dls table entry
1573 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1575 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1576 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1578 rval = i;
1579 break;
1582 } while (FALSE);
1584 return rval;
1588 ==========================================================================
1589 Description:
1591 IRQL = DISPATCH_LEVEL
1593 ==========================================================================
1595 VOID RTMPSendDLSTearDownFrame(
1596 IN PRTMP_ADAPTER pAd,
1597 IN PUCHAR pDA)
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;
1608 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
1609 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
1610 return;
1612 DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame \n"));
1614 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1615 if (NStatus != NDIS_STATUS_SUCCESS)
1617 DBGPRINT(RT_DEBUG_ERROR,("ASSOC - RTMPSendDLSTearDownFrame() allocate memory failed \n"));
1618 return;
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);
1631 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1632 MlmeFreeMemory(pAd, pOutBuffer);
1634 // Remove key in local dls table entry
1635 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1637 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1638 && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1640 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1644 // Remove key in peer dls table entry
1645 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1647 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1648 && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1650 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1654 DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame and remove key in (i=%d) \n", i));
1658 ==========================================================================
1659 Description:
1661 IRQL = DISPATCH_LEVEL
1663 ==========================================================================
1665 NDIS_STATUS RTMPSendSTAKeyRequest(
1666 IN PRTMP_ADAPTER pAd,
1667 IN PUCHAR pDA)
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];
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]));
1682 pAd->Sequence ++;
1683 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
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
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))
1694 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1696 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1698 Packet.KeyDesc.Type = WPA2_KEY_DESC;
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));
1705 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1706 Packet.KeyDesc.KeyInfo.Secure = 1;
1707 Packet.KeyDesc.KeyInfo.Request = 1;
1709 Packet.KeyDesc.KeyDataLen[1] = 12;
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);
1720 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1722 // Allocate buffer for transmitting message
1723 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1724 if (NStatus != NDIS_STATUS_SUCCESS)
1725 return NStatus;
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);
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);
1738 // calculate MIC
1739 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
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);
1746 else
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);
1753 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1754 sizeof(Header802_3), Header802_3,
1755 Packet.Body_Len[1] + 4, &Packet,
1756 END_OF_ARGS);
1758 NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1759 if (NStatus == NDIS_STATUS_SUCCESS)
1761 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1762 STASendPacket(pAd, pNdisPacket);
1763 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1766 MlmeFreeMemory(pAd, pOutBuffer);
1768 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyRequest- Send STAKey request (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1770 return NStatus;
1774 ==========================================================================
1775 Description:
1777 IRQL = DISPATCH_LEVEL
1779 ==========================================================================
1781 NDIS_STATUS RTMPSendSTAKeyHandShake(
1782 IN PRTMP_ADAPTER pAd,
1783 IN PUCHAR pDA)
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
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]));
1798 pAd->Sequence ++;
1799 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
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
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))
1810 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1812 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1814 Packet.KeyDesc.Type = WPA2_KEY_DESC;
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));
1821 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1822 Packet.KeyDesc.KeyInfo.Secure = 1;
1824 Packet.KeyDesc.KeyDataLen[1] = 12;
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);
1835 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1837 // Allocate buffer for transmitting message
1838 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1839 if (NStatus != NDIS_STATUS_SUCCESS)
1840 return NStatus;
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);
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);
1853 // calculate MIC
1854 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
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);
1861 else
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);
1868 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1869 sizeof(Header802_3), Header802_3,
1870 Packet.Body_Len[1] + 4, &Packet,
1871 END_OF_ARGS);
1873 NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1874 if (NStatus == NDIS_STATUS_SUCCESS)
1876 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1877 STASendPacket(pAd, pNdisPacket);
1878 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1881 MlmeFreeMemory(pAd, pOutBuffer);
1883 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyHandShake- Send STAKey Message-2 (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1885 return NStatus;
1888 VOID DlsTimeoutAction(
1889 IN PVOID SystemSpecific1,
1890 IN PVOID FunctionContext,
1891 IN PVOID SystemSpecific2,
1892 IN PVOID SystemSpecific3)
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;
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]));
1902 if ((pDLS) && (pDLS->Valid))
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);
1914 ================================================================
1915 Description : because DLS and CLI share the same WCID table in ASIC.
1916 Mesh entry also insert to pAd->MacTab.content[]. Such is marked as ValidAsDls = TRUE.
1917 Also fills the pairwise key.
1918 Because front MAX_AID_BA entries have direct mapping to BAEntry, which is only used as CLI. So we insert Dls
1919 from index MAX_AID_BA.
1920 ================================================================
1922 MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
1923 IN PRTMP_ADAPTER pAd,
1924 IN PUCHAR pAddr,
1925 IN UINT DlsEntryIdx)
1927 PMAC_TABLE_ENTRY pEntry = NULL;
1929 DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableInsertDlsEntry\n"));
1930 // if FULL, return
1931 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
1932 return NULL;
1936 if((pEntry = DlsEntryTableLookup(pAd, pAddr, TRUE)) != NULL)
1937 break;
1939 // allocate one MAC entry
1940 pEntry = MacTableInsertEntry(pAd, pAddr, DlsEntryIdx + MIN_NET_DEVICE_FOR_DLS, TRUE);
1941 if (pEntry)
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;
1949 DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertDlsEntry - allocate entry #%d, Total= %d\n",pEntry->Aid, pAd->MacTab.Size));
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))
1954 UCHAR KeyIdx = 0;
1955 UCHAR CipherAlg = 0;
1957 KeyIdx = pAd->StaCfg.DefaultKeyId;
1959 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1961 RTMPAddWcidAttributeEntry(pAd,
1962 BSS0,
1963 pAd->StaCfg.DefaultKeyId,
1964 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1965 pEntry);
1968 break;
1970 } while(FALSE);
1972 DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableInsertDlsEntry\n"));
1974 return pEntry;
1979 ==========================================================================
1980 Description:
1981 Delete all Mesh Entry in pAd->MacTab
1982 ==========================================================================
1984 BOOLEAN MacTableDeleteDlsEntry(
1985 IN PRTMP_ADAPTER pAd,
1986 IN USHORT wcid,
1987 IN PUCHAR pAddr)
1989 DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableDeleteDlsEntry\n"));
1991 if (!VALID_WCID(wcid))
1992 return FALSE;
1994 MacTableDeleteEntry(pAd, wcid, pAddr);
1996 DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableDeleteDlsEntry\n"));
1998 return TRUE;
2001 MAC_TABLE_ENTRY *DlsEntryTableLookup(
2002 IN PRTMP_ADAPTER pAd,
2003 IN PUCHAR pAddr,
2004 IN BOOLEAN bResetIdelCount)
2006 ULONG HashIdx;
2007 MAC_TABLE_ENTRY *pEntry = NULL;
2009 RTMP_SEM_LOCK(&pAd->MacTabLock);
2010 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2011 pEntry = pAd->MacTab.Hash[HashIdx];
2013 while (pEntry)
2015 if ((pEntry->ValidAsDls == TRUE)
2016 && MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2018 if(bResetIdelCount)
2019 pEntry->NoDataIdleCount = 0;
2020 break;
2022 else
2023 pEntry = pEntry->pNext;
2026 RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2027 return pEntry;
2030 MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
2031 IN PRTMP_ADAPTER pAd,
2032 IN UCHAR wcid,
2033 IN PUCHAR pAddr,
2034 IN BOOLEAN bResetIdelCount)
2036 ULONG DLsIndex;
2037 PMAC_TABLE_ENTRY pCurEntry = NULL;
2038 PMAC_TABLE_ENTRY pEntry = NULL;
2040 if (!VALID_WCID(wcid))
2041 return NULL;
2043 RTMP_SEM_LOCK(&pAd->MacTabLock);
2047 pCurEntry = &pAd->MacTab.Content[wcid];
2049 DLsIndex = 0xff;
2050 if ((pCurEntry) && (pCurEntry->ValidAsDls== TRUE))
2052 DLsIndex = pCurEntry->MatchDlsEntryIdx;
2055 if (DLsIndex == 0xff)
2056 break;
2058 if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr))
2060 if(bResetIdelCount)
2061 pCurEntry->NoDataIdleCount = 0;
2062 pEntry = pCurEntry;
2063 break;
2065 } while(FALSE);
2067 RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2069 return pEntry;
2072 INT Set_DlsEntryInfo_Display_Proc(
2073 IN PRTMP_ADAPTER pAd,
2074 IN PUCHAR arg)
2076 INT i;
2078 DBGPRINT(RT_DEBUG_OFF, ("\n%-19s%-8s\n", "MAC", "TIMEOUT\n"));
2079 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
2081 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2083 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[pAd->StaCfg.DLSEntry[i].MacTabMatchWCID];
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));
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"));
2120 return TRUE;
2123 INT Set_DlsAddEntry_Proc(
2124 IN PRTMP_ADAPTER pAd,
2125 IN PSTRING arg)
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;
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;
2137 token = strchr(arg, DASH);
2138 if ((token != NULL) && (strlen(token)>1))
2140 Timeout = (USHORT) simple_strtol((token+1), 0, 10);
2142 *token = '\0';
2143 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2145 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2146 return FALSE;
2147 AtoH(token, (&mac[i]), 1);
2149 if(i != 6)
2150 return FALSE;
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));
2155 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2156 Dls.TimeOut = Timeout;
2157 COPY_MAC_ADDR(Dls.MacAddr, mac);
2158 Dls.Valid = 1;
2160 MlmeEnqueue(pAd,
2161 MLME_CNTL_STATE_MACHINE,
2162 RT_OID_802_11_SET_DLS_PARAM,
2163 sizeof(RT_802_11_DLS),
2164 &Dls);
2166 return TRUE;
2169 return FALSE;
2173 INT Set_DlsTearDownEntry_Proc(
2174 IN PRTMP_ADAPTER pAd,
2175 IN PSTRING arg)
2177 UCHAR macAddr[MAC_ADDR_LEN];
2178 PSTRING value;
2179 INT i;
2180 RT_802_11_DLS Dls;
2182 if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
2183 return FALSE;
2185 for (i=0, value = rstrtok(arg,":"); value; value = rstrtok(NULL,":"))
2187 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
2188 return FALSE; //Invalid
2190 AtoH(value, &macAddr[i++], 2);
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]));
2196 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2197 COPY_MAC_ADDR(Dls.MacAddr, macAddr);
2198 Dls.Valid = 0;
2200 MlmeEnqueue(pAd,
2201 MLME_CNTL_STATE_MACHINE,
2202 RT_OID_802_11_SET_DLS_PARAM,
2203 sizeof(RT_802_11_DLS),
2204 &Dls);
2206 return TRUE;