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