Staging: add rt2870 wireless driver
[linux-2.6/mini2440.git] / drivers / staging / rt2870 / sta / dls.c
blob56bfbc33d6f5a494d72aeec28ef2384dbf2689b5
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
27 Module Name:
28 dls.c
30 Abstract:
31 Handle WMM-DLS state machine
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Rory Chen 02-14-2006
37 Arvin Tai 06-03-2008 Modified for RT28xx
40 #include "../rt_config.h"
43 ==========================================================================
44 Description:
45 dls state machine init, including state transition and timer init
46 Parameters:
47 Sm - pointer to the dls state machine
48 Note:
49 The state machine looks like this
51 DLS_IDLE
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
58 IRQL = PASSIVE_LEVEL
60 ==========================================================================
62 void DlsStateMachineInit(
63 IN PRTMP_ADAPTER pAd,
64 IN STATE_MACHINE *Sm,
65 OUT STATE_MACHINE_FUNC Trans[])
67 UCHAR i;
69 StateMachineInit(Sm, (STATE_MACHINE_FUNC*)Trans, MAX_DLS_STATE, MAX_DLS_MSG, (STATE_MACHINE_FUNC)Drop, DLS_IDLE, DLS_MACHINE_BASE);
71 // the first column
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 ==========================================================================
87 Description:
89 IRQL = DISPATCH_LEVEL
91 ==========================================================================
93 VOID MlmeDlsReqAction(
94 IN PRTMP_ADAPTER pAd,
95 IN MLME_QUEUE_ELEM *Elem)
97 PUCHAR pOutBuffer = NULL;
98 NDIS_STATUS NStatus;
99 ULONG FrameLen = 0;
100 HEADER_802_11 DlsReqHdr;
101 PRT_802_11_DLS pDLS = NULL;
102 UCHAR Category = CATEGORY_DLS;
103 UCHAR Action = ACTION_DLS_REQUEST;
104 ULONG tmp;
105 USHORT reason;
106 ULONG Timeout;
107 BOOLEAN TimerCancelled;
109 if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &reason))
110 return;
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"));
118 return;
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,
126 1, &Category,
127 1, &Action,
128 6, &pDLS->MacAddr,
129 6, pAd->CurrentAddress,
130 2, &pAd->StaActive.CapabilityInfo,
131 2, &pDLS->TimeOut,
132 1, &SupRateIe,
133 1, &pAd->MlmeAux.SupRateLen,
134 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
135 END_OF_ARGS);
137 if (pAd->MlmeAux.ExtRateLen != 0)
139 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
140 1, &ExtRateIe,
141 1, &pAd->MlmeAux.ExtRateLen,
142 pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
143 END_OF_ARGS);
144 FrameLen += tmp;
147 #ifdef DOT11_N_SUPPORT
148 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
150 UCHAR HtLen;
152 #ifdef RT_BIG_ENDIAN
153 HT_CAPABILITY_IE HtCapabilityTmp;
154 #endif
156 // add HT Capability IE
157 HtLen = sizeof(HT_CAPABILITY_IE);
158 #ifndef RT_BIG_ENDIAN
159 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
160 1, &HtCapIe,
161 1, &HtLen,
162 HtLen, &pAd->CommonCfg.HtCapability,
163 END_OF_ARGS);
164 #else
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,
170 1, &HtCapIe,
171 1, &HtLen,
172 HtLen, &HtCapabilityTmp,
173 END_OF_ARGS);
174 #endif
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 ==========================================================================
189 Description:
191 IRQL = DISPATCH_LEVEL
193 ==========================================================================
195 VOID PeerDlsReqAction(
196 IN PRTMP_ADAPTER pAd,
197 IN MLME_QUEUE_ELEM *Elem)
199 PUCHAR pOutBuffer = NULL;
200 NDIS_STATUS NStatus;
201 ULONG FrameLen = 0;
202 USHORT StatusCode = MLME_SUCCESS;
203 HEADER_802_11 DlsRspHdr;
204 UCHAR Category = CATEGORY_DLS;
205 UCHAR Action = ACTION_DLS_RESPONSE;
206 ULONG tmp;
207 USHORT CapabilityInfo;
208 UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
209 USHORT DLSTimeOut;
210 SHORT i;
211 ULONG Timeout;
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))
222 return;
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"));
237 return;
240 if (!INFRA_ON(pAd))
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;
252 else
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;
261 else
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;
272 else
273 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
274 pDLS = &pAd->StaCfg.DLSEntry[i];
275 break;
279 // can not find in table, create a new one
280 if (i < 0)
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;
294 else
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;
307 else
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;
340 else
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;
361 CHAR ii;
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;
370 else
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));
382 else
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--)
392 j = ii/8;
393 bitmask = (1<<(ii-(j*8)));
394 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
396 pEntry->MaxHTPhyMode.field.MCS = ii;
397 break;
399 if (ii==0)
400 break;
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)
457 PUCHAR pTable;
458 UCHAR TableSize = 0;
460 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
461 pEntry->bAutoTxRateSwitch = TRUE;
463 else
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;
473 break;
477 StatusCode = MLME_SUCCESS;
479 // can not find in table, create a new one
480 if (i < 0)
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));
485 else
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,
499 1, &Category,
500 1, &Action,
501 2, &StatusCode,
502 6, SA,
503 6, pAd->CurrentAddress,
504 2, &pAd->StaActive.CapabilityInfo,
505 1, &SupRateIe,
506 1, &pAd->MlmeAux.SupRateLen,
507 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
508 END_OF_ARGS);
510 if (pAd->MlmeAux.ExtRateLen != 0)
512 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
513 1, &ExtRateIe,
514 1, &pAd->MlmeAux.ExtRateLen,
515 pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
516 END_OF_ARGS);
517 FrameLen += tmp;
520 #ifdef DOT11_N_SUPPORT
521 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
523 UCHAR HtLen;
525 #ifdef RT_BIG_ENDIAN
526 HT_CAPABILITY_IE HtCapabilityTmp;
527 #endif
529 // add HT Capability IE
530 HtLen = sizeof(HT_CAPABILITY_IE);
531 #ifndef RT_BIG_ENDIAN
532 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
533 1, &HtCapIe,
534 1, &HtLen,
535 HtLen, &pAd->CommonCfg.HtCapability,
536 END_OF_ARGS);
537 #else
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,
543 1, &HtCapIe,
544 1, &HtLen,
545 HtLen, &HtCapabilityTmp,
546 END_OF_ARGS);
547 #endif
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);
559 else
561 MakeOutgoingFrame(pOutBuffer, &FrameLen,
562 sizeof(HEADER_802_11), &DlsRspHdr,
563 1, &Category,
564 1, &Action,
565 2, &StatusCode,
566 6, SA,
567 6, pAd->CurrentAddress,
568 END_OF_ARGS);
571 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
572 MlmeFreeMemory(pAd, pOutBuffer);
576 ==========================================================================
577 Description:
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];
589 USHORT StatusCode;
590 SHORT i;
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)
599 return;
601 if (!INFRA_ON(pAd))
602 return;
604 if (!PeerDlsRspSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &StatusCode,
605 &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
606 return;
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;
657 else
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;
678 CHAR ii;
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;
687 else
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));
699 else
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--)
709 j = ii/8;
710 bitmask = (1<<(ii-(j*8)));
711 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
713 pEntry->MaxHTPhyMode.field.MCS = ii;
714 break;
716 if (ii==0)
717 break;
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)
769 PUCHAR pTable;
770 UCHAR TableSize = 0;
772 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
773 pEntry->bAutoTxRateSwitch = TRUE;
775 else
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"));
800 else
802 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
803 DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
806 else
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;
817 else
818 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
820 else
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;
873 else
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;
894 CHAR ii;
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;
903 else
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));
915 else
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--)
925 j = ii/8;
926 bitmask = (1<<(ii-(j*8)));
927 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
929 pEntry->MaxHTPhyMode.field.MCS = ii;
930 break;
932 if (ii==0)
933 break;
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)
988 PUCHAR pTable;
989 UCHAR TableSize = 0;
991 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
992 pEntry->bAutoTxRateSwitch = TRUE;
994 else
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"));
1019 else
1021 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
1022 DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
1025 else
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;
1034 else
1035 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
1037 else
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 ==========================================================================
1052 Description:
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;
1064 ULONG FrameLen = 0;
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;
1071 UCHAR i;
1073 if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &ReasonCode))
1074 return;
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"));
1082 return;
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,
1090 1, &Category,
1091 1, &Action,
1092 6, &pDLS->MacAddr,
1093 6, pAd->CurrentAddress,
1094 2, &ReasonCode,
1095 END_OF_ARGS);
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 ==========================================================================
1125 Description:
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];
1136 USHORT ReasonCode;
1137 UINT i;
1138 BOOLEAN TimerCancelled;
1140 if (!pAd->CommonCfg.bDLSCapable)
1141 return;
1143 if (!INFRA_ON(pAd))
1144 return;
1146 if (!PeerDlsTearDownSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &ReasonCode))
1147 return;
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 ==========================================================================
1182 Description:
1184 IRQL = DISPATCH_LEVEL
1186 ==========================================================================
1188 VOID RTMPCheckDLSTimeOut(
1189 IN PRTMP_ADAPTER pAd)
1191 ULONG i;
1192 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1193 USHORT reason = REASON_QOS_UNSPECIFY;
1195 if (! pAd->CommonCfg.bDLSCapable)
1196 return;
1198 if (! INFRA_ON(pAd))
1199 return;
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 ==========================================================================
1244 Description:
1246 IRQL = DISPATCH_LEVEL
1248 ==========================================================================
1250 BOOLEAN RTMPRcvFrameDLSCheck(
1251 IN PRTMP_ADAPTER pAd,
1252 IN PHEADER_802_11 pHeader,
1253 IN ULONG Len,
1254 IN PRT28XX_RXD_STRUC pRxD)
1256 ULONG i;
1257 BOOLEAN bFindEntry = FALSE;
1258 BOOLEAN bSTAKeyFrame = FALSE;
1259 PEAPOL_PACKET pEap;
1260 PUCHAR pProto, pAddr = NULL;
1261 PUCHAR pSTAKey = NULL;
1262 UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
1263 UCHAR Mic[16], OldMic[16];
1264 UCHAR digest[80];
1265 UCHAR DlsPTK[80];
1266 UCHAR temp[64];
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
1287 if (pRxD->L2PAD)
1289 pProto += 2;
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;
1328 // Check MIC value
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)
1339 // AES
1340 HMAC_SHA1((PUCHAR) pEap, pEap->Body_Len[1] + 4, DlsPTK, LEN_EAP_MICK, digest);
1341 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
1343 else
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;
1353 else
1354 DBGPRINT(RT_DEBUG_TRACE, ("MIC VALID in Msg1 of STAKey handshake! \n"));
1355 #if 1
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;
1367 #else
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;
1379 #endif
1382 else if (Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE))
1384 #if 0
1385 RTMPMoveMemory(pAd->StaCfg.ReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1387 #endif
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))
1403 if (bSTAKeyFrame)
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
1422 #ifdef RT2870
1424 RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
1425 COPY_MAC_ADDR(KeyInfo.MacAddr,pAd->StaCfg.DLSEntry[i].MacAddr);
1426 KeyInfo.MacTabMatchWCID=pAd->StaCfg.DLSEntry[i].MacTabMatchWCID;
1427 NdisMoveMemory(&KeyInfo.CipherKey, &PairwiseKey,sizeof(CIPHER_KEY));
1428 RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_KEY_TABLE, &KeyInfo, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY));
1431 PMAC_TABLE_ENTRY pDLSEntry;
1432 pDLSEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1433 pDLSEntry->PairwiseKey.CipherAlg=PairwiseKey.CipherAlg;
1434 RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_RX_WCID_TABLE, pDLSEntry, sizeof(MAC_TABLE_ENTRY));
1436 #endif // RT2870 //
1437 NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
1438 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n"));
1440 RTMPSendSTAKeyHandShake(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
1442 DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Initiator side)\n"));
1444 else
1446 // Data frame, update timeout value
1447 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1449 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1450 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1454 bFindEntry = TRUE;
1458 // update peer dls table entry
1459 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1461 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1463 if (bSTAKeyFrame)
1465 PMAC_TABLE_ENTRY pEntry = NULL;
1467 // STAKey frame, add pairwise key table, and send STAkey Msg-2
1468 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1469 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1471 PairwiseKey.KeyLen = LEN_TKIP_EK;
1472 NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
1473 NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
1474 NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
1476 PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
1478 pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1479 //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
1480 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1481 // Add Pair-wise key to Asic
1482 #ifdef RT2870
1484 RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
1485 COPY_MAC_ADDR(KeyInfo.MacAddr,pAd->StaCfg.DLSEntry[i].MacAddr);
1486 KeyInfo.MacTabMatchWCID=pAd->StaCfg.DLSEntry[i].MacTabMatchWCID;
1487 NdisMoveMemory(&KeyInfo.CipherKey, &PairwiseKey,sizeof(CIPHER_KEY));
1488 RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_KEY_TABLE, &KeyInfo, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY));
1491 PMAC_TABLE_ENTRY pDLSEntry;
1492 pDLSEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1493 pDLSEntry->PairwiseKey.CipherAlg=PairwiseKey.CipherAlg;
1494 RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_RX_WCID_TABLE, pDLSEntry, sizeof(MAC_TABLE_ENTRY));
1496 #endif // RT2870 //
1497 NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
1498 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n"));
1500 // If support WPA or WPA2, start STAKey hand shake,
1501 // If failed hand shake, just tear down peer DLS
1502 if (RTMPSendSTAKeyHandShake(pAd, pAddr) != NDIS_STATUS_SUCCESS)
1504 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1505 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
1507 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1508 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1509 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1510 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1512 else
1514 DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Peer side)\n"));
1517 else
1519 // Data frame, update timeout value
1520 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1522 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1526 bFindEntry = TRUE;
1531 return bSTAKeyFrame;
1535 ========================================================================
1537 Routine Description:
1538 Check if the frame can be sent through DLS direct link interface
1540 Arguments:
1541 pAd Pointer to adapter
1543 Return Value:
1544 DLS entry index
1546 Note:
1548 ========================================================================
1550 INT RTMPCheckDLSFrame(
1551 IN PRTMP_ADAPTER pAd,
1552 IN PUCHAR pDA)
1554 INT rval = -1;
1555 INT i;
1557 if (!pAd->CommonCfg.bDLSCapable)
1558 return rval;
1560 if (!INFRA_ON(pAd))
1561 return rval;
1564 // check local dls table entry
1565 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1567 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1568 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1570 rval = i;
1571 break;
1575 // check peer dls table entry
1576 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1578 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1579 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1581 rval = i;
1582 break;
1585 } while (FALSE);
1587 return rval;
1591 ==========================================================================
1592 Description:
1594 IRQL = DISPATCH_LEVEL
1596 ==========================================================================
1598 VOID RTMPSendDLSTearDownFrame(
1599 IN PRTMP_ADAPTER pAd,
1600 IN PUCHAR pDA)
1602 PUCHAR pOutBuffer = NULL;
1603 NDIS_STATUS NStatus;
1604 HEADER_802_11 DlsTearDownHdr;
1605 ULONG FrameLen = 0;
1606 USHORT Reason = REASON_QOS_QSTA_LEAVING_QBSS;
1607 UCHAR Category = CATEGORY_DLS;
1608 UCHAR Action = ACTION_DLS_TEARDOWN;
1609 UCHAR i = 0;
1611 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
1612 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
1613 return;
1615 DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame \n"));
1617 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1618 if (NStatus != NDIS_STATUS_SUCCESS)
1620 DBGPRINT(RT_DEBUG_ERROR,("ASSOC - RTMPSendDLSTearDownFrame() allocate memory failed \n"));
1621 return;
1624 ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1625 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1626 sizeof(HEADER_802_11), &DlsTearDownHdr,
1627 1, &Category,
1628 1, &Action,
1629 6, pDA,
1630 6, pAd->CurrentAddress,
1631 2, &Reason,
1632 END_OF_ARGS);
1634 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1635 MlmeFreeMemory(pAd, pOutBuffer);
1637 // Remove key in local dls table entry
1638 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1640 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1641 && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1643 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1647 // Remove key in peer dls table entry
1648 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1650 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1651 && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1653 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1657 DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame and remove key in (i=%d) \n", i));
1661 ==========================================================================
1662 Description:
1664 IRQL = DISPATCH_LEVEL
1666 ==========================================================================
1668 NDIS_STATUS RTMPSendSTAKeyRequest(
1669 IN PRTMP_ADAPTER pAd,
1670 IN PUCHAR pDA)
1672 UCHAR Header802_3[14];
1673 NDIS_STATUS NStatus;
1674 ULONG FrameLen = 0;
1675 EAPOL_PACKET Packet;
1676 UCHAR Mic[16];
1677 UCHAR digest[80];
1678 PUCHAR pOutBuffer = NULL;
1679 PNDIS_PACKET pNdisPacket;
1680 UCHAR temp[64];
1681 UCHAR DlsPTK[80];
1683 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]));
1685 pAd->Sequence ++;
1686 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1688 // Zero message body
1689 NdisZeroMemory(&Packet, sizeof(Packet));
1690 Packet.ProVer = EAPOL_VER;
1691 Packet.ProType = EAPOLKey;
1692 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE andPeer MAC address
1694 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1695 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1697 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1699 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1701 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1704 // Key descriptor version
1705 Packet.KeyDesc.KeyInfo.KeyDescVer =
1706 (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1708 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1709 Packet.KeyDesc.KeyInfo.Secure = 1;
1710 Packet.KeyDesc.KeyInfo.Request = 1;
1712 Packet.KeyDesc.KeyDataLen[1] = 12;
1714 // use our own OUI to distinguish proprietary with standard.
1715 Packet.KeyDesc.KeyData[0] = 0xDD;
1716 Packet.KeyDesc.KeyData[1] = 0x0A;
1717 Packet.KeyDesc.KeyData[2] = 0x00;
1718 Packet.KeyDesc.KeyData[3] = 0x0C;
1719 Packet.KeyDesc.KeyData[4] = 0x43;
1720 Packet.KeyDesc.KeyData[5] = 0x03;
1721 NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
1723 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1725 // Allocate buffer for transmitting message
1726 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1727 if (NStatus != NDIS_STATUS_SUCCESS)
1728 return NStatus;
1730 // Prepare EAPOL frame for MIC calculation
1731 // Be careful, only EAPOL frame is counted for MIC calculation
1732 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1733 Packet.Body_Len[1] + 4, &Packet,
1734 END_OF_ARGS);
1736 // use proprietary PTK
1737 NdisZeroMemory(temp, 64);
1738 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1739 WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1741 // calculate MIC
1742 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1744 // AES
1745 NdisZeroMemory(digest, sizeof(digest));
1746 HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
1747 NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
1749 else
1751 NdisZeroMemory(Mic, sizeof(Mic));
1752 hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1753 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1756 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1757 sizeof(Header802_3), Header802_3,
1758 Packet.Body_Len[1] + 4, &Packet,
1759 END_OF_ARGS);
1761 NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1762 if (NStatus == NDIS_STATUS_SUCCESS)
1764 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1765 STASendPacket(pAd, pNdisPacket);
1766 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1769 MlmeFreeMemory(pAd, pOutBuffer);
1771 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyRequest- Send STAKey request (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1773 return NStatus;
1777 ==========================================================================
1778 Description:
1780 IRQL = DISPATCH_LEVEL
1782 ==========================================================================
1784 NDIS_STATUS RTMPSendSTAKeyHandShake(
1785 IN PRTMP_ADAPTER pAd,
1786 IN PUCHAR pDA)
1788 UCHAR Header802_3[14];
1789 NDIS_STATUS NStatus;
1790 ULONG FrameLen = 0;
1791 EAPOL_PACKET Packet;
1792 UCHAR Mic[16];
1793 UCHAR digest[80];
1794 PUCHAR pOutBuffer = NULL;
1795 PNDIS_PACKET pNdisPacket;
1796 UCHAR temp[64];
1797 UCHAR DlsPTK[80]; // Due to dirver can not get PTK, use proprietary PTK
1799 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]));
1801 pAd->Sequence ++;
1802 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1804 // Zero message body
1805 NdisZeroMemory(&Packet, sizeof(Packet));
1806 Packet.ProVer = EAPOL_VER;
1807 Packet.ProType = EAPOLKey;
1808 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE and Peer MAC address
1810 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1811 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1813 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1815 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1817 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1820 // Key descriptor version
1821 Packet.KeyDesc.KeyInfo.KeyDescVer =
1822 (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1824 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1825 Packet.KeyDesc.KeyInfo.Secure = 1;
1827 Packet.KeyDesc.KeyDataLen[1] = 12;
1829 // use our own OUI to distinguish proprietary with standard.
1830 Packet.KeyDesc.KeyData[0] = 0xDD;
1831 Packet.KeyDesc.KeyData[1] = 0x0A;
1832 Packet.KeyDesc.KeyData[2] = 0x00;
1833 Packet.KeyDesc.KeyData[3] = 0x0C;
1834 Packet.KeyDesc.KeyData[4] = 0x43;
1835 Packet.KeyDesc.KeyData[5] = 0x03;
1836 NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
1838 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1840 // Allocate buffer for transmitting message
1841 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1842 if (NStatus != NDIS_STATUS_SUCCESS)
1843 return NStatus;
1845 // Prepare EAPOL frame for MIC calculation
1846 // Be careful, only EAPOL frame is counted for MIC calculation
1847 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1848 Packet.Body_Len[1] + 4, &Packet,
1849 END_OF_ARGS);
1851 // use proprietary PTK
1852 NdisZeroMemory(temp, 64);
1853 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1854 WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1856 // calculate MIC
1857 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1859 // AES
1860 NdisZeroMemory(digest, sizeof(digest));
1861 HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
1862 NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
1864 else
1866 NdisZeroMemory(Mic, sizeof(Mic));
1867 hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1868 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1871 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1872 sizeof(Header802_3), Header802_3,
1873 Packet.Body_Len[1] + 4, &Packet,
1874 END_OF_ARGS);
1876 NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1877 if (NStatus == NDIS_STATUS_SUCCESS)
1879 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1880 STASendPacket(pAd, pNdisPacket);
1881 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1884 MlmeFreeMemory(pAd, pOutBuffer);
1886 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyHandShake- Send STAKey Message-2 (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1888 return NStatus;
1891 VOID DlsTimeoutAction(
1892 IN PVOID SystemSpecific1,
1893 IN PVOID FunctionContext,
1894 IN PVOID SystemSpecific2,
1895 IN PVOID SystemSpecific3)
1897 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1898 USHORT reason;
1899 PRT_802_11_DLS pDLS = (PRT_802_11_DLS)FunctionContext;
1900 PRTMP_ADAPTER pAd = pDLS->pAd;
1902 DBGPRINT(RT_DEBUG_TRACE, ("DlsTimeout - Tear down DLS links (%02x:%02x:%02x:%02x:%02x:%02x)\n",
1903 pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5]));
1905 if ((pDLS) && (pDLS->Valid))
1907 reason = REASON_QOS_REQUEST_TIMEOUT;
1908 pDLS->Valid = FALSE;
1909 pDLS->Status = DLS_NONE;
1910 DlsParmFill(pAd, &MlmeDlsReq, pDLS, reason);
1911 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1912 RT28XX_MLME_HANDLER(pAd);
1917 ================================================================
1918 Description : because DLS and CLI share the same WCID table in ASIC.
1919 Mesh entry also insert to pAd->MacTab.content[]. Such is marked as ValidAsDls = TRUE.
1920 Also fills the pairwise key.
1921 Because front MAX_AID_BA entries have direct mapping to BAEntry, which is only used as CLI. So we insert Dls
1922 from index MAX_AID_BA.
1923 ================================================================
1925 MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
1926 IN PRTMP_ADAPTER pAd,
1927 IN PUCHAR pAddr,
1928 IN UINT DlsEntryIdx)
1930 PMAC_TABLE_ENTRY pEntry = NULL;
1932 DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableInsertDlsEntry\n"));
1933 // if FULL, return
1934 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
1935 return NULL;
1939 if((pEntry = DlsEntryTableLookup(pAd, pAddr, TRUE)) != NULL)
1940 break;
1942 // allocate one MAC entry
1943 pEntry = MacTableInsertEntry(pAd, pAddr, DlsEntryIdx + MIN_NET_DEVICE_FOR_DLS, TRUE);
1944 if (pEntry)
1946 pAd->StaCfg.DLSEntry[DlsEntryIdx].MacTabMatchWCID = pEntry->Aid;
1947 pEntry->MatchDlsEntryIdx = DlsEntryIdx;
1948 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1949 pEntry->WepStatus = pAd->StaCfg.WepStatus;
1950 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1952 DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertDlsEntry - allocate entry #%d, Total= %d\n",pEntry->Aid, pAd->MacTab.Size));
1954 // If legacy WEP is used, set pair-wise cipherAlg into WCID attribute table for this entry
1955 if ((pEntry->ValidAsDls) && (pEntry->WepStatus == Ndis802_11WEPEnabled))
1957 UCHAR KeyIdx = 0;
1958 UCHAR CipherAlg = 0;
1960 KeyIdx = pAd->StaCfg.DefaultKeyId;
1962 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1964 RTMPAddWcidAttributeEntry(pAd,
1965 BSS0,
1966 pAd->StaCfg.DefaultKeyId,
1967 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1968 pEntry);
1971 break;
1973 } while(FALSE);
1975 DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableInsertDlsEntry\n"));
1977 return pEntry;
1982 ==========================================================================
1983 Description:
1984 Delete all Mesh Entry in pAd->MacTab
1985 ==========================================================================
1987 BOOLEAN MacTableDeleteDlsEntry(
1988 IN PRTMP_ADAPTER pAd,
1989 IN USHORT wcid,
1990 IN PUCHAR pAddr)
1992 DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableDeleteDlsEntry\n"));
1994 if (!VALID_WCID(wcid))
1995 return FALSE;
1997 MacTableDeleteEntry(pAd, wcid, pAddr);
1999 DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableDeleteDlsEntry\n"));
2001 return TRUE;
2004 MAC_TABLE_ENTRY *DlsEntryTableLookup(
2005 IN PRTMP_ADAPTER pAd,
2006 IN PUCHAR pAddr,
2007 IN BOOLEAN bResetIdelCount)
2009 ULONG HashIdx;
2010 MAC_TABLE_ENTRY *pEntry = NULL;
2012 RTMP_SEM_LOCK(&pAd->MacTabLock);
2013 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2014 pEntry = pAd->MacTab.Hash[HashIdx];
2016 while (pEntry)
2018 if ((pEntry->ValidAsDls == TRUE)
2019 && MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2021 if(bResetIdelCount)
2022 pEntry->NoDataIdleCount = 0;
2023 break;
2025 else
2026 pEntry = pEntry->pNext;
2029 RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2030 return pEntry;
2033 MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
2034 IN PRTMP_ADAPTER pAd,
2035 IN UCHAR wcid,
2036 IN PUCHAR pAddr,
2037 IN BOOLEAN bResetIdelCount)
2039 ULONG DLsIndex;
2040 PMAC_TABLE_ENTRY pCurEntry = NULL;
2041 PMAC_TABLE_ENTRY pEntry = NULL;
2043 if (!VALID_WCID(wcid))
2044 return NULL;
2046 RTMP_SEM_LOCK(&pAd->MacTabLock);
2050 pCurEntry = &pAd->MacTab.Content[wcid];
2052 DLsIndex = 0xff;
2053 if ((pCurEntry) && (pCurEntry->ValidAsDls== TRUE))
2055 DLsIndex = pCurEntry->MatchDlsEntryIdx;
2058 if (DLsIndex == 0xff)
2059 break;
2061 if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr))
2063 if(bResetIdelCount)
2064 pCurEntry->NoDataIdleCount = 0;
2065 pEntry = pCurEntry;
2066 break;
2068 } while(FALSE);
2070 RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2072 return pEntry;
2075 INT Set_DlsEntryInfo_Display_Proc(
2076 IN PRTMP_ADAPTER pAd,
2077 IN PUCHAR arg)
2079 INT i;
2081 printk("\n%-19s%-8s\n", "MAC", "TIMEOUT\n");
2082 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
2084 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2086 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[pAd->StaCfg.DLSEntry[i].MacTabMatchWCID];
2088 printk("%02x:%02x:%02x:%02x:%02x:%02x ",
2089 pAd->StaCfg.DLSEntry[i].MacAddr[0], pAd->StaCfg.DLSEntry[i].MacAddr[1], pAd->StaCfg.DLSEntry[i].MacAddr[2],
2090 pAd->StaCfg.DLSEntry[i].MacAddr[3], pAd->StaCfg.DLSEntry[i].MacAddr[4], pAd->StaCfg.DLSEntry[i].MacAddr[5]);
2091 printk("%-8d\n", pAd->StaCfg.DLSEntry[i].TimeOut);
2093 printk("\n");
2094 printk("\n%-19s%-4s%-4s%-4s%-4s%-7s%-7s%-7s","MAC", "AID", "BSS", "PSM", "WMM", "RSSI0", "RSSI1", "RSSI2");
2095 #ifdef DOT11_N_SUPPORT
2096 printk("%-8s%-10s%-6s%-6s%-6s%-6s", "MIMOPS", "PhMd", "BW", "MCS", "SGI", "STBC");
2097 #endif // DOT11_N_SUPPORT //
2098 printk("\n%02X:%02X:%02X:%02X:%02X:%02X ",
2099 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
2100 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
2101 printk("%-4d", (int)pEntry->Aid);
2102 printk("%-4d", (int)pEntry->apidx);
2103 printk("%-4d", (int)pEntry->PsMode);
2104 printk("%-4d", (int)CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE));
2105 printk("%-7d", pEntry->RssiSample.AvgRssi0);
2106 printk("%-7d", pEntry->RssiSample.AvgRssi1);
2107 printk("%-7d", pEntry->RssiSample.AvgRssi2);
2108 #ifdef DOT11_N_SUPPORT
2109 printk("%-8d", (int)pEntry->MmpsMode);
2110 printk("%-10s", GetPhyMode(pEntry->HTPhyMode.field.MODE));
2111 printk("%-6s", GetBW(pEntry->HTPhyMode.field.BW));
2112 printk("%-6d", pEntry->HTPhyMode.field.MCS);
2113 printk("%-6d", pEntry->HTPhyMode.field.ShortGI);
2114 printk("%-6d", pEntry->HTPhyMode.field.STBC);
2115 #endif // DOT11_N_SUPPORT //
2116 printk("%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount,
2117 (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0);
2118 printk("\n");
2123 return TRUE;
2126 INT Set_DlsAddEntry_Proc(
2127 IN PRTMP_ADAPTER pAd,
2128 IN PUCHAR arg)
2130 UCHAR mac[MAC_ADDR_LEN];
2131 USHORT Timeout;
2132 char *token, sepValue[] = ":", DASH = '-';
2133 INT i;
2134 RT_802_11_DLS Dls;
2136 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and timeout value in decimal format.
2137 return FALSE;
2139 token = strchr(arg, DASH);
2140 if ((token != NULL) && (strlen(token)>1))
2142 Timeout = simple_strtol((token+1), 0, 10);
2144 *token = '\0';
2145 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2147 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2148 return FALSE;
2149 AtoH(token, (PUCHAR)(&mac[i]), 1);
2151 if(i != 6)
2152 return FALSE;
2154 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%d", mac[0], mac[1],
2155 mac[2], mac[3], mac[4], mac[5], (int)Timeout);
2157 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2158 Dls.TimeOut = Timeout;
2159 COPY_MAC_ADDR(Dls.MacAddr, mac);
2160 Dls.Valid = 1;
2162 MlmeEnqueue(pAd,
2163 MLME_CNTL_STATE_MACHINE,
2164 RT_OID_802_11_SET_DLS_PARAM,
2165 sizeof(RT_802_11_DLS),
2166 &Dls);
2168 return TRUE;
2171 return FALSE;
2175 INT Set_DlsTearDownEntry_Proc(
2176 IN PRTMP_ADAPTER pAd,
2177 IN PUCHAR arg)
2179 UCHAR macAddr[MAC_ADDR_LEN];
2180 CHAR *value;
2181 INT i;
2182 RT_802_11_DLS Dls;
2184 if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
2185 return FALSE;
2187 for (i=0, value = rstrtok(arg,":"); value; value = rstrtok(NULL,":"))
2189 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
2190 return FALSE; //Invalid
2192 AtoH(value, &macAddr[i++], 2);
2195 printk("\n%02x:%02x:%02x:%02x:%02x:%02x", macAddr[0], macAddr[1],
2196 macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
2198 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2199 COPY_MAC_ADDR(Dls.MacAddr, macAddr);
2200 Dls.Valid = 0;
2202 MlmeEnqueue(pAd,
2203 MLME_CNTL_STATE_MACHINE,
2204 RT_OID_802_11_SET_DLS_PARAM,
2205 sizeof(RT_802_11_DLS),
2206 &Dls);
2208 return TRUE;