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