2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 *************************************************************************
31 Handle WMM-DLS state machine
35 -------- ---------- ----------------------------------------------
37 Arvin Tai 06-03-2008 Modified for RT28xx
40 #include "../rt_config.h"
43 ==========================================================================
45 dls state machine init, including state transition and timer init
47 Sm - pointer to the dls state machine
49 The state machine looks like this
52 MT2_MLME_DLS_REQUEST MlmeDlsReqAction
53 MT2_PEER_DLS_REQUEST PeerDlsReqAction
54 MT2_PEER_DLS_RESPONSE PeerDlsRspAction
55 MT2_MLME_DLS_TEARDOWN MlmeTearDownAction
56 MT2_PEER_DLS_TEARDOWN PeerTearDownAction
60 ==========================================================================
62 void DlsStateMachineInit(
65 OUT STATE_MACHINE_FUNC Trans
[])
69 StateMachineInit(Sm
, (STATE_MACHINE_FUNC
*)Trans
, MAX_DLS_STATE
, MAX_DLS_MSG
, (STATE_MACHINE_FUNC
)Drop
, DLS_IDLE
, DLS_MACHINE_BASE
);
72 StateMachineSetAction(Sm
, DLS_IDLE
, MT2_MLME_DLS_REQ
, (STATE_MACHINE_FUNC
)MlmeDlsReqAction
);
73 StateMachineSetAction(Sm
, DLS_IDLE
, MT2_PEER_DLS_REQ
, (STATE_MACHINE_FUNC
)PeerDlsReqAction
);
74 StateMachineSetAction(Sm
, DLS_IDLE
, MT2_PEER_DLS_RSP
, (STATE_MACHINE_FUNC
)PeerDlsRspAction
);
75 StateMachineSetAction(Sm
, DLS_IDLE
, MT2_MLME_DLS_TEAR_DOWN
, (STATE_MACHINE_FUNC
)MlmeDlsTearDownAction
);
76 StateMachineSetAction(Sm
, DLS_IDLE
, MT2_PEER_DLS_TEAR_DOWN
, (STATE_MACHINE_FUNC
)PeerDlsTearDownAction
);
78 for (i
=0; i
<MAX_NUM_OF_DLS_ENTRY
; i
++)
80 pAd
->StaCfg
.DLSEntry
[i
].pAd
= pAd
;
81 RTMPInitTimer(pAd
, &pAd
->StaCfg
.DLSEntry
[i
].Timer
, GET_TIMER_FUNCTION(DlsTimeoutAction
), pAd
, FALSE
);
86 ==========================================================================
91 ==========================================================================
93 VOID
MlmeDlsReqAction(
95 IN MLME_QUEUE_ELEM
*Elem
)
97 PUCHAR pOutBuffer
= NULL
;
100 HEADER_802_11 DlsReqHdr
;
101 PRT_802_11_DLS pDLS
= NULL
;
102 UCHAR Category
= CATEGORY_DLS
;
103 UCHAR Action
= ACTION_DLS_REQUEST
;
107 BOOLEAN TimerCancelled
;
109 if(!MlmeDlsReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &pDLS
, &reason
))
112 DBGPRINT(RT_DEBUG_TRACE
,("DLS - MlmeDlsReqAction() \n"));
114 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
115 if (NStatus
!= NDIS_STATUS_SUCCESS
)
117 DBGPRINT(RT_DEBUG_ERROR
,("DLS - MlmeDlsReqAction() allocate memory failed \n"));
121 ActHeaderInit(pAd
, &DlsReqHdr
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
123 // Build basic frame first
124 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
125 sizeof(HEADER_802_11
), &DlsReqHdr
,
129 6, pAd
->CurrentAddress
,
130 2, &pAd
->StaActive
.CapabilityInfo
,
133 1, &pAd
->MlmeAux
.SupRateLen
,
134 pAd
->MlmeAux
.SupRateLen
, pAd
->MlmeAux
.SupRate
,
137 if (pAd
->MlmeAux
.ExtRateLen
!= 0)
139 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
141 1, &pAd
->MlmeAux
.ExtRateLen
,
142 pAd
->MlmeAux
.ExtRateLen
, pAd
->MlmeAux
.ExtRate
,
147 #ifdef DOT11_N_SUPPORT
148 if ((pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
))
153 HT_CAPABILITY_IE HtCapabilityTmp
;
156 // add HT Capability IE
157 HtLen
= sizeof(HT_CAPABILITY_IE
);
158 #ifndef RT_BIG_ENDIAN
159 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
162 HtLen
, &pAd
->CommonCfg
.HtCapability
,
165 NdisMoveMemory(&HtCapabilityTmp
, &pAd
->CommonCfg
.HtCapability
, HtLen
);
166 *(USHORT
*)(&HtCapabilityTmp
.HtCapInfo
) = SWAP16(*(USHORT
*)(&HtCapabilityTmp
.HtCapInfo
));
167 *(USHORT
*)(&HtCapabilityTmp
.ExtHtCapInfo
) = SWAP16(*(USHORT
*)(&HtCapabilityTmp
.ExtHtCapInfo
));
169 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
172 HtLen
, &HtCapabilityTmp
,
175 FrameLen
= FrameLen
+ tmp
;
177 #endif // DOT11_N_SUPPORT //
179 RTMPCancelTimer(&pDLS
->Timer
, &TimerCancelled
);
180 Timeout
= DLS_TIMEOUT
;
181 RTMPSetTimer(&pDLS
->Timer
, Timeout
);
183 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
);
184 MlmeFreeMemory(pAd
, pOutBuffer
);
188 ==========================================================================
191 IRQL = DISPATCH_LEVEL
193 ==========================================================================
195 VOID
PeerDlsReqAction(
196 IN PRTMP_ADAPTER pAd
,
197 IN MLME_QUEUE_ELEM
*Elem
)
199 PUCHAR pOutBuffer
= NULL
;
202 USHORT StatusCode
= MLME_SUCCESS
;
203 HEADER_802_11 DlsRspHdr
;
204 UCHAR Category
= CATEGORY_DLS
;
205 UCHAR Action
= ACTION_DLS_RESPONSE
;
207 USHORT CapabilityInfo
;
208 UCHAR DA
[MAC_ADDR_LEN
], SA
[MAC_ADDR_LEN
];
212 BOOLEAN TimerCancelled
;
213 PRT_802_11_DLS pDLS
= NULL
;
214 UCHAR MaxSupportedRateIn500Kbps
= 0;
215 UCHAR SupportedRatesLen
;
216 UCHAR SupportedRates
[MAX_LEN_OF_SUPPORTED_RATES
];
217 UCHAR HtCapabilityLen
;
218 HT_CAPABILITY_IE HtCapability
;
220 if (!PeerDlsReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, DA
, SA
, &CapabilityInfo
, &DLSTimeOut
,
221 &SupportedRatesLen
, &SupportedRates
[0], &HtCapabilityLen
, &HtCapability
))
224 // supported rates array may not be sorted. sort it and find the maximum rate
225 for (i
= 0; i
< SupportedRatesLen
; i
++)
227 if (MaxSupportedRateIn500Kbps
< (SupportedRates
[i
] & 0x7f))
228 MaxSupportedRateIn500Kbps
= SupportedRates
[i
] & 0x7f;
231 DBGPRINT(RT_DEBUG_TRACE
,("DLS - PeerDlsReqAction() from %02x:%02x:%02x:%02x:%02x:%02x\n", SA
[0], SA
[1], SA
[2], SA
[3], SA
[4], SA
[5]));
233 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
234 if (NStatus
!= NDIS_STATUS_SUCCESS
)
236 DBGPRINT(RT_DEBUG_ERROR
,("DLS - PeerDlsReqAction() allocate memory failed \n"));
242 StatusCode
= MLME_REQUEST_DECLINED
;
244 else if (!pAd
->CommonCfg
.bWmmCapable
)
246 StatusCode
= MLME_DEST_STA_IS_NOT_A_QSTA
;
248 else if (!pAd
->CommonCfg
.bDLSCapable
)
250 StatusCode
= MLME_REQUEST_DECLINED
;
254 // find table to update parameters
255 for (i
= (MAX_NUM_OF_DLS_ENTRY
-1); i
>= 0; i
--)
257 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& MAC_ADDR_EQUAL(SA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
259 if (pAd
->StaCfg
.AuthMode
>= Ndis802_11AuthModeWPA
)
260 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_WAIT_KEY
;
263 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
264 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_FINISH
;
267 pAd
->StaCfg
.DLSEntry
[i
].Sequence
= 0;
268 pAd
->StaCfg
.DLSEntry
[i
].TimeOut
= DLSTimeOut
;
269 pAd
->StaCfg
.DLSEntry
[i
].CountDownTimer
= DLSTimeOut
;
270 if (HtCapabilityLen
!= 0)
271 pAd
->StaCfg
.DLSEntry
[i
].bHTCap
= TRUE
;
273 pAd
->StaCfg
.DLSEntry
[i
].bHTCap
= FALSE
;
274 pDLS
= &pAd
->StaCfg
.DLSEntry
[i
];
279 // can not find in table, create a new one
282 DBGPRINT(RT_DEBUG_TRACE
,("DLS - PeerDlsReqAction() can not find same entry \n"));
283 for (i
=(MAX_NUM_OF_DLS_ENTRY
- 1); i
>= MAX_NUM_OF_INIT_DLS_ENTRY
; i
--)
285 if (!pAd
->StaCfg
.DLSEntry
[i
].Valid
)
287 MAC_TABLE_ENTRY
*pEntry
;
288 UCHAR MaxSupportedRate
= RATE_11
;
290 if (pAd
->StaCfg
.AuthMode
>= Ndis802_11AuthModeWPA
)
292 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_WAIT_KEY
;
296 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
297 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_FINISH
;
300 pAd
->StaCfg
.DLSEntry
[i
].Sequence
= 0;
301 pAd
->StaCfg
.DLSEntry
[i
].Valid
= TRUE
;
302 pAd
->StaCfg
.DLSEntry
[i
].TimeOut
= DLSTimeOut
;
303 pAd
->StaCfg
.DLSEntry
[i
].CountDownTimer
= DLSTimeOut
;
304 NdisMoveMemory(pAd
->StaCfg
.DLSEntry
[i
].MacAddr
, SA
, MAC_ADDR_LEN
);
305 if (HtCapabilityLen
!= 0)
306 pAd
->StaCfg
.DLSEntry
[i
].bHTCap
= TRUE
;
308 pAd
->StaCfg
.DLSEntry
[i
].bHTCap
= FALSE
;
309 pDLS
= &pAd
->StaCfg
.DLSEntry
[i
];
310 pEntry
= MacTableInsertDlsEntry(pAd
, SA
, i
);
312 switch (MaxSupportedRateIn500Kbps
)
314 case 108: MaxSupportedRate
= RATE_54
; break;
315 case 96: MaxSupportedRate
= RATE_48
; break;
316 case 72: MaxSupportedRate
= RATE_36
; break;
317 case 48: MaxSupportedRate
= RATE_24
; break;
318 case 36: MaxSupportedRate
= RATE_18
; break;
319 case 24: MaxSupportedRate
= RATE_12
; break;
320 case 18: MaxSupportedRate
= RATE_9
; break;
321 case 12: MaxSupportedRate
= RATE_6
; break;
322 case 22: MaxSupportedRate
= RATE_11
; break;
323 case 11: MaxSupportedRate
= RATE_5_5
; break;
324 case 4: MaxSupportedRate
= RATE_2
; break;
325 case 2: MaxSupportedRate
= RATE_1
; break;
326 default: MaxSupportedRate
= RATE_11
; break;
329 pEntry
->MaxSupportedRate
= min(pAd
->CommonCfg
.MaxTxRate
, MaxSupportedRate
);
331 if (pEntry
->MaxSupportedRate
< RATE_FIRST_OFDM_RATE
)
333 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_CCK
;
334 pEntry
->MaxHTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
335 pEntry
->MinHTPhyMode
.field
.MODE
= MODE_CCK
;
336 pEntry
->MinHTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
337 pEntry
->HTPhyMode
.field
.MODE
= MODE_CCK
;
338 pEntry
->HTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
342 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_OFDM
;
343 pEntry
->MaxHTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
344 pEntry
->MinHTPhyMode
.field
.MODE
= MODE_OFDM
;
345 pEntry
->MinHTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
346 pEntry
->HTPhyMode
.field
.MODE
= MODE_OFDM
;
347 pEntry
->HTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
350 pEntry
->MaxHTPhyMode
.field
.BW
= BW_20
;
351 pEntry
->MinHTPhyMode
.field
.BW
= BW_20
;
353 #ifdef DOT11_N_SUPPORT
354 pEntry
->HTCapability
.MCSSet
[0] = 0;
355 pEntry
->HTCapability
.MCSSet
[1] = 0;
357 // If this Entry supports 802.11n, upgrade to HT rate.
358 if ((HtCapabilityLen
!= 0) && (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
))
360 UCHAR j
, bitmask
; //k,bitmask;
363 DBGPRINT(RT_DEBUG_OFF
, ("DLS - PeerDlsReqAction() Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
364 SA
[0], SA
[1], SA
[2], SA
[3], SA
[4], SA
[5]));
366 if ((HtCapability
.HtCapInfo
.GF
) && (pAd
->CommonCfg
.DesiredHtPhy
.GF
))
368 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTGREENFIELD
;
372 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTMIX
;
373 pAd
->MacTab
.fAnyStationNonGF
= TRUE
;
374 pAd
->CommonCfg
.AddHTInfo
.AddHtInfo2
.NonGfPresent
= 1;
377 if ((HtCapability
.HtCapInfo
.ChannelWidth
) && (pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
))
379 pEntry
->MaxHTPhyMode
.field
.BW
= BW_40
;
380 pEntry
->MaxHTPhyMode
.field
.ShortGI
= ((pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor40
)&(HtCapability
.HtCapInfo
.ShortGIfor40
));
384 pEntry
->MaxHTPhyMode
.field
.BW
= BW_20
;
385 pEntry
->MaxHTPhyMode
.field
.ShortGI
= ((pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor20
)&(HtCapability
.HtCapInfo
.ShortGIfor20
));
386 pAd
->MacTab
.fAnyStation20Only
= TRUE
;
389 // find max fixed rate
390 for (ii
=15; ii
>=0; ii
--)
393 bitmask
= (1<<(ii
-(j
*8)));
394 if ( (pAd
->StaCfg
.DesiredHtPhyInfo
.MCSSet
[j
]&bitmask
) && (HtCapability
.MCSSet
[j
]&bitmask
))
396 pEntry
->MaxHTPhyMode
.field
.MCS
= ii
;
404 if (pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
!= MCS_AUTO
)
407 printk("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
408 pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
);
409 if (pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
== 32)
411 // Fix MCS as HT Duplicated Mode
412 pEntry
->MaxHTPhyMode
.field
.BW
= 1;
413 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTMIX
;
414 pEntry
->MaxHTPhyMode
.field
.STBC
= 0;
415 pEntry
->MaxHTPhyMode
.field
.ShortGI
= 0;
416 pEntry
->MaxHTPhyMode
.field
.MCS
= 32;
418 else if (pEntry
->MaxHTPhyMode
.field
.MCS
> pAd
->StaCfg
.HTPhyMode
.field
.MCS
)
420 // STA supports fixed MCS
421 pEntry
->MaxHTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
425 pEntry
->MaxHTPhyMode
.field
.STBC
= (HtCapability
.HtCapInfo
.RxSTBC
& (pAd
->CommonCfg
.DesiredHtPhy
.TxSTBC
));
426 pEntry
->MpduDensity
= HtCapability
.HtCapParm
.MpduDensity
;
427 pEntry
->MaxRAmpduFactor
= HtCapability
.HtCapParm
.MaxRAmpduFactor
;
428 pEntry
->MmpsMode
= (UCHAR
)HtCapability
.HtCapInfo
.MimoPs
;
429 pEntry
->AMsduSize
= (UCHAR
)HtCapability
.HtCapInfo
.AMsduSize
;
430 pEntry
->HTPhyMode
.word
= pEntry
->MaxHTPhyMode
.word
;
432 if (HtCapability
.HtCapInfo
.ShortGIfor20
)
433 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_SGI20_CAPABLE
);
434 if (HtCapability
.HtCapInfo
.ShortGIfor40
)
435 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_SGI40_CAPABLE
);
436 if (HtCapability
.HtCapInfo
.TxSTBC
)
437 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_TxSTBC_CAPABLE
);
438 if (HtCapability
.HtCapInfo
.RxSTBC
)
439 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_RxSTBC_CAPABLE
);
440 if (HtCapability
.ExtHtCapInfo
.PlusHTC
)
441 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_HTC_CAPABLE
);
442 if (pAd
->CommonCfg
.bRdg
&& HtCapability
.ExtHtCapInfo
.RDGSupport
)
443 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_RDG_CAPABLE
);
444 if (HtCapability
.ExtHtCapInfo
.MCSFeedback
== 0x03)
445 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE
);
447 NdisMoveMemory(&pEntry
->HTCapability
, &HtCapability
, sizeof(HT_CAPABILITY_IE
));
449 #endif // DOT11_N_SUPPORT //
451 pEntry
->HTPhyMode
.word
= pEntry
->MaxHTPhyMode
.word
;
452 pEntry
->CurrTxRate
= pEntry
->MaxSupportedRate
;
453 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_WMM_CAPABLE
);
455 if (pAd
->StaCfg
.bAutoTxRateSwitch
== TRUE
)
460 MlmeSelectTxRateTable(pAd
, pEntry
, &pTable
, &TableSize
, &pEntry
->CurrTxRateIndex
);
461 pEntry
->bAutoTxRateSwitch
= TRUE
;
465 pEntry
->HTPhyMode
.field
.MODE
= pAd
->StaCfg
.HTPhyMode
.field
.MODE
;
466 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
467 pEntry
->bAutoTxRateSwitch
= FALSE
;
469 RTMPUpdateLegacyTxSetting((UCHAR
)pAd
->StaCfg
.DesiredTransmitSetting
.field
.FixedTxMode
, pEntry
);
471 pEntry
->RateLen
= SupportedRatesLen
;
477 StatusCode
= MLME_SUCCESS
;
479 // can not find in table, create a new one
482 StatusCode
= MLME_QOS_UNSPECIFY
;
483 DBGPRINT(RT_DEBUG_ERROR
,("DLS - PeerDlsReqAction() DLSEntry table full(only can support %d DLS session) \n", MAX_NUM_OF_DLS_ENTRY
- MAX_NUM_OF_INIT_DLS_ENTRY
));
487 DBGPRINT(RT_DEBUG_TRACE
,("DLS - PeerDlsReqAction() use entry(%d) %02x:%02x:%02x:%02x:%02x:%02x\n",
488 i
, SA
[0], SA
[1], SA
[2], SA
[3], SA
[4], SA
[5]));
492 ActHeaderInit(pAd
, &DlsRspHdr
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
494 // Build basic frame first
495 if (StatusCode
== MLME_SUCCESS
)
497 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
498 sizeof(HEADER_802_11
), &DlsRspHdr
,
503 6, pAd
->CurrentAddress
,
504 2, &pAd
->StaActive
.CapabilityInfo
,
506 1, &pAd
->MlmeAux
.SupRateLen
,
507 pAd
->MlmeAux
.SupRateLen
, pAd
->MlmeAux
.SupRate
,
510 if (pAd
->MlmeAux
.ExtRateLen
!= 0)
512 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
514 1, &pAd
->MlmeAux
.ExtRateLen
,
515 pAd
->MlmeAux
.ExtRateLen
, pAd
->MlmeAux
.ExtRate
,
520 #ifdef DOT11_N_SUPPORT
521 if ((pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
))
526 HT_CAPABILITY_IE HtCapabilityTmp
;
529 // add HT Capability IE
530 HtLen
= sizeof(HT_CAPABILITY_IE
);
531 #ifndef RT_BIG_ENDIAN
532 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
535 HtLen
, &pAd
->CommonCfg
.HtCapability
,
538 NdisMoveMemory(&HtCapabilityTmp
, &pAd
->CommonCfg
.HtCapability
, HtLen
);
539 *(USHORT
*)(&HtCapabilityTmp
.HtCapInfo
) = SWAP16(*(USHORT
*)(&HtCapabilityTmp
.HtCapInfo
));
540 *(USHORT
*)(&HtCapabilityTmp
.ExtHtCapInfo
) = SWAP16(*(USHORT
*)(&HtCapabilityTmp
.ExtHtCapInfo
));
542 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
545 HtLen
, &HtCapabilityTmp
,
548 FrameLen
= FrameLen
+ tmp
;
550 #endif // DOT11_N_SUPPORT //
552 if (pDLS
&& (pDLS
->Status
!= DLS_FINISH
))
554 RTMPCancelTimer(&pDLS
->Timer
, &TimerCancelled
);
555 Timeout
= DLS_TIMEOUT
;
556 RTMPSetTimer(&pDLS
->Timer
, Timeout
);
561 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
562 sizeof(HEADER_802_11
), &DlsRspHdr
,
567 6, pAd
->CurrentAddress
,
571 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
);
572 MlmeFreeMemory(pAd
, pOutBuffer
);
576 ==========================================================================
579 IRQL = DISPATCH_LEVEL
581 ==========================================================================
583 VOID
PeerDlsRspAction(
584 IN PRTMP_ADAPTER pAd
,
585 IN MLME_QUEUE_ELEM
*Elem
)
587 USHORT CapabilityInfo
;
588 UCHAR DA
[MAC_ADDR_LEN
], SA
[MAC_ADDR_LEN
];
591 BOOLEAN TimerCancelled
;
592 UCHAR MaxSupportedRateIn500Kbps
= 0;
593 UCHAR SupportedRatesLen
;
594 UCHAR SupportedRates
[MAX_LEN_OF_SUPPORTED_RATES
];
595 UCHAR HtCapabilityLen
;
596 HT_CAPABILITY_IE HtCapability
;
598 if (!pAd
->CommonCfg
.bDLSCapable
)
604 if (!PeerDlsRspSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, DA
, SA
, &CapabilityInfo
, &StatusCode
,
605 &SupportedRatesLen
, &SupportedRates
[0], &HtCapabilityLen
, &HtCapability
))
608 // supported rates array may not be sorted. sort it and find the maximum rate
609 for (i
=0; i
<SupportedRatesLen
; i
++)
611 if (MaxSupportedRateIn500Kbps
< (SupportedRates
[i
] & 0x7f))
612 MaxSupportedRateIn500Kbps
= SupportedRates
[i
] & 0x7f;
615 DBGPRINT(RT_DEBUG_TRACE
,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x with StatusCode=%d, CapabilityInfo=0x%x\n",
616 SA
[0], SA
[1], SA
[2], SA
[3], SA
[4], SA
[5], StatusCode
, CapabilityInfo
));
618 for (i
= 0; i
< MAX_NUM_OF_INIT_DLS_ENTRY
; i
++)
620 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& MAC_ADDR_EQUAL(SA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
622 if (StatusCode
== MLME_SUCCESS
)
624 MAC_TABLE_ENTRY
*pEntry
;
625 UCHAR MaxSupportedRate
= RATE_11
;
627 pEntry
= MacTableInsertDlsEntry(pAd
, SA
, i
);
629 switch (MaxSupportedRateIn500Kbps
)
631 case 108: MaxSupportedRate
= RATE_54
; break;
632 case 96: MaxSupportedRate
= RATE_48
; break;
633 case 72: MaxSupportedRate
= RATE_36
; break;
634 case 48: MaxSupportedRate
= RATE_24
; break;
635 case 36: MaxSupportedRate
= RATE_18
; break;
636 case 24: MaxSupportedRate
= RATE_12
; break;
637 case 18: MaxSupportedRate
= RATE_9
; break;
638 case 12: MaxSupportedRate
= RATE_6
; break;
639 case 22: MaxSupportedRate
= RATE_11
; break;
640 case 11: MaxSupportedRate
= RATE_5_5
; break;
641 case 4: MaxSupportedRate
= RATE_2
; break;
642 case 2: MaxSupportedRate
= RATE_1
; break;
643 default: MaxSupportedRate
= RATE_11
; break;
646 pEntry
->MaxSupportedRate
= min(pAd
->CommonCfg
.MaxTxRate
, MaxSupportedRate
);
648 if (pEntry
->MaxSupportedRate
< RATE_FIRST_OFDM_RATE
)
650 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_CCK
;
651 pEntry
->MaxHTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
652 pEntry
->MinHTPhyMode
.field
.MODE
= MODE_CCK
;
653 pEntry
->MinHTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
654 pEntry
->HTPhyMode
.field
.MODE
= MODE_CCK
;
655 pEntry
->HTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
659 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_OFDM
;
660 pEntry
->MaxHTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
661 pEntry
->MinHTPhyMode
.field
.MODE
= MODE_OFDM
;
662 pEntry
->MinHTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
663 pEntry
->HTPhyMode
.field
.MODE
= MODE_OFDM
;
664 pEntry
->HTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
667 pEntry
->MaxHTPhyMode
.field
.BW
= BW_20
;
668 pEntry
->MinHTPhyMode
.field
.BW
= BW_20
;
670 #ifdef DOT11_N_SUPPORT
671 pEntry
->HTCapability
.MCSSet
[0] = 0;
672 pEntry
->HTCapability
.MCSSet
[1] = 0;
674 // If this Entry supports 802.11n, upgrade to HT rate.
675 if ((HtCapabilityLen
!= 0) && (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
))
677 UCHAR j
, bitmask
; //k,bitmask;
680 DBGPRINT(RT_DEBUG_OFF
, ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
681 SA
[0], SA
[1], SA
[2], SA
[3], SA
[4], SA
[5]));
683 if ((HtCapability
.HtCapInfo
.GF
) && (pAd
->CommonCfg
.DesiredHtPhy
.GF
))
685 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTGREENFIELD
;
689 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTMIX
;
690 pAd
->MacTab
.fAnyStationNonGF
= TRUE
;
691 pAd
->CommonCfg
.AddHTInfo
.AddHtInfo2
.NonGfPresent
= 1;
694 if ((HtCapability
.HtCapInfo
.ChannelWidth
) && (pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
))
696 pEntry
->MaxHTPhyMode
.field
.BW
= BW_40
;
697 pEntry
->MaxHTPhyMode
.field
.ShortGI
= ((pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor40
)&(HtCapability
.HtCapInfo
.ShortGIfor40
));
701 pEntry
->MaxHTPhyMode
.field
.BW
= BW_20
;
702 pEntry
->MaxHTPhyMode
.field
.ShortGI
= ((pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor20
)&(HtCapability
.HtCapInfo
.ShortGIfor20
));
703 pAd
->MacTab
.fAnyStation20Only
= TRUE
;
706 // find max fixed rate
707 for (ii
=15; ii
>=0; ii
--)
710 bitmask
= (1<<(ii
-(j
*8)));
711 if ( (pAd
->StaCfg
.DesiredHtPhyInfo
.MCSSet
[j
]&bitmask
) && (HtCapability
.MCSSet
[j
]&bitmask
))
713 pEntry
->MaxHTPhyMode
.field
.MCS
= ii
;
720 if (pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
!= MCS_AUTO
)
722 if (pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
== 32)
724 // Fix MCS as HT Duplicated Mode
725 pEntry
->MaxHTPhyMode
.field
.BW
= 1;
726 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTMIX
;
727 pEntry
->MaxHTPhyMode
.field
.STBC
= 0;
728 pEntry
->MaxHTPhyMode
.field
.ShortGI
= 0;
729 pEntry
->MaxHTPhyMode
.field
.MCS
= 32;
731 else if (pEntry
->MaxHTPhyMode
.field
.MCS
> pAd
->StaCfg
.HTPhyMode
.field
.MCS
)
733 // STA supports fixed MCS
734 pEntry
->MaxHTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
738 pEntry
->MaxHTPhyMode
.field
.STBC
= (HtCapability
.HtCapInfo
.RxSTBC
& (pAd
->CommonCfg
.DesiredHtPhy
.TxSTBC
));
739 pEntry
->MpduDensity
= HtCapability
.HtCapParm
.MpduDensity
;
740 pEntry
->MaxRAmpduFactor
= HtCapability
.HtCapParm
.MaxRAmpduFactor
;
741 pEntry
->MmpsMode
= (UCHAR
)HtCapability
.HtCapInfo
.MimoPs
;
742 pEntry
->AMsduSize
= (UCHAR
)HtCapability
.HtCapInfo
.AMsduSize
;
743 pEntry
->HTPhyMode
.word
= pEntry
->MaxHTPhyMode
.word
;
745 if (HtCapability
.HtCapInfo
.ShortGIfor20
)
746 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_SGI20_CAPABLE
);
747 if (HtCapability
.HtCapInfo
.ShortGIfor40
)
748 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_SGI40_CAPABLE
);
749 if (HtCapability
.HtCapInfo
.TxSTBC
)
750 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_TxSTBC_CAPABLE
);
751 if (HtCapability
.HtCapInfo
.RxSTBC
)
752 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_RxSTBC_CAPABLE
);
753 if (HtCapability
.ExtHtCapInfo
.PlusHTC
)
754 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_HTC_CAPABLE
);
755 if (pAd
->CommonCfg
.bRdg
&& HtCapability
.ExtHtCapInfo
.RDGSupport
)
756 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_RDG_CAPABLE
);
757 if (HtCapability
.ExtHtCapInfo
.MCSFeedback
== 0x03)
758 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE
);
760 NdisMoveMemory(&pEntry
->HTCapability
, &HtCapability
, sizeof(HT_CAPABILITY_IE
));
762 #endif // DOT11_N_SUPPORT //
763 pEntry
->HTPhyMode
.word
= pEntry
->MaxHTPhyMode
.word
;
764 pEntry
->CurrTxRate
= pEntry
->MaxSupportedRate
;
765 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_WMM_CAPABLE
);
767 if (pAd
->StaCfg
.bAutoTxRateSwitch
== TRUE
)
772 MlmeSelectTxRateTable(pAd
, pEntry
, &pTable
, &TableSize
, &pEntry
->CurrTxRateIndex
);
773 pEntry
->bAutoTxRateSwitch
= TRUE
;
777 pEntry
->HTPhyMode
.field
.MODE
= pAd
->StaCfg
.HTPhyMode
.field
.MODE
;
778 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
779 pEntry
->bAutoTxRateSwitch
= FALSE
;
781 RTMPUpdateLegacyTxSetting((UCHAR
)pAd
->StaCfg
.DesiredTransmitSetting
.field
.FixedTxMode
, pEntry
);
783 pEntry
->RateLen
= SupportedRatesLen
;
785 if (pAd
->StaCfg
.AuthMode
>= Ndis802_11AuthModeWPA
)
787 // If support WPA or WPA2, start STAKey hand shake,
788 // If failed hand shake, just tear down peer DLS
789 if (RTMPSendSTAKeyRequest(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
) != NDIS_STATUS_SUCCESS
)
791 MLME_DLS_REQ_STRUCT MlmeDlsReq
;
792 USHORT reason
= REASON_QOS_CIPHER_NOT_SUPPORT
;
794 DlsParmFill(pAd
, &MlmeDlsReq
, &pAd
->StaCfg
.DLSEntry
[i
], reason
);
795 MlmeEnqueue(pAd
, DLS_STATE_MACHINE
, MT2_MLME_DLS_TEAR_DOWN
, sizeof(MLME_DLS_REQ_STRUCT
), &MlmeDlsReq
);
796 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
797 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
798 DBGPRINT(RT_DEBUG_ERROR
,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
802 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_WAIT_KEY
;
803 DBGPRINT(RT_DEBUG_TRACE
,("DLS - waiting for STAKey handshake procedure\n"));
808 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
809 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_FINISH
;
810 DBGPRINT(RT_DEBUG_TRACE
,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x Succeed with WEP or no security\n", SA
[0], SA
[1], SA
[2], SA
[3], SA
[4], SA
[5]));
813 //initialize seq no for DLS frames.
814 pAd
->StaCfg
.DLSEntry
[i
].Sequence
= 0;
815 if (HtCapabilityLen
!= 0)
816 pAd
->StaCfg
.DLSEntry
[i
].bHTCap
= TRUE
;
818 pAd
->StaCfg
.DLSEntry
[i
].bHTCap
= FALSE
;
822 // DLS setup procedure failed.
823 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
824 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
825 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
826 DBGPRINT(RT_DEBUG_ERROR
,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode
));
831 if (i
>= MAX_NUM_OF_INIT_DLS_ENTRY
)
833 DBGPRINT(RT_DEBUG_TRACE
,("DLS - PeerDlsRspAction() update timeout value \n"));
834 for (i
=(MAX_NUM_OF_DLS_ENTRY
-1); i
>=MAX_NUM_OF_INIT_DLS_ENTRY
; i
--)
836 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& MAC_ADDR_EQUAL(SA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
838 if (StatusCode
== MLME_SUCCESS
)
840 MAC_TABLE_ENTRY
*pEntry
;
841 UCHAR MaxSupportedRate
= RATE_11
;
843 pEntry
= MacTableInsertDlsEntry(pAd
, SA
, i
);
845 switch (MaxSupportedRateIn500Kbps
)
847 case 108: MaxSupportedRate
= RATE_54
; break;
848 case 96: MaxSupportedRate
= RATE_48
; break;
849 case 72: MaxSupportedRate
= RATE_36
; break;
850 case 48: MaxSupportedRate
= RATE_24
; break;
851 case 36: MaxSupportedRate
= RATE_18
; break;
852 case 24: MaxSupportedRate
= RATE_12
; break;
853 case 18: MaxSupportedRate
= RATE_9
; break;
854 case 12: MaxSupportedRate
= RATE_6
; break;
855 case 22: MaxSupportedRate
= RATE_11
; break;
856 case 11: MaxSupportedRate
= RATE_5_5
; break;
857 case 4: MaxSupportedRate
= RATE_2
; break;
858 case 2: MaxSupportedRate
= RATE_1
; break;
859 default: MaxSupportedRate
= RATE_11
; break;
862 pEntry
->MaxSupportedRate
= min(pAd
->CommonCfg
.MaxTxRate
, MaxSupportedRate
);
864 if (pEntry
->MaxSupportedRate
< RATE_FIRST_OFDM_RATE
)
866 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_CCK
;
867 pEntry
->MaxHTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
868 pEntry
->MinHTPhyMode
.field
.MODE
= MODE_CCK
;
869 pEntry
->MinHTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
870 pEntry
->HTPhyMode
.field
.MODE
= MODE_CCK
;
871 pEntry
->HTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
875 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_OFDM
;
876 pEntry
->MaxHTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
877 pEntry
->MinHTPhyMode
.field
.MODE
= MODE_OFDM
;
878 pEntry
->MinHTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
879 pEntry
->HTPhyMode
.field
.MODE
= MODE_OFDM
;
880 pEntry
->HTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
883 pEntry
->MaxHTPhyMode
.field
.BW
= BW_20
;
884 pEntry
->MinHTPhyMode
.field
.BW
= BW_20
;
886 #ifdef DOT11_N_SUPPORT
887 pEntry
->HTCapability
.MCSSet
[0] = 0;
888 pEntry
->HTCapability
.MCSSet
[1] = 0;
890 // If this Entry supports 802.11n, upgrade to HT rate.
891 if ((HtCapabilityLen
!= 0) && (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
))
893 UCHAR j
, bitmask
; //k,bitmask;
896 DBGPRINT(RT_DEBUG_OFF
, ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
897 SA
[0], SA
[1], SA
[2], SA
[3], SA
[4], SA
[5]));
899 if ((HtCapability
.HtCapInfo
.GF
) && (pAd
->CommonCfg
.DesiredHtPhy
.GF
))
901 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTGREENFIELD
;
905 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTMIX
;
906 pAd
->MacTab
.fAnyStationNonGF
= TRUE
;
907 pAd
->CommonCfg
.AddHTInfo
.AddHtInfo2
.NonGfPresent
= 1;
910 if ((HtCapability
.HtCapInfo
.ChannelWidth
) && (pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
))
912 pEntry
->MaxHTPhyMode
.field
.BW
= BW_40
;
913 pEntry
->MaxHTPhyMode
.field
.ShortGI
= ((pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor40
)&(HtCapability
.HtCapInfo
.ShortGIfor40
));
917 pEntry
->MaxHTPhyMode
.field
.BW
= BW_20
;
918 pEntry
->MaxHTPhyMode
.field
.ShortGI
= ((pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor20
)&(HtCapability
.HtCapInfo
.ShortGIfor20
));
919 pAd
->MacTab
.fAnyStation20Only
= TRUE
;
922 // find max fixed rate
923 for (ii
=15; ii
>=0; ii
--)
926 bitmask
= (1<<(ii
-(j
*8)));
927 if ( (pAd
->StaCfg
.DesiredHtPhyInfo
.MCSSet
[j
]&bitmask
) && (HtCapability
.MCSSet
[j
]&bitmask
))
929 pEntry
->MaxHTPhyMode
.field
.MCS
= ii
;
936 if (pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
!= MCS_AUTO
)
938 printk("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
939 pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
);
940 if (pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
== 32)
942 // Fix MCS as HT Duplicated Mode
943 pEntry
->MaxHTPhyMode
.field
.BW
= 1;
944 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTMIX
;
945 pEntry
->MaxHTPhyMode
.field
.STBC
= 0;
946 pEntry
->MaxHTPhyMode
.field
.ShortGI
= 0;
947 pEntry
->MaxHTPhyMode
.field
.MCS
= 32;
949 else if (pEntry
->MaxHTPhyMode
.field
.MCS
> pAd
->StaCfg
.HTPhyMode
.field
.MCS
)
951 // STA supports fixed MCS
952 pEntry
->MaxHTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
956 pEntry
->MaxHTPhyMode
.field
.STBC
= (HtCapability
.HtCapInfo
.RxSTBC
& (pAd
->CommonCfg
.DesiredHtPhy
.TxSTBC
));
957 pEntry
->MpduDensity
= HtCapability
.HtCapParm
.MpduDensity
;
958 pEntry
->MaxRAmpduFactor
= HtCapability
.HtCapParm
.MaxRAmpduFactor
;
959 pEntry
->MmpsMode
= (UCHAR
)HtCapability
.HtCapInfo
.MimoPs
;
960 pEntry
->AMsduSize
= (UCHAR
)HtCapability
.HtCapInfo
.AMsduSize
;
961 pEntry
->HTPhyMode
.word
= pEntry
->MaxHTPhyMode
.word
;
963 if (HtCapability
.HtCapInfo
.ShortGIfor20
)
964 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_SGI20_CAPABLE
);
965 if (HtCapability
.HtCapInfo
.ShortGIfor40
)
966 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_SGI40_CAPABLE
);
967 if (HtCapability
.HtCapInfo
.TxSTBC
)
968 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_TxSTBC_CAPABLE
);
969 if (HtCapability
.HtCapInfo
.RxSTBC
)
970 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_RxSTBC_CAPABLE
);
971 if (HtCapability
.ExtHtCapInfo
.PlusHTC
)
972 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_HTC_CAPABLE
);
973 if (pAd
->CommonCfg
.bRdg
&& HtCapability
.ExtHtCapInfo
.RDGSupport
)
974 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_RDG_CAPABLE
);
975 if (HtCapability
.ExtHtCapInfo
.MCSFeedback
== 0x03)
976 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE
);
978 NdisMoveMemory(&pEntry
->HTCapability
, &HtCapability
, sizeof(HT_CAPABILITY_IE
));
980 #endif // DOT11_N_SUPPORT //
982 pEntry
->HTPhyMode
.word
= pEntry
->MaxHTPhyMode
.word
;
983 pEntry
->CurrTxRate
= pEntry
->MaxSupportedRate
;
984 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_WMM_CAPABLE
);
986 if (pAd
->StaCfg
.bAutoTxRateSwitch
== TRUE
)
991 MlmeSelectTxRateTable(pAd
, pEntry
, &pTable
, &TableSize
, &pEntry
->CurrTxRateIndex
);
992 pEntry
->bAutoTxRateSwitch
= TRUE
;
996 pEntry
->HTPhyMode
.field
.MODE
= pAd
->StaCfg
.HTPhyMode
.field
.MODE
;
997 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
998 pEntry
->bAutoTxRateSwitch
= FALSE
;
1000 RTMPUpdateLegacyTxSetting((UCHAR
)pAd
->StaCfg
.DesiredTransmitSetting
.field
.FixedTxMode
, pEntry
);
1002 pEntry
->RateLen
= SupportedRatesLen
;
1004 if (pAd
->StaCfg
.AuthMode
>= Ndis802_11AuthModeWPA
)
1006 // If support WPA or WPA2, start STAKey hand shake,
1007 // If failed hand shake, just tear down peer DLS
1008 if (RTMPSendSTAKeyRequest(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
) != NDIS_STATUS_SUCCESS
)
1010 MLME_DLS_REQ_STRUCT MlmeDlsReq
;
1011 USHORT reason
= REASON_QOS_CIPHER_NOT_SUPPORT
;
1013 DlsParmFill(pAd
, &MlmeDlsReq
, &pAd
->StaCfg
.DLSEntry
[i
], reason
);
1014 MlmeEnqueue(pAd
, DLS_STATE_MACHINE
, MT2_MLME_DLS_TEAR_DOWN
, sizeof(MLME_DLS_REQ_STRUCT
), &MlmeDlsReq
);
1015 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
1016 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
1017 DBGPRINT(RT_DEBUG_ERROR
,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
1021 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_WAIT_KEY
;
1022 DBGPRINT(RT_DEBUG_TRACE
,("DLS - waiting for STAKey handshake procedure\n"));
1027 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
1028 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_FINISH
;
1029 DBGPRINT(RT_DEBUG_TRACE
,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x Succeed with WEP or no security\n", SA
[0], SA
[1], SA
[2], SA
[3], SA
[4], SA
[5]));
1031 pAd
->StaCfg
.DLSEntry
[i
].Sequence
= 0;
1032 if (HtCapabilityLen
!= 0)
1033 pAd
->StaCfg
.DLSEntry
[i
].bHTCap
= TRUE
;
1035 pAd
->StaCfg
.DLSEntry
[i
].bHTCap
= FALSE
;
1039 // DLS setup procedure failed.
1040 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
1041 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
1042 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
1043 DBGPRINT(RT_DEBUG_ERROR
,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode
));
1051 ==========================================================================
1054 IRQL = DISPATCH_LEVEL
1056 ==========================================================================
1058 VOID
MlmeDlsTearDownAction(
1059 IN PRTMP_ADAPTER pAd
,
1060 IN MLME_QUEUE_ELEM
*Elem
)
1062 PUCHAR pOutBuffer
= NULL
;
1063 NDIS_STATUS NStatus
;
1065 UCHAR Category
= CATEGORY_DLS
;
1066 UCHAR Action
= ACTION_DLS_TEARDOWN
;
1067 USHORT ReasonCode
= REASON_QOS_UNSPECIFY
;
1068 HEADER_802_11 DlsTearDownHdr
;
1069 PRT_802_11_DLS pDLS
;
1070 BOOLEAN TimerCancelled
;
1073 if(!MlmeDlsReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &pDLS
, &ReasonCode
))
1076 DBGPRINT(RT_DEBUG_TRACE
,("DLS - MlmeDlsTearDownAction() with ReasonCode=%d \n", ReasonCode
));
1078 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
1079 if (NStatus
!= NDIS_STATUS_SUCCESS
)
1081 DBGPRINT(RT_DEBUG_ERROR
,("DLS - MlmeDlsTearDownAction() allocate memory failed \n"));
1085 ActHeaderInit(pAd
, &DlsTearDownHdr
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
1087 // Build basic frame first
1088 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1089 sizeof(HEADER_802_11
), &DlsTearDownHdr
,
1093 6, pAd
->CurrentAddress
,
1097 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
);
1098 MlmeFreeMemory(pAd
, pOutBuffer
);
1099 RTMPCancelTimer(&pDLS
->Timer
, &TimerCancelled
);
1101 // Remove key in local dls table entry
1102 for (i
= 0; i
< MAX_NUM_OF_INIT_DLS_ENTRY
; i
++)
1104 if (MAC_ADDR_EQUAL(pDLS
->MacAddr
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1106 MacTableDeleteDlsEntry(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
);
1110 // clear peer dls table entry
1111 for (i
= MAX_NUM_OF_INIT_DLS_ENTRY
; i
< MAX_NUM_OF_DLS_ENTRY
; i
++)
1113 if (MAC_ADDR_EQUAL(pDLS
->MacAddr
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1115 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
1116 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
1117 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
1118 MacTableDeleteDlsEntry(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
);
1124 ==========================================================================
1127 IRQL = DISPATCH_LEVEL
1129 ==========================================================================
1131 VOID
PeerDlsTearDownAction(
1132 IN PRTMP_ADAPTER pAd
,
1133 IN MLME_QUEUE_ELEM
*Elem
)
1135 UCHAR DA
[MAC_ADDR_LEN
], SA
[MAC_ADDR_LEN
];
1138 BOOLEAN TimerCancelled
;
1140 if (!pAd
->CommonCfg
.bDLSCapable
)
1146 if (!PeerDlsTearDownSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, DA
, SA
, &ReasonCode
))
1149 DBGPRINT(RT_DEBUG_TRACE
,("DLS - PeerDlsTearDownAction() from %02x:%02x:%02x:%02x:%02x:%02x with ReasonCode=%d\n", SA
[0], SA
[1], SA
[2], SA
[3], SA
[4], SA
[5], ReasonCode
));
1151 // clear local dls table entry
1152 for (i
=0; i
<MAX_NUM_OF_INIT_DLS_ENTRY
; i
++)
1154 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& MAC_ADDR_EQUAL(SA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1156 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
1157 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
1158 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
1159 //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1160 //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1161 MacTableDeleteDlsEntry(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
);
1165 // clear peer dls table entry
1166 for (i
=MAX_NUM_OF_INIT_DLS_ENTRY
; i
<MAX_NUM_OF_DLS_ENTRY
; i
++)
1168 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& MAC_ADDR_EQUAL(SA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1170 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
1171 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
1172 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
1173 //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1174 //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1175 MacTableDeleteDlsEntry(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
);
1181 ==========================================================================
1184 IRQL = DISPATCH_LEVEL
1186 ==========================================================================
1188 VOID
RTMPCheckDLSTimeOut(
1189 IN PRTMP_ADAPTER pAd
)
1192 MLME_DLS_REQ_STRUCT MlmeDlsReq
;
1193 USHORT reason
= REASON_QOS_UNSPECIFY
;
1195 if (! pAd
->CommonCfg
.bDLSCapable
)
1198 if (! INFRA_ON(pAd
))
1201 // If timeout value is equaled to zero, it means always not be timeout.
1203 // update local dls table entry
1204 for (i
=0; i
<MAX_NUM_OF_INIT_DLS_ENTRY
; i
++)
1206 if ((pAd
->StaCfg
.DLSEntry
[i
].Valid
) && (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
)
1207 && (pAd
->StaCfg
.DLSEntry
[i
].TimeOut
!= 0))
1209 pAd
->StaCfg
.DLSEntry
[i
].CountDownTimer
--;
1211 if (pAd
->StaCfg
.DLSEntry
[i
].CountDownTimer
== 0)
1213 reason
= REASON_QOS_REQUEST_TIMEOUT
;
1214 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
1215 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
1216 DlsParmFill(pAd
, &MlmeDlsReq
, &pAd
->StaCfg
.DLSEntry
[i
], reason
);
1217 MlmeEnqueue(pAd
, DLS_STATE_MACHINE
, MT2_MLME_DLS_TEAR_DOWN
, sizeof(MLME_DLS_REQ_STRUCT
), &MlmeDlsReq
);
1222 // update peer dls table entry
1223 for (i
=MAX_NUM_OF_INIT_DLS_ENTRY
; i
<MAX_NUM_OF_DLS_ENTRY
; i
++)
1225 if ((pAd
->StaCfg
.DLSEntry
[i
].Valid
) && (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
)
1226 && (pAd
->StaCfg
.DLSEntry
[i
].TimeOut
!= 0))
1228 pAd
->StaCfg
.DLSEntry
[i
].CountDownTimer
--;
1230 if (pAd
->StaCfg
.DLSEntry
[i
].CountDownTimer
== 0)
1232 reason
= REASON_QOS_REQUEST_TIMEOUT
;
1233 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
1234 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
1235 DlsParmFill(pAd
, &MlmeDlsReq
, &pAd
->StaCfg
.DLSEntry
[i
], reason
);
1236 MlmeEnqueue(pAd
, DLS_STATE_MACHINE
, MT2_MLME_DLS_TEAR_DOWN
, sizeof(MLME_DLS_REQ_STRUCT
), &MlmeDlsReq
);
1243 ==========================================================================
1246 IRQL = DISPATCH_LEVEL
1248 ==========================================================================
1250 BOOLEAN
RTMPRcvFrameDLSCheck(
1251 IN PRTMP_ADAPTER pAd
,
1252 IN PHEADER_802_11 pHeader
,
1254 IN PRT28XX_RXD_STRUC pRxD
)
1257 BOOLEAN bFindEntry
= FALSE
;
1258 BOOLEAN bSTAKeyFrame
= FALSE
;
1260 PUCHAR pProto
, pAddr
= NULL
;
1261 PUCHAR pSTAKey
= NULL
;
1262 UCHAR ZeroReplay
[LEN_KEY_DESC_REPLAY
];
1263 UCHAR Mic
[16], OldMic
[16];
1267 BOOLEAN TimerCancelled
;
1268 CIPHER_KEY PairwiseKey
;
1271 if (! pAd
->CommonCfg
.bDLSCapable
)
1272 return bSTAKeyFrame
;
1274 if (! INFRA_ON(pAd
))
1275 return bSTAKeyFrame
;
1277 if (! (pHeader
->FC
.SubType
& 0x08))
1278 return bSTAKeyFrame
;
1280 if (Len
< LENGTH_802_11
+ 6 + 2 + 2)
1281 return bSTAKeyFrame
;
1283 pProto
= (PUCHAR
)pHeader
+ LENGTH_802_11
+ 2 + 6; // QOS Control field , 0xAA 0xAA 0xAA 0x00 0x00 0x00
1284 pAddr
= pHeader
->Addr2
;
1286 // L2PAD bit on will pad 2 bytes at LLC
1292 if (RTMPEqualMemory(EAPOL
, pProto
, 2) && (pAd
->StaCfg
.AuthMode
>= Ndis802_11AuthModeWPA
))
1294 pEap
= (PEAPOL_PACKET
) (pProto
+ 2);
1296 DBGPRINT(RT_DEBUG_TRACE
,("DLS - Sniff Len=%ld, DataLen=%d, KeyMic=%d, Install=%d, KeyAck=%d, Secure=%d, EKD_DL=%d, Error=%d, Request=%d\n", Len
,
1297 (LENGTH_802_11
+ 6 + 2 + 2 + sizeof(EAPOL_PACKET
) - MAX_LEN_OF_RSNIE
+ 16),
1298 pEap
->KeyDesc
.KeyInfo
.KeyMic
,
1299 pEap
->KeyDesc
.KeyInfo
.Install
,
1300 pEap
->KeyDesc
.KeyInfo
.KeyAck
,
1301 pEap
->KeyDesc
.KeyInfo
.Secure
,
1302 pEap
->KeyDesc
.KeyInfo
.EKD_DL
,
1303 pEap
->KeyDesc
.KeyInfo
.Error
,
1304 pEap
->KeyDesc
.KeyInfo
.Request
));
1306 if ((Len
>= (LENGTH_802_11
+ 6 + 2 + 2 + sizeof(EAPOL_PACKET
) - MAX_LEN_OF_RSNIE
+ 16)) && pEap
->KeyDesc
.KeyInfo
.KeyMic
1307 && pEap
->KeyDesc
.KeyInfo
.Install
&& pEap
->KeyDesc
.KeyInfo
.KeyAck
&& pEap
->KeyDesc
.KeyInfo
.Secure
1308 && pEap
->KeyDesc
.KeyInfo
.EKD_DL
&& !pEap
->KeyDesc
.KeyInfo
.Error
&& !pEap
->KeyDesc
.KeyInfo
.Request
)
1310 // First validate replay counter, only accept message with larger replay counter
1311 // Let equal pass, some AP start with all zero replay counter
1312 NdisZeroMemory(ZeroReplay
, LEN_KEY_DESC_REPLAY
);
1313 if ((RTMPCompareMemory(pEap
->KeyDesc
.ReplayCounter
, pAd
->StaCfg
.ReplayCounter
, LEN_KEY_DESC_REPLAY
) != 1) &&
1314 (RTMPCompareMemory(pEap
->KeyDesc
.ReplayCounter
, ZeroReplay
, LEN_KEY_DESC_REPLAY
) != 0))
1315 return bSTAKeyFrame
;
1317 //RTMPMoveMemory(pAd->StaCfg.ReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1318 RTMPMoveMemory(pAd
->StaCfg
.DlsReplayCounter
, pEap
->KeyDesc
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
1319 DBGPRINT(RT_DEBUG_TRACE
,("DLS - Sniff replay counter (%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
1320 pAd
->StaCfg
.ReplayCounter
[0], pAd
->StaCfg
.ReplayCounter
[1], pAd
->StaCfg
.ReplayCounter
[2],
1321 pAd
->StaCfg
.ReplayCounter
[3], pAd
->StaCfg
.ReplayCounter
[4], pAd
->StaCfg
.ReplayCounter
[5],
1322 pAd
->StaCfg
.ReplayCounter
[6], pAd
->StaCfg
.ReplayCounter
[7], Len
, pEap
->KeyDesc
.KeyData
[1]));
1324 // put these code segment to get the replay counter
1325 if (pAd
->StaCfg
.PortSecured
== WPA_802_1X_PORT_NOT_SECURED
)
1326 return bSTAKeyFrame
;
1329 // Save the MIC and replace with zero
1330 // use proprietary PTK
1331 NdisZeroMemory(temp
, 64);
1332 NdisMoveMemory(temp
, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1333 WpaCountPTK(pAd
, temp
, temp
, pAd
->CommonCfg
.Bssid
, temp
, pAd
->CurrentAddress
, DlsPTK
, LEN_PTK
);
1335 NdisMoveMemory(OldMic
, pEap
->KeyDesc
.KeyMic
, LEN_KEY_DESC_MIC
);
1336 NdisZeroMemory(pEap
->KeyDesc
.KeyMic
, LEN_KEY_DESC_MIC
);
1337 if (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
1340 HMAC_SHA1((PUCHAR
) pEap
, pEap
->Body_Len
[1] + 4, DlsPTK
, LEN_EAP_MICK
, digest
);
1341 NdisMoveMemory(Mic
, digest
, LEN_KEY_DESC_MIC
);
1345 hmac_md5(DlsPTK
, LEN_EAP_MICK
, (PUCHAR
) pEap
, pEap
->Body_Len
[1] + 4, Mic
);
1348 if (!NdisEqualMemory(OldMic
, Mic
, LEN_KEY_DESC_MIC
))
1350 DBGPRINT(RT_DEBUG_ERROR
, ("MIC Different in Msg1 of STAKey handshake! \n"));
1351 return bSTAKeyFrame
;
1354 DBGPRINT(RT_DEBUG_TRACE
, ("MIC VALID in Msg1 of STAKey handshake! \n"));
1356 if ((pEap
->KeyDesc
.KeyData
[0] == 0xDD) && (pEap
->KeyDesc
.KeyData
[2] == 0x00) && (pEap
->KeyDesc
.KeyData
[3] == 0x0C)
1357 && (pEap
->KeyDesc
.KeyData
[4] == 0x43) && (pEap
->KeyDesc
.KeyData
[5] == 0x02))
1359 pAddr
= pEap
->KeyDesc
.KeyData
+ 8; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2)
1360 pSTAKey
= pEap
->KeyDesc
.KeyData
+ 14; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6)
1362 DBGPRINT(RT_DEBUG_TRACE
,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%ld, KeyDataLen=%d\n",
1363 pAddr
[0], pAddr
[1], pAddr
[2], pAddr
[3], pAddr
[4], pAddr
[5], Len
, pEap
->KeyDesc
.KeyData
[1]));
1365 bSTAKeyFrame
= TRUE
;
1368 if ((pEap
->KeyDesc
.KeyData
[0] == 0xDD) && (pEap
->KeyDesc
.KeyData
[2] == 0x00) && (pEap
->KeyDesc
.KeyData
[3] == 0x0F)
1369 && (pEap
->KeyDesc
.KeyData
[4] == 0xAC) && (pEap
->KeyDesc
.KeyData
[5] == 0x02))
1371 pAddr
= pEap
->KeyDesc
.KeyData
+ 8; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2)
1372 pSTAKey
= pEap
->KeyDesc
.KeyData
+ 14; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6)
1374 DBGPRINT(RT_DEBUG_TRACE
,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%d, KeyDataLen=%d\n",
1375 pAddr
[0], pAddr
[1], pAddr
[2], pAddr
[3], pAddr
[4], pAddr
[5], Len
, pEap
->KeyDesc
.KeyData
[1]));
1377 bSTAKeyFrame
= TRUE
;
1382 else if (Len
>= (LENGTH_802_11
+ 6 + 2 + 2 + sizeof(EAPOL_PACKET
) - MAX_LEN_OF_RSNIE
))
1385 RTMPMoveMemory(pAd
->StaCfg
.ReplayCounter
, pEap
->KeyDesc
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
1388 RTMPMoveMemory(pAd
->StaCfg
.DlsReplayCounter
, pEap
->KeyDesc
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
1389 DBGPRINT(RT_DEBUG_TRACE
,("DLS - Sniff replay counter 2(%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
1390 pAd
->StaCfg
.ReplayCounter
[0], pAd
->StaCfg
.ReplayCounter
[1], pAd
->StaCfg
.ReplayCounter
[2],
1391 pAd
->StaCfg
.ReplayCounter
[3], pAd
->StaCfg
.ReplayCounter
[4], pAd
->StaCfg
.ReplayCounter
[5],
1392 pAd
->StaCfg
.ReplayCounter
[6], pAd
->StaCfg
.ReplayCounter
[7], Len
, pEap
->KeyDesc
.KeyData
[1]));
1397 // If timeout value is equaled to zero, it means always not be timeout.
1398 // update local dls table entry
1399 for (i
= 0; i
< MAX_NUM_OF_INIT_DLS_ENTRY
; i
++)
1401 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& MAC_ADDR_EQUAL(pAddr
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1405 PMAC_TABLE_ENTRY pEntry
;
1407 // STAKey frame, add pairwise key table
1408 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_FINISH
;
1409 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
1411 PairwiseKey
.KeyLen
= LEN_TKIP_EK
;
1412 NdisMoveMemory(PairwiseKey
.Key
, &pSTAKey
[0], LEN_TKIP_EK
);
1413 NdisMoveMemory(PairwiseKey
.TxMic
, &pSTAKey
[16], LEN_TKIP_RXMICK
);
1414 NdisMoveMemory(PairwiseKey
.RxMic
, &pSTAKey
[24], LEN_TKIP_TXMICK
);
1416 PairwiseKey
.CipherAlg
= pAd
->SharedKey
[BSS0
][pAd
->StaCfg
.DefaultKeyId
].CipherAlg
;
1418 pEntry
= DlsEntryTableLookup(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
, TRUE
);
1419 //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
1420 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1421 // Add Pair-wise key to Asic
1424 RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo
;
1425 COPY_MAC_ADDR(KeyInfo
.MacAddr
,pAd
->StaCfg
.DLSEntry
[i
].MacAddr
);
1426 KeyInfo
.MacTabMatchWCID
=pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
;
1427 NdisMoveMemory(&KeyInfo
.CipherKey
, &PairwiseKey
,sizeof(CIPHER_KEY
));
1428 RTUSBEnqueueInternalCmd(pAd
, RT_CMD_SET_KEY_TABLE
, &KeyInfo
, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY
));
1431 PMAC_TABLE_ENTRY pDLSEntry
;
1432 pDLSEntry
= DlsEntryTableLookup(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
, TRUE
);
1433 pDLSEntry
->PairwiseKey
.CipherAlg
=PairwiseKey
.CipherAlg
;
1434 RTUSBEnqueueInternalCmd(pAd
, RT_CMD_SET_RX_WCID_TABLE
, pDLSEntry
, sizeof(MAC_TABLE_ENTRY
));
1437 NdisMoveMemory(&pEntry
->PairwiseKey
, &PairwiseKey
, sizeof(CIPHER_KEY
));
1438 DBGPRINT(RT_DEBUG_TRACE
,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n"));
1440 RTMPSendSTAKeyHandShake(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
);
1442 DBGPRINT(RT_DEBUG_TRACE
,("DLS - Finish STAKey handshake procedure (Initiator side)\n"));
1446 // Data frame, update timeout value
1447 if (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
)
1449 pAd
->StaCfg
.DLSEntry
[i
].CountDownTimer
= pAd
->StaCfg
.DLSEntry
[i
].TimeOut
;
1450 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1458 // update peer dls table entry
1459 for (i
=MAX_NUM_OF_INIT_DLS_ENTRY
; i
<MAX_NUM_OF_DLS_ENTRY
; i
++)
1461 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& MAC_ADDR_EQUAL(pAddr
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1465 PMAC_TABLE_ENTRY pEntry
= NULL
;
1467 // STAKey frame, add pairwise key table, and send STAkey Msg-2
1468 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_FINISH
;
1469 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
1471 PairwiseKey
.KeyLen
= LEN_TKIP_EK
;
1472 NdisMoveMemory(PairwiseKey
.Key
, &pSTAKey
[0], LEN_TKIP_EK
);
1473 NdisMoveMemory(PairwiseKey
.TxMic
, &pSTAKey
[16], LEN_TKIP_RXMICK
);
1474 NdisMoveMemory(PairwiseKey
.RxMic
, &pSTAKey
[24], LEN_TKIP_TXMICK
);
1476 PairwiseKey
.CipherAlg
= pAd
->SharedKey
[BSS0
][pAd
->StaCfg
.DefaultKeyId
].CipherAlg
;
1478 pEntry
= DlsEntryTableLookup(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
, TRUE
);
1479 //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
1480 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1481 // Add Pair-wise key to Asic
1484 RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo
;
1485 COPY_MAC_ADDR(KeyInfo
.MacAddr
,pAd
->StaCfg
.DLSEntry
[i
].MacAddr
);
1486 KeyInfo
.MacTabMatchWCID
=pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
;
1487 NdisMoveMemory(&KeyInfo
.CipherKey
, &PairwiseKey
,sizeof(CIPHER_KEY
));
1488 RTUSBEnqueueInternalCmd(pAd
, RT_CMD_SET_KEY_TABLE
, &KeyInfo
, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY
));
1491 PMAC_TABLE_ENTRY pDLSEntry
;
1492 pDLSEntry
= DlsEntryTableLookup(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
, TRUE
);
1493 pDLSEntry
->PairwiseKey
.CipherAlg
=PairwiseKey
.CipherAlg
;
1494 RTUSBEnqueueInternalCmd(pAd
, RT_CMD_SET_RX_WCID_TABLE
, pDLSEntry
, sizeof(MAC_TABLE_ENTRY
));
1497 NdisMoveMemory(&pEntry
->PairwiseKey
, &PairwiseKey
, sizeof(CIPHER_KEY
));
1498 DBGPRINT(RT_DEBUG_TRACE
,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n"));
1500 // If support WPA or WPA2, start STAKey hand shake,
1501 // If failed hand shake, just tear down peer DLS
1502 if (RTMPSendSTAKeyHandShake(pAd
, pAddr
) != NDIS_STATUS_SUCCESS
)
1504 MLME_DLS_REQ_STRUCT MlmeDlsReq
;
1505 USHORT reason
= REASON_QOS_CIPHER_NOT_SUPPORT
;
1507 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
1508 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
1509 DlsParmFill(pAd
, &MlmeDlsReq
, &pAd
->StaCfg
.DLSEntry
[i
], reason
);
1510 MlmeEnqueue(pAd
, DLS_STATE_MACHINE
, MT2_MLME_DLS_TEAR_DOWN
, sizeof(MLME_DLS_REQ_STRUCT
), &MlmeDlsReq
);
1514 DBGPRINT(RT_DEBUG_TRACE
,("DLS - Finish STAKey handshake procedure (Peer side)\n"));
1519 // Data frame, update timeout value
1520 if (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
)
1522 pAd
->StaCfg
.DLSEntry
[i
].CountDownTimer
= pAd
->StaCfg
.DLSEntry
[i
].TimeOut
;
1531 return bSTAKeyFrame
;
1535 ========================================================================
1537 Routine Description:
1538 Check if the frame can be sent through DLS direct link interface
1541 pAd Pointer to adapter
1548 ========================================================================
1550 INT
RTMPCheckDLSFrame(
1551 IN PRTMP_ADAPTER pAd
,
1557 if (!pAd
->CommonCfg
.bDLSCapable
)
1564 // check local dls table entry
1565 for (i
=0; i
<MAX_NUM_OF_INIT_DLS_ENTRY
; i
++)
1567 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
) &&
1568 MAC_ADDR_EQUAL(pDA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1575 // check peer dls table entry
1576 for (i
=MAX_NUM_OF_INIT_DLS_ENTRY
; i
<MAX_NUM_OF_DLS_ENTRY
; i
++)
1578 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
) &&
1579 MAC_ADDR_EQUAL(pDA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1591 ==========================================================================
1594 IRQL = DISPATCH_LEVEL
1596 ==========================================================================
1598 VOID
RTMPSendDLSTearDownFrame(
1599 IN PRTMP_ADAPTER pAd
,
1602 PUCHAR pOutBuffer
= NULL
;
1603 NDIS_STATUS NStatus
;
1604 HEADER_802_11 DlsTearDownHdr
;
1606 USHORT Reason
= REASON_QOS_QSTA_LEAVING_QBSS
;
1607 UCHAR Category
= CATEGORY_DLS
;
1608 UCHAR Action
= ACTION_DLS_TEARDOWN
;
1611 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
) ||
1612 RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
))
1615 DBGPRINT(RT_DEBUG_TRACE
, ("Send DLS TearDown Frame \n"));
1617 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
1618 if (NStatus
!= NDIS_STATUS_SUCCESS
)
1620 DBGPRINT(RT_DEBUG_ERROR
,("ASSOC - RTMPSendDLSTearDownFrame() allocate memory failed \n"));
1624 ActHeaderInit(pAd
, &DlsTearDownHdr
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
1625 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1626 sizeof(HEADER_802_11
), &DlsTearDownHdr
,
1630 6, pAd
->CurrentAddress
,
1634 MiniportMMRequest(pAd
, 0, pOutBuffer
, FrameLen
);
1635 MlmeFreeMemory(pAd
, pOutBuffer
);
1637 // Remove key in local dls table entry
1638 for (i
= 0; i
< MAX_NUM_OF_INIT_DLS_ENTRY
; i
++)
1640 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
)
1641 && MAC_ADDR_EQUAL(pDA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1643 MacTableDeleteDlsEntry(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
);
1647 // Remove key in peer dls table entry
1648 for (i
=MAX_NUM_OF_INIT_DLS_ENTRY
; i
<MAX_NUM_OF_DLS_ENTRY
; i
++)
1650 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
)
1651 && MAC_ADDR_EQUAL(pDA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1653 MacTableDeleteDlsEntry(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
);
1657 DBGPRINT(RT_DEBUG_TRACE
, ("Send DLS TearDown Frame and remove key in (i=%d) \n", i
));
1661 ==========================================================================
1664 IRQL = DISPATCH_LEVEL
1666 ==========================================================================
1668 NDIS_STATUS
RTMPSendSTAKeyRequest(
1669 IN PRTMP_ADAPTER pAd
,
1672 UCHAR Header802_3
[14];
1673 NDIS_STATUS NStatus
;
1675 EAPOL_PACKET Packet
;
1678 PUCHAR pOutBuffer
= NULL
;
1679 PNDIS_PACKET pNdisPacket
;
1683 DBGPRINT(RT_DEBUG_TRACE
,("DLS - RTMPSendSTAKeyRequest() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA
[0], pDA
[1], pDA
[2], pDA
[3], pDA
[4], pDA
[5]));
1686 MAKE_802_3_HEADER(Header802_3
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, EAPOL
);
1688 // Zero message body
1689 NdisZeroMemory(&Packet
, sizeof(Packet
));
1690 Packet
.ProVer
= EAPOL_VER
;
1691 Packet
.ProType
= EAPOLKey
;
1692 Packet
.Body_Len
[1] = sizeof(KEY_DESCRIPTER
) - MAX_LEN_OF_RSNIE
+ 6 + MAC_ADDR_LEN
; // data field contain KDE andPeer MAC address
1694 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1695 if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPAPSK
))
1697 Packet
.KeyDesc
.Type
= WPA1_KEY_DESC
;
1699 else if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2PSK
))
1701 Packet
.KeyDesc
.Type
= WPA2_KEY_DESC
;
1704 // Key descriptor version
1705 Packet
.KeyDesc
.KeyInfo
.KeyDescVer
=
1706 (((pAd
->StaCfg
.PairCipher
== Ndis802_11Encryption3Enabled
) || (pAd
->StaCfg
.GroupCipher
== Ndis802_11Encryption3Enabled
)) ? (DESC_TYPE_AES
) : (DESC_TYPE_TKIP
));
1708 Packet
.KeyDesc
.KeyInfo
.KeyMic
= 1;
1709 Packet
.KeyDesc
.KeyInfo
.Secure
= 1;
1710 Packet
.KeyDesc
.KeyInfo
.Request
= 1;
1712 Packet
.KeyDesc
.KeyDataLen
[1] = 12;
1714 // use our own OUI to distinguish proprietary with standard.
1715 Packet
.KeyDesc
.KeyData
[0] = 0xDD;
1716 Packet
.KeyDesc
.KeyData
[1] = 0x0A;
1717 Packet
.KeyDesc
.KeyData
[2] = 0x00;
1718 Packet
.KeyDesc
.KeyData
[3] = 0x0C;
1719 Packet
.KeyDesc
.KeyData
[4] = 0x43;
1720 Packet
.KeyDesc
.KeyData
[5] = 0x03;
1721 NdisMoveMemory(&Packet
.KeyDesc
.KeyData
[6], pDA
, MAC_ADDR_LEN
);
1723 NdisMoveMemory(Packet
.KeyDesc
.ReplayCounter
, pAd
->StaCfg
.DlsReplayCounter
, LEN_KEY_DESC_REPLAY
);
1725 // Allocate buffer for transmitting message
1726 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
);
1727 if (NStatus
!= NDIS_STATUS_SUCCESS
)
1730 // Prepare EAPOL frame for MIC calculation
1731 // Be careful, only EAPOL frame is counted for MIC calculation
1732 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1733 Packet
.Body_Len
[1] + 4, &Packet
,
1736 // use proprietary PTK
1737 NdisZeroMemory(temp
, 64);
1738 NdisMoveMemory(temp
, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1739 WpaCountPTK(pAd
, temp
, temp
, pAd
->CommonCfg
.Bssid
, temp
, pAd
->CurrentAddress
, DlsPTK
, LEN_PTK
);
1742 if (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
1745 NdisZeroMemory(digest
, sizeof(digest
));
1746 HMAC_SHA1(pOutBuffer
, FrameLen
, DlsPTK
, LEN_EAP_MICK
, digest
);
1747 NdisMoveMemory(Packet
.KeyDesc
.KeyMic
, digest
, LEN_KEY_DESC_MIC
);
1751 NdisZeroMemory(Mic
, sizeof(Mic
));
1752 hmac_md5(DlsPTK
, LEN_EAP_MICK
, pOutBuffer
, FrameLen
, Mic
);
1753 NdisMoveMemory(Packet
.KeyDesc
.KeyMic
, Mic
, LEN_KEY_DESC_MIC
);
1756 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1757 sizeof(Header802_3
), Header802_3
,
1758 Packet
.Body_Len
[1] + 4, &Packet
,
1761 NStatus
= RTMPAllocateNdisPacket(pAd
, &pNdisPacket
, NULL
, 0, pOutBuffer
, FrameLen
);
1762 if (NStatus
== NDIS_STATUS_SUCCESS
)
1764 RTMP_SET_PACKET_WCID(pNdisPacket
, BSSID_WCID
);
1765 STASendPacket(pAd
, pNdisPacket
);
1766 RTMPDeQueuePacket(pAd
, FALSE
, NUM_OF_TX_RING
, MAX_TX_PROCESS
);
1769 MlmeFreeMemory(pAd
, pOutBuffer
);
1771 DBGPRINT(RT_DEBUG_TRACE
, ("RTMPSendSTAKeyRequest- Send STAKey request (NStatus=%x, FrameLen=%ld)\n", NStatus
, FrameLen
));
1777 ==========================================================================
1780 IRQL = DISPATCH_LEVEL
1782 ==========================================================================
1784 NDIS_STATUS
RTMPSendSTAKeyHandShake(
1785 IN PRTMP_ADAPTER pAd
,
1788 UCHAR Header802_3
[14];
1789 NDIS_STATUS NStatus
;
1791 EAPOL_PACKET Packet
;
1794 PUCHAR pOutBuffer
= NULL
;
1795 PNDIS_PACKET pNdisPacket
;
1797 UCHAR DlsPTK
[80]; // Due to dirver can not get PTK, use proprietary PTK
1799 DBGPRINT(RT_DEBUG_TRACE
,("DLS - RTMPSendSTAKeyHandShake() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA
[0], pDA
[1], pDA
[2], pDA
[3], pDA
[4], pDA
[5]));
1802 MAKE_802_3_HEADER(Header802_3
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, EAPOL
);
1804 // Zero message body
1805 NdisZeroMemory(&Packet
, sizeof(Packet
));
1806 Packet
.ProVer
= EAPOL_VER
;
1807 Packet
.ProType
= EAPOLKey
;
1808 Packet
.Body_Len
[1] = sizeof(KEY_DESCRIPTER
) - MAX_LEN_OF_RSNIE
+ 6 + MAC_ADDR_LEN
; // data field contain KDE and Peer MAC address
1810 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1811 if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPAPSK
))
1813 Packet
.KeyDesc
.Type
= WPA1_KEY_DESC
;
1815 else if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2PSK
))
1817 Packet
.KeyDesc
.Type
= WPA2_KEY_DESC
;
1820 // Key descriptor version
1821 Packet
.KeyDesc
.KeyInfo
.KeyDescVer
=
1822 (((pAd
->StaCfg
.PairCipher
== Ndis802_11Encryption3Enabled
) || (pAd
->StaCfg
.GroupCipher
== Ndis802_11Encryption3Enabled
)) ? (DESC_TYPE_AES
) : (DESC_TYPE_TKIP
));
1824 Packet
.KeyDesc
.KeyInfo
.KeyMic
= 1;
1825 Packet
.KeyDesc
.KeyInfo
.Secure
= 1;
1827 Packet
.KeyDesc
.KeyDataLen
[1] = 12;
1829 // use our own OUI to distinguish proprietary with standard.
1830 Packet
.KeyDesc
.KeyData
[0] = 0xDD;
1831 Packet
.KeyDesc
.KeyData
[1] = 0x0A;
1832 Packet
.KeyDesc
.KeyData
[2] = 0x00;
1833 Packet
.KeyDesc
.KeyData
[3] = 0x0C;
1834 Packet
.KeyDesc
.KeyData
[4] = 0x43;
1835 Packet
.KeyDesc
.KeyData
[5] = 0x03;
1836 NdisMoveMemory(&Packet
.KeyDesc
.KeyData
[6], pDA
, MAC_ADDR_LEN
);
1838 NdisMoveMemory(Packet
.KeyDesc
.ReplayCounter
, pAd
->StaCfg
.DlsReplayCounter
, LEN_KEY_DESC_REPLAY
);
1840 // Allocate buffer for transmitting message
1841 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
);
1842 if (NStatus
!= NDIS_STATUS_SUCCESS
)
1845 // Prepare EAPOL frame for MIC calculation
1846 // Be careful, only EAPOL frame is counted for MIC calculation
1847 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1848 Packet
.Body_Len
[1] + 4, &Packet
,
1851 // use proprietary PTK
1852 NdisZeroMemory(temp
, 64);
1853 NdisMoveMemory(temp
, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1854 WpaCountPTK(pAd
, temp
, temp
, pAd
->CommonCfg
.Bssid
, temp
, pAd
->CurrentAddress
, DlsPTK
, LEN_PTK
);
1857 if (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
1860 NdisZeroMemory(digest
, sizeof(digest
));
1861 HMAC_SHA1(pOutBuffer
, FrameLen
, DlsPTK
, LEN_EAP_MICK
, digest
);
1862 NdisMoveMemory(Packet
.KeyDesc
.KeyMic
, digest
, LEN_KEY_DESC_MIC
);
1866 NdisZeroMemory(Mic
, sizeof(Mic
));
1867 hmac_md5(DlsPTK
, LEN_EAP_MICK
, pOutBuffer
, FrameLen
, Mic
);
1868 NdisMoveMemory(Packet
.KeyDesc
.KeyMic
, Mic
, LEN_KEY_DESC_MIC
);
1871 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1872 sizeof(Header802_3
), Header802_3
,
1873 Packet
.Body_Len
[1] + 4, &Packet
,
1876 NStatus
= RTMPAllocateNdisPacket(pAd
, &pNdisPacket
, NULL
, 0, pOutBuffer
, FrameLen
);
1877 if (NStatus
== NDIS_STATUS_SUCCESS
)
1879 RTMP_SET_PACKET_WCID(pNdisPacket
, BSSID_WCID
);
1880 STASendPacket(pAd
, pNdisPacket
);
1881 RTMPDeQueuePacket(pAd
, FALSE
, NUM_OF_TX_RING
, MAX_TX_PROCESS
);
1884 MlmeFreeMemory(pAd
, pOutBuffer
);
1886 DBGPRINT(RT_DEBUG_TRACE
, ("RTMPSendSTAKeyHandShake- Send STAKey Message-2 (NStatus=%x, FrameLen=%ld)\n", NStatus
, FrameLen
));
1891 VOID
DlsTimeoutAction(
1892 IN PVOID SystemSpecific1
,
1893 IN PVOID FunctionContext
,
1894 IN PVOID SystemSpecific2
,
1895 IN PVOID SystemSpecific3
)
1897 MLME_DLS_REQ_STRUCT MlmeDlsReq
;
1899 PRT_802_11_DLS pDLS
= (PRT_802_11_DLS
)FunctionContext
;
1900 PRTMP_ADAPTER pAd
= pDLS
->pAd
;
1902 DBGPRINT(RT_DEBUG_TRACE
, ("DlsTimeout - Tear down DLS links (%02x:%02x:%02x:%02x:%02x:%02x)\n",
1903 pDLS
->MacAddr
[0], pDLS
->MacAddr
[1], pDLS
->MacAddr
[2], pDLS
->MacAddr
[3], pDLS
->MacAddr
[4], pDLS
->MacAddr
[5]));
1905 if ((pDLS
) && (pDLS
->Valid
))
1907 reason
= REASON_QOS_REQUEST_TIMEOUT
;
1908 pDLS
->Valid
= FALSE
;
1909 pDLS
->Status
= DLS_NONE
;
1910 DlsParmFill(pAd
, &MlmeDlsReq
, pDLS
, reason
);
1911 MlmeEnqueue(pAd
, DLS_STATE_MACHINE
, MT2_MLME_DLS_TEAR_DOWN
, sizeof(MLME_DLS_REQ_STRUCT
), &MlmeDlsReq
);
1912 RT28XX_MLME_HANDLER(pAd
);
1917 ================================================================
1918 Description : because DLS and CLI share the same WCID table in ASIC.
1919 Mesh entry also insert to pAd->MacTab.content[]. Such is marked as ValidAsDls = TRUE.
1920 Also fills the pairwise key.
1921 Because front MAX_AID_BA entries have direct mapping to BAEntry, which is only used as CLI. So we insert Dls
1922 from index MAX_AID_BA.
1923 ================================================================
1925 MAC_TABLE_ENTRY
*MacTableInsertDlsEntry(
1926 IN PRTMP_ADAPTER pAd
,
1928 IN UINT DlsEntryIdx
)
1930 PMAC_TABLE_ENTRY pEntry
= NULL
;
1932 DBGPRINT(RT_DEBUG_TRACE
, ("====> MacTableInsertDlsEntry\n"));
1934 if (pAd
->MacTab
.Size
>= MAX_LEN_OF_MAC_TABLE
)
1939 if((pEntry
= DlsEntryTableLookup(pAd
, pAddr
, TRUE
)) != NULL
)
1942 // allocate one MAC entry
1943 pEntry
= MacTableInsertEntry(pAd
, pAddr
, DlsEntryIdx
+ MIN_NET_DEVICE_FOR_DLS
, TRUE
);
1946 pAd
->StaCfg
.DLSEntry
[DlsEntryIdx
].MacTabMatchWCID
= pEntry
->Aid
;
1947 pEntry
->MatchDlsEntryIdx
= DlsEntryIdx
;
1948 pEntry
->AuthMode
= pAd
->StaCfg
.AuthMode
;
1949 pEntry
->WepStatus
= pAd
->StaCfg
.WepStatus
;
1950 pEntry
->PortSecured
= WPA_802_1X_PORT_SECURED
;
1952 DBGPRINT(RT_DEBUG_TRACE
, ("MacTableInsertDlsEntry - allocate entry #%d, Total= %d\n",pEntry
->Aid
, pAd
->MacTab
.Size
));
1954 // If legacy WEP is used, set pair-wise cipherAlg into WCID attribute table for this entry
1955 if ((pEntry
->ValidAsDls
) && (pEntry
->WepStatus
== Ndis802_11WEPEnabled
))
1958 UCHAR CipherAlg
= 0;
1960 KeyIdx
= pAd
->StaCfg
.DefaultKeyId
;
1962 CipherAlg
= pAd
->SharedKey
[BSS0
][KeyIdx
].CipherAlg
;
1964 RTMPAddWcidAttributeEntry(pAd
,
1966 pAd
->StaCfg
.DefaultKeyId
,
1967 pAd
->SharedKey
[BSS0
][pAd
->StaCfg
.DefaultKeyId
].CipherAlg
,
1975 DBGPRINT(RT_DEBUG_TRACE
, ("<==== MacTableInsertDlsEntry\n"));
1982 ==========================================================================
1984 Delete all Mesh Entry in pAd->MacTab
1985 ==========================================================================
1987 BOOLEAN
MacTableDeleteDlsEntry(
1988 IN PRTMP_ADAPTER pAd
,
1992 DBGPRINT(RT_DEBUG_TRACE
, ("====> MacTableDeleteDlsEntry\n"));
1994 if (!VALID_WCID(wcid
))
1997 MacTableDeleteEntry(pAd
, wcid
, pAddr
);
1999 DBGPRINT(RT_DEBUG_TRACE
, ("<==== MacTableDeleteDlsEntry\n"));
2004 MAC_TABLE_ENTRY
*DlsEntryTableLookup(
2005 IN PRTMP_ADAPTER pAd
,
2007 IN BOOLEAN bResetIdelCount
)
2010 MAC_TABLE_ENTRY
*pEntry
= NULL
;
2012 RTMP_SEM_LOCK(&pAd
->MacTabLock
);
2013 HashIdx
= MAC_ADDR_HASH_INDEX(pAddr
);
2014 pEntry
= pAd
->MacTab
.Hash
[HashIdx
];
2018 if ((pEntry
->ValidAsDls
== TRUE
)
2019 && MAC_ADDR_EQUAL(pEntry
->Addr
, pAddr
))
2022 pEntry
->NoDataIdleCount
= 0;
2026 pEntry
= pEntry
->pNext
;
2029 RTMP_SEM_UNLOCK(&pAd
->MacTabLock
);
2033 MAC_TABLE_ENTRY
*DlsEntryTableLookupByWcid(
2034 IN PRTMP_ADAPTER pAd
,
2037 IN BOOLEAN bResetIdelCount
)
2040 PMAC_TABLE_ENTRY pCurEntry
= NULL
;
2041 PMAC_TABLE_ENTRY pEntry
= NULL
;
2043 if (!VALID_WCID(wcid
))
2046 RTMP_SEM_LOCK(&pAd
->MacTabLock
);
2050 pCurEntry
= &pAd
->MacTab
.Content
[wcid
];
2053 if ((pCurEntry
) && (pCurEntry
->ValidAsDls
== TRUE
))
2055 DLsIndex
= pCurEntry
->MatchDlsEntryIdx
;
2058 if (DLsIndex
== 0xff)
2061 if (MAC_ADDR_EQUAL(pCurEntry
->Addr
, pAddr
))
2064 pCurEntry
->NoDataIdleCount
= 0;
2070 RTMP_SEM_UNLOCK(&pAd
->MacTabLock
);
2075 INT
Set_DlsEntryInfo_Display_Proc(
2076 IN PRTMP_ADAPTER pAd
,
2081 printk("\n%-19s%-8s\n", "MAC", "TIMEOUT\n");
2082 for (i
=0; i
<MAX_NUM_OF_DLS_ENTRY
; i
++)
2084 if ((pAd
->StaCfg
.DLSEntry
[i
].Valid
) && (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
))
2086 PMAC_TABLE_ENTRY pEntry
= &pAd
->MacTab
.Content
[pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
];
2088 printk("%02x:%02x:%02x:%02x:%02x:%02x ",
2089 pAd
->StaCfg
.DLSEntry
[i
].MacAddr
[0], pAd
->StaCfg
.DLSEntry
[i
].MacAddr
[1], pAd
->StaCfg
.DLSEntry
[i
].MacAddr
[2],
2090 pAd
->StaCfg
.DLSEntry
[i
].MacAddr
[3], pAd
->StaCfg
.DLSEntry
[i
].MacAddr
[4], pAd
->StaCfg
.DLSEntry
[i
].MacAddr
[5]);
2091 printk("%-8d\n", pAd
->StaCfg
.DLSEntry
[i
].TimeOut
);
2094 printk("\n%-19s%-4s%-4s%-4s%-4s%-7s%-7s%-7s","MAC", "AID", "BSS", "PSM", "WMM", "RSSI0", "RSSI1", "RSSI2");
2095 #ifdef DOT11_N_SUPPORT
2096 printk("%-8s%-10s%-6s%-6s%-6s%-6s", "MIMOPS", "PhMd", "BW", "MCS", "SGI", "STBC");
2097 #endif // DOT11_N_SUPPORT //
2098 printk("\n%02X:%02X:%02X:%02X:%02X:%02X ",
2099 pEntry
->Addr
[0], pEntry
->Addr
[1], pEntry
->Addr
[2],
2100 pEntry
->Addr
[3], pEntry
->Addr
[4], pEntry
->Addr
[5]);
2101 printk("%-4d", (int)pEntry
->Aid
);
2102 printk("%-4d", (int)pEntry
->apidx
);
2103 printk("%-4d", (int)pEntry
->PsMode
);
2104 printk("%-4d", (int)CLIENT_STATUS_TEST_FLAG(pEntry
, fCLIENT_STATUS_WMM_CAPABLE
));
2105 printk("%-7d", pEntry
->RssiSample
.AvgRssi0
);
2106 printk("%-7d", pEntry
->RssiSample
.AvgRssi1
);
2107 printk("%-7d", pEntry
->RssiSample
.AvgRssi2
);
2108 #ifdef DOT11_N_SUPPORT
2109 printk("%-8d", (int)pEntry
->MmpsMode
);
2110 printk("%-10s", GetPhyMode(pEntry
->HTPhyMode
.field
.MODE
));
2111 printk("%-6s", GetBW(pEntry
->HTPhyMode
.field
.BW
));
2112 printk("%-6d", pEntry
->HTPhyMode
.field
.MCS
);
2113 printk("%-6d", pEntry
->HTPhyMode
.field
.ShortGI
);
2114 printk("%-6d", pEntry
->HTPhyMode
.field
.STBC
);
2115 #endif // DOT11_N_SUPPORT //
2116 printk("%-10d, %d, %d%%\n", pEntry
->DebugFIFOCount
, pEntry
->DebugTxCount
,
2117 (pEntry
->DebugTxCount
) ? ((pEntry
->DebugTxCount
-pEntry
->DebugFIFOCount
)*100/pEntry
->DebugTxCount
) : 0);
2126 INT
Set_DlsAddEntry_Proc(
2127 IN PRTMP_ADAPTER pAd
,
2130 UCHAR mac
[MAC_ADDR_LEN
];
2132 char *token
, sepValue
[] = ":", DASH
= '-';
2136 if(strlen(arg
) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and timeout value in decimal format.
2139 token
= strchr(arg
, DASH
);
2140 if ((token
!= NULL
) && (strlen(token
)>1))
2142 Timeout
= simple_strtol((token
+1), 0, 10);
2145 for (i
= 0, token
= rstrtok(arg
, &sepValue
[0]); token
; token
= rstrtok(NULL
, &sepValue
[0]), i
++)
2147 if((strlen(token
) != 2) || (!isxdigit(*token
)) || (!isxdigit(*(token
+1))))
2149 AtoH(token
, (PUCHAR
)(&mac
[i
]), 1);
2154 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%d", mac
[0], mac
[1],
2155 mac
[2], mac
[3], mac
[4], mac
[5], (int)Timeout
);
2157 NdisZeroMemory(&Dls
, sizeof(RT_802_11_DLS
));
2158 Dls
.TimeOut
= Timeout
;
2159 COPY_MAC_ADDR(Dls
.MacAddr
, mac
);
2163 MLME_CNTL_STATE_MACHINE
,
2164 RT_OID_802_11_SET_DLS_PARAM
,
2165 sizeof(RT_802_11_DLS
),
2175 INT
Set_DlsTearDownEntry_Proc(
2176 IN PRTMP_ADAPTER pAd
,
2179 UCHAR macAddr
[MAC_ADDR_LEN
];
2184 if(strlen(arg
) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
2187 for (i
=0, value
= rstrtok(arg
,":"); value
; value
= rstrtok(NULL
,":"))
2189 if((strlen(value
) != 2) || (!isxdigit(*value
)) || (!isxdigit(*(value
+1))) )
2190 return FALSE
; //Invalid
2192 AtoH(value
, &macAddr
[i
++], 2);
2195 printk("\n%02x:%02x:%02x:%02x:%02x:%02x", macAddr
[0], macAddr
[1],
2196 macAddr
[2], macAddr
[3], macAddr
[4], macAddr
[5]);
2198 NdisZeroMemory(&Dls
, sizeof(RT_802_11_DLS
));
2199 COPY_MAC_ADDR(Dls
.MacAddr
, macAddr
);
2203 MLME_CNTL_STATE_MACHINE
,
2204 RT_OID_802_11_SET_DLS_PARAM
,
2205 sizeof(RT_802_11_DLS
),