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 DBGPRINT(RT_DEBUG_OFF, ("DLS - PeerDlsReqAction() Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
364 SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
366 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
368 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
372 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
373 pAd->MacTab.fAnyStationNonGF = TRUE;
374 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
377 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
379 pEntry->MaxHTPhyMode.field.BW= BW_40;
380 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
384 pEntry->MaxHTPhyMode.field.BW = BW_20;
385 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
386 pAd->MacTab.fAnyStation20Only = TRUE;
389 // find max fixed rate
390 for (ii=15; ii>=0; ii--)
393 bitmask = (1<<(ii-(j*8)));
394 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
396 pEntry->MaxHTPhyMode.field.MCS = ii;
404 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
407 printk("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
408 pAd->StaCfg.DesiredTransmitSetting.field.MCS);
409 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
411 // Fix MCS as HT Duplicated Mode
412 pEntry->MaxHTPhyMode.field.BW = 1;
413 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
414 pEntry->MaxHTPhyMode.field.STBC = 0;
415 pEntry->MaxHTPhyMode.field.ShortGI = 0;
416 pEntry->MaxHTPhyMode.field.MCS = 32;
418 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
420 // STA supports fixed MCS
421 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
425 pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
426 pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
427 pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
428 pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
429 pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
430 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
432 if (HtCapability.HtCapInfo.ShortGIfor20)
433 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
434 if (HtCapability.HtCapInfo.ShortGIfor40)
435 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
436 if (HtCapability.HtCapInfo.TxSTBC)
437 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
438 if (HtCapability.HtCapInfo.RxSTBC)
439 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
440 if (HtCapability.ExtHtCapInfo.PlusHTC)
441 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
442 if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
443 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
444 if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
445 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
447 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
449 #endif // DOT11_N_SUPPORT //
451 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
452 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
453 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
455 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
460 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
461 pEntry->bAutoTxRateSwitch = TRUE;
465 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
466 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
467 pEntry->bAutoTxRateSwitch = FALSE;
469 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
471 pEntry->RateLen = SupportedRatesLen;
477 StatusCode = MLME_SUCCESS;
479 // can not find in table, create a new one
482 StatusCode = MLME_QOS_UNSPECIFY;
483 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));
487 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() use entry(%d) %02x:%02x:%02x:%02x:%02x:%02x\n",
488 i, SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
492 ActHeaderInit(pAd, &DlsRspHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
494 // Build basic frame first
495 if (StatusCode == MLME_SUCCESS)
497 MakeOutgoingFrame(pOutBuffer, &FrameLen,
498 sizeof(HEADER_802_11), &DlsRspHdr,
503 6, pAd->CurrentAddress,
504 2, &pAd->StaActive.CapabilityInfo,
506 1, &pAd->MlmeAux.SupRateLen,
507 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
510 if (pAd->MlmeAux.ExtRateLen != 0)
512 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
514 1, &pAd->MlmeAux.ExtRateLen,
515 pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
520 #ifdef DOT11_N_SUPPORT
521 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
526 HT_CAPABILITY_IE HtCapabilityTmp;
529 // add HT Capability IE
530 HtLen = sizeof(HT_CAPABILITY_IE);
531 #ifndef RT_BIG_ENDIAN
532 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
535 HtLen, &pAd->CommonCfg.HtCapability,
538 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
539 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
540 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
542 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
545 HtLen, &HtCapabilityTmp,
548 FrameLen = FrameLen + tmp;
550 #endif // DOT11_N_SUPPORT //
552 if (pDLS && (pDLS->Status != DLS_FINISH))
554 RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
555 Timeout = DLS_TIMEOUT;
556 RTMPSetTimer(&pDLS->Timer, Timeout);
561 MakeOutgoingFrame(pOutBuffer, &FrameLen,
562 sizeof(HEADER_802_11), &DlsRspHdr,
567 6, pAd->CurrentAddress,
571 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
572 MlmeFreeMemory(pAd, pOutBuffer);
576 ==========================================================================
579 IRQL = DISPATCH_LEVEL
581 ==========================================================================
583 VOID PeerDlsRspAction(
584 IN PRTMP_ADAPTER pAd,
585 IN MLME_QUEUE_ELEM *Elem)
587 USHORT CapabilityInfo;
588 UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
591 BOOLEAN TimerCancelled;
592 UCHAR MaxSupportedRateIn500Kbps = 0;
593 UCHAR SupportedRatesLen;
594 UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
595 UCHAR HtCapabilityLen;
596 HT_CAPABILITY_IE HtCapability;
598 if (!pAd->CommonCfg.bDLSCapable)
604 if (!PeerDlsRspSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &StatusCode,
605 &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
608 // supported rates array may not be sorted. sort it and find the maximum rate
609 for (i=0; i<SupportedRatesLen; i++)
611 if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
612 MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
615 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x with StatusCode=%d, CapabilityInfo=0x%x\n",
616 SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], StatusCode, CapabilityInfo));
618 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
620 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
622 if (StatusCode == MLME_SUCCESS)
624 MAC_TABLE_ENTRY *pEntry;
625 UCHAR MaxSupportedRate = RATE_11;
627 pEntry = MacTableInsertDlsEntry(pAd, SA, i);
629 switch (MaxSupportedRateIn500Kbps)
631 case 108: MaxSupportedRate = RATE_54; break;
632 case 96: MaxSupportedRate = RATE_48; break;
633 case 72: MaxSupportedRate = RATE_36; break;
634 case 48: MaxSupportedRate = RATE_24; break;
635 case 36: MaxSupportedRate = RATE_18; break;
636 case 24: MaxSupportedRate = RATE_12; break;
637 case 18: MaxSupportedRate = RATE_9; break;
638 case 12: MaxSupportedRate = RATE_6; break;
639 case 22: MaxSupportedRate = RATE_11; break;
640 case 11: MaxSupportedRate = RATE_5_5; break;
641 case 4: MaxSupportedRate = RATE_2; break;
642 case 2: MaxSupportedRate = RATE_1; break;
643 default: MaxSupportedRate = RATE_11; break;
646 pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
648 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
650 pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
651 pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
652 pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
653 pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
654 pEntry->HTPhyMode.field.MODE = MODE_CCK;
655 pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
659 pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
660 pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
661 pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
662 pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
663 pEntry->HTPhyMode.field.MODE = MODE_OFDM;
664 pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
667 pEntry->MaxHTPhyMode.field.BW = BW_20;
668 pEntry->MinHTPhyMode.field.BW = BW_20;
670 #ifdef DOT11_N_SUPPORT
671 pEntry->HTCapability.MCSSet[0] = 0;
672 pEntry->HTCapability.MCSSet[1] = 0;
674 // If this Entry supports 802.11n, upgrade to HT rate.
675 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
677 UCHAR j, bitmask; //k,bitmask;
680 DBGPRINT(RT_DEBUG_OFF, ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
681 SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
683 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
685 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
689 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
690 pAd->MacTab.fAnyStationNonGF = TRUE;
691 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
694 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
696 pEntry->MaxHTPhyMode.field.BW= BW_40;
697 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
701 pEntry->MaxHTPhyMode.field.BW = BW_20;
702 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
703 pAd->MacTab.fAnyStation20Only = TRUE;
706 // find max fixed rate
707 for (ii=15; ii>=0; ii--)
710 bitmask = (1<<(ii-(j*8)));
711 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
713 pEntry->MaxHTPhyMode.field.MCS = ii;
720 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
722 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
724 // Fix MCS as HT Duplicated Mode
725 pEntry->MaxHTPhyMode.field.BW = 1;
726 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
727 pEntry->MaxHTPhyMode.field.STBC = 0;
728 pEntry->MaxHTPhyMode.field.ShortGI = 0;
729 pEntry->MaxHTPhyMode.field.MCS = 32;
731 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
733 // STA supports fixed MCS
734 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
738 pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
739 pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
740 pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
741 pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
742 pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
743 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
745 if (HtCapability.HtCapInfo.ShortGIfor20)
746 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
747 if (HtCapability.HtCapInfo.ShortGIfor40)
748 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
749 if (HtCapability.HtCapInfo.TxSTBC)
750 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
751 if (HtCapability.HtCapInfo.RxSTBC)
752 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
753 if (HtCapability.ExtHtCapInfo.PlusHTC)
754 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
755 if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
756 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
757 if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
758 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
760 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
762 #endif // DOT11_N_SUPPORT //
763 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
764 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
765 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
767 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
772 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
773 pEntry->bAutoTxRateSwitch = TRUE;
777 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
778 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
779 pEntry->bAutoTxRateSwitch = FALSE;
781 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
783 pEntry->RateLen = SupportedRatesLen;
785 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
787 // If support WPA or WPA2, start STAKey hand shake,
788 // If failed hand shake, just tear down peer DLS
789 if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
791 MLME_DLS_REQ_STRUCT MlmeDlsReq;
792 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
794 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
795 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
796 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
797 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
798 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
802 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
803 DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
808 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
809 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
810 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]));
813 //initialize seq no for DLS frames.
814 pAd->StaCfg.DLSEntry[i].Sequence = 0;
815 if (HtCapabilityLen != 0)
816 pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
818 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
822 // DLS setup procedure failed.
823 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
824 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
825 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
826 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
831 if (i >= MAX_NUM_OF_INIT_DLS_ENTRY)
833 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() update timeout value \n"));
834 for (i=(MAX_NUM_OF_DLS_ENTRY-1); i>=MAX_NUM_OF_INIT_DLS_ENTRY; i--)
836 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
838 if (StatusCode == MLME_SUCCESS)
840 MAC_TABLE_ENTRY *pEntry;
841 UCHAR MaxSupportedRate = RATE_11;
843 pEntry = MacTableInsertDlsEntry(pAd, SA, i);
845 switch (MaxSupportedRateIn500Kbps)
847 case 108: MaxSupportedRate = RATE_54; break;
848 case 96: MaxSupportedRate = RATE_48; break;
849 case 72: MaxSupportedRate = RATE_36; break;
850 case 48: MaxSupportedRate = RATE_24; break;
851 case 36: MaxSupportedRate = RATE_18; break;
852 case 24: MaxSupportedRate = RATE_12; break;
853 case 18: MaxSupportedRate = RATE_9; break;
854 case 12: MaxSupportedRate = RATE_6; break;
855 case 22: MaxSupportedRate = RATE_11; break;
856 case 11: MaxSupportedRate = RATE_5_5; break;
857 case 4: MaxSupportedRate = RATE_2; break;
858 case 2: MaxSupportedRate = RATE_1; break;
859 default: MaxSupportedRate = RATE_11; break;
862 pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
864 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
866 pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
867 pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
868 pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
869 pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
870 pEntry->HTPhyMode.field.MODE = MODE_CCK;
871 pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
875 pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
876 pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
877 pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
878 pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
879 pEntry->HTPhyMode.field.MODE = MODE_OFDM;
880 pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
883 pEntry->MaxHTPhyMode.field.BW = BW_20;
884 pEntry->MinHTPhyMode.field.BW = BW_20;
886 #ifdef DOT11_N_SUPPORT
887 pEntry->HTCapability.MCSSet[0] = 0;
888 pEntry->HTCapability.MCSSet[1] = 0;
890 // If this Entry supports 802.11n, upgrade to HT rate.
891 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
893 UCHAR j, bitmask; //k,bitmask;
896 DBGPRINT(RT_DEBUG_OFF, ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
897 SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
899 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
901 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
905 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
906 pAd->MacTab.fAnyStationNonGF = TRUE;
907 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
910 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
912 pEntry->MaxHTPhyMode.field.BW= BW_40;
913 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
917 pEntry->MaxHTPhyMode.field.BW = BW_20;
918 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
919 pAd->MacTab.fAnyStation20Only = TRUE;
922 // find max fixed rate
923 for (ii=15; ii>=0; ii--)
926 bitmask = (1<<(ii-(j*8)));
927 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
929 pEntry->MaxHTPhyMode.field.MCS = ii;
936 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
938 printk("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
939 pAd->StaCfg.DesiredTransmitSetting.field.MCS);
940 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
942 // Fix MCS as HT Duplicated Mode
943 pEntry->MaxHTPhyMode.field.BW = 1;
944 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
945 pEntry->MaxHTPhyMode.field.STBC = 0;
946 pEntry->MaxHTPhyMode.field.ShortGI = 0;
947 pEntry->MaxHTPhyMode.field.MCS = 32;
949 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
951 // STA supports fixed MCS
952 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
956 pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
957 pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
958 pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
959 pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
960 pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
961 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
963 if (HtCapability.HtCapInfo.ShortGIfor20)
964 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
965 if (HtCapability.HtCapInfo.ShortGIfor40)
966 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
967 if (HtCapability.HtCapInfo.TxSTBC)
968 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
969 if (HtCapability.HtCapInfo.RxSTBC)
970 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
971 if (HtCapability.ExtHtCapInfo.PlusHTC)
972 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
973 if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
974 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
975 if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
976 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
978 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
980 #endif // DOT11_N_SUPPORT //
982 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
983 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
984 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
986 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
991 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
992 pEntry->bAutoTxRateSwitch = TRUE;
996 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
997 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
998 pEntry->bAutoTxRateSwitch = FALSE;
1000 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1002 pEntry->RateLen = SupportedRatesLen;
1004 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
1006 // If support WPA or WPA2, start STAKey hand shake,
1007 // If failed hand shake, just tear down peer DLS
1008 if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
1010 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1011 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
1013 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1014 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1015 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1016 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1017 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
1021 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
1022 DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
1027 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1028 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1029 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x Succeed with WEP or no security\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
1031 pAd->StaCfg.DLSEntry[i].Sequence = 0;
1032 if (HtCapabilityLen != 0)
1033 pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
1035 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
1039 // DLS setup procedure failed.
1040 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1041 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1042 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1043 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
1051 ==========================================================================
1054 IRQL = DISPATCH_LEVEL
1056 ==========================================================================
1058 VOID MlmeDlsTearDownAction(
1059 IN PRTMP_ADAPTER pAd,
1060 IN MLME_QUEUE_ELEM *Elem)
1062 PUCHAR pOutBuffer = NULL;
1063 NDIS_STATUS NStatus;
1065 UCHAR Category = CATEGORY_DLS;
1066 UCHAR Action = ACTION_DLS_TEARDOWN;
1067 USHORT ReasonCode = REASON_QOS_UNSPECIFY;
1068 HEADER_802_11 DlsTearDownHdr;
1069 PRT_802_11_DLS pDLS;
1070 BOOLEAN TimerCancelled;
1073 if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &ReasonCode))
1076 DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsTearDownAction() with ReasonCode=%d \n", ReasonCode));
1078 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1079 if (NStatus != NDIS_STATUS_SUCCESS)
1081 DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsTearDownAction() allocate memory failed \n"));
1085 ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1087 // Build basic frame first
1088 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1089 sizeof(HEADER_802_11), &DlsTearDownHdr,
1093 6, pAd->CurrentAddress,
1097 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1098 MlmeFreeMemory(pAd, pOutBuffer);
1099 RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
1101 // Remove key in local dls table entry
1102 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1104 if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1106 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1110 // clear peer dls table entry
1111 for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; i++)
1113 if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1115 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1116 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1117 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1118 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1124 ==========================================================================
1127 IRQL = DISPATCH_LEVEL
1129 ==========================================================================
1131 VOID PeerDlsTearDownAction(
1132 IN PRTMP_ADAPTER pAd,
1133 IN MLME_QUEUE_ELEM *Elem)
1135 UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
1138 BOOLEAN TimerCancelled;
1140 if (!pAd->CommonCfg.bDLSCapable)
1146 if (!PeerDlsTearDownSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &ReasonCode))
1149 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsTearDownAction() from %02x:%02x:%02x:%02x:%02x:%02x with ReasonCode=%d\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], ReasonCode));
1151 // clear local dls table entry
1152 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1154 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
1156 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1157 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1158 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1159 //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1160 //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1161 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1165 // clear peer dls table entry
1166 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1168 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
1170 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1171 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1172 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1173 //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1174 //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1175 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1181 ==========================================================================
1184 IRQL = DISPATCH_LEVEL
1186 ==========================================================================
1188 VOID RTMPCheckDLSTimeOut(
1189 IN PRTMP_ADAPTER pAd)
1192 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1193 USHORT reason = REASON_QOS_UNSPECIFY;
1195 if (! pAd->CommonCfg.bDLSCapable)
1198 if (! INFRA_ON(pAd))
1201 // If timeout value is equaled to zero, it means always not be timeout.
1203 // update local dls table entry
1204 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1206 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1207 && (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
1209 pAd->StaCfg.DLSEntry[i].CountDownTimer --;
1211 if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
1213 reason = REASON_QOS_REQUEST_TIMEOUT;
1214 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1215 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1216 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1217 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1222 // update peer dls table entry
1223 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1225 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1226 && (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
1228 pAd->StaCfg.DLSEntry[i].CountDownTimer --;
1230 if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
1232 reason = REASON_QOS_REQUEST_TIMEOUT;
1233 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1234 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1235 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1236 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1243 ==========================================================================
1246 IRQL = DISPATCH_LEVEL
1248 ==========================================================================
1250 BOOLEAN RTMPRcvFrameDLSCheck(
1251 IN PRTMP_ADAPTER pAd,
1252 IN PHEADER_802_11 pHeader,
1254 IN PRT28XX_RXD_STRUC pRxD)
1257 BOOLEAN bFindEntry = FALSE;
1258 BOOLEAN bSTAKeyFrame = FALSE;
1260 PUCHAR pProto, pAddr = NULL;
1261 PUCHAR pSTAKey = NULL;
1262 UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
1263 UCHAR Mic[16], OldMic[16];
1267 BOOLEAN TimerCancelled;
1268 CIPHER_KEY PairwiseKey;
1271 if (! pAd->CommonCfg.bDLSCapable)
1272 return bSTAKeyFrame;
1274 if (! INFRA_ON(pAd))
1275 return bSTAKeyFrame;
1277 if (! (pHeader->FC.SubType & 0x08))
1278 return bSTAKeyFrame;
1280 if (Len < LENGTH_802_11 + 6 + 2 + 2)
1281 return bSTAKeyFrame;
1283 pProto = (PUCHAR)pHeader + LENGTH_802_11 + 2 + 6; // QOS Control field , 0xAA 0xAA 0xAA 0x00 0x00 0x00
1284 pAddr = pHeader->Addr2;
1286 // L2PAD bit on will pad 2 bytes at LLC
1292 if (RTMPEqualMemory(EAPOL, pProto, 2) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1294 pEap = (PEAPOL_PACKET) (pProto + 2);
1296 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,
1297 (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16),
1298 pEap->KeyDesc.KeyInfo.KeyMic,
1299 pEap->KeyDesc.KeyInfo.Install,
1300 pEap->KeyDesc.KeyInfo.KeyAck,
1301 pEap->KeyDesc.KeyInfo.Secure,
1302 pEap->KeyDesc.KeyInfo.EKD_DL,
1303 pEap->KeyDesc.KeyInfo.Error,
1304 pEap->KeyDesc.KeyInfo.Request));
1306 if ((Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16)) && pEap->KeyDesc.KeyInfo.KeyMic
1307 && pEap->KeyDesc.KeyInfo.Install && pEap->KeyDesc.KeyInfo.KeyAck && pEap->KeyDesc.KeyInfo.Secure
1308 && pEap->KeyDesc.KeyInfo.EKD_DL && !pEap->KeyDesc.KeyInfo.Error && !pEap->KeyDesc.KeyInfo.Request)
1310 // First validate replay counter, only accept message with larger replay counter
1311 // Let equal pass, some AP start with all zero replay counter
1312 NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
1313 if ((RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) &&
1314 (RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
1315 return bSTAKeyFrame;
1317 //RTMPMoveMemory(pAd->StaCfg.ReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1318 RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1319 DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter (%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
1320 pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
1321 pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4], pAd->StaCfg.ReplayCounter[5],
1322 pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
1324 // put these code segment to get the replay counter
1325 if (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)
1326 return bSTAKeyFrame;
1329 // Save the MIC and replace with zero
1330 // use proprietary PTK
1331 NdisZeroMemory(temp, 64);
1332 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1333 WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1335 NdisMoveMemory(OldMic, pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1336 NdisZeroMemory(pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1337 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1340 HMAC_SHA1((PUCHAR) pEap, pEap->Body_Len[1] + 4, DlsPTK, LEN_EAP_MICK, digest);
1341 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
1345 hmac_md5(DlsPTK, LEN_EAP_MICK, (PUCHAR) pEap, pEap->Body_Len[1] + 4, Mic);
1348 if (!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
1350 DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in Msg1 of STAKey handshake! \n"));
1351 return bSTAKeyFrame;
1354 DBGPRINT(RT_DEBUG_TRACE, ("MIC VALID in Msg1 of STAKey handshake! \n"));
1356 if ((pEap->KeyDesc.KeyData[0] == 0xDD) && (pEap->KeyDesc.KeyData[2] == 0x00) && (pEap->KeyDesc.KeyData[3] == 0x0C)
1357 && (pEap->KeyDesc.KeyData[4] == 0x43) && (pEap->KeyDesc.KeyData[5] == 0x02))
1359 pAddr = pEap->KeyDesc.KeyData + 8; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2)
1360 pSTAKey = pEap->KeyDesc.KeyData + 14; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6)
1362 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%ld, KeyDataLen=%d\n",
1363 pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], Len, pEap->KeyDesc.KeyData[1]));
1365 bSTAKeyFrame = TRUE;
1368 if ((pEap->KeyDesc.KeyData[0] == 0xDD) && (pEap->KeyDesc.KeyData[2] == 0x00) && (pEap->KeyDesc.KeyData[3] == 0x0F)
1369 && (pEap->KeyDesc.KeyData[4] == 0xAC) && (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=%d, KeyDataLen=%d\n",
1375 pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], Len, pEap->KeyDesc.KeyData[1]));
1377 bSTAKeyFrame = TRUE;
1382 else if (Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE))
1385 RTMPMoveMemory(pAd->StaCfg.ReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1388 RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1389 DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter 2(%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
1390 pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
1391 pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4], pAd->StaCfg.ReplayCounter[5],
1392 pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
1397 // If timeout value is equaled to zero, it means always not be timeout.
1398 // update local dls table entry
1399 for (i= 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1401 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1405 PMAC_TABLE_ENTRY pEntry;
1407 // STAKey frame, add pairwise key table
1408 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1409 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1411 PairwiseKey.KeyLen = LEN_TKIP_EK;
1412 NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
1413 NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
1414 NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
1416 PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
1418 pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1419 //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
1420 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1421 // Add Pair-wise key to Asic
1423 AsicAddPairwiseKeyEntry(pAd,
1424 pAd->StaCfg.DLSEntry[i].MacAddr,
1425 (UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
1428 RTMPAddWcidAttributeEntry(pAd,
1431 PairwiseKey.CipherAlg,
1435 NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
1436 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n"));
1438 RTMPSendSTAKeyHandShake(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
1440 DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Initiator side)\n"));
1444 // Data frame, update timeout value
1445 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1447 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1448 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1456 // update peer dls table entry
1457 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1459 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1463 PMAC_TABLE_ENTRY pEntry = NULL;
1465 // STAKey frame, add pairwise key table, and send STAkey Msg-2
1466 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1467 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1469 PairwiseKey.KeyLen = LEN_TKIP_EK;
1470 NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
1471 NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
1472 NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
1474 PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
1476 pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1477 //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
1478 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1479 // Add Pair-wise key to Asic
1481 AsicAddPairwiseKeyEntry(pAd,
1482 pAd->StaCfg.DLSEntry[i].MacAddr,
1483 (UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
1486 RTMPAddWcidAttributeEntry(pAd,
1489 PairwiseKey.CipherAlg,
1492 NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
1493 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n"));
1495 // If support WPA or WPA2, start STAKey hand shake,
1496 // If failed hand shake, just tear down peer DLS
1497 if (RTMPSendSTAKeyHandShake(pAd, pAddr) != NDIS_STATUS_SUCCESS)
1499 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1500 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
1502 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1503 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1504 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1505 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1509 DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Peer side)\n"));
1514 // Data frame, update timeout value
1515 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1517 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1526 return bSTAKeyFrame;
1530 ========================================================================
1532 Routine Description:
1533 Check if the frame can be sent through DLS direct link interface
1536 pAd Pointer to adapter
1543 ========================================================================
1545 INT RTMPCheckDLSFrame(
1546 IN PRTMP_ADAPTER pAd,
1552 if (!pAd->CommonCfg.bDLSCapable)
1559 // check local dls table entry
1560 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1562 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1563 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1570 // check peer dls table entry
1571 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1573 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1574 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1586 ==========================================================================
1589 IRQL = DISPATCH_LEVEL
1591 ==========================================================================
1593 VOID RTMPSendDLSTearDownFrame(
1594 IN PRTMP_ADAPTER pAd,
1597 PUCHAR pOutBuffer = NULL;
1598 NDIS_STATUS NStatus;
1599 HEADER_802_11 DlsTearDownHdr;
1601 USHORT Reason = REASON_QOS_QSTA_LEAVING_QBSS;
1602 UCHAR Category = CATEGORY_DLS;
1603 UCHAR Action = ACTION_DLS_TEARDOWN;
1606 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
1607 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
1610 DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame \n"));
1612 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1613 if (NStatus != NDIS_STATUS_SUCCESS)
1615 DBGPRINT(RT_DEBUG_ERROR,("ASSOC - RTMPSendDLSTearDownFrame() allocate memory failed \n"));
1619 ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1620 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1621 sizeof(HEADER_802_11), &DlsTearDownHdr,
1625 6, pAd->CurrentAddress,
1629 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1630 MlmeFreeMemory(pAd, pOutBuffer);
1632 // Remove key in local dls table entry
1633 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1635 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1636 && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1638 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1642 // Remove key in peer dls table entry
1643 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1645 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1646 && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1648 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1652 DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame and remove key in (i=%d) \n", i));
1656 ==========================================================================
1659 IRQL = DISPATCH_LEVEL
1661 ==========================================================================
1663 NDIS_STATUS RTMPSendSTAKeyRequest(
1664 IN PRTMP_ADAPTER pAd,
1667 UCHAR Header802_3[14];
1668 NDIS_STATUS NStatus;
1670 EAPOL_PACKET Packet;
1673 PUCHAR pOutBuffer = NULL;
1674 PNDIS_PACKET pNdisPacket;
1678 DBGPRINT(RT_DEBUG_TRACE,("DLS - RTMPSendSTAKeyRequest() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5]));
1681 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1683 // Zero message body
1684 NdisZeroMemory(&Packet, sizeof(Packet));
1685 Packet.ProVer = EAPOL_VER;
1686 Packet.ProType = EAPOLKey;
1687 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE andPeer MAC address
1689 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1690 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1692 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1694 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1696 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1699 // Key descriptor version
1700 Packet.KeyDesc.KeyInfo.KeyDescVer =
1701 (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1703 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1704 Packet.KeyDesc.KeyInfo.Secure = 1;
1705 Packet.KeyDesc.KeyInfo.Request = 1;
1707 Packet.KeyDesc.KeyDataLen[1] = 12;
1709 // use our own OUI to distinguish proprietary with standard.
1710 Packet.KeyDesc.KeyData[0] = 0xDD;
1711 Packet.KeyDesc.KeyData[1] = 0x0A;
1712 Packet.KeyDesc.KeyData[2] = 0x00;
1713 Packet.KeyDesc.KeyData[3] = 0x0C;
1714 Packet.KeyDesc.KeyData[4] = 0x43;
1715 Packet.KeyDesc.KeyData[5] = 0x03;
1716 NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
1718 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1720 // Allocate buffer for transmitting message
1721 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1722 if (NStatus != NDIS_STATUS_SUCCESS)
1725 // Prepare EAPOL frame for MIC calculation
1726 // Be careful, only EAPOL frame is counted for MIC calculation
1727 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1728 Packet.Body_Len[1] + 4, &Packet,
1731 // use proprietary PTK
1732 NdisZeroMemory(temp, 64);
1733 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1734 WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1737 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1740 NdisZeroMemory(digest, sizeof(digest));
1741 HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
1742 NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
1746 NdisZeroMemory(Mic, sizeof(Mic));
1747 hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1748 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1751 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1752 sizeof(Header802_3), Header802_3,
1753 Packet.Body_Len[1] + 4, &Packet,
1756 NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1757 if (NStatus == NDIS_STATUS_SUCCESS)
1759 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1760 STASendPacket(pAd, pNdisPacket);
1761 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1764 MlmeFreeMemory(pAd, pOutBuffer);
1766 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyRequest- Send STAKey request (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1772 ==========================================================================
1775 IRQL = DISPATCH_LEVEL
1777 ==========================================================================
1779 NDIS_STATUS RTMPSendSTAKeyHandShake(
1780 IN PRTMP_ADAPTER pAd,
1783 UCHAR Header802_3[14];
1784 NDIS_STATUS NStatus;
1786 EAPOL_PACKET Packet;
1789 PUCHAR pOutBuffer = NULL;
1790 PNDIS_PACKET pNdisPacket;
1792 UCHAR DlsPTK[80]; // Due to dirver can not get PTK, use proprietary PTK
1794 DBGPRINT(RT_DEBUG_TRACE,("DLS - RTMPSendSTAKeyHandShake() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5]));
1797 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1799 // Zero message body
1800 NdisZeroMemory(&Packet, sizeof(Packet));
1801 Packet.ProVer = EAPOL_VER;
1802 Packet.ProType = EAPOLKey;
1803 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE and Peer MAC address
1805 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1806 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1808 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1810 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1812 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1815 // Key descriptor version
1816 Packet.KeyDesc.KeyInfo.KeyDescVer =
1817 (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1819 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1820 Packet.KeyDesc.KeyInfo.Secure = 1;
1822 Packet.KeyDesc.KeyDataLen[1] = 12;
1824 // use our own OUI to distinguish proprietary with standard.
1825 Packet.KeyDesc.KeyData[0] = 0xDD;
1826 Packet.KeyDesc.KeyData[1] = 0x0A;
1827 Packet.KeyDesc.KeyData[2] = 0x00;
1828 Packet.KeyDesc.KeyData[3] = 0x0C;
1829 Packet.KeyDesc.KeyData[4] = 0x43;
1830 Packet.KeyDesc.KeyData[5] = 0x03;
1831 NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
1833 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1835 // Allocate buffer for transmitting message
1836 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1837 if (NStatus != NDIS_STATUS_SUCCESS)
1840 // Prepare EAPOL frame for MIC calculation
1841 // Be careful, only EAPOL frame is counted for MIC calculation
1842 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1843 Packet.Body_Len[1] + 4, &Packet,
1846 // use proprietary PTK
1847 NdisZeroMemory(temp, 64);
1848 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1849 WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1852 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1855 NdisZeroMemory(digest, sizeof(digest));
1856 HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
1857 NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
1861 NdisZeroMemory(Mic, sizeof(Mic));
1862 hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1863 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1866 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1867 sizeof(Header802_3), Header802_3,
1868 Packet.Body_Len[1] + 4, &Packet,
1871 NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1872 if (NStatus == NDIS_STATUS_SUCCESS)
1874 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1875 STASendPacket(pAd, pNdisPacket);
1876 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1879 MlmeFreeMemory(pAd, pOutBuffer);
1881 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyHandShake- Send STAKey Message-2 (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1886 VOID DlsTimeoutAction(
1887 IN PVOID SystemSpecific1,
1888 IN PVOID FunctionContext,
1889 IN PVOID SystemSpecific2,
1890 IN PVOID SystemSpecific3)
1892 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1894 PRT_802_11_DLS pDLS = (PRT_802_11_DLS)FunctionContext;
1895 PRTMP_ADAPTER pAd = pDLS->pAd;
1897 DBGPRINT(RT_DEBUG_TRACE, ("DlsTimeout - Tear down DLS links (%02x:%02x:%02x:%02x:%02x:%02x)\n",
1898 pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5]));
1900 if ((pDLS) && (pDLS->Valid))
1902 reason = REASON_QOS_REQUEST_TIMEOUT;
1903 pDLS->Valid = FALSE;
1904 pDLS->Status = DLS_NONE;
1905 DlsParmFill(pAd, &MlmeDlsReq, pDLS, reason);
1906 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1907 RT28XX_MLME_HANDLER(pAd);
1912 ================================================================
1913 Description : because DLS and CLI share the same WCID table in ASIC.
1914 Mesh entry also insert to pAd->MacTab.content[]. Such is marked as ValidAsDls = TRUE.
1915 Also fills the pairwise key.
1916 Because front MAX_AID_BA entries have direct mapping to BAEntry, which is only used as CLI. So we insert Dls
1917 from index MAX_AID_BA.
1918 ================================================================
1920 MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
1921 IN PRTMP_ADAPTER pAd,
1923 IN UINT DlsEntryIdx)
1925 PMAC_TABLE_ENTRY pEntry = NULL;
1927 DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableInsertDlsEntry\n"));
1929 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
1934 if((pEntry = DlsEntryTableLookup(pAd, pAddr, TRUE)) != NULL)
1937 // allocate one MAC entry
1938 pEntry = MacTableInsertEntry(pAd, pAddr, DlsEntryIdx + MIN_NET_DEVICE_FOR_DLS, TRUE);
1941 pAd->StaCfg.DLSEntry[DlsEntryIdx].MacTabMatchWCID = pEntry->Aid;
1942 pEntry->MatchDlsEntryIdx = DlsEntryIdx;
1943 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1944 pEntry->WepStatus = pAd->StaCfg.WepStatus;
1945 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1947 DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertDlsEntry - allocate entry #%d, Total= %d\n",pEntry->Aid, pAd->MacTab.Size));
1949 // If legacy WEP is used, set pair-wise cipherAlg into WCID attribute table for this entry
1950 if ((pEntry->ValidAsDls) && (pEntry->WepStatus == Ndis802_11WEPEnabled))
1953 UCHAR CipherAlg = 0;
1955 KeyIdx = pAd->StaCfg.DefaultKeyId;
1957 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1959 RTMPAddWcidAttributeEntry(pAd,
1961 pAd->StaCfg.DefaultKeyId,
1962 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1970 DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableInsertDlsEntry\n"));
1977 ==========================================================================
1979 Delete all Mesh Entry in pAd->MacTab
1980 ==========================================================================
1982 BOOLEAN MacTableDeleteDlsEntry(
1983 IN PRTMP_ADAPTER pAd,
1987 DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableDeleteDlsEntry\n"));
1989 if (!VALID_WCID(wcid))
1992 MacTableDeleteEntry(pAd, wcid, pAddr);
1994 DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableDeleteDlsEntry\n"));
1999 MAC_TABLE_ENTRY *DlsEntryTableLookup(
2000 IN PRTMP_ADAPTER pAd,
2002 IN BOOLEAN bResetIdelCount)
2005 MAC_TABLE_ENTRY *pEntry = NULL;
2007 RTMP_SEM_LOCK(&pAd->MacTabLock);
2008 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2009 pEntry = pAd->MacTab.Hash[HashIdx];
2013 if ((pEntry->ValidAsDls == TRUE)
2014 && MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2017 pEntry->NoDataIdleCount = 0;
2021 pEntry = pEntry->pNext;
2024 RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2028 MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
2029 IN PRTMP_ADAPTER pAd,
2032 IN BOOLEAN bResetIdelCount)
2035 PMAC_TABLE_ENTRY pCurEntry = NULL;
2036 PMAC_TABLE_ENTRY pEntry = NULL;
2038 if (!VALID_WCID(wcid))
2041 RTMP_SEM_LOCK(&pAd->MacTabLock);
2045 pCurEntry = &pAd->MacTab.Content[wcid];
2048 if ((pCurEntry) && (pCurEntry->ValidAsDls== TRUE))
2050 DLsIndex = pCurEntry->MatchDlsEntryIdx;
2053 if (DLsIndex == 0xff)
2056 if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr))
2059 pCurEntry->NoDataIdleCount = 0;
2065 RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2070 INT Set_DlsEntryInfo_Display_Proc(
2071 IN PRTMP_ADAPTER pAd,
2076 printk("\n%-19s%-8s\n", "MAC", "TIMEOUT\n");
2077 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
2079 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2081 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[pAd->StaCfg.DLSEntry[i].MacTabMatchWCID];
2083 printk("%02x:%02x:%02x:%02x:%02x:%02x ",
2084 pAd->StaCfg.DLSEntry[i].MacAddr[0], pAd->StaCfg.DLSEntry[i].MacAddr[1], pAd->StaCfg.DLSEntry[i].MacAddr[2],
2085 pAd->StaCfg.DLSEntry[i].MacAddr[3], pAd->StaCfg.DLSEntry[i].MacAddr[4], pAd->StaCfg.DLSEntry[i].MacAddr[5]);
2086 printk("%-8d\n", pAd->StaCfg.DLSEntry[i].TimeOut);
2089 printk("\n%-19s%-4s%-4s%-4s%-4s%-8s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n",
2090 "MAC", "AID", "BSS", "PSM", "WMM", "MIMOPS", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC");
2091 printk("%02X:%02X:%02X:%02X:%02X:%02X ",
2092 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
2093 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
2094 printk("%-4d", (int)pEntry->Aid);
2095 printk("%-4d", (int)pEntry->apidx);
2096 printk("%-4d", (int)pEntry->PsMode);
2097 printk("%-4d", (int)CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE));
2098 printk("%-8d", (int)pEntry->MmpsMode);
2099 printk("%-7d", pEntry->RssiSample.AvgRssi0);
2100 printk("%-7d", pEntry->RssiSample.AvgRssi1);
2101 printk("%-7d", pEntry->RssiSample.AvgRssi2);
2102 printk("%-10s", GetPhyMode(pEntry->HTPhyMode.field.MODE));
2103 printk("%-6s", GetBW(pEntry->HTPhyMode.field.BW));
2104 printk("%-6d", pEntry->HTPhyMode.field.MCS);
2105 printk("%-6d", pEntry->HTPhyMode.field.ShortGI);
2106 printk("%-6d", pEntry->HTPhyMode.field.STBC);
2107 printk("%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount,
2108 (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0);
2117 INT Set_DlsAddEntry_Proc(
2118 IN PRTMP_ADAPTER pAd,
2121 UCHAR mac[MAC_ADDR_LEN];
2123 char *token, sepValue[] = ":", DASH = '-';
2127 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and timeout value in decimal format.
2130 token = strchr(arg, DASH);
2131 if ((token != NULL) && (strlen(token)>1))
2133 Timeout = simple_strtol((token+1), 0, 10);
2136 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2138 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2140 AtoH(token, (PUCHAR)(&mac[i]), 1);
2145 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%d", mac[0], mac[1],
2146 mac[2], mac[3], mac[4], mac[5], (int)Timeout);
2148 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2149 Dls.TimeOut = Timeout;
2150 COPY_MAC_ADDR(Dls.MacAddr, mac);
2154 MLME_CNTL_STATE_MACHINE,
2155 RT_OID_802_11_SET_DLS_PARAM,
2156 sizeof(RT_802_11_DLS),
2166 INT Set_DlsTearDownEntry_Proc(
2167 IN PRTMP_ADAPTER pAd,
2170 UCHAR macAddr[MAC_ADDR_LEN];
2175 if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
2178 for (i=0, value = rstrtok(arg,":"); value; value = rstrtok(NULL,":"))
2180 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
2181 return FALSE; //Invalid
2183 AtoH(value, &macAddr[i++], 2);
2186 printk("\n%02x:%02x:%02x:%02x:%02x:%02x", macAddr[0], macAddr[1],
2187 macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
2189 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2190 COPY_MAC_ADDR(Dls.MacAddr, macAddr);
2194 MLME_CNTL_STATE_MACHINE,
2195 RT_OID_802_11_SET_DLS_PARAM,
2196 sizeof(RT_802_11_DLS),