Staging: rt3070: remove dead MULTIPLE_CARD_SUPPORT code
[linux-2.6] / drivers / staging / rt2860 / 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                 AsicAddPairwiseKeyEntry(pAd,
1423                                                                                 pAd->StaCfg.DLSEntry[i].MacAddr,
1424                                                                                 (UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
1425                                                                                 &PairwiseKey);
1426
1427                                 RTMPAddWcidAttributeEntry(pAd,
1428                                                                                   BSS0,
1429                                                                                   0,
1430                                                                                   PairwiseKey.CipherAlg,
1431                                                                                   pEntry);
1432
1433                                 NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
1434                                 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n"));
1435
1436                                 RTMPSendSTAKeyHandShake(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
1437
1438                                 DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Initiator side)\n"));
1439                         }
1440                         else
1441                         {
1442                                 // Data frame, update timeout value
1443                                 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1444                                 {
1445                                         pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1446                                         //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1447                                 }
1448                         }
1449
1450                         bFindEntry = TRUE;
1451                 }
1452         }
1453
1454         // update peer dls table entry
1455         for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1456         {
1457                 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1458                 {
1459                         if (bSTAKeyFrame)
1460                         {
1461                                 PMAC_TABLE_ENTRY pEntry = NULL;
1462
1463                                 // STAKey frame, add pairwise key table, and send STAkey Msg-2
1464                                 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1465                                 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1466
1467                                 PairwiseKey.KeyLen = LEN_TKIP_EK;
1468                                 NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
1469                                 NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
1470                                 NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
1471
1472                                 PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
1473
1474                                 pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1475                                 //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE);     // reserve 0 for multicast, 1 for unicast
1476                                 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1477                                 // Add Pair-wise key to Asic
1478                 AsicAddPairwiseKeyEntry(pAd,
1479                                                                                 pAd->StaCfg.DLSEntry[i].MacAddr,
1480                                                                                 (UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
1481                                                                                 &PairwiseKey);
1482
1483                                 RTMPAddWcidAttributeEntry(pAd,
1484                                                                                   BSS0,
1485                                                                                   0,
1486                                                                                   PairwiseKey.CipherAlg,
1487                                                                                   pEntry);
1488                                 NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
1489                                 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n"));
1490
1491                                 // If support WPA or WPA2, start STAKey hand shake,
1492                                 // If failed hand shake, just tear down peer DLS
1493                                 if (RTMPSendSTAKeyHandShake(pAd, pAddr) != NDIS_STATUS_SUCCESS)
1494                                 {
1495                                         MLME_DLS_REQ_STRUCT     MlmeDlsReq;
1496                                         USHORT                          reason = REASON_QOS_CIPHER_NOT_SUPPORT;
1497
1498                                         pAd->StaCfg.DLSEntry[i].Valid   = FALSE;
1499                                         pAd->StaCfg.DLSEntry[i].Status  = DLS_NONE;
1500                                         DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1501                                         MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1502                                 }
1503                                 else
1504                                 {
1505                                         DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Peer side)\n"));
1506                                 }
1507                         }
1508                         else
1509                         {
1510                                 // Data frame, update timeout value
1511                                 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1512                                 {
1513                                         pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1514                                 }
1515                         }
1516
1517                         bFindEntry = TRUE;
1518                 }
1519         }
1520
1521
1522         return bSTAKeyFrame;
1523 }
1524
1525 /*
1526         ========================================================================
1527
1528         Routine Description:
1529                 Check if the frame can be sent through DLS direct link interface
1530
1531         Arguments:
1532                 pAd             Pointer to adapter
1533
1534         Return Value:
1535                 DLS entry index
1536
1537         Note:
1538
1539         ========================================================================
1540 */
1541 INT     RTMPCheckDLSFrame(
1542         IN      PRTMP_ADAPTER   pAd,
1543         IN  PUCHAR          pDA)
1544 {
1545         INT rval = -1;
1546         INT     i;
1547
1548         if (!pAd->CommonCfg.bDLSCapable)
1549                 return rval;
1550
1551         if (!INFRA_ON(pAd))
1552                 return rval;
1553
1554         do{
1555                 // check local dls table entry
1556                 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1557                 {
1558                         if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1559                                 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1560                         {
1561                                 rval = i;
1562                                 break;
1563                         }
1564                 }
1565
1566                 // check peer dls table entry
1567                 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1568                 {
1569                         if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1570                                 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1571                         {
1572                                 rval = i;
1573                                 break;
1574                         }
1575                 }
1576         } while (FALSE);
1577
1578         return rval;
1579 }
1580
1581 /*
1582     ==========================================================================
1583     Description:
1584
1585         IRQL = DISPATCH_LEVEL
1586
1587     ==========================================================================
1588  */
1589 VOID RTMPSendDLSTearDownFrame(
1590         IN      PRTMP_ADAPTER   pAd,
1591         IN  PUCHAR          pDA)
1592 {
1593         PUCHAR                  pOutBuffer = NULL;
1594         NDIS_STATUS             NStatus;
1595         HEADER_802_11   DlsTearDownHdr;
1596         ULONG                   FrameLen = 0;
1597         USHORT                  Reason = REASON_QOS_QSTA_LEAVING_QBSS;
1598         UCHAR                   Category = CATEGORY_DLS;
1599         UCHAR                   Action = ACTION_DLS_TEARDOWN;
1600         UCHAR                   i = 0;
1601
1602         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
1603                 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
1604                 return;
1605
1606         DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame \n"));
1607
1608         NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
1609         if (NStatus != NDIS_STATUS_SUCCESS)
1610         {
1611                 DBGPRINT(RT_DEBUG_ERROR,("ASSOC - RTMPSendDLSTearDownFrame() allocate memory failed \n"));
1612                 return;
1613         }
1614
1615         ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1616         MakeOutgoingFrame(pOutBuffer,                           &FrameLen,
1617                                         sizeof(HEADER_802_11),          &DlsTearDownHdr,
1618                                         1,                                                      &Category,
1619                                         1,                                                      &Action,
1620                                         6,                                                      pDA,
1621                                         6,                                                      pAd->CurrentAddress,
1622                                         2,                                                      &Reason,
1623                                         END_OF_ARGS);
1624
1625         MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1626         MlmeFreeMemory(pAd, pOutBuffer);
1627
1628         // Remove key in local dls table entry
1629         for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1630         {
1631                 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1632                         && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1633                 {
1634                         MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1635                 }
1636         }
1637
1638         // Remove key in peer dls table entry
1639         for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1640         {
1641                 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1642                         && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1643                 {
1644                         MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1645                 }
1646         }
1647
1648         DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame and remove key in (i=%d) \n", i));
1649 }
1650
1651 /*
1652     ==========================================================================
1653     Description:
1654
1655         IRQL = DISPATCH_LEVEL
1656
1657     ==========================================================================
1658  */
1659 NDIS_STATUS RTMPSendSTAKeyRequest(
1660         IN      PRTMP_ADAPTER   pAd,
1661         IN      PUCHAR                  pDA)
1662 {
1663         UCHAR                           Header802_3[14];
1664         NDIS_STATUS                     NStatus;
1665         ULONG                           FrameLen = 0;
1666         EAPOL_PACKET            Packet;
1667         UCHAR                           Mic[16];
1668         UCHAR                           digest[80];
1669         PUCHAR                          pOutBuffer = NULL;
1670         PNDIS_PACKET            pNdisPacket;
1671         UCHAR                           temp[64];
1672         UCHAR                           DlsPTK[80];
1673
1674         DBGPRINT(RT_DEBUG_TRACE,("DLS - RTMPSendSTAKeyRequest() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5]));
1675
1676         pAd->Sequence ++;
1677         MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1678
1679         // Zero message body
1680         NdisZeroMemory(&Packet, sizeof(Packet));
1681         Packet.ProVer = EAPOL_VER;
1682         Packet.ProType    = EAPOLKey;
1683         Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN;             // data field contain KDE andPeer MAC address
1684
1685         // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1686         if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1687     {
1688         Packet.KeyDesc.Type = WPA1_KEY_DESC;
1689     }
1690     else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1691     {
1692         Packet.KeyDesc.Type = WPA2_KEY_DESC;
1693     }
1694
1695         // Key descriptor version
1696         Packet.KeyDesc.KeyInfo.KeyDescVer =
1697                 (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1698
1699         Packet.KeyDesc.KeyInfo.KeyMic   = 1;
1700         Packet.KeyDesc.KeyInfo.Secure   = 1;
1701         Packet.KeyDesc.KeyInfo.Request  = 1;
1702
1703         Packet.KeyDesc.KeyDataLen[1]    = 12;
1704
1705         // use our own OUI to distinguish proprietary with standard.
1706         Packet.KeyDesc.KeyData[0]               = 0xDD;
1707         Packet.KeyDesc.KeyData[1]               = 0x0A;
1708         Packet.KeyDesc.KeyData[2]               = 0x00;
1709         Packet.KeyDesc.KeyData[3]               = 0x0C;
1710         Packet.KeyDesc.KeyData[4]               = 0x43;
1711         Packet.KeyDesc.KeyData[5]               = 0x03;
1712         NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
1713
1714         NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1715
1716         // Allocate buffer for transmitting message
1717         NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1718         if (NStatus     != NDIS_STATUS_SUCCESS)
1719                 return NStatus;
1720
1721         // Prepare EAPOL frame for MIC calculation
1722         // Be careful, only EAPOL frame is counted for MIC calculation
1723         MakeOutgoingFrame(pOutBuffer,           &FrameLen,
1724                               Packet.Body_Len[1] + 4,    &Packet,
1725                               END_OF_ARGS);
1726
1727         // use proprietary PTK
1728         NdisZeroMemory(temp, 64);
1729         NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1730         WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1731
1732         // calculate MIC
1733         if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1734         {
1735                 // AES
1736                 NdisZeroMemory(digest,  sizeof(digest));
1737                 HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
1738                 NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
1739         }
1740         else
1741         {
1742                 NdisZeroMemory(Mic,     sizeof(Mic));
1743                 hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1744                 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1745         }
1746
1747         MakeOutgoingFrame(pOutBuffer,           &FrameLen,
1748                           sizeof(Header802_3),  Header802_3,
1749                               Packet.Body_Len[1] + 4,   &Packet,
1750                               END_OF_ARGS);
1751
1752         NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1753         if (NStatus == NDIS_STATUS_SUCCESS)
1754         {
1755                 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1756                 STASendPacket(pAd, pNdisPacket);
1757                 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1758         }
1759
1760         MlmeFreeMemory(pAd, pOutBuffer);
1761
1762         DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyRequest- Send STAKey request (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1763
1764         return NStatus;
1765 }
1766
1767 /*
1768     ==========================================================================
1769     Description:
1770
1771         IRQL = DISPATCH_LEVEL
1772
1773     ==========================================================================
1774  */
1775 NDIS_STATUS RTMPSendSTAKeyHandShake(
1776         IN      PRTMP_ADAPTER   pAd,
1777         IN      PUCHAR                  pDA)
1778 {
1779         UCHAR                           Header802_3[14];
1780         NDIS_STATUS                     NStatus;
1781         ULONG                           FrameLen = 0;
1782         EAPOL_PACKET            Packet;
1783         UCHAR                           Mic[16];
1784         UCHAR                           digest[80];
1785         PUCHAR                          pOutBuffer = NULL;
1786         PNDIS_PACKET            pNdisPacket;
1787         UCHAR                           temp[64];
1788         UCHAR                           DlsPTK[80];                     // Due to dirver can not get PTK, use proprietary PTK
1789
1790         DBGPRINT(RT_DEBUG_TRACE,("DLS - RTMPSendSTAKeyHandShake() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5]));
1791
1792         pAd->Sequence ++;
1793         MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1794
1795         // Zero message body
1796         NdisZeroMemory(&Packet, sizeof(Packet));
1797         Packet.ProVer = EAPOL_VER;
1798         Packet.ProType    = EAPOLKey;
1799         Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN;             // data field contain KDE and Peer MAC address
1800
1801         // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1802         if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1803     {
1804         Packet.KeyDesc.Type = WPA1_KEY_DESC;
1805     }
1806     else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1807     {
1808         Packet.KeyDesc.Type = WPA2_KEY_DESC;
1809     }
1810
1811         // Key descriptor version
1812         Packet.KeyDesc.KeyInfo.KeyDescVer =
1813                 (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1814
1815         Packet.KeyDesc.KeyInfo.KeyMic   = 1;
1816         Packet.KeyDesc.KeyInfo.Secure   = 1;
1817
1818         Packet.KeyDesc.KeyDataLen[1]    = 12;
1819
1820         // use our own OUI to distinguish proprietary with standard.
1821         Packet.KeyDesc.KeyData[0]               = 0xDD;
1822         Packet.KeyDesc.KeyData[1]               = 0x0A;
1823         Packet.KeyDesc.KeyData[2]               = 0x00;
1824         Packet.KeyDesc.KeyData[3]               = 0x0C;
1825         Packet.KeyDesc.KeyData[4]               = 0x43;
1826         Packet.KeyDesc.KeyData[5]               = 0x03;
1827         NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
1828
1829         NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1830
1831         // Allocate buffer for transmitting message
1832         NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1833         if (NStatus     != NDIS_STATUS_SUCCESS)
1834                 return NStatus;
1835
1836         // Prepare EAPOL frame for MIC calculation
1837         // Be careful, only EAPOL frame is counted for MIC calculation
1838         MakeOutgoingFrame(pOutBuffer,           &FrameLen,
1839                               Packet.Body_Len[1] + 4,    &Packet,
1840                               END_OF_ARGS);
1841
1842         // use proprietary PTK
1843         NdisZeroMemory(temp, 64);
1844         NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1845         WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1846
1847         // calculate MIC
1848         if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1849         {
1850                 // AES
1851                 NdisZeroMemory(digest,  sizeof(digest));
1852                 HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
1853                 NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
1854         }
1855         else
1856         {
1857                 NdisZeroMemory(Mic,     sizeof(Mic));
1858                 hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1859                 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1860         }
1861
1862         MakeOutgoingFrame(pOutBuffer,           &FrameLen,
1863                           sizeof(Header802_3),  Header802_3,
1864                               Packet.Body_Len[1] + 4,   &Packet,
1865                               END_OF_ARGS);
1866
1867         NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1868         if (NStatus == NDIS_STATUS_SUCCESS)
1869         {
1870                 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1871                 STASendPacket(pAd, pNdisPacket);
1872                 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1873         }
1874
1875         MlmeFreeMemory(pAd, pOutBuffer);
1876
1877         DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyHandShake- Send STAKey Message-2 (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1878
1879         return NStatus;
1880 }
1881
1882 VOID DlsTimeoutAction(
1883         IN PVOID SystemSpecific1,
1884         IN PVOID FunctionContext,
1885         IN PVOID SystemSpecific2,
1886         IN PVOID SystemSpecific3)
1887 {
1888         MLME_DLS_REQ_STRUCT             MlmeDlsReq;
1889         USHORT                                  reason;
1890         PRT_802_11_DLS                  pDLS = (PRT_802_11_DLS)FunctionContext;
1891         PRTMP_ADAPTER                   pAd = pDLS->pAd;
1892
1893         DBGPRINT(RT_DEBUG_TRACE, ("DlsTimeout - Tear down DLS links (%02x:%02x:%02x:%02x:%02x:%02x)\n",
1894                 pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5]));
1895
1896         if ((pDLS) && (pDLS->Valid))
1897         {
1898                 reason                  = REASON_QOS_REQUEST_TIMEOUT;
1899                 pDLS->Valid             = FALSE;
1900                 pDLS->Status    = DLS_NONE;
1901                 DlsParmFill(pAd, &MlmeDlsReq, pDLS, reason);
1902                 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1903                 RT28XX_MLME_HANDLER(pAd);
1904         }
1905 }
1906
1907 /*
1908 ================================================================
1909 Description : because DLS and CLI share the same WCID table in ASIC.
1910 Mesh entry also insert to pAd->MacTab.content[].  Such is marked as ValidAsDls = TRUE.
1911 Also fills the pairwise key.
1912 Because front MAX_AID_BA entries have direct mapping to BAEntry, which is only used as CLI. So we insert Dls
1913 from index MAX_AID_BA.
1914 ================================================================
1915 */
1916 MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
1917         IN  PRTMP_ADAPTER   pAd,
1918         IN  PUCHAR      pAddr,
1919         IN  UINT        DlsEntryIdx)
1920 {
1921         PMAC_TABLE_ENTRY pEntry = NULL;
1922
1923         DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableInsertDlsEntry\n"));
1924         // if FULL, return
1925         if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
1926                 return NULL;
1927
1928         do
1929         {
1930                 if((pEntry = DlsEntryTableLookup(pAd, pAddr, TRUE)) != NULL)
1931                         break;
1932
1933                 // allocate one MAC entry
1934                 pEntry = MacTableInsertEntry(pAd, pAddr, DlsEntryIdx + MIN_NET_DEVICE_FOR_DLS, TRUE);
1935                 if (pEntry)
1936                 {
1937                         pAd->StaCfg.DLSEntry[DlsEntryIdx].MacTabMatchWCID = pEntry->Aid;
1938                         pEntry->MatchDlsEntryIdx = DlsEntryIdx;
1939                         pEntry->AuthMode = pAd->StaCfg.AuthMode;
1940                         pEntry->WepStatus = pAd->StaCfg.WepStatus;
1941                         pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1942
1943                         DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertDlsEntry - allocate entry #%d, Total= %d\n",pEntry->Aid, pAd->MacTab.Size));
1944
1945                         // If legacy WEP is used, set pair-wise cipherAlg into WCID attribute table for this entry
1946                         if ((pEntry->ValidAsDls) && (pEntry->WepStatus == Ndis802_11WEPEnabled))
1947                         {
1948                                 UCHAR KeyIdx = 0;
1949                                 UCHAR CipherAlg = 0;
1950
1951                                 KeyIdx  = pAd->StaCfg.DefaultKeyId;
1952
1953                                 CipherAlg       = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1954
1955                                 RTMPAddWcidAttributeEntry(pAd,
1956                                                                                         BSS0,
1957                                                                                         pAd->StaCfg.DefaultKeyId,
1958                                                                                         pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1959                                                                                         pEntry);
1960                         }
1961
1962                         break;
1963                 }
1964         } while(FALSE);
1965
1966         DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableInsertDlsEntry\n"));
1967
1968         return pEntry;
1969 }
1970
1971
1972 /*
1973         ==========================================================================
1974         Description:
1975                 Delete all Mesh Entry in pAd->MacTab
1976         ==========================================================================
1977  */
1978 BOOLEAN MacTableDeleteDlsEntry(
1979         IN PRTMP_ADAPTER pAd,
1980         IN USHORT wcid,
1981         IN PUCHAR pAddr)
1982 {
1983         DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableDeleteDlsEntry\n"));
1984
1985         if (!VALID_WCID(wcid))
1986                 return FALSE;
1987
1988         MacTableDeleteEntry(pAd, wcid, pAddr);
1989
1990         DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableDeleteDlsEntry\n"));
1991
1992         return TRUE;
1993 }
1994
1995 MAC_TABLE_ENTRY *DlsEntryTableLookup(
1996         IN PRTMP_ADAPTER pAd,
1997         IN PUCHAR       pAddr,
1998         IN BOOLEAN      bResetIdelCount)
1999 {
2000         ULONG HashIdx;
2001         MAC_TABLE_ENTRY *pEntry = NULL;
2002
2003         RTMP_SEM_LOCK(&pAd->MacTabLock);
2004         HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2005         pEntry = pAd->MacTab.Hash[HashIdx];
2006
2007         while (pEntry)
2008         {
2009                 if ((pEntry->ValidAsDls == TRUE)
2010                         && MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2011                 {
2012                         if(bResetIdelCount)
2013                                 pEntry->NoDataIdleCount = 0;
2014                         break;
2015                 }
2016                 else
2017                         pEntry = pEntry->pNext;
2018         }
2019
2020         RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2021         return pEntry;
2022 }
2023
2024 MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
2025         IN PRTMP_ADAPTER pAd,
2026         IN UCHAR        wcid,
2027         IN PUCHAR       pAddr,
2028         IN BOOLEAN      bResetIdelCount)
2029 {
2030         ULONG DLsIndex;
2031         PMAC_TABLE_ENTRY pCurEntry = NULL;
2032         PMAC_TABLE_ENTRY pEntry = NULL;
2033
2034         if (!VALID_WCID(wcid))
2035                 return NULL;
2036
2037         RTMP_SEM_LOCK(&pAd->MacTabLock);
2038
2039         do
2040         {
2041                 pCurEntry = &pAd->MacTab.Content[wcid];
2042
2043                 DLsIndex = 0xff;
2044                 if ((pCurEntry) && (pCurEntry->ValidAsDls== TRUE))
2045                 {
2046                         DLsIndex = pCurEntry->MatchDlsEntryIdx;
2047                 }
2048
2049                 if (DLsIndex == 0xff)
2050                         break;
2051
2052                 if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr))
2053                 {
2054                         if(bResetIdelCount)
2055                                 pCurEntry->NoDataIdleCount = 0;
2056                         pEntry = pCurEntry;
2057                         break;
2058                 }
2059         } while(FALSE);
2060
2061         RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2062
2063         return pEntry;
2064 }
2065
2066 INT Set_DlsEntryInfo_Display_Proc(
2067         IN PRTMP_ADAPTER pAd,
2068         IN PUCHAR arg)
2069 {
2070         INT i;
2071
2072         printk("\n%-19s%-8s\n", "MAC", "TIMEOUT\n");
2073         for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
2074         {
2075                 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2076                 {
2077                         PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[pAd->StaCfg.DLSEntry[i].MacTabMatchWCID];
2078
2079                         printk("%02x:%02x:%02x:%02x:%02x:%02x  ",
2080                                 pAd->StaCfg.DLSEntry[i].MacAddr[0], pAd->StaCfg.DLSEntry[i].MacAddr[1], pAd->StaCfg.DLSEntry[i].MacAddr[2],
2081                                 pAd->StaCfg.DLSEntry[i].MacAddr[3], pAd->StaCfg.DLSEntry[i].MacAddr[4], pAd->StaCfg.DLSEntry[i].MacAddr[5]);
2082                         printk("%-8d\n", pAd->StaCfg.DLSEntry[i].TimeOut);
2083
2084                         printk("\n");
2085                         printk("\n%-19s%-4s%-4s%-4s%-4s%-8s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n",
2086                                    "MAC", "AID", "BSS", "PSM", "WMM", "MIMOPS", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC");
2087                         printk("%02X:%02X:%02X:%02X:%02X:%02X  ",
2088                                 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
2089                                 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
2090                         printk("%-4d", (int)pEntry->Aid);
2091                         printk("%-4d", (int)pEntry->apidx);
2092                         printk("%-4d", (int)pEntry->PsMode);
2093                         printk("%-4d", (int)CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE));
2094                         printk("%-8d", (int)pEntry->MmpsMode);
2095                         printk("%-7d", pEntry->RssiSample.AvgRssi0);
2096                         printk("%-7d", pEntry->RssiSample.AvgRssi1);
2097                         printk("%-7d", pEntry->RssiSample.AvgRssi2);
2098                         printk("%-10s", GetPhyMode(pEntry->HTPhyMode.field.MODE));
2099                         printk("%-6s", GetBW(pEntry->HTPhyMode.field.BW));
2100                         printk("%-6d", pEntry->HTPhyMode.field.MCS);
2101                         printk("%-6d", pEntry->HTPhyMode.field.ShortGI);
2102                         printk("%-6d", pEntry->HTPhyMode.field.STBC);
2103                         printk("%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount,
2104                                                 (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0);
2105                         printk("\n");
2106
2107                 }
2108         }
2109
2110         return TRUE;
2111 }
2112
2113 INT     Set_DlsAddEntry_Proc(
2114         IN      PRTMP_ADAPTER   pAd,
2115         IN      PUCHAR                  arg)
2116 {
2117     UCHAR       mac[MAC_ADDR_LEN];
2118         USHORT  Timeout;
2119         char *token, sepValue[] = ":", DASH = '-';
2120         INT i;
2121     RT_802_11_DLS       Dls;
2122
2123     if(strlen(arg) < 19)  //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and timeout value in decimal format.
2124                 return FALSE;
2125
2126         token = strchr(arg, DASH);
2127         if ((token != NULL) && (strlen(token)>1))
2128         {
2129                 Timeout = simple_strtol((token+1), 0, 10);
2130
2131                 *token = '\0';
2132                 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2133                 {
2134                         if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2135                                 return FALSE;
2136                         AtoH(token, (PUCHAR)(&mac[i]), 1);
2137                 }
2138                 if(i != 6)
2139                         return FALSE;
2140
2141             printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%d", mac[0], mac[1],
2142                    mac[2], mac[3], mac[4], mac[5], (int)Timeout);
2143
2144                 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2145                 Dls.TimeOut = Timeout;
2146                 COPY_MAC_ADDR(Dls.MacAddr, mac);
2147                 Dls.Valid = 1;
2148
2149                 MlmeEnqueue(pAd,
2150                                         MLME_CNTL_STATE_MACHINE,
2151                                         RT_OID_802_11_SET_DLS_PARAM,
2152                                         sizeof(RT_802_11_DLS),
2153                                         &Dls);
2154
2155                 return TRUE;
2156         }
2157
2158         return FALSE;
2159
2160 }
2161
2162 INT     Set_DlsTearDownEntry_Proc(
2163         IN      PRTMP_ADAPTER   pAd,
2164         IN      PUCHAR                  arg)
2165 {
2166         UCHAR                   macAddr[MAC_ADDR_LEN];
2167         CHAR                    *value;
2168         INT                             i;
2169         RT_802_11_DLS   Dls;
2170
2171         if(strlen(arg) != 17)  //Mac address acceptable format 01:02:03:04:05:06 length 17
2172                 return FALSE;
2173
2174         for (i=0, value = rstrtok(arg,":"); value; value = rstrtok(NULL,":"))
2175         {
2176                 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
2177                         return FALSE;  //Invalid
2178
2179                 AtoH(value, &macAddr[i++], 2);
2180         }
2181
2182         printk("\n%02x:%02x:%02x:%02x:%02x:%02x", macAddr[0], macAddr[1],
2183                    macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
2184
2185         NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2186         COPY_MAC_ADDR(Dls.MacAddr, macAddr);
2187         Dls.Valid = 0;
2188
2189         MlmeEnqueue(pAd,
2190                                 MLME_CNTL_STATE_MACHINE,
2191                                 RT_OID_802_11_SET_DLS_PARAM,
2192                                 sizeof(RT_802_11_DLS),
2193                                 &Dls);
2194
2195         return TRUE;
2196 }
2197