2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
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. *
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. *
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. *
25 *************************************************************************
31 Handle WMM-DLS state machine
35 -------- ---------- ----------------------------------------------
37 Arvin Tai 06-03-2008 Modified for RT28xx
40 #include "../rt_config.h"
43 ==========================================================================
45 dls state machine init, including state transition and timer init
47 Sm - pointer to the dls state machine
49 The state machine looks like this
52 MT2_MLME_DLS_REQUEST MlmeDlsReqAction
53 MT2_PEER_DLS_REQUEST PeerDlsReqAction
54 MT2_PEER_DLS_RESPONSE PeerDlsRspAction
55 MT2_MLME_DLS_TEARDOWN MlmeTearDownAction
56 MT2_PEER_DLS_TEARDOWN PeerTearDownAction
60 ==========================================================================
62 void DlsStateMachineInit(
65 OUT STATE_MACHINE_FUNC Trans[])
69 StateMachineInit(Sm, (STATE_MACHINE_FUNC*)Trans, MAX_DLS_STATE, MAX_DLS_MSG, (STATE_MACHINE_FUNC)Drop, DLS_IDLE, DLS_MACHINE_BASE);
72 StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_REQ, (STATE_MACHINE_FUNC)MlmeDlsReqAction);
73 StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_REQ, (STATE_MACHINE_FUNC)PeerDlsReqAction);
74 StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_RSP, (STATE_MACHINE_FUNC)PeerDlsRspAction);
75 StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)MlmeDlsTearDownAction);
76 StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)PeerDlsTearDownAction);
78 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
80 pAd->StaCfg.DLSEntry[i].pAd = pAd;
81 RTMPInitTimer(pAd, &pAd->StaCfg.DLSEntry[i].Timer, GET_TIMER_FUNCTION(DlsTimeoutAction), pAd, FALSE);
86 ==========================================================================
91 ==========================================================================
93 VOID MlmeDlsReqAction(
95 IN MLME_QUEUE_ELEM *Elem)
97 PUCHAR pOutBuffer = NULL;
100 HEADER_802_11 DlsReqHdr;
101 PRT_802_11_DLS pDLS = NULL;
102 UCHAR Category = CATEGORY_DLS;
103 UCHAR Action = ACTION_DLS_REQUEST;
107 BOOLEAN TimerCancelled;
109 if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &reason))
112 DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsReqAction() \n"));
114 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
115 if (NStatus != NDIS_STATUS_SUCCESS)
117 DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsReqAction() allocate memory failed \n"));
121 ActHeaderInit(pAd, &DlsReqHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
123 // Build basic frame first
124 MakeOutgoingFrame(pOutBuffer, &FrameLen,
125 sizeof(HEADER_802_11), &DlsReqHdr,
129 6, pAd->CurrentAddress,
130 2, &pAd->StaActive.CapabilityInfo,
133 1, &pAd->MlmeAux.SupRateLen,
134 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
137 if (pAd->MlmeAux.ExtRateLen != 0)
139 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
141 1, &pAd->MlmeAux.ExtRateLen,
142 pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
147 #ifdef DOT11_N_SUPPORT
148 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
153 HT_CAPABILITY_IE HtCapabilityTmp;
156 // add HT Capability IE
157 HtLen = sizeof(HT_CAPABILITY_IE);
158 #ifndef RT_BIG_ENDIAN
159 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
162 HtLen, &pAd->CommonCfg.HtCapability,
165 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
166 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
167 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
169 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
172 HtLen, &HtCapabilityTmp,
175 FrameLen = FrameLen + tmp;
177 #endif // DOT11_N_SUPPORT //
179 RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
180 Timeout = DLS_TIMEOUT;
181 RTMPSetTimer(&pDLS->Timer, Timeout);
183 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
184 MlmeFreeMemory(pAd, pOutBuffer);
188 ==========================================================================
191 IRQL = DISPATCH_LEVEL
193 ==========================================================================
195 VOID PeerDlsReqAction(
196 IN PRTMP_ADAPTER pAd,
197 IN MLME_QUEUE_ELEM *Elem)
199 PUCHAR pOutBuffer = NULL;
202 USHORT StatusCode = MLME_SUCCESS;
203 HEADER_802_11 DlsRspHdr;
204 UCHAR Category = CATEGORY_DLS;
205 UCHAR Action = ACTION_DLS_RESPONSE;
207 USHORT CapabilityInfo;
208 UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
212 BOOLEAN TimerCancelled;
213 PRT_802_11_DLS pDLS = NULL;
214 UCHAR MaxSupportedRateIn500Kbps = 0;
215 UCHAR SupportedRatesLen;
216 UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
217 UCHAR HtCapabilityLen;
218 HT_CAPABILITY_IE HtCapability;
220 if (!PeerDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &DLSTimeOut,
221 &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
224 // supported rates array may not be sorted. sort it and find the maximum rate
225 for (i = 0; i < SupportedRatesLen; i++)
227 if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
228 MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
231 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 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
234 if (NStatus != NDIS_STATUS_SUCCESS)
236 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsReqAction() allocate memory failed \n"));
242 StatusCode = MLME_REQUEST_DECLINED;
244 else if (!pAd->CommonCfg.bWmmCapable)
246 StatusCode = MLME_DEST_STA_IS_NOT_A_QSTA;
248 else if (!pAd->CommonCfg.bDLSCapable)
250 StatusCode = MLME_REQUEST_DECLINED;
254 // find table to update parameters
255 for (i = (MAX_NUM_OF_DLS_ENTRY-1); i >= 0; i--)
257 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
259 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
260 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
263 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
264 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
267 pAd->StaCfg.DLSEntry[i].Sequence = 0;
268 pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut;
269 pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut;
270 if (HtCapabilityLen != 0)
271 pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
273 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
274 pDLS = &pAd->StaCfg.DLSEntry[i];
279 // can not find in table, create a new one
282 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() can not find same entry \n"));
283 for (i=(MAX_NUM_OF_DLS_ENTRY - 1); i >= MAX_NUM_OF_INIT_DLS_ENTRY; i--)
285 if (!pAd->StaCfg.DLSEntry[i].Valid)
287 MAC_TABLE_ENTRY *pEntry;
288 UCHAR MaxSupportedRate = RATE_11;
290 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
292 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
296 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
297 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
300 pAd->StaCfg.DLSEntry[i].Sequence = 0;
301 pAd->StaCfg.DLSEntry[i].Valid = TRUE;
302 pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut;
303 pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut;
304 NdisMoveMemory(pAd->StaCfg.DLSEntry[i].MacAddr, SA, MAC_ADDR_LEN);
305 if (HtCapabilityLen != 0)
306 pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
308 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
309 pDLS = &pAd->StaCfg.DLSEntry[i];
310 pEntry = MacTableInsertDlsEntry(pAd, SA, i);
312 switch (MaxSupportedRateIn500Kbps)
314 case 108: MaxSupportedRate = RATE_54; break;
315 case 96: MaxSupportedRate = RATE_48; break;
316 case 72: MaxSupportedRate = RATE_36; break;
317 case 48: MaxSupportedRate = RATE_24; break;
318 case 36: MaxSupportedRate = RATE_18; break;
319 case 24: MaxSupportedRate = RATE_12; break;
320 case 18: MaxSupportedRate = RATE_9; break;
321 case 12: MaxSupportedRate = RATE_6; break;
322 case 22: MaxSupportedRate = RATE_11; break;
323 case 11: MaxSupportedRate = RATE_5_5; break;
324 case 4: MaxSupportedRate = RATE_2; break;
325 case 2: MaxSupportedRate = RATE_1; break;
326 default: MaxSupportedRate = RATE_11; break;
329 pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
331 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
333 pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
334 pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
335 pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
336 pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
337 pEntry->HTPhyMode.field.MODE = MODE_CCK;
338 pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
342 pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
343 pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
344 pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
345 pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
346 pEntry->HTPhyMode.field.MODE = MODE_OFDM;
347 pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
350 pEntry->MaxHTPhyMode.field.BW = BW_20;
351 pEntry->MinHTPhyMode.field.BW = BW_20;
353 #ifdef DOT11_N_SUPPORT
354 pEntry->HTCapability.MCSSet[0] = 0;
355 pEntry->HTCapability.MCSSet[1] = 0;
357 // If this Entry supports 802.11n, upgrade to HT rate.
358 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
360 UCHAR j, bitmask; //k,bitmask;
363 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
365 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
369 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
370 pAd->MacTab.fAnyStationNonGF = TRUE;
371 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
374 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
376 pEntry->MaxHTPhyMode.field.BW= BW_40;
377 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
381 pEntry->MaxHTPhyMode.field.BW = BW_20;
382 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
383 pAd->MacTab.fAnyStation20Only = TRUE;
386 // find max fixed rate
387 for (ii=15; ii>=0; ii--)
390 bitmask = (1<<(ii-(j*8)));
391 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
393 pEntry->MaxHTPhyMode.field.MCS = ii;
401 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
404 printk("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
405 pAd->StaCfg.DesiredTransmitSetting.field.MCS);
406 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
408 // Fix MCS as HT Duplicated Mode
409 pEntry->MaxHTPhyMode.field.BW = 1;
410 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
411 pEntry->MaxHTPhyMode.field.STBC = 0;
412 pEntry->MaxHTPhyMode.field.ShortGI = 0;
413 pEntry->MaxHTPhyMode.field.MCS = 32;
415 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
417 // STA supports fixed MCS
418 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
422 pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
423 pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
424 pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
425 pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
426 pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
427 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
429 if (HtCapability.HtCapInfo.ShortGIfor20)
430 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
431 if (HtCapability.HtCapInfo.ShortGIfor40)
432 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
433 if (HtCapability.HtCapInfo.TxSTBC)
434 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
435 if (HtCapability.HtCapInfo.RxSTBC)
436 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
437 if (HtCapability.ExtHtCapInfo.PlusHTC)
438 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
439 if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
440 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
441 if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
442 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
444 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
446 #endif // DOT11_N_SUPPORT //
448 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
449 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
450 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
452 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
457 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
458 pEntry->bAutoTxRateSwitch = TRUE;
462 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
463 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
464 pEntry->bAutoTxRateSwitch = FALSE;
466 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
468 pEntry->RateLen = SupportedRatesLen;
474 StatusCode = MLME_SUCCESS;
476 // can not find in table, create a new one
479 StatusCode = MLME_QOS_UNSPECIFY;
480 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));
484 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() use entry(%d) %02x:%02x:%02x:%02x:%02x:%02x\n",
485 i, SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
489 ActHeaderInit(pAd, &DlsRspHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
491 // Build basic frame first
492 if (StatusCode == MLME_SUCCESS)
494 MakeOutgoingFrame(pOutBuffer, &FrameLen,
495 sizeof(HEADER_802_11), &DlsRspHdr,
500 6, pAd->CurrentAddress,
501 2, &pAd->StaActive.CapabilityInfo,
503 1, &pAd->MlmeAux.SupRateLen,
504 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
507 if (pAd->MlmeAux.ExtRateLen != 0)
509 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
511 1, &pAd->MlmeAux.ExtRateLen,
512 pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
517 #ifdef DOT11_N_SUPPORT
518 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
523 HT_CAPABILITY_IE HtCapabilityTmp;
526 // add HT Capability IE
527 HtLen = sizeof(HT_CAPABILITY_IE);
528 #ifndef RT_BIG_ENDIAN
529 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
532 HtLen, &pAd->CommonCfg.HtCapability,
535 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
536 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
537 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
539 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
542 HtLen, &HtCapabilityTmp,
545 FrameLen = FrameLen + tmp;
547 #endif // DOT11_N_SUPPORT //
549 if (pDLS && (pDLS->Status != DLS_FINISH))
551 RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
552 Timeout = DLS_TIMEOUT;
553 RTMPSetTimer(&pDLS->Timer, Timeout);
558 MakeOutgoingFrame(pOutBuffer, &FrameLen,
559 sizeof(HEADER_802_11), &DlsRspHdr,
564 6, pAd->CurrentAddress,
568 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
569 MlmeFreeMemory(pAd, pOutBuffer);
573 ==========================================================================
576 IRQL = DISPATCH_LEVEL
578 ==========================================================================
580 VOID PeerDlsRspAction(
581 IN PRTMP_ADAPTER pAd,
582 IN MLME_QUEUE_ELEM *Elem)
584 USHORT CapabilityInfo;
585 UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
588 BOOLEAN TimerCancelled;
589 UCHAR MaxSupportedRateIn500Kbps = 0;
590 UCHAR SupportedRatesLen;
591 UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
592 UCHAR HtCapabilityLen;
593 HT_CAPABILITY_IE HtCapability;
595 if (!pAd->CommonCfg.bDLSCapable)
601 if (!PeerDlsRspSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &StatusCode,
602 &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
605 // supported rates array may not be sorted. sort it and find the maximum rate
606 for (i=0; i<SupportedRatesLen; i++)
608 if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
609 MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
612 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x with StatusCode=%d, CapabilityInfo=0x%x\n",
613 SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], StatusCode, CapabilityInfo));
615 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
617 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
619 if (StatusCode == MLME_SUCCESS)
621 MAC_TABLE_ENTRY *pEntry;
622 UCHAR MaxSupportedRate = RATE_11;
624 pEntry = MacTableInsertDlsEntry(pAd, SA, i);
626 switch (MaxSupportedRateIn500Kbps)
628 case 108: MaxSupportedRate = RATE_54; break;
629 case 96: MaxSupportedRate = RATE_48; break;
630 case 72: MaxSupportedRate = RATE_36; break;
631 case 48: MaxSupportedRate = RATE_24; break;
632 case 36: MaxSupportedRate = RATE_18; break;
633 case 24: MaxSupportedRate = RATE_12; break;
634 case 18: MaxSupportedRate = RATE_9; break;
635 case 12: MaxSupportedRate = RATE_6; break;
636 case 22: MaxSupportedRate = RATE_11; break;
637 case 11: MaxSupportedRate = RATE_5_5; break;
638 case 4: MaxSupportedRate = RATE_2; break;
639 case 2: MaxSupportedRate = RATE_1; break;
640 default: MaxSupportedRate = RATE_11; break;
643 pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
645 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
647 pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
648 pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
649 pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
650 pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
651 pEntry->HTPhyMode.field.MODE = MODE_CCK;
652 pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
656 pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
657 pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
658 pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
659 pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
660 pEntry->HTPhyMode.field.MODE = MODE_OFDM;
661 pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
664 pEntry->MaxHTPhyMode.field.BW = BW_20;
665 pEntry->MinHTPhyMode.field.BW = BW_20;
667 #ifdef DOT11_N_SUPPORT
668 pEntry->HTCapability.MCSSet[0] = 0;
669 pEntry->HTCapability.MCSSet[1] = 0;
671 // If this Entry supports 802.11n, upgrade to HT rate.
672 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
674 UCHAR j, bitmask; //k,bitmask;
677 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
679 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
683 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
684 pAd->MacTab.fAnyStationNonGF = TRUE;
685 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
688 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
690 pEntry->MaxHTPhyMode.field.BW= BW_40;
691 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
695 pEntry->MaxHTPhyMode.field.BW = BW_20;
696 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
697 pAd->MacTab.fAnyStation20Only = TRUE;
700 // find max fixed rate
701 for (ii=15; ii>=0; ii--)
704 bitmask = (1<<(ii-(j*8)));
705 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
707 pEntry->MaxHTPhyMode.field.MCS = ii;
714 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
716 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
718 // Fix MCS as HT Duplicated Mode
719 pEntry->MaxHTPhyMode.field.BW = 1;
720 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
721 pEntry->MaxHTPhyMode.field.STBC = 0;
722 pEntry->MaxHTPhyMode.field.ShortGI = 0;
723 pEntry->MaxHTPhyMode.field.MCS = 32;
725 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
727 // STA supports fixed MCS
728 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
732 pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
733 pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
734 pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
735 pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
736 pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
737 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
739 if (HtCapability.HtCapInfo.ShortGIfor20)
740 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
741 if (HtCapability.HtCapInfo.ShortGIfor40)
742 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
743 if (HtCapability.HtCapInfo.TxSTBC)
744 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
745 if (HtCapability.HtCapInfo.RxSTBC)
746 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
747 if (HtCapability.ExtHtCapInfo.PlusHTC)
748 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
749 if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
750 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
751 if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
752 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
754 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
756 #endif // DOT11_N_SUPPORT //
757 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
758 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
759 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
761 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
766 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
767 pEntry->bAutoTxRateSwitch = TRUE;
771 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
772 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
773 pEntry->bAutoTxRateSwitch = FALSE;
775 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
777 pEntry->RateLen = SupportedRatesLen;
779 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
781 // If support WPA or WPA2, start STAKey hand shake,
782 // If failed hand shake, just tear down peer DLS
783 if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
785 MLME_DLS_REQ_STRUCT MlmeDlsReq;
786 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
788 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
789 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
790 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
791 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
792 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
796 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
797 DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
802 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
803 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
804 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]));
807 //initialize seq no for DLS frames.
808 pAd->StaCfg.DLSEntry[i].Sequence = 0;
809 if (HtCapabilityLen != 0)
810 pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
812 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
816 // DLS setup procedure failed.
817 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
818 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
819 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
820 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
825 if (i >= MAX_NUM_OF_INIT_DLS_ENTRY)
827 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() update timeout value \n"));
828 for (i=(MAX_NUM_OF_DLS_ENTRY-1); i>=MAX_NUM_OF_INIT_DLS_ENTRY; i--)
830 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
832 if (StatusCode == MLME_SUCCESS)
834 MAC_TABLE_ENTRY *pEntry;
835 UCHAR MaxSupportedRate = RATE_11;
837 pEntry = MacTableInsertDlsEntry(pAd, SA, i);
839 switch (MaxSupportedRateIn500Kbps)
841 case 108: MaxSupportedRate = RATE_54; break;
842 case 96: MaxSupportedRate = RATE_48; break;
843 case 72: MaxSupportedRate = RATE_36; break;
844 case 48: MaxSupportedRate = RATE_24; break;
845 case 36: MaxSupportedRate = RATE_18; break;
846 case 24: MaxSupportedRate = RATE_12; break;
847 case 18: MaxSupportedRate = RATE_9; break;
848 case 12: MaxSupportedRate = RATE_6; break;
849 case 22: MaxSupportedRate = RATE_11; break;
850 case 11: MaxSupportedRate = RATE_5_5; break;
851 case 4: MaxSupportedRate = RATE_2; break;
852 case 2: MaxSupportedRate = RATE_1; break;
853 default: MaxSupportedRate = RATE_11; break;
856 pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
858 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
860 pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
861 pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
862 pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
863 pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
864 pEntry->HTPhyMode.field.MODE = MODE_CCK;
865 pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
869 pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
870 pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
871 pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
872 pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
873 pEntry->HTPhyMode.field.MODE = MODE_OFDM;
874 pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
877 pEntry->MaxHTPhyMode.field.BW = BW_20;
878 pEntry->MinHTPhyMode.field.BW = BW_20;
880 #ifdef DOT11_N_SUPPORT
881 pEntry->HTCapability.MCSSet[0] = 0;
882 pEntry->HTCapability.MCSSet[1] = 0;
884 // If this Entry supports 802.11n, upgrade to HT rate.
885 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
887 UCHAR j, bitmask; //k,bitmask;
890 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
892 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
896 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
897 pAd->MacTab.fAnyStationNonGF = TRUE;
898 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
901 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
903 pEntry->MaxHTPhyMode.field.BW= BW_40;
904 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
908 pEntry->MaxHTPhyMode.field.BW = BW_20;
909 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
910 pAd->MacTab.fAnyStation20Only = TRUE;
913 // find max fixed rate
914 for (ii=15; ii>=0; ii--)
917 bitmask = (1<<(ii-(j*8)));
918 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
920 pEntry->MaxHTPhyMode.field.MCS = ii;
927 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
929 printk("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
930 pAd->StaCfg.DesiredTransmitSetting.field.MCS);
931 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
933 // Fix MCS as HT Duplicated Mode
934 pEntry->MaxHTPhyMode.field.BW = 1;
935 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
936 pEntry->MaxHTPhyMode.field.STBC = 0;
937 pEntry->MaxHTPhyMode.field.ShortGI = 0;
938 pEntry->MaxHTPhyMode.field.MCS = 32;
940 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
942 // STA supports fixed MCS
943 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
947 pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
948 pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
949 pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
950 pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
951 pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
952 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
954 if (HtCapability.HtCapInfo.ShortGIfor20)
955 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
956 if (HtCapability.HtCapInfo.ShortGIfor40)
957 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
958 if (HtCapability.HtCapInfo.TxSTBC)
959 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
960 if (HtCapability.HtCapInfo.RxSTBC)
961 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
962 if (HtCapability.ExtHtCapInfo.PlusHTC)
963 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
964 if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
965 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
966 if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
967 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
969 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
971 #endif // DOT11_N_SUPPORT //
973 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
974 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
975 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
977 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
982 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
983 pEntry->bAutoTxRateSwitch = TRUE;
987 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
988 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
989 pEntry->bAutoTxRateSwitch = FALSE;
991 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
993 pEntry->RateLen = SupportedRatesLen;
995 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
997 // If support WPA or WPA2, start STAKey hand shake,
998 // If failed hand shake, just tear down peer DLS
999 if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
1001 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1002 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
1004 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1005 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1006 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1007 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1008 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
1012 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
1013 DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
1018 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1019 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1020 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]));
1022 pAd->StaCfg.DLSEntry[i].Sequence = 0;
1023 if (HtCapabilityLen != 0)
1024 pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
1026 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
1030 // DLS setup procedure failed.
1031 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1032 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1033 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1034 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
1042 ==========================================================================
1045 IRQL = DISPATCH_LEVEL
1047 ==========================================================================
1049 VOID MlmeDlsTearDownAction(
1050 IN PRTMP_ADAPTER pAd,
1051 IN MLME_QUEUE_ELEM *Elem)
1053 PUCHAR pOutBuffer = NULL;
1054 NDIS_STATUS NStatus;
1056 UCHAR Category = CATEGORY_DLS;
1057 UCHAR Action = ACTION_DLS_TEARDOWN;
1058 USHORT ReasonCode = REASON_QOS_UNSPECIFY;
1059 HEADER_802_11 DlsTearDownHdr;
1060 PRT_802_11_DLS pDLS;
1061 BOOLEAN TimerCancelled;
1064 if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &ReasonCode))
1067 DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsTearDownAction() with ReasonCode=%d \n", ReasonCode));
1069 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1070 if (NStatus != NDIS_STATUS_SUCCESS)
1072 DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsTearDownAction() allocate memory failed \n"));
1076 ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1078 // Build basic frame first
1079 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1080 sizeof(HEADER_802_11), &DlsTearDownHdr,
1084 6, pAd->CurrentAddress,
1088 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1089 MlmeFreeMemory(pAd, pOutBuffer);
1090 RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
1092 // Remove key in local dls table entry
1093 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1095 if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1097 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1101 // clear peer dls table entry
1102 for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; i++)
1104 if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1106 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1107 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1108 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1109 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1115 ==========================================================================
1118 IRQL = DISPATCH_LEVEL
1120 ==========================================================================
1122 VOID PeerDlsTearDownAction(
1123 IN PRTMP_ADAPTER pAd,
1124 IN MLME_QUEUE_ELEM *Elem)
1126 UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
1129 BOOLEAN TimerCancelled;
1131 if (!pAd->CommonCfg.bDLSCapable)
1137 if (!PeerDlsTearDownSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &ReasonCode))
1140 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));
1142 // clear local dls table entry
1143 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1145 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
1147 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1148 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1149 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1150 //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1151 //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1152 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1156 // clear peer dls table entry
1157 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1159 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
1161 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1162 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1163 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1164 //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1165 //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1166 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1172 ==========================================================================
1175 IRQL = DISPATCH_LEVEL
1177 ==========================================================================
1179 VOID RTMPCheckDLSTimeOut(
1180 IN PRTMP_ADAPTER pAd)
1183 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1184 USHORT reason = REASON_QOS_UNSPECIFY;
1186 if (! pAd->CommonCfg.bDLSCapable)
1189 if (! INFRA_ON(pAd))
1192 // If timeout value is equaled to zero, it means always not be timeout.
1194 // update local dls table entry
1195 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1197 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1198 && (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
1200 pAd->StaCfg.DLSEntry[i].CountDownTimer --;
1202 if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
1204 reason = REASON_QOS_REQUEST_TIMEOUT;
1205 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1206 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1207 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1208 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1213 // update peer dls table entry
1214 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1216 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1217 && (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
1219 pAd->StaCfg.DLSEntry[i].CountDownTimer --;
1221 if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
1223 reason = REASON_QOS_REQUEST_TIMEOUT;
1224 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1225 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1226 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1227 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1234 ==========================================================================
1237 IRQL = DISPATCH_LEVEL
1239 ==========================================================================
1241 BOOLEAN RTMPRcvFrameDLSCheck(
1242 IN PRTMP_ADAPTER pAd,
1243 IN PHEADER_802_11 pHeader,
1245 IN PRT28XX_RXD_STRUC pRxD)
1248 BOOLEAN bFindEntry = FALSE;
1249 BOOLEAN bSTAKeyFrame = FALSE;
1251 PUCHAR pProto, pAddr = NULL;
1252 PUCHAR pSTAKey = NULL;
1253 UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
1254 UCHAR Mic[16], OldMic[16];
1258 BOOLEAN TimerCancelled;
1259 CIPHER_KEY PairwiseKey;
1262 if (! pAd->CommonCfg.bDLSCapable)
1263 return bSTAKeyFrame;
1265 if (! INFRA_ON(pAd))
1266 return bSTAKeyFrame;
1268 if (! (pHeader->FC.SubType & 0x08))
1269 return bSTAKeyFrame;
1271 if (Len < LENGTH_802_11 + 6 + 2 + 2)
1272 return bSTAKeyFrame;
1274 pProto = (PUCHAR)pHeader + LENGTH_802_11 + 2 + 6; // QOS Control field , 0xAA 0xAA 0xAA 0x00 0x00 0x00
1275 pAddr = pHeader->Addr2;
1277 // L2PAD bit on will pad 2 bytes at LLC
1283 if (RTMPEqualMemory(EAPOL, pProto, 2) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1285 pEap = (PEAPOL_PACKET) (pProto + 2);
1287 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,
1288 (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16),
1289 pEap->KeyDesc.KeyInfo.KeyMic,
1290 pEap->KeyDesc.KeyInfo.Install,
1291 pEap->KeyDesc.KeyInfo.KeyAck,
1292 pEap->KeyDesc.KeyInfo.Secure,
1293 pEap->KeyDesc.KeyInfo.EKD_DL,
1294 pEap->KeyDesc.KeyInfo.Error,
1295 pEap->KeyDesc.KeyInfo.Request));
1297 if ((Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16)) && pEap->KeyDesc.KeyInfo.KeyMic
1298 && pEap->KeyDesc.KeyInfo.Install && pEap->KeyDesc.KeyInfo.KeyAck && pEap->KeyDesc.KeyInfo.Secure
1299 && pEap->KeyDesc.KeyInfo.EKD_DL && !pEap->KeyDesc.KeyInfo.Error && !pEap->KeyDesc.KeyInfo.Request)
1301 // First validate replay counter, only accept message with larger replay counter
1302 // Let equal pass, some AP start with all zero replay counter
1303 NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
1304 if ((RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) &&
1305 (RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
1306 return bSTAKeyFrame;
1308 //RTMPMoveMemory(pAd->StaCfg.ReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1309 RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1310 DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter (%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
1311 pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
1312 pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4], pAd->StaCfg.ReplayCounter[5],
1313 pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
1315 // put these code segment to get the replay counter
1316 if (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)
1317 return bSTAKeyFrame;
1320 // Save the MIC and replace with zero
1321 // use proprietary PTK
1322 NdisZeroMemory(temp, 64);
1323 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1324 WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1326 NdisMoveMemory(OldMic, pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1327 NdisZeroMemory(pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1328 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1331 HMAC_SHA1((PUCHAR) pEap, pEap->Body_Len[1] + 4, DlsPTK, LEN_EAP_MICK, digest);
1332 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
1336 hmac_md5(DlsPTK, LEN_EAP_MICK, (PUCHAR) pEap, pEap->Body_Len[1] + 4, Mic);
1339 if (!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
1341 DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in Msg1 of STAKey handshake! \n"));
1342 return bSTAKeyFrame;
1345 DBGPRINT(RT_DEBUG_TRACE, ("MIC VALID in Msg1 of STAKey handshake! \n"));
1347 if ((pEap->KeyDesc.KeyData[0] == 0xDD) && (pEap->KeyDesc.KeyData[2] == 0x00) && (pEap->KeyDesc.KeyData[3] == 0x0C)
1348 && (pEap->KeyDesc.KeyData[4] == 0x43) && (pEap->KeyDesc.KeyData[5] == 0x02))
1350 pAddr = pEap->KeyDesc.KeyData + 8; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2)
1351 pSTAKey = pEap->KeyDesc.KeyData + 14; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6)
1353 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%ld, KeyDataLen=%d\n",
1354 pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], Len, pEap->KeyDesc.KeyData[1]));
1356 bSTAKeyFrame = TRUE;
1359 if ((pEap->KeyDesc.KeyData[0] == 0xDD) && (pEap->KeyDesc.KeyData[2] == 0x00) && (pEap->KeyDesc.KeyData[3] == 0x0F)
1360 && (pEap->KeyDesc.KeyData[4] == 0xAC) && (pEap->KeyDesc.KeyData[5] == 0x02))
1362 pAddr = pEap->KeyDesc.KeyData + 8; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2)
1363 pSTAKey = pEap->KeyDesc.KeyData + 14; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6)
1365 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%d, KeyDataLen=%d\n",
1366 pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], Len, pEap->KeyDesc.KeyData[1]));
1368 bSTAKeyFrame = TRUE;
1373 else if (Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE))
1375 RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1376 DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter 2(%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
1377 pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
1378 pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4], pAd->StaCfg.ReplayCounter[5],
1379 pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
1384 // If timeout value is equaled to zero, it means always not be timeout.
1385 // update local dls table entry
1386 for (i= 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1388 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1392 PMAC_TABLE_ENTRY pEntry;
1394 // STAKey frame, add pairwise key table
1395 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1396 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1398 PairwiseKey.KeyLen = LEN_TKIP_EK;
1399 NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
1400 NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
1401 NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
1403 PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
1405 pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1406 //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
1407 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1408 // Add Pair-wise key to Asic
1410 //Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
1412 RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
1413 COPY_MAC_ADDR(KeyInfo.MacAddr,pAd->StaCfg.DLSEntry[i].MacAddr);
1414 KeyInfo.MacTabMatchWCID=pAd->StaCfg.DLSEntry[i].MacTabMatchWCID;
1415 NdisMoveMemory(&KeyInfo.CipherKey, &PairwiseKey,sizeof(CIPHER_KEY));
1416 RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_KEY_TABLE, &KeyInfo, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY));
1419 PMAC_TABLE_ENTRY pDLSEntry;
1420 pDLSEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1421 pDLSEntry->PairwiseKey.CipherAlg=PairwiseKey.CipherAlg;
1422 RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_RX_WCID_TABLE, pDLSEntry, sizeof(MAC_TABLE_ENTRY));
1424 //Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
1426 NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
1427 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n"));
1429 RTMPSendSTAKeyHandShake(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
1431 DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Initiator side)\n"));
1435 // Data frame, update timeout value
1436 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1438 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1439 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1447 // update peer dls table entry
1448 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1450 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1454 PMAC_TABLE_ENTRY pEntry = NULL;
1456 // STAKey frame, add pairwise key table, and send STAkey Msg-2
1457 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1458 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1460 PairwiseKey.KeyLen = LEN_TKIP_EK;
1461 NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
1462 NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
1463 NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
1465 PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
1467 pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1468 //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
1469 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1470 // Add Pair-wise key to Asic
1472 //Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
1474 RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
1475 COPY_MAC_ADDR(KeyInfo.MacAddr,pAd->StaCfg.DLSEntry[i].MacAddr);
1476 KeyInfo.MacTabMatchWCID=pAd->StaCfg.DLSEntry[i].MacTabMatchWCID;
1477 NdisMoveMemory(&KeyInfo.CipherKey, &PairwiseKey,sizeof(CIPHER_KEY));
1478 RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_KEY_TABLE, &KeyInfo, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY));
1481 PMAC_TABLE_ENTRY pDLSEntry;
1482 pDLSEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1483 pDLSEntry->PairwiseKey.CipherAlg=PairwiseKey.CipherAlg;
1484 RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_RX_WCID_TABLE, pDLSEntry, sizeof(MAC_TABLE_ENTRY));
1486 //Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
1488 NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
1489 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n"));
1491 // If support WPA or WPA2, start STAKey hand shake,
1492 // If failed hand shake, just tear down peer DLS
1493 if (RTMPSendSTAKeyHandShake(pAd, pAddr) != NDIS_STATUS_SUCCESS)
1495 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1496 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
1498 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1499 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1500 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1501 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1505 DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Peer side)\n"));
1510 // Data frame, update timeout value
1511 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1513 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1522 return bSTAKeyFrame;
1526 ========================================================================
1528 Routine Description:
1529 Check if the frame can be sent through DLS direct link interface
1532 pAd Pointer to adapter
1539 ========================================================================
1541 INT RTMPCheckDLSFrame(
1542 IN PRTMP_ADAPTER pAd,
1548 if (!pAd->CommonCfg.bDLSCapable)
1555 // check local dls table entry
1556 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1558 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1559 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1566 // check peer dls table entry
1567 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1569 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1570 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1582 ==========================================================================
1585 IRQL = DISPATCH_LEVEL
1587 ==========================================================================
1589 VOID RTMPSendDLSTearDownFrame(
1590 IN PRTMP_ADAPTER pAd,
1593 PUCHAR pOutBuffer = NULL;
1594 NDIS_STATUS NStatus;
1595 HEADER_802_11 DlsTearDownHdr;
1597 USHORT Reason = REASON_QOS_QSTA_LEAVING_QBSS;
1598 UCHAR Category = CATEGORY_DLS;
1599 UCHAR Action = ACTION_DLS_TEARDOWN;
1602 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
1603 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
1606 DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame \n"));
1608 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1609 if (NStatus != NDIS_STATUS_SUCCESS)
1611 DBGPRINT(RT_DEBUG_ERROR,("ASSOC - RTMPSendDLSTearDownFrame() allocate memory failed \n"));
1615 ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1616 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1617 sizeof(HEADER_802_11), &DlsTearDownHdr,
1621 6, pAd->CurrentAddress,
1625 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1626 MlmeFreeMemory(pAd, pOutBuffer);
1628 // Remove key in local dls table entry
1629 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1631 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1632 && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1634 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1638 // Remove key in peer dls table entry
1639 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1641 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1642 && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1644 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1648 DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame and remove key in (i=%d) \n", i));
1652 ==========================================================================
1655 IRQL = DISPATCH_LEVEL
1657 ==========================================================================
1659 NDIS_STATUS RTMPSendSTAKeyRequest(
1660 IN PRTMP_ADAPTER pAd,
1663 UCHAR Header802_3[14];
1664 NDIS_STATUS NStatus;
1666 EAPOL_PACKET Packet;
1669 PUCHAR pOutBuffer = NULL;
1670 PNDIS_PACKET pNdisPacket;
1674 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]));
1677 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1679 // Zero message body
1680 NdisZeroMemory(&Packet, sizeof(Packet));
1681 Packet.ProVer = EAPOL_VER;
1682 Packet.ProType = EAPOLKey;
1683 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE andPeer MAC address
1685 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1686 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1688 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1690 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1692 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1695 // Key descriptor version
1696 Packet.KeyDesc.KeyInfo.KeyDescVer =
1697 (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1699 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1700 Packet.KeyDesc.KeyInfo.Secure = 1;
1701 Packet.KeyDesc.KeyInfo.Request = 1;
1703 Packet.KeyDesc.KeyDataLen[1] = 12;
1705 // use our own OUI to distinguish proprietary with standard.
1706 Packet.KeyDesc.KeyData[0] = 0xDD;
1707 Packet.KeyDesc.KeyData[1] = 0x0A;
1708 Packet.KeyDesc.KeyData[2] = 0x00;
1709 Packet.KeyDesc.KeyData[3] = 0x0C;
1710 Packet.KeyDesc.KeyData[4] = 0x43;
1711 Packet.KeyDesc.KeyData[5] = 0x03;
1712 NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
1714 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1716 // Allocate buffer for transmitting message
1717 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1718 if (NStatus != NDIS_STATUS_SUCCESS)
1721 // Prepare EAPOL frame for MIC calculation
1722 // Be careful, only EAPOL frame is counted for MIC calculation
1723 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1724 Packet.Body_Len[1] + 4, &Packet,
1727 // use proprietary PTK
1728 NdisZeroMemory(temp, 64);
1729 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1730 WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1733 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1736 NdisZeroMemory(digest, sizeof(digest));
1737 HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
1738 NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
1742 NdisZeroMemory(Mic, sizeof(Mic));
1743 hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1744 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1747 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1748 sizeof(Header802_3), Header802_3,
1749 Packet.Body_Len[1] + 4, &Packet,
1752 NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1753 if (NStatus == NDIS_STATUS_SUCCESS)
1755 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1756 STASendPacket(pAd, pNdisPacket);
1757 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1760 MlmeFreeMemory(pAd, pOutBuffer);
1762 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyRequest- Send STAKey request (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1768 ==========================================================================
1771 IRQL = DISPATCH_LEVEL
1773 ==========================================================================
1775 NDIS_STATUS RTMPSendSTAKeyHandShake(
1776 IN PRTMP_ADAPTER pAd,
1779 UCHAR Header802_3[14];
1780 NDIS_STATUS NStatus;
1782 EAPOL_PACKET Packet;
1785 PUCHAR pOutBuffer = NULL;
1786 PNDIS_PACKET pNdisPacket;
1788 UCHAR DlsPTK[80]; // Due to dirver can not get PTK, use proprietary PTK
1790 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]));
1793 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1795 // Zero message body
1796 NdisZeroMemory(&Packet, sizeof(Packet));
1797 Packet.ProVer = EAPOL_VER;
1798 Packet.ProType = EAPOLKey;
1799 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE and Peer MAC address
1801 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1802 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1804 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1806 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1808 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1811 // Key descriptor version
1812 Packet.KeyDesc.KeyInfo.KeyDescVer =
1813 (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1815 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1816 Packet.KeyDesc.KeyInfo.Secure = 1;
1818 Packet.KeyDesc.KeyDataLen[1] = 12;
1820 // use our own OUI to distinguish proprietary with standard.
1821 Packet.KeyDesc.KeyData[0] = 0xDD;
1822 Packet.KeyDesc.KeyData[1] = 0x0A;
1823 Packet.KeyDesc.KeyData[2] = 0x00;
1824 Packet.KeyDesc.KeyData[3] = 0x0C;
1825 Packet.KeyDesc.KeyData[4] = 0x43;
1826 Packet.KeyDesc.KeyData[5] = 0x03;
1827 NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
1829 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1831 // Allocate buffer for transmitting message
1832 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1833 if (NStatus != NDIS_STATUS_SUCCESS)
1836 // Prepare EAPOL frame for MIC calculation
1837 // Be careful, only EAPOL frame is counted for MIC calculation
1838 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1839 Packet.Body_Len[1] + 4, &Packet,
1842 // use proprietary PTK
1843 NdisZeroMemory(temp, 64);
1844 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1845 WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1848 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1851 NdisZeroMemory(digest, sizeof(digest));
1852 HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
1853 NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
1857 NdisZeroMemory(Mic, sizeof(Mic));
1858 hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1859 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1862 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1863 sizeof(Header802_3), Header802_3,
1864 Packet.Body_Len[1] + 4, &Packet,
1867 NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1868 if (NStatus == NDIS_STATUS_SUCCESS)
1870 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1871 STASendPacket(pAd, pNdisPacket);
1872 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1875 MlmeFreeMemory(pAd, pOutBuffer);
1877 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyHandShake- Send STAKey Message-2 (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1882 VOID DlsTimeoutAction(
1883 IN PVOID SystemSpecific1,
1884 IN PVOID FunctionContext,
1885 IN PVOID SystemSpecific2,
1886 IN PVOID SystemSpecific3)
1888 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1890 PRT_802_11_DLS pDLS = (PRT_802_11_DLS)FunctionContext;
1891 PRTMP_ADAPTER pAd = pDLS->pAd;
1893 DBGPRINT(RT_DEBUG_TRACE, ("DlsTimeout - Tear down DLS links (%02x:%02x:%02x:%02x:%02x:%02x)\n",
1894 pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5]));
1896 if ((pDLS) && (pDLS->Valid))
1898 reason = REASON_QOS_REQUEST_TIMEOUT;
1899 pDLS->Valid = FALSE;
1900 pDLS->Status = DLS_NONE;
1901 DlsParmFill(pAd, &MlmeDlsReq, pDLS, reason);
1902 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1903 RT28XX_MLME_HANDLER(pAd);
1908 ================================================================
1909 Description : because DLS and CLI share the same WCID table in ASIC.
1910 Mesh entry also insert to pAd->MacTab.content[]. Such is marked as ValidAsDls = TRUE.
1911 Also fills the pairwise key.
1912 Because front MAX_AID_BA entries have direct mapping to BAEntry, which is only used as CLI. So we insert Dls
1913 from index MAX_AID_BA.
1914 ================================================================
1916 MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
1917 IN PRTMP_ADAPTER pAd,
1919 IN UINT DlsEntryIdx)
1921 PMAC_TABLE_ENTRY pEntry = NULL;
1923 DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableInsertDlsEntry\n"));
1925 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
1930 if((pEntry = DlsEntryTableLookup(pAd, pAddr, TRUE)) != NULL)
1933 // allocate one MAC entry
1934 pEntry = MacTableInsertEntry(pAd, pAddr, DlsEntryIdx + MIN_NET_DEVICE_FOR_DLS, TRUE);
1937 pAd->StaCfg.DLSEntry[DlsEntryIdx].MacTabMatchWCID = pEntry->Aid;
1938 pEntry->MatchDlsEntryIdx = DlsEntryIdx;
1939 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1940 pEntry->WepStatus = pAd->StaCfg.WepStatus;
1942 DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertDlsEntry - allocate entry #%d, Total= %d\n",pEntry->Aid, pAd->MacTab.Size));
1944 // If legacy WEP is used, set pair-wise cipherAlg into WCID attribute table for this entry
1945 if ((pEntry->ValidAsDls) && (pEntry->WepStatus == Ndis802_11WEPEnabled))
1948 UCHAR CipherAlg = 0;
1950 KeyIdx = pAd->StaCfg.DefaultKeyId;
1952 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1954 RTMPAddWcidAttributeEntry(pAd,
1956 pAd->StaCfg.DefaultKeyId,
1957 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1965 DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableInsertDlsEntry\n"));
1972 ==========================================================================
1974 Delete all Mesh Entry in pAd->MacTab
1975 ==========================================================================
1977 BOOLEAN MacTableDeleteDlsEntry(
1978 IN PRTMP_ADAPTER pAd,
1982 DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableDeleteDlsEntry\n"));
1984 if (!VALID_WCID(wcid))
1987 MacTableDeleteEntry(pAd, wcid, pAddr);
1989 DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableDeleteDlsEntry\n"));
1994 MAC_TABLE_ENTRY *DlsEntryTableLookup(
1995 IN PRTMP_ADAPTER pAd,
1997 IN BOOLEAN bResetIdelCount)
2000 MAC_TABLE_ENTRY *pEntry = NULL;
2002 RTMP_SEM_LOCK(&pAd->MacTabLock);
2003 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2004 pEntry = pAd->MacTab.Hash[HashIdx];
2008 if ((pEntry->ValidAsDls == TRUE)
2009 && MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2012 pEntry->NoDataIdleCount = 0;
2016 pEntry = pEntry->pNext;
2019 RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2023 MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
2024 IN PRTMP_ADAPTER pAd,
2027 IN BOOLEAN bResetIdelCount)
2030 PMAC_TABLE_ENTRY pCurEntry = NULL;
2031 PMAC_TABLE_ENTRY pEntry = NULL;
2033 if (!VALID_WCID(wcid))
2036 RTMP_SEM_LOCK(&pAd->MacTabLock);
2040 pCurEntry = &pAd->MacTab.Content[wcid];
2043 if ((pCurEntry) && (pCurEntry->ValidAsDls== TRUE))
2045 DLsIndex = pCurEntry->MatchDlsEntryIdx;
2048 if (DLsIndex == 0xff)
2051 if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr))
2054 pCurEntry->NoDataIdleCount = 0;
2060 RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2065 INT Set_DlsEntryInfo_Display_Proc(
2066 IN PRTMP_ADAPTER pAd,
2071 printk("\n%-19s%-8s\n", "MAC", "TIMEOUT\n");
2072 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
2074 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2076 printk("%02x:%02x:%02x:%02x:%02x:%02x ",
2077 pAd->StaCfg.DLSEntry[i].MacAddr[0], pAd->StaCfg.DLSEntry[i].MacAddr[1], pAd->StaCfg.DLSEntry[i].MacAddr[2],
2078 pAd->StaCfg.DLSEntry[i].MacAddr[3], pAd->StaCfg.DLSEntry[i].MacAddr[4], pAd->StaCfg.DLSEntry[i].MacAddr[5]);
2079 printk("%-8d\n", pAd->StaCfg.DLSEntry[i].TimeOut);
2086 INT Set_DlsAddEntry_Proc(
2087 IN PRTMP_ADAPTER pAd,
2090 UCHAR mac[MAC_ADDR_LEN];
2092 char *token, sepValue[] = ":", DASH = '-';
2096 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and timeout value in decimal format.
2099 token = strchr(arg, DASH);
2100 if ((token != NULL) && (strlen(token)>1))
2102 Timeout = simple_strtol((token+1), 0, 10);
2105 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2107 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2109 AtoH(token, (PUCHAR)(&mac[i]), 1);
2114 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%d", mac[0], mac[1],
2115 mac[2], mac[3], mac[4], mac[5], (int)Timeout);
2117 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2118 Dls.TimeOut = Timeout;
2119 COPY_MAC_ADDR(Dls.MacAddr, mac);
2123 MLME_CNTL_STATE_MACHINE,
2124 RT_OID_802_11_SET_DLS_PARAM,
2125 sizeof(RT_802_11_DLS),
2135 INT Set_DlsTearDownEntry_Proc(
2136 IN PRTMP_ADAPTER pAd,
2139 UCHAR macAddr[MAC_ADDR_LEN];
2144 if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
2147 for (i=0, value = rstrtok(arg,":"); value; value = rstrtok(NULL,":"))
2149 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
2150 return FALSE; //Invalid
2152 AtoH(value, &macAddr[i++], 2);
2155 printk("\n%02x:%02x:%02x:%02x:%02x:%02x", macAddr[0], macAddr[1],
2156 macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
2158 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2159 COPY_MAC_ADDR(Dls.MacAddr, macAddr);
2163 MLME_CNTL_STATE_MACHINE,
2164 RT_OID_802_11_SET_DLS_PARAM,
2165 sizeof(RT_802_11_DLS),