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"
44 ==========================================================================
46 dls state machine init, including state transition and timer init
48 Sm - pointer to the dls state machine
50 The state machine looks like this
53 MT2_MLME_DLS_REQUEST MlmeDlsReqAction
54 MT2_PEER_DLS_REQUEST PeerDlsReqAction
55 MT2_PEER_DLS_RESPONSE PeerDlsRspAction
56 MT2_MLME_DLS_TEARDOWN MlmeTearDownAction
57 MT2_PEER_DLS_TEARDOWN PeerTearDownAction
61 ==========================================================================
63 void DlsStateMachineInit(
66 OUT STATE_MACHINE_FUNC Trans
[])
70 StateMachineInit(Sm
, (STATE_MACHINE_FUNC
*)Trans
, MAX_DLS_STATE
, MAX_DLS_MSG
, (STATE_MACHINE_FUNC
)Drop
, DLS_IDLE
, DLS_MACHINE_BASE
);
73 StateMachineSetAction(Sm
, DLS_IDLE
, MT2_MLME_DLS_REQ
, (STATE_MACHINE_FUNC
)MlmeDlsReqAction
);
74 StateMachineSetAction(Sm
, DLS_IDLE
, MT2_PEER_DLS_REQ
, (STATE_MACHINE_FUNC
)PeerDlsReqAction
);
75 StateMachineSetAction(Sm
, DLS_IDLE
, MT2_PEER_DLS_RSP
, (STATE_MACHINE_FUNC
)PeerDlsRspAction
);
76 StateMachineSetAction(Sm
, DLS_IDLE
, MT2_MLME_DLS_TEAR_DOWN
, (STATE_MACHINE_FUNC
)MlmeDlsTearDownAction
);
77 StateMachineSetAction(Sm
, DLS_IDLE
, MT2_PEER_DLS_TEAR_DOWN
, (STATE_MACHINE_FUNC
)PeerDlsTearDownAction
);
79 for (i
=0; i
<MAX_NUM_OF_DLS_ENTRY
; i
++)
81 pAd
->StaCfg
.DLSEntry
[i
].pAd
= pAd
;
82 RTMPInitTimer(pAd
, &pAd
->StaCfg
.DLSEntry
[i
].Timer
, GET_TIMER_FUNCTION(DlsTimeoutAction
), pAd
, FALSE
);
87 ==========================================================================
92 ==========================================================================
94 VOID
MlmeDlsReqAction(
96 IN MLME_QUEUE_ELEM
*Elem
)
98 PUCHAR pOutBuffer
= NULL
;
101 HEADER_802_11 DlsReqHdr
;
102 PRT_802_11_DLS pDLS
= NULL
;
103 UCHAR Category
= CATEGORY_DLS
;
104 UCHAR Action
= ACTION_DLS_REQUEST
;
108 BOOLEAN TimerCancelled
;
110 if(!MlmeDlsReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &pDLS
, &reason
))
113 DBGPRINT(RT_DEBUG_TRACE
,("DLS - MlmeDlsReqAction() \n"));
115 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
116 if (NStatus
!= NDIS_STATUS_SUCCESS
)
118 DBGPRINT(RT_DEBUG_ERROR
,("DLS - MlmeDlsReqAction() allocate memory failed \n"));
122 ActHeaderInit(pAd
, &DlsReqHdr
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
124 // Build basic frame first
125 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
126 sizeof(HEADER_802_11
), &DlsReqHdr
,
130 6, pAd
->CurrentAddress
,
131 2, &pAd
->StaActive
.CapabilityInfo
,
134 1, &pAd
->MlmeAux
.SupRateLen
,
135 pAd
->MlmeAux
.SupRateLen
, pAd
->MlmeAux
.SupRate
,
138 if (pAd
->MlmeAux
.ExtRateLen
!= 0)
140 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
142 1, &pAd
->MlmeAux
.ExtRateLen
,
143 pAd
->MlmeAux
.ExtRateLen
, pAd
->MlmeAux
.ExtRate
,
148 #ifdef DOT11_N_SUPPORT
149 if ((pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
))
154 HT_CAPABILITY_IE HtCapabilityTmp
;
157 // add HT Capability IE
158 HtLen
= sizeof(HT_CAPABILITY_IE
);
159 #ifndef RT_BIG_ENDIAN
160 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
163 HtLen
, &pAd
->CommonCfg
.HtCapability
,
166 NdisMoveMemory(&HtCapabilityTmp
, &pAd
->CommonCfg
.HtCapability
, HtLen
);
167 *(USHORT
*)(&HtCapabilityTmp
.HtCapInfo
) = SWAP16(*(USHORT
*)(&HtCapabilityTmp
.HtCapInfo
));
168 *(USHORT
*)(&HtCapabilityTmp
.ExtHtCapInfo
) = SWAP16(*(USHORT
*)(&HtCapabilityTmp
.ExtHtCapInfo
));
170 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
173 HtLen
, &HtCapabilityTmp
,
176 FrameLen
= FrameLen
+ tmp
;
178 #endif // DOT11_N_SUPPORT //
180 RTMPCancelTimer(&pDLS
->Timer
, &TimerCancelled
);
181 Timeout
= DLS_TIMEOUT
;
182 RTMPSetTimer(&pDLS
->Timer
, Timeout
);
184 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
);
185 MlmeFreeMemory(pAd
, pOutBuffer
);
189 ==========================================================================
192 IRQL = DISPATCH_LEVEL
194 ==========================================================================
196 VOID
PeerDlsReqAction(
197 IN PRTMP_ADAPTER pAd
,
198 IN MLME_QUEUE_ELEM
*Elem
)
200 PUCHAR pOutBuffer
= NULL
;
203 USHORT StatusCode
= MLME_SUCCESS
;
204 HEADER_802_11 DlsRspHdr
;
205 UCHAR Category
= CATEGORY_DLS
;
206 UCHAR Action
= ACTION_DLS_RESPONSE
;
208 USHORT CapabilityInfo
;
209 UCHAR DA
[MAC_ADDR_LEN
], SA
[MAC_ADDR_LEN
];
213 BOOLEAN TimerCancelled
;
214 PRT_802_11_DLS pDLS
= NULL
;
215 UCHAR MaxSupportedRateIn500Kbps
= 0;
216 UCHAR SupportedRatesLen
;
217 UCHAR SupportedRates
[MAX_LEN_OF_SUPPORTED_RATES
];
218 UCHAR HtCapabilityLen
;
219 HT_CAPABILITY_IE HtCapability
;
221 if (!PeerDlsReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, DA
, SA
, &CapabilityInfo
, &DLSTimeOut
,
222 &SupportedRatesLen
, &SupportedRates
[0], &HtCapabilityLen
, &HtCapability
))
225 // supported rates array may not be sorted. sort it and find the maximum rate
226 for (i
= 0; i
< SupportedRatesLen
; i
++)
228 if (MaxSupportedRateIn500Kbps
< (SupportedRates
[i
] & 0x7f))
229 MaxSupportedRateIn500Kbps
= SupportedRates
[i
] & 0x7f;
232 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]));
234 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
235 if (NStatus
!= NDIS_STATUS_SUCCESS
)
237 DBGPRINT(RT_DEBUG_ERROR
,("DLS - PeerDlsReqAction() allocate memory failed \n"));
243 StatusCode
= MLME_REQUEST_DECLINED
;
245 else if (!pAd
->CommonCfg
.bWmmCapable
)
247 StatusCode
= MLME_DEST_STA_IS_NOT_A_QSTA
;
249 else if (!pAd
->CommonCfg
.bDLSCapable
)
251 StatusCode
= MLME_REQUEST_DECLINED
;
255 // find table to update parameters
256 for (i
= (MAX_NUM_OF_DLS_ENTRY
-1); i
>= 0; i
--)
258 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& MAC_ADDR_EQUAL(SA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
260 if (pAd
->StaCfg
.AuthMode
>= Ndis802_11AuthModeWPA
)
261 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_WAIT_KEY
;
264 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
265 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_FINISH
;
268 pAd
->StaCfg
.DLSEntry
[i
].Sequence
= 0;
269 pAd
->StaCfg
.DLSEntry
[i
].TimeOut
= DLSTimeOut
;
270 pAd
->StaCfg
.DLSEntry
[i
].CountDownTimer
= DLSTimeOut
;
271 if (HtCapabilityLen
!= 0)
272 pAd
->StaCfg
.DLSEntry
[i
].bHTCap
= TRUE
;
274 pAd
->StaCfg
.DLSEntry
[i
].bHTCap
= FALSE
;
275 pDLS
= &pAd
->StaCfg
.DLSEntry
[i
];
280 // can not find in table, create a new one
283 DBGPRINT(RT_DEBUG_TRACE
,("DLS - PeerDlsReqAction() can not find same entry \n"));
284 for (i
=(MAX_NUM_OF_DLS_ENTRY
- 1); i
>= MAX_NUM_OF_INIT_DLS_ENTRY
; i
--)
286 if (!pAd
->StaCfg
.DLSEntry
[i
].Valid
)
288 MAC_TABLE_ENTRY
*pEntry
;
289 UCHAR MaxSupportedRate
= RATE_11
;
291 if (pAd
->StaCfg
.AuthMode
>= Ndis802_11AuthModeWPA
)
293 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_WAIT_KEY
;
297 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
298 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_FINISH
;
301 pAd
->StaCfg
.DLSEntry
[i
].Sequence
= 0;
302 pAd
->StaCfg
.DLSEntry
[i
].Valid
= TRUE
;
303 pAd
->StaCfg
.DLSEntry
[i
].TimeOut
= DLSTimeOut
;
304 pAd
->StaCfg
.DLSEntry
[i
].CountDownTimer
= DLSTimeOut
;
305 NdisMoveMemory(pAd
->StaCfg
.DLSEntry
[i
].MacAddr
, SA
, MAC_ADDR_LEN
);
306 if (HtCapabilityLen
!= 0)
307 pAd
->StaCfg
.DLSEntry
[i
].bHTCap
= TRUE
;
309 pAd
->StaCfg
.DLSEntry
[i
].bHTCap
= FALSE
;
310 pDLS
= &pAd
->StaCfg
.DLSEntry
[i
];
311 pEntry
= MacTableInsertDlsEntry(pAd
, SA
, i
);
313 switch (MaxSupportedRateIn500Kbps
)
315 case 108: MaxSupportedRate
= RATE_54
; break;
316 case 96: MaxSupportedRate
= RATE_48
; break;
317 case 72: MaxSupportedRate
= RATE_36
; break;
318 case 48: MaxSupportedRate
= RATE_24
; break;
319 case 36: MaxSupportedRate
= RATE_18
; break;
320 case 24: MaxSupportedRate
= RATE_12
; break;
321 case 18: MaxSupportedRate
= RATE_9
; break;
322 case 12: MaxSupportedRate
= RATE_6
; break;
323 case 22: MaxSupportedRate
= RATE_11
; break;
324 case 11: MaxSupportedRate
= RATE_5_5
; break;
325 case 4: MaxSupportedRate
= RATE_2
; break;
326 case 2: MaxSupportedRate
= RATE_1
; break;
327 default: MaxSupportedRate
= RATE_11
; break;
330 pEntry
->MaxSupportedRate
= min(pAd
->CommonCfg
.MaxTxRate
, MaxSupportedRate
);
332 if (pEntry
->MaxSupportedRate
< RATE_FIRST_OFDM_RATE
)
334 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_CCK
;
335 pEntry
->MaxHTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
336 pEntry
->MinHTPhyMode
.field
.MODE
= MODE_CCK
;
337 pEntry
->MinHTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
338 pEntry
->HTPhyMode
.field
.MODE
= MODE_CCK
;
339 pEntry
->HTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
343 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_OFDM
;
344 pEntry
->MaxHTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
345 pEntry
->MinHTPhyMode
.field
.MODE
= MODE_OFDM
;
346 pEntry
->MinHTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
347 pEntry
->HTPhyMode
.field
.MODE
= MODE_OFDM
;
348 pEntry
->HTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
351 pEntry
->MaxHTPhyMode
.field
.BW
= BW_20
;
352 pEntry
->MinHTPhyMode
.field
.BW
= BW_20
;
354 #ifdef DOT11_N_SUPPORT
355 pEntry
->HTCapability
.MCSSet
[0] = 0;
356 pEntry
->HTCapability
.MCSSet
[1] = 0;
358 // If this Entry supports 802.11n, upgrade to HT rate.
359 if ((HtCapabilityLen
!= 0) && (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
))
361 UCHAR j
, bitmask
; //k,bitmask;
364 DBGPRINT(RT_DEBUG_TRACE
, ("DLS - PeerDlsReqAction() Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
365 SA
[0], SA
[1], SA
[2], SA
[3], SA
[4], SA
[5]));
367 if ((HtCapability
.HtCapInfo
.GF
) && (pAd
->CommonCfg
.DesiredHtPhy
.GF
))
369 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTGREENFIELD
;
373 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTMIX
;
374 pAd
->MacTab
.fAnyStationNonGF
= TRUE
;
375 pAd
->CommonCfg
.AddHTInfo
.AddHtInfo2
.NonGfPresent
= 1;
378 if ((HtCapability
.HtCapInfo
.ChannelWidth
) && (pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
))
380 pEntry
->MaxHTPhyMode
.field
.BW
= BW_40
;
381 pEntry
->MaxHTPhyMode
.field
.ShortGI
= ((pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor40
)&(HtCapability
.HtCapInfo
.ShortGIfor40
));
385 pEntry
->MaxHTPhyMode
.field
.BW
= BW_20
;
386 pEntry
->MaxHTPhyMode
.field
.ShortGI
= ((pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor20
)&(HtCapability
.HtCapInfo
.ShortGIfor20
));
387 pAd
->MacTab
.fAnyStation20Only
= TRUE
;
390 // find max fixed rate
391 for (ii
=15; ii
>=0; ii
--)
394 bitmask
= (1<<(ii
-(j
*8)));
395 if ( (pAd
->StaCfg
.DesiredHtPhyInfo
.MCSSet
[j
]&bitmask
) && (HtCapability
.MCSSet
[j
]&bitmask
))
397 pEntry
->MaxHTPhyMode
.field
.MCS
= ii
;
405 if (pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
!= MCS_AUTO
)
408 DBGPRINT(RT_DEBUG_OFF
, ("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
409 pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
));
410 if (pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
== 32)
412 // Fix MCS as HT Duplicated Mode
413 pEntry
->MaxHTPhyMode
.field
.BW
= 1;
414 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTMIX
;
415 pEntry
->MaxHTPhyMode
.field
.STBC
= 0;
416 pEntry
->MaxHTPhyMode
.field
.ShortGI
= 0;
417 pEntry
->MaxHTPhyMode
.field
.MCS
= 32;
419 else if (pEntry
->MaxHTPhyMode
.field
.MCS
> pAd
->StaCfg
.HTPhyMode
.field
.MCS
)
421 // STA supports fixed MCS
422 pEntry
->MaxHTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
426 pEntry
->MaxHTPhyMode
.field
.STBC
= (HtCapability
.HtCapInfo
.RxSTBC
& (pAd
->CommonCfg
.DesiredHtPhy
.TxSTBC
));
427 pEntry
->MpduDensity
= HtCapability
.HtCapParm
.MpduDensity
;
428 pEntry
->MaxRAmpduFactor
= HtCapability
.HtCapParm
.MaxRAmpduFactor
;
429 pEntry
->MmpsMode
= (UCHAR
)HtCapability
.HtCapInfo
.MimoPs
;
430 pEntry
->AMsduSize
= (UCHAR
)HtCapability
.HtCapInfo
.AMsduSize
;
431 pEntry
->HTPhyMode
.word
= pEntry
->MaxHTPhyMode
.word
;
433 if (HtCapability
.HtCapInfo
.ShortGIfor20
)
434 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_SGI20_CAPABLE
);
435 if (HtCapability
.HtCapInfo
.ShortGIfor40
)
436 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_SGI40_CAPABLE
);
437 if (HtCapability
.HtCapInfo
.TxSTBC
)
438 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_TxSTBC_CAPABLE
);
439 if (HtCapability
.HtCapInfo
.RxSTBC
)
440 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_RxSTBC_CAPABLE
);
441 if (HtCapability
.ExtHtCapInfo
.PlusHTC
)
442 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_HTC_CAPABLE
);
443 if (pAd
->CommonCfg
.bRdg
&& HtCapability
.ExtHtCapInfo
.RDGSupport
)
444 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_RDG_CAPABLE
);
445 if (HtCapability
.ExtHtCapInfo
.MCSFeedback
== 0x03)
446 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE
);
448 NdisMoveMemory(&pEntry
->HTCapability
, &HtCapability
, sizeof(HT_CAPABILITY_IE
));
450 #endif // DOT11_N_SUPPORT //
452 pEntry
->HTPhyMode
.word
= pEntry
->MaxHTPhyMode
.word
;
453 pEntry
->CurrTxRate
= pEntry
->MaxSupportedRate
;
454 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_WMM_CAPABLE
);
456 if (pAd
->StaCfg
.bAutoTxRateSwitch
== TRUE
)
461 MlmeSelectTxRateTable(pAd
, pEntry
, &pTable
, &TableSize
, &pEntry
->CurrTxRateIndex
);
462 pEntry
->bAutoTxRateSwitch
= TRUE
;
466 pEntry
->HTPhyMode
.field
.MODE
= pAd
->StaCfg
.HTPhyMode
.field
.MODE
;
467 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
468 pEntry
->bAutoTxRateSwitch
= FALSE
;
470 RTMPUpdateLegacyTxSetting((UCHAR
)pAd
->StaCfg
.DesiredTransmitSetting
.field
.FixedTxMode
, pEntry
);
472 pEntry
->RateLen
= SupportedRatesLen
;
478 StatusCode
= MLME_SUCCESS
;
480 // can not find in table, create a new one
483 StatusCode
= MLME_QOS_UNSPECIFY
;
484 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
));
488 DBGPRINT(RT_DEBUG_TRACE
,("DLS - PeerDlsReqAction() use entry(%d) %02x:%02x:%02x:%02x:%02x:%02x\n",
489 i
, SA
[0], SA
[1], SA
[2], SA
[3], SA
[4], SA
[5]));
493 ActHeaderInit(pAd
, &DlsRspHdr
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
495 // Build basic frame first
496 if (StatusCode
== MLME_SUCCESS
)
498 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
499 sizeof(HEADER_802_11
), &DlsRspHdr
,
504 6, pAd
->CurrentAddress
,
505 2, &pAd
->StaActive
.CapabilityInfo
,
507 1, &pAd
->MlmeAux
.SupRateLen
,
508 pAd
->MlmeAux
.SupRateLen
, pAd
->MlmeAux
.SupRate
,
511 if (pAd
->MlmeAux
.ExtRateLen
!= 0)
513 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
515 1, &pAd
->MlmeAux
.ExtRateLen
,
516 pAd
->MlmeAux
.ExtRateLen
, pAd
->MlmeAux
.ExtRate
,
521 #ifdef DOT11_N_SUPPORT
522 if ((pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
))
527 HT_CAPABILITY_IE HtCapabilityTmp
;
530 // add HT Capability IE
531 HtLen
= sizeof(HT_CAPABILITY_IE
);
532 #ifndef RT_BIG_ENDIAN
533 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
536 HtLen
, &pAd
->CommonCfg
.HtCapability
,
539 NdisMoveMemory(&HtCapabilityTmp
, &pAd
->CommonCfg
.HtCapability
, HtLen
);
540 *(USHORT
*)(&HtCapabilityTmp
.HtCapInfo
) = SWAP16(*(USHORT
*)(&HtCapabilityTmp
.HtCapInfo
));
541 *(USHORT
*)(&HtCapabilityTmp
.ExtHtCapInfo
) = SWAP16(*(USHORT
*)(&HtCapabilityTmp
.ExtHtCapInfo
));
543 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
546 HtLen
, &HtCapabilityTmp
,
549 FrameLen
= FrameLen
+ tmp
;
551 #endif // DOT11_N_SUPPORT //
553 if (pDLS
&& (pDLS
->Status
!= DLS_FINISH
))
555 RTMPCancelTimer(&pDLS
->Timer
, &TimerCancelled
);
556 Timeout
= DLS_TIMEOUT
;
557 RTMPSetTimer(&pDLS
->Timer
, Timeout
);
562 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
563 sizeof(HEADER_802_11
), &DlsRspHdr
,
568 6, pAd
->CurrentAddress
,
572 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
);
573 MlmeFreeMemory(pAd
, pOutBuffer
);
577 ==========================================================================
580 IRQL = DISPATCH_LEVEL
582 ==========================================================================
584 VOID
PeerDlsRspAction(
585 IN PRTMP_ADAPTER pAd
,
586 IN MLME_QUEUE_ELEM
*Elem
)
588 USHORT CapabilityInfo
;
589 UCHAR DA
[MAC_ADDR_LEN
], SA
[MAC_ADDR_LEN
];
592 BOOLEAN TimerCancelled
;
593 UCHAR MaxSupportedRateIn500Kbps
= 0;
594 UCHAR SupportedRatesLen
;
595 UCHAR SupportedRates
[MAX_LEN_OF_SUPPORTED_RATES
];
596 UCHAR HtCapabilityLen
;
597 HT_CAPABILITY_IE HtCapability
;
599 if (!pAd
->CommonCfg
.bDLSCapable
)
605 if (!PeerDlsRspSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, DA
, SA
, &CapabilityInfo
, &StatusCode
,
606 &SupportedRatesLen
, &SupportedRates
[0], &HtCapabilityLen
, &HtCapability
))
609 // supported rates array may not be sorted. sort it and find the maximum rate
610 for (i
=0; i
<SupportedRatesLen
; i
++)
612 if (MaxSupportedRateIn500Kbps
< (SupportedRates
[i
] & 0x7f))
613 MaxSupportedRateIn500Kbps
= SupportedRates
[i
] & 0x7f;
616 DBGPRINT(RT_DEBUG_TRACE
,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x with StatusCode=%d, CapabilityInfo=0x%x\n",
617 SA
[0], SA
[1], SA
[2], SA
[3], SA
[4], SA
[5], StatusCode
, CapabilityInfo
));
619 for (i
= 0; i
< MAX_NUM_OF_INIT_DLS_ENTRY
; i
++)
621 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& MAC_ADDR_EQUAL(SA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
623 if (StatusCode
== MLME_SUCCESS
)
625 MAC_TABLE_ENTRY
*pEntry
;
626 UCHAR MaxSupportedRate
= RATE_11
;
628 pEntry
= MacTableInsertDlsEntry(pAd
, SA
, i
);
630 switch (MaxSupportedRateIn500Kbps
)
632 case 108: MaxSupportedRate
= RATE_54
; break;
633 case 96: MaxSupportedRate
= RATE_48
; break;
634 case 72: MaxSupportedRate
= RATE_36
; break;
635 case 48: MaxSupportedRate
= RATE_24
; break;
636 case 36: MaxSupportedRate
= RATE_18
; break;
637 case 24: MaxSupportedRate
= RATE_12
; break;
638 case 18: MaxSupportedRate
= RATE_9
; break;
639 case 12: MaxSupportedRate
= RATE_6
; break;
640 case 22: MaxSupportedRate
= RATE_11
; break;
641 case 11: MaxSupportedRate
= RATE_5_5
; break;
642 case 4: MaxSupportedRate
= RATE_2
; break;
643 case 2: MaxSupportedRate
= RATE_1
; break;
644 default: MaxSupportedRate
= RATE_11
; break;
647 pEntry
->MaxSupportedRate
= min(pAd
->CommonCfg
.MaxTxRate
, MaxSupportedRate
);
649 if (pEntry
->MaxSupportedRate
< RATE_FIRST_OFDM_RATE
)
651 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_CCK
;
652 pEntry
->MaxHTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
653 pEntry
->MinHTPhyMode
.field
.MODE
= MODE_CCK
;
654 pEntry
->MinHTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
655 pEntry
->HTPhyMode
.field
.MODE
= MODE_CCK
;
656 pEntry
->HTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
660 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_OFDM
;
661 pEntry
->MaxHTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
662 pEntry
->MinHTPhyMode
.field
.MODE
= MODE_OFDM
;
663 pEntry
->MinHTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
664 pEntry
->HTPhyMode
.field
.MODE
= MODE_OFDM
;
665 pEntry
->HTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
668 pEntry
->MaxHTPhyMode
.field
.BW
= BW_20
;
669 pEntry
->MinHTPhyMode
.field
.BW
= BW_20
;
671 #ifdef DOT11_N_SUPPORT
672 pEntry
->HTCapability
.MCSSet
[0] = 0;
673 pEntry
->HTCapability
.MCSSet
[1] = 0;
675 // If this Entry supports 802.11n, upgrade to HT rate.
676 if ((HtCapabilityLen
!= 0) && (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
))
678 UCHAR j
, bitmask
; //k,bitmask;
681 DBGPRINT(RT_DEBUG_OFF
, ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
682 SA
[0], SA
[1], SA
[2], SA
[3], SA
[4], SA
[5]));
684 if ((HtCapability
.HtCapInfo
.GF
) && (pAd
->CommonCfg
.DesiredHtPhy
.GF
))
686 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTGREENFIELD
;
690 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTMIX
;
691 pAd
->MacTab
.fAnyStationNonGF
= TRUE
;
692 pAd
->CommonCfg
.AddHTInfo
.AddHtInfo2
.NonGfPresent
= 1;
695 if ((HtCapability
.HtCapInfo
.ChannelWidth
) && (pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
))
697 pEntry
->MaxHTPhyMode
.field
.BW
= BW_40
;
698 pEntry
->MaxHTPhyMode
.field
.ShortGI
= ((pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor40
)&(HtCapability
.HtCapInfo
.ShortGIfor40
));
702 pEntry
->MaxHTPhyMode
.field
.BW
= BW_20
;
703 pEntry
->MaxHTPhyMode
.field
.ShortGI
= ((pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor20
)&(HtCapability
.HtCapInfo
.ShortGIfor20
));
704 pAd
->MacTab
.fAnyStation20Only
= TRUE
;
707 // find max fixed rate
708 for (ii
=15; ii
>=0; ii
--)
711 bitmask
= (1<<(ii
-(j
*8)));
712 if ( (pAd
->StaCfg
.DesiredHtPhyInfo
.MCSSet
[j
]&bitmask
) && (HtCapability
.MCSSet
[j
]&bitmask
))
714 pEntry
->MaxHTPhyMode
.field
.MCS
= ii
;
721 if (pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
!= MCS_AUTO
)
723 if (pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
== 32)
725 // Fix MCS as HT Duplicated Mode
726 pEntry
->MaxHTPhyMode
.field
.BW
= 1;
727 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTMIX
;
728 pEntry
->MaxHTPhyMode
.field
.STBC
= 0;
729 pEntry
->MaxHTPhyMode
.field
.ShortGI
= 0;
730 pEntry
->MaxHTPhyMode
.field
.MCS
= 32;
732 else if (pEntry
->MaxHTPhyMode
.field
.MCS
> pAd
->StaCfg
.HTPhyMode
.field
.MCS
)
734 // STA supports fixed MCS
735 pEntry
->MaxHTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
739 pEntry
->MaxHTPhyMode
.field
.STBC
= (HtCapability
.HtCapInfo
.RxSTBC
& (pAd
->CommonCfg
.DesiredHtPhy
.TxSTBC
));
740 pEntry
->MpduDensity
= HtCapability
.HtCapParm
.MpduDensity
;
741 pEntry
->MaxRAmpduFactor
= HtCapability
.HtCapParm
.MaxRAmpduFactor
;
742 pEntry
->MmpsMode
= (UCHAR
)HtCapability
.HtCapInfo
.MimoPs
;
743 pEntry
->AMsduSize
= (UCHAR
)HtCapability
.HtCapInfo
.AMsduSize
;
744 pEntry
->HTPhyMode
.word
= pEntry
->MaxHTPhyMode
.word
;
746 if (HtCapability
.HtCapInfo
.ShortGIfor20
)
747 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_SGI20_CAPABLE
);
748 if (HtCapability
.HtCapInfo
.ShortGIfor40
)
749 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_SGI40_CAPABLE
);
750 if (HtCapability
.HtCapInfo
.TxSTBC
)
751 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_TxSTBC_CAPABLE
);
752 if (HtCapability
.HtCapInfo
.RxSTBC
)
753 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_RxSTBC_CAPABLE
);
754 if (HtCapability
.ExtHtCapInfo
.PlusHTC
)
755 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_HTC_CAPABLE
);
756 if (pAd
->CommonCfg
.bRdg
&& HtCapability
.ExtHtCapInfo
.RDGSupport
)
757 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_RDG_CAPABLE
);
758 if (HtCapability
.ExtHtCapInfo
.MCSFeedback
== 0x03)
759 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE
);
761 NdisMoveMemory(&pEntry
->HTCapability
, &HtCapability
, sizeof(HT_CAPABILITY_IE
));
763 #endif // DOT11_N_SUPPORT //
764 pEntry
->HTPhyMode
.word
= pEntry
->MaxHTPhyMode
.word
;
765 pEntry
->CurrTxRate
= pEntry
->MaxSupportedRate
;
766 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_WMM_CAPABLE
);
768 if (pAd
->StaCfg
.bAutoTxRateSwitch
== TRUE
)
773 MlmeSelectTxRateTable(pAd
, pEntry
, &pTable
, &TableSize
, &pEntry
->CurrTxRateIndex
);
774 pEntry
->bAutoTxRateSwitch
= TRUE
;
778 pEntry
->HTPhyMode
.field
.MODE
= pAd
->StaCfg
.HTPhyMode
.field
.MODE
;
779 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
780 pEntry
->bAutoTxRateSwitch
= FALSE
;
782 RTMPUpdateLegacyTxSetting((UCHAR
)pAd
->StaCfg
.DesiredTransmitSetting
.field
.FixedTxMode
, pEntry
);
784 pEntry
->RateLen
= SupportedRatesLen
;
786 if (pAd
->StaCfg
.AuthMode
>= Ndis802_11AuthModeWPA
)
788 // If support WPA or WPA2, start STAKey hand shake,
789 // If failed hand shake, just tear down peer DLS
790 if (RTMPSendSTAKeyRequest(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
) != NDIS_STATUS_SUCCESS
)
792 MLME_DLS_REQ_STRUCT MlmeDlsReq
;
793 USHORT reason
= REASON_QOS_CIPHER_NOT_SUPPORT
;
795 DlsParmFill(pAd
, &MlmeDlsReq
, &pAd
->StaCfg
.DLSEntry
[i
], reason
);
796 MlmeEnqueue(pAd
, DLS_STATE_MACHINE
, MT2_MLME_DLS_TEAR_DOWN
, sizeof(MLME_DLS_REQ_STRUCT
), &MlmeDlsReq
);
797 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
798 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
799 DBGPRINT(RT_DEBUG_ERROR
,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
803 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_WAIT_KEY
;
804 DBGPRINT(RT_DEBUG_TRACE
,("DLS - waiting for STAKey handshake procedure\n"));
809 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
810 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_FINISH
;
811 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]));
814 //initialize seq no for DLS frames.
815 pAd
->StaCfg
.DLSEntry
[i
].Sequence
= 0;
816 if (HtCapabilityLen
!= 0)
817 pAd
->StaCfg
.DLSEntry
[i
].bHTCap
= TRUE
;
819 pAd
->StaCfg
.DLSEntry
[i
].bHTCap
= FALSE
;
823 // DLS setup procedure failed.
824 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
825 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
826 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
827 DBGPRINT(RT_DEBUG_ERROR
,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode
));
832 if (i
>= MAX_NUM_OF_INIT_DLS_ENTRY
)
834 DBGPRINT(RT_DEBUG_TRACE
,("DLS - PeerDlsRspAction() update timeout value \n"));
835 for (i
=(MAX_NUM_OF_DLS_ENTRY
-1); i
>=MAX_NUM_OF_INIT_DLS_ENTRY
; i
--)
837 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& MAC_ADDR_EQUAL(SA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
839 if (StatusCode
== MLME_SUCCESS
)
841 MAC_TABLE_ENTRY
*pEntry
;
842 UCHAR MaxSupportedRate
= RATE_11
;
844 pEntry
= MacTableInsertDlsEntry(pAd
, SA
, i
);
846 switch (MaxSupportedRateIn500Kbps
)
848 case 108: MaxSupportedRate
= RATE_54
; break;
849 case 96: MaxSupportedRate
= RATE_48
; break;
850 case 72: MaxSupportedRate
= RATE_36
; break;
851 case 48: MaxSupportedRate
= RATE_24
; break;
852 case 36: MaxSupportedRate
= RATE_18
; break;
853 case 24: MaxSupportedRate
= RATE_12
; break;
854 case 18: MaxSupportedRate
= RATE_9
; break;
855 case 12: MaxSupportedRate
= RATE_6
; break;
856 case 22: MaxSupportedRate
= RATE_11
; break;
857 case 11: MaxSupportedRate
= RATE_5_5
; break;
858 case 4: MaxSupportedRate
= RATE_2
; break;
859 case 2: MaxSupportedRate
= RATE_1
; break;
860 default: MaxSupportedRate
= RATE_11
; break;
863 pEntry
->MaxSupportedRate
= min(pAd
->CommonCfg
.MaxTxRate
, MaxSupportedRate
);
865 if (pEntry
->MaxSupportedRate
< RATE_FIRST_OFDM_RATE
)
867 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_CCK
;
868 pEntry
->MaxHTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
869 pEntry
->MinHTPhyMode
.field
.MODE
= MODE_CCK
;
870 pEntry
->MinHTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
871 pEntry
->HTPhyMode
.field
.MODE
= MODE_CCK
;
872 pEntry
->HTPhyMode
.field
.MCS
= pEntry
->MaxSupportedRate
;
876 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_OFDM
;
877 pEntry
->MaxHTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
878 pEntry
->MinHTPhyMode
.field
.MODE
= MODE_OFDM
;
879 pEntry
->MinHTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
880 pEntry
->HTPhyMode
.field
.MODE
= MODE_OFDM
;
881 pEntry
->HTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pEntry
->MaxSupportedRate
];
884 pEntry
->MaxHTPhyMode
.field
.BW
= BW_20
;
885 pEntry
->MinHTPhyMode
.field
.BW
= BW_20
;
887 #ifdef DOT11_N_SUPPORT
888 pEntry
->HTCapability
.MCSSet
[0] = 0;
889 pEntry
->HTCapability
.MCSSet
[1] = 0;
891 // If this Entry supports 802.11n, upgrade to HT rate.
892 if ((HtCapabilityLen
!= 0) && (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
))
894 UCHAR j
, bitmask
; //k,bitmask;
897 DBGPRINT(RT_DEBUG_TRACE
, ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
898 SA
[0], SA
[1], SA
[2], SA
[3], SA
[4], SA
[5]));
900 if ((HtCapability
.HtCapInfo
.GF
) && (pAd
->CommonCfg
.DesiredHtPhy
.GF
))
902 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTGREENFIELD
;
906 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTMIX
;
907 pAd
->MacTab
.fAnyStationNonGF
= TRUE
;
908 pAd
->CommonCfg
.AddHTInfo
.AddHtInfo2
.NonGfPresent
= 1;
911 if ((HtCapability
.HtCapInfo
.ChannelWidth
) && (pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
))
913 pEntry
->MaxHTPhyMode
.field
.BW
= BW_40
;
914 pEntry
->MaxHTPhyMode
.field
.ShortGI
= ((pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor40
)&(HtCapability
.HtCapInfo
.ShortGIfor40
));
918 pEntry
->MaxHTPhyMode
.field
.BW
= BW_20
;
919 pEntry
->MaxHTPhyMode
.field
.ShortGI
= ((pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor20
)&(HtCapability
.HtCapInfo
.ShortGIfor20
));
920 pAd
->MacTab
.fAnyStation20Only
= TRUE
;
923 // find max fixed rate
924 for (ii
=15; ii
>=0; ii
--)
927 bitmask
= (1<<(ii
-(j
*8)));
928 if ( (pAd
->StaCfg
.DesiredHtPhyInfo
.MCSSet
[j
]&bitmask
) && (HtCapability
.MCSSet
[j
]&bitmask
))
930 pEntry
->MaxHTPhyMode
.field
.MCS
= ii
;
937 if (pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
!= MCS_AUTO
)
939 DBGPRINT(RT_DEBUG_OFF
, ("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
940 pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
));
941 if (pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
== 32)
943 // Fix MCS as HT Duplicated Mode
944 pEntry
->MaxHTPhyMode
.field
.BW
= 1;
945 pEntry
->MaxHTPhyMode
.field
.MODE
= MODE_HTMIX
;
946 pEntry
->MaxHTPhyMode
.field
.STBC
= 0;
947 pEntry
->MaxHTPhyMode
.field
.ShortGI
= 0;
948 pEntry
->MaxHTPhyMode
.field
.MCS
= 32;
950 else if (pEntry
->MaxHTPhyMode
.field
.MCS
> pAd
->StaCfg
.HTPhyMode
.field
.MCS
)
952 // STA supports fixed MCS
953 pEntry
->MaxHTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
957 pEntry
->MaxHTPhyMode
.field
.STBC
= (HtCapability
.HtCapInfo
.RxSTBC
& (pAd
->CommonCfg
.DesiredHtPhy
.TxSTBC
));
958 pEntry
->MpduDensity
= HtCapability
.HtCapParm
.MpduDensity
;
959 pEntry
->MaxRAmpduFactor
= HtCapability
.HtCapParm
.MaxRAmpduFactor
;
960 pEntry
->MmpsMode
= (UCHAR
)HtCapability
.HtCapInfo
.MimoPs
;
961 pEntry
->AMsduSize
= (UCHAR
)HtCapability
.HtCapInfo
.AMsduSize
;
962 pEntry
->HTPhyMode
.word
= pEntry
->MaxHTPhyMode
.word
;
964 if (HtCapability
.HtCapInfo
.ShortGIfor20
)
965 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_SGI20_CAPABLE
);
966 if (HtCapability
.HtCapInfo
.ShortGIfor40
)
967 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_SGI40_CAPABLE
);
968 if (HtCapability
.HtCapInfo
.TxSTBC
)
969 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_TxSTBC_CAPABLE
);
970 if (HtCapability
.HtCapInfo
.RxSTBC
)
971 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_RxSTBC_CAPABLE
);
972 if (HtCapability
.ExtHtCapInfo
.PlusHTC
)
973 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_HTC_CAPABLE
);
974 if (pAd
->CommonCfg
.bRdg
&& HtCapability
.ExtHtCapInfo
.RDGSupport
)
975 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_RDG_CAPABLE
);
976 if (HtCapability
.ExtHtCapInfo
.MCSFeedback
== 0x03)
977 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE
);
979 NdisMoveMemory(&pEntry
->HTCapability
, &HtCapability
, sizeof(HT_CAPABILITY_IE
));
981 #endif // DOT11_N_SUPPORT //
983 pEntry
->HTPhyMode
.word
= pEntry
->MaxHTPhyMode
.word
;
984 pEntry
->CurrTxRate
= pEntry
->MaxSupportedRate
;
985 CLIENT_STATUS_SET_FLAG(pEntry
, fCLIENT_STATUS_WMM_CAPABLE
);
987 if (pAd
->StaCfg
.bAutoTxRateSwitch
== TRUE
)
992 MlmeSelectTxRateTable(pAd
, pEntry
, &pTable
, &TableSize
, &pEntry
->CurrTxRateIndex
);
993 pEntry
->bAutoTxRateSwitch
= TRUE
;
997 pEntry
->HTPhyMode
.field
.MODE
= pAd
->StaCfg
.HTPhyMode
.field
.MODE
;
998 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
999 pEntry
->bAutoTxRateSwitch
= FALSE
;
1001 RTMPUpdateLegacyTxSetting((UCHAR
)pAd
->StaCfg
.DesiredTransmitSetting
.field
.FixedTxMode
, pEntry
);
1003 pEntry
->RateLen
= SupportedRatesLen
;
1005 if (pAd
->StaCfg
.AuthMode
>= Ndis802_11AuthModeWPA
)
1007 // If support WPA or WPA2, start STAKey hand shake,
1008 // If failed hand shake, just tear down peer DLS
1009 if (RTMPSendSTAKeyRequest(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
) != NDIS_STATUS_SUCCESS
)
1011 MLME_DLS_REQ_STRUCT MlmeDlsReq
;
1012 USHORT reason
= REASON_QOS_CIPHER_NOT_SUPPORT
;
1014 DlsParmFill(pAd
, &MlmeDlsReq
, &pAd
->StaCfg
.DLSEntry
[i
], reason
);
1015 MlmeEnqueue(pAd
, DLS_STATE_MACHINE
, MT2_MLME_DLS_TEAR_DOWN
, sizeof(MLME_DLS_REQ_STRUCT
), &MlmeDlsReq
);
1016 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
1017 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
1018 DBGPRINT(RT_DEBUG_ERROR
,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
1022 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_WAIT_KEY
;
1023 DBGPRINT(RT_DEBUG_TRACE
,("DLS - waiting for STAKey handshake procedure\n"));
1028 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
1029 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_FINISH
;
1030 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]));
1032 pAd
->StaCfg
.DLSEntry
[i
].Sequence
= 0;
1033 if (HtCapabilityLen
!= 0)
1034 pAd
->StaCfg
.DLSEntry
[i
].bHTCap
= TRUE
;
1036 pAd
->StaCfg
.DLSEntry
[i
].bHTCap
= FALSE
;
1040 // DLS setup procedure failed.
1041 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
1042 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
1043 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
1044 DBGPRINT(RT_DEBUG_ERROR
,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode
));
1052 ==========================================================================
1055 IRQL = DISPATCH_LEVEL
1057 ==========================================================================
1059 VOID
MlmeDlsTearDownAction(
1060 IN PRTMP_ADAPTER pAd
,
1061 IN MLME_QUEUE_ELEM
*Elem
)
1063 PUCHAR pOutBuffer
= NULL
;
1064 NDIS_STATUS NStatus
;
1066 UCHAR Category
= CATEGORY_DLS
;
1067 UCHAR Action
= ACTION_DLS_TEARDOWN
;
1068 USHORT ReasonCode
= REASON_QOS_UNSPECIFY
;
1069 HEADER_802_11 DlsTearDownHdr
;
1070 PRT_802_11_DLS pDLS
;
1071 BOOLEAN TimerCancelled
;
1074 if(!MlmeDlsReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &pDLS
, &ReasonCode
))
1077 DBGPRINT(RT_DEBUG_TRACE
,("DLS - MlmeDlsTearDownAction() with ReasonCode=%d \n", ReasonCode
));
1079 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
1080 if (NStatus
!= NDIS_STATUS_SUCCESS
)
1082 DBGPRINT(RT_DEBUG_ERROR
,("DLS - MlmeDlsTearDownAction() allocate memory failed \n"));
1086 ActHeaderInit(pAd
, &DlsTearDownHdr
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
1088 // Build basic frame first
1089 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1090 sizeof(HEADER_802_11
), &DlsTearDownHdr
,
1094 6, pAd
->CurrentAddress
,
1098 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
);
1099 MlmeFreeMemory(pAd
, pOutBuffer
);
1100 RTMPCancelTimer(&pDLS
->Timer
, &TimerCancelled
);
1102 // Remove key in local dls table entry
1103 for (i
= 0; i
< MAX_NUM_OF_INIT_DLS_ENTRY
; i
++)
1105 if (MAC_ADDR_EQUAL(pDLS
->MacAddr
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1107 MacTableDeleteDlsEntry(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
);
1111 // clear peer dls table entry
1112 for (i
= MAX_NUM_OF_INIT_DLS_ENTRY
; i
< MAX_NUM_OF_DLS_ENTRY
; i
++)
1114 if (MAC_ADDR_EQUAL(pDLS
->MacAddr
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1116 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
1117 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
1118 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
1119 MacTableDeleteDlsEntry(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
);
1125 ==========================================================================
1128 IRQL = DISPATCH_LEVEL
1130 ==========================================================================
1132 VOID
PeerDlsTearDownAction(
1133 IN PRTMP_ADAPTER pAd
,
1134 IN MLME_QUEUE_ELEM
*Elem
)
1136 UCHAR DA
[MAC_ADDR_LEN
], SA
[MAC_ADDR_LEN
];
1139 BOOLEAN TimerCancelled
;
1141 if (!pAd
->CommonCfg
.bDLSCapable
)
1147 if (!PeerDlsTearDownSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, DA
, SA
, &ReasonCode
))
1150 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
));
1152 // clear local dls table entry
1153 for (i
=0; i
<MAX_NUM_OF_INIT_DLS_ENTRY
; i
++)
1155 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& MAC_ADDR_EQUAL(SA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1157 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
1158 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
1159 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
1160 //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1161 //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1162 MacTableDeleteDlsEntry(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
);
1166 // clear peer dls table entry
1167 for (i
=MAX_NUM_OF_INIT_DLS_ENTRY
; i
<MAX_NUM_OF_DLS_ENTRY
; i
++)
1169 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& MAC_ADDR_EQUAL(SA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1171 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
1172 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
1173 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
1174 //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1175 //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1176 MacTableDeleteDlsEntry(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
);
1182 ==========================================================================
1185 IRQL = DISPATCH_LEVEL
1187 ==========================================================================
1189 VOID
RTMPCheckDLSTimeOut(
1190 IN PRTMP_ADAPTER pAd
)
1193 MLME_DLS_REQ_STRUCT MlmeDlsReq
;
1194 USHORT reason
= REASON_QOS_UNSPECIFY
;
1196 if (! pAd
->CommonCfg
.bDLSCapable
)
1199 if (! INFRA_ON(pAd
))
1202 // If timeout value is equaled to zero, it means always not be timeout.
1204 // update local dls table entry
1205 for (i
=0; i
<MAX_NUM_OF_INIT_DLS_ENTRY
; i
++)
1207 if ((pAd
->StaCfg
.DLSEntry
[i
].Valid
) && (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
)
1208 && (pAd
->StaCfg
.DLSEntry
[i
].TimeOut
!= 0))
1210 pAd
->StaCfg
.DLSEntry
[i
].CountDownTimer
--;
1212 if (pAd
->StaCfg
.DLSEntry
[i
].CountDownTimer
== 0)
1214 reason
= REASON_QOS_REQUEST_TIMEOUT
;
1215 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
1216 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
1217 DlsParmFill(pAd
, &MlmeDlsReq
, &pAd
->StaCfg
.DLSEntry
[i
], reason
);
1218 MlmeEnqueue(pAd
, DLS_STATE_MACHINE
, MT2_MLME_DLS_TEAR_DOWN
, sizeof(MLME_DLS_REQ_STRUCT
), &MlmeDlsReq
);
1223 // update peer dls table entry
1224 for (i
=MAX_NUM_OF_INIT_DLS_ENTRY
; i
<MAX_NUM_OF_DLS_ENTRY
; i
++)
1226 if ((pAd
->StaCfg
.DLSEntry
[i
].Valid
) && (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
)
1227 && (pAd
->StaCfg
.DLSEntry
[i
].TimeOut
!= 0))
1229 pAd
->StaCfg
.DLSEntry
[i
].CountDownTimer
--;
1231 if (pAd
->StaCfg
.DLSEntry
[i
].CountDownTimer
== 0)
1233 reason
= REASON_QOS_REQUEST_TIMEOUT
;
1234 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
1235 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
1236 DlsParmFill(pAd
, &MlmeDlsReq
, &pAd
->StaCfg
.DLSEntry
[i
], reason
);
1237 MlmeEnqueue(pAd
, DLS_STATE_MACHINE
, MT2_MLME_DLS_TEAR_DOWN
, sizeof(MLME_DLS_REQ_STRUCT
), &MlmeDlsReq
);
1244 ==========================================================================
1247 IRQL = DISPATCH_LEVEL
1249 ==========================================================================
1251 BOOLEAN
RTMPRcvFrameDLSCheck(
1252 IN PRTMP_ADAPTER pAd
,
1253 IN PHEADER_802_11 pHeader
,
1255 IN PRT28XX_RXD_STRUC pRxD
)
1258 BOOLEAN bFindEntry
= FALSE
;
1259 BOOLEAN bSTAKeyFrame
= FALSE
;
1261 PUCHAR pProto
, pAddr
= NULL
;
1262 PUCHAR pSTAKey
= NULL
;
1263 UCHAR ZeroReplay
[LEN_KEY_DESC_REPLAY
];
1264 UCHAR Mic
[16], OldMic
[16];
1268 BOOLEAN TimerCancelled
;
1269 CIPHER_KEY PairwiseKey
;
1272 if (! pAd
->CommonCfg
.bDLSCapable
)
1273 return bSTAKeyFrame
;
1275 if (! INFRA_ON(pAd
))
1276 return bSTAKeyFrame
;
1278 if (Len
< LENGTH_802_11
+ 6 + 2) /* LENGTH_802_11 + LLC + EAPOL protocol type */
1279 return bSTAKeyFrame
;
1281 pProto
= (PUCHAR
)pHeader
+ LENGTH_802_11
;
1283 if ((pHeader
->FC
.SubType
& 0x08))
1284 pProto
+= 2; /* QOS Control field */
1286 /* Skip 4-bytes for HTC */
1287 if (pHeader
->FC
.Order
&& (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_AGGREGATION_INUSED
)))
1292 /* L2PAD bit on will pad 2 bytes at LLC */
1298 pProto
+= 6; /* 0xAA 0xAA 0xAA 0x00 0x00 0x00 */
1300 if ((!(pHeader
->FC
.SubType
& 0x08)) && (!RTMPEqualMemory(EAPOL
, pProto
, 2)))
1301 return bSTAKeyFrame
;
1303 pAddr
= pHeader
->Addr2
;
1305 if (RTMPEqualMemory(EAPOL
, pProto
, 2) && (pAd
->StaCfg
.AuthMode
>= Ndis802_11AuthModeWPA
))
1307 pEap
= (PEAPOL_PACKET
) (pProto
+ 2);
1309 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
,
1310 (LENGTH_802_11
+ 6 + 2 + 2 + sizeof(EAPOL_PACKET
) - MAX_LEN_OF_RSNIE
+ 16),
1311 pEap
->KeyDesc
.KeyInfo
.KeyMic
,
1312 pEap
->KeyDesc
.KeyInfo
.Install
,
1313 pEap
->KeyDesc
.KeyInfo
.KeyAck
,
1314 pEap
->KeyDesc
.KeyInfo
.Secure
,
1315 pEap
->KeyDesc
.KeyInfo
.EKD_DL
,
1316 pEap
->KeyDesc
.KeyInfo
.Error
,
1317 pEap
->KeyDesc
.KeyInfo
.Request
));
1319 if ((Len
>= (LENGTH_802_11
+ 6 + 2 + 2 + sizeof(EAPOL_PACKET
) - MAX_LEN_OF_RSNIE
+ 16)) && pEap
->KeyDesc
.KeyInfo
.KeyMic
1320 && pEap
->KeyDesc
.KeyInfo
.Install
&& pEap
->KeyDesc
.KeyInfo
.KeyAck
&& pEap
->KeyDesc
.KeyInfo
.Secure
1321 && pEap
->KeyDesc
.KeyInfo
.EKD_DL
&& !pEap
->KeyDesc
.KeyInfo
.Error
&& !pEap
->KeyDesc
.KeyInfo
.Request
)
1323 // First validate replay counter, only accept message with larger replay counter
1324 // Let equal pass, some AP start with all zero replay counter
1325 NdisZeroMemory(ZeroReplay
, LEN_KEY_DESC_REPLAY
);
1326 if ((RTMPCompareMemory(pEap
->KeyDesc
.ReplayCounter
, pAd
->StaCfg
.ReplayCounter
, LEN_KEY_DESC_REPLAY
) != 1) &&
1327 (RTMPCompareMemory(pEap
->KeyDesc
.ReplayCounter
, ZeroReplay
, LEN_KEY_DESC_REPLAY
) != 0))
1328 return bSTAKeyFrame
;
1330 //RTMPMoveMemory(pAd->StaCfg.ReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1331 RTMPMoveMemory(pAd
->StaCfg
.DlsReplayCounter
, pEap
->KeyDesc
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
1332 DBGPRINT(RT_DEBUG_TRACE
,("DLS - Sniff replay counter (%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
1333 pAd
->StaCfg
.ReplayCounter
[0], pAd
->StaCfg
.ReplayCounter
[1], pAd
->StaCfg
.ReplayCounter
[2],
1334 pAd
->StaCfg
.ReplayCounter
[3], pAd
->StaCfg
.ReplayCounter
[4], pAd
->StaCfg
.ReplayCounter
[5],
1335 pAd
->StaCfg
.ReplayCounter
[6], pAd
->StaCfg
.ReplayCounter
[7], Len
, pEap
->KeyDesc
.KeyData
[1]));
1337 // put these code segment to get the replay counter
1338 if (pAd
->StaCfg
.PortSecured
== WPA_802_1X_PORT_NOT_SECURED
)
1339 return bSTAKeyFrame
;
1342 // Save the MIC and replace with zero
1343 // use proprietary PTK
1344 NdisZeroMemory(temp
, 64);
1345 NdisMoveMemory(temp
, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1346 WpaDerivePTK(pAd
, temp
, temp
, pAd
->CommonCfg
.Bssid
, temp
, pAd
->CurrentAddress
, DlsPTK
, LEN_PTK
);
1348 NdisMoveMemory(OldMic
, pEap
->KeyDesc
.KeyMic
, LEN_KEY_DESC_MIC
);
1349 NdisZeroMemory(pEap
->KeyDesc
.KeyMic
, LEN_KEY_DESC_MIC
);
1350 if (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
1353 HMAC_SHA1(DlsPTK
, LEN_EAP_MICK
, (PUCHAR
) pEap
, pEap
->Body_Len
[1] + 4, digest
, SHA1_DIGEST_SIZE
);
1354 NdisMoveMemory(Mic
, digest
, LEN_KEY_DESC_MIC
);
1358 HMAC_MD5(DlsPTK
, LEN_EAP_MICK
, (PUCHAR
) pEap
, pEap
->Body_Len
[1] + 4, Mic
, MD5_DIGEST_SIZE
);
1361 if (!NdisEqualMemory(OldMic
, Mic
, LEN_KEY_DESC_MIC
))
1363 DBGPRINT(RT_DEBUG_ERROR
, ("MIC Different in Msg1 of STAKey handshake! \n"));
1364 return bSTAKeyFrame
;
1367 DBGPRINT(RT_DEBUG_TRACE
, ("MIC VALID in Msg1 of STAKey handshake! \n"));
1368 if ((pEap
->KeyDesc
.KeyData
[0] == 0xDD) && (pEap
->KeyDesc
.KeyData
[2] == 0x00) && (pEap
->KeyDesc
.KeyData
[3] == 0x0C)
1369 && (pEap
->KeyDesc
.KeyData
[4] == 0x43) && (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=%ld, KeyDataLen=%d\n",
1375 pAddr
[0], pAddr
[1], pAddr
[2], pAddr
[3], pAddr
[4], pAddr
[5], Len
, pEap
->KeyDesc
.KeyData
[1]));
1377 bSTAKeyFrame
= TRUE
;
1381 else if (Len
>= (LENGTH_802_11
+ 6 + 2 + 2 + sizeof(EAPOL_PACKET
) - MAX_LEN_OF_RSNIE
))
1383 RTMPMoveMemory(pAd
->StaCfg
.DlsReplayCounter
, pEap
->KeyDesc
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
1384 DBGPRINT(RT_DEBUG_TRACE
,("DLS - Sniff replay counter 2(%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
1385 pAd
->StaCfg
.ReplayCounter
[0], pAd
->StaCfg
.ReplayCounter
[1], pAd
->StaCfg
.ReplayCounter
[2],
1386 pAd
->StaCfg
.ReplayCounter
[3], pAd
->StaCfg
.ReplayCounter
[4], pAd
->StaCfg
.ReplayCounter
[5],
1387 pAd
->StaCfg
.ReplayCounter
[6], pAd
->StaCfg
.ReplayCounter
[7], Len
, pEap
->KeyDesc
.KeyData
[1]));
1391 // If timeout value is equaled to zero, it means always not be timeout.
1392 // update local dls table entry
1393 for (i
= 0; i
< MAX_NUM_OF_INIT_DLS_ENTRY
; i
++)
1395 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& MAC_ADDR_EQUAL(pAddr
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1399 PMAC_TABLE_ENTRY pEntry
;
1401 // STAKey frame, add pairwise key table
1402 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_FINISH
;
1403 RTMPCancelTimer(&pAd
->StaCfg
.DLSEntry
[i
].Timer
, &TimerCancelled
);
1405 PairwiseKey
.KeyLen
= LEN_TKIP_EK
;
1406 NdisMoveMemory(PairwiseKey
.Key
, &pSTAKey
[0], LEN_TKIP_EK
);
1407 NdisMoveMemory(PairwiseKey
.TxMic
, &pSTAKey
[16], LEN_TKIP_RXMICK
);
1408 NdisMoveMemory(PairwiseKey
.RxMic
, &pSTAKey
[24], LEN_TKIP_TXMICK
);
1410 //PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
1411 if (pAd
->StaCfg
.PairCipher
== Ndis802_11Encryption2Enabled
)
1412 PairwiseKey
.CipherAlg
= CIPHER_TKIP
;
1413 else if (pAd
->StaCfg
.PairCipher
== Ndis802_11Encryption3Enabled
)
1414 PairwiseKey
.CipherAlg
= CIPHER_AES
;
1416 pEntry
= DlsEntryTableLookup(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
, TRUE
);
1417 //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
1418 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1419 // Add Pair-wise key to Asic
1421 AsicAddPairwiseKeyEntry(pAd
,
1422 pAd
->StaCfg
.DLSEntry
[i
].MacAddr
,
1423 (UCHAR
)pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
,
1426 RTMPAddWcidAttributeEntry(pAd
,
1429 PairwiseKey
.CipherAlg
,
1432 #endif // RTMP_MAC_PCI //
1433 NdisMoveMemory(&pEntry
->PairwiseKey
, &PairwiseKey
, sizeof(CIPHER_KEY
));
1434 DBGPRINT(RT_DEBUG_TRACE
,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n"));
1436 RTMPSendSTAKeyHandShake(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
);
1438 DBGPRINT(RT_DEBUG_TRACE
,("DLS - Finish STAKey handshake procedure (Initiator side)\n"));
1442 // Data frame, update timeout value
1443 if (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
)
1445 pAd
->StaCfg
.DLSEntry
[i
].CountDownTimer
= pAd
->StaCfg
.DLSEntry
[i
].TimeOut
;
1446 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1454 // update peer dls table entry
1455 for (i
=MAX_NUM_OF_INIT_DLS_ENTRY
; i
<MAX_NUM_OF_DLS_ENTRY
; i
++)
1457 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& MAC_ADDR_EQUAL(pAddr
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1461 PMAC_TABLE_ENTRY pEntry
= NULL
;
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
);
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
);
1472 //PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
1473 if (pAd
->StaCfg
.PairCipher
== Ndis802_11Encryption2Enabled
)
1474 PairwiseKey
.CipherAlg
= CIPHER_TKIP
;
1475 else if (pAd
->StaCfg
.PairCipher
== Ndis802_11Encryption3Enabled
)
1476 PairwiseKey
.CipherAlg
= CIPHER_AES
;
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
1483 AsicAddPairwiseKeyEntry(pAd
,
1484 pAd
->StaCfg
.DLSEntry
[i
].MacAddr
,
1485 (UCHAR
)pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
,
1488 RTMPAddWcidAttributeEntry(pAd
,
1491 PairwiseKey
.CipherAlg
,
1493 #endif // RTMP_MAC_PCI //
1494 NdisMoveMemory(&pEntry
->PairwiseKey
, &PairwiseKey
, sizeof(CIPHER_KEY
));
1495 DBGPRINT(RT_DEBUG_TRACE
,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n"));
1497 // If support WPA or WPA2, start STAKey hand shake,
1498 // If failed hand shake, just tear down peer DLS
1499 if (RTMPSendSTAKeyHandShake(pAd
, pAddr
) != NDIS_STATUS_SUCCESS
)
1501 MLME_DLS_REQ_STRUCT MlmeDlsReq
;
1502 USHORT reason
= REASON_QOS_CIPHER_NOT_SUPPORT
;
1504 pAd
->StaCfg
.DLSEntry
[i
].Valid
= FALSE
;
1505 pAd
->StaCfg
.DLSEntry
[i
].Status
= DLS_NONE
;
1506 DlsParmFill(pAd
, &MlmeDlsReq
, &pAd
->StaCfg
.DLSEntry
[i
], reason
);
1507 MlmeEnqueue(pAd
, DLS_STATE_MACHINE
, MT2_MLME_DLS_TEAR_DOWN
, sizeof(MLME_DLS_REQ_STRUCT
), &MlmeDlsReq
);
1511 DBGPRINT(RT_DEBUG_TRACE
,("DLS - Finish STAKey handshake procedure (Peer side)\n"));
1516 // Data frame, update timeout value
1517 if (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
)
1519 pAd
->StaCfg
.DLSEntry
[i
].CountDownTimer
= pAd
->StaCfg
.DLSEntry
[i
].TimeOut
;
1528 return bSTAKeyFrame
;
1532 ========================================================================
1534 Routine Description:
1535 Check if the frame can be sent through DLS direct link interface
1538 pAd Pointer to adapter
1545 ========================================================================
1547 INT
RTMPCheckDLSFrame(
1548 IN PRTMP_ADAPTER pAd
,
1554 if (!pAd
->CommonCfg
.bDLSCapable
)
1561 // check local dls table entry
1562 for (i
=0; i
<MAX_NUM_OF_INIT_DLS_ENTRY
; i
++)
1564 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
) &&
1565 MAC_ADDR_EQUAL(pDA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1572 // check peer dls table entry
1573 for (i
=MAX_NUM_OF_INIT_DLS_ENTRY
; i
<MAX_NUM_OF_DLS_ENTRY
; i
++)
1575 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
) &&
1576 MAC_ADDR_EQUAL(pDA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1588 ==========================================================================
1591 IRQL = DISPATCH_LEVEL
1593 ==========================================================================
1595 VOID
RTMPSendDLSTearDownFrame(
1596 IN PRTMP_ADAPTER pAd
,
1599 PUCHAR pOutBuffer
= NULL
;
1600 NDIS_STATUS NStatus
;
1601 HEADER_802_11 DlsTearDownHdr
;
1603 USHORT Reason
= REASON_QOS_QSTA_LEAVING_QBSS
;
1604 UCHAR Category
= CATEGORY_DLS
;
1605 UCHAR Action
= ACTION_DLS_TEARDOWN
;
1608 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
) ||
1609 RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
))
1612 DBGPRINT(RT_DEBUG_TRACE
, ("Send DLS TearDown Frame \n"));
1614 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
1615 if (NStatus
!= NDIS_STATUS_SUCCESS
)
1617 DBGPRINT(RT_DEBUG_ERROR
,("ASSOC - RTMPSendDLSTearDownFrame() allocate memory failed \n"));
1621 ActHeaderInit(pAd
, &DlsTearDownHdr
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
1622 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1623 sizeof(HEADER_802_11
), &DlsTearDownHdr
,
1627 6, pAd
->CurrentAddress
,
1631 MiniportMMRequest(pAd
, 0, pOutBuffer
, FrameLen
);
1632 MlmeFreeMemory(pAd
, pOutBuffer
);
1634 // Remove key in local dls table entry
1635 for (i
= 0; i
< MAX_NUM_OF_INIT_DLS_ENTRY
; i
++)
1637 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
)
1638 && MAC_ADDR_EQUAL(pDA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1640 MacTableDeleteDlsEntry(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
);
1644 // Remove key in peer dls table entry
1645 for (i
=MAX_NUM_OF_INIT_DLS_ENTRY
; i
<MAX_NUM_OF_DLS_ENTRY
; i
++)
1647 if (pAd
->StaCfg
.DLSEntry
[i
].Valid
&& (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
)
1648 && MAC_ADDR_EQUAL(pDA
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
))
1650 MacTableDeleteDlsEntry(pAd
, pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
, pAd
->StaCfg
.DLSEntry
[i
].MacAddr
);
1654 DBGPRINT(RT_DEBUG_TRACE
, ("Send DLS TearDown Frame and remove key in (i=%d) \n", i
));
1658 ==========================================================================
1661 IRQL = DISPATCH_LEVEL
1663 ==========================================================================
1665 NDIS_STATUS
RTMPSendSTAKeyRequest(
1666 IN PRTMP_ADAPTER pAd
,
1669 UCHAR Header802_3
[14];
1670 NDIS_STATUS NStatus
;
1672 EAPOL_PACKET Packet
;
1675 PUCHAR pOutBuffer
= NULL
;
1676 PNDIS_PACKET pNdisPacket
;
1680 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]));
1683 MAKE_802_3_HEADER(Header802_3
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, EAPOL
);
1685 // Zero message body
1686 NdisZeroMemory(&Packet
, sizeof(Packet
));
1687 Packet
.ProVer
= EAPOL_VER
;
1688 Packet
.ProType
= EAPOLKey
;
1689 Packet
.Body_Len
[1] = sizeof(KEY_DESCRIPTER
) - MAX_LEN_OF_RSNIE
+ 6 + MAC_ADDR_LEN
; // data field contain KDE andPeer MAC address
1691 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1692 if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPAPSK
))
1694 Packet
.KeyDesc
.Type
= WPA1_KEY_DESC
;
1696 else if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2PSK
))
1698 Packet
.KeyDesc
.Type
= WPA2_KEY_DESC
;
1701 // Key descriptor version
1702 Packet
.KeyDesc
.KeyInfo
.KeyDescVer
=
1703 (((pAd
->StaCfg
.PairCipher
== Ndis802_11Encryption3Enabled
) || (pAd
->StaCfg
.GroupCipher
== Ndis802_11Encryption3Enabled
)) ? (DESC_TYPE_AES
) : (DESC_TYPE_TKIP
));
1705 Packet
.KeyDesc
.KeyInfo
.KeyMic
= 1;
1706 Packet
.KeyDesc
.KeyInfo
.Secure
= 1;
1707 Packet
.KeyDesc
.KeyInfo
.Request
= 1;
1709 Packet
.KeyDesc
.KeyDataLen
[1] = 12;
1711 // use our own OUI to distinguish proprietary with standard.
1712 Packet
.KeyDesc
.KeyData
[0] = 0xDD;
1713 Packet
.KeyDesc
.KeyData
[1] = 0x0A;
1714 Packet
.KeyDesc
.KeyData
[2] = 0x00;
1715 Packet
.KeyDesc
.KeyData
[3] = 0x0C;
1716 Packet
.KeyDesc
.KeyData
[4] = 0x43;
1717 Packet
.KeyDesc
.KeyData
[5] = 0x03;
1718 NdisMoveMemory(&Packet
.KeyDesc
.KeyData
[6], pDA
, MAC_ADDR_LEN
);
1720 NdisMoveMemory(Packet
.KeyDesc
.ReplayCounter
, pAd
->StaCfg
.DlsReplayCounter
, LEN_KEY_DESC_REPLAY
);
1722 // Allocate buffer for transmitting message
1723 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
);
1724 if (NStatus
!= NDIS_STATUS_SUCCESS
)
1727 // Prepare EAPOL frame for MIC calculation
1728 // Be careful, only EAPOL frame is counted for MIC calculation
1729 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1730 Packet
.Body_Len
[1] + 4, &Packet
,
1733 // use proprietary PTK
1734 NdisZeroMemory(temp
, 64);
1735 NdisMoveMemory(temp
, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1736 WpaDerivePTK(pAd
, temp
, temp
, pAd
->CommonCfg
.Bssid
, temp
, pAd
->CurrentAddress
, DlsPTK
, LEN_PTK
);
1739 if (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
1742 NdisZeroMemory(digest
, sizeof(digest
));
1743 HMAC_SHA1(DlsPTK
, LEN_EAP_MICK
, pOutBuffer
, FrameLen
, digest
, SHA1_DIGEST_SIZE
);
1744 NdisMoveMemory(Packet
.KeyDesc
.KeyMic
, digest
, LEN_KEY_DESC_MIC
);
1748 NdisZeroMemory(Mic
, sizeof(Mic
));
1749 HMAC_MD5(DlsPTK
, LEN_EAP_MICK
, pOutBuffer
, FrameLen
, Mic
, MD5_DIGEST_SIZE
);
1750 NdisMoveMemory(Packet
.KeyDesc
.KeyMic
, Mic
, LEN_KEY_DESC_MIC
);
1753 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1754 sizeof(Header802_3
), Header802_3
,
1755 Packet
.Body_Len
[1] + 4, &Packet
,
1758 NStatus
= RTMPAllocateNdisPacket(pAd
, &pNdisPacket
, NULL
, 0, pOutBuffer
, FrameLen
);
1759 if (NStatus
== NDIS_STATUS_SUCCESS
)
1761 RTMP_SET_PACKET_WCID(pNdisPacket
, BSSID_WCID
);
1762 STASendPacket(pAd
, pNdisPacket
);
1763 RTMPDeQueuePacket(pAd
, FALSE
, NUM_OF_TX_RING
, MAX_TX_PROCESS
);
1766 MlmeFreeMemory(pAd
, pOutBuffer
);
1768 DBGPRINT(RT_DEBUG_TRACE
, ("RTMPSendSTAKeyRequest- Send STAKey request (NStatus=%x, FrameLen=%ld)\n", NStatus
, FrameLen
));
1774 ==========================================================================
1777 IRQL = DISPATCH_LEVEL
1779 ==========================================================================
1781 NDIS_STATUS
RTMPSendSTAKeyHandShake(
1782 IN PRTMP_ADAPTER pAd
,
1785 UCHAR Header802_3
[14];
1786 NDIS_STATUS NStatus
;
1788 EAPOL_PACKET Packet
;
1791 PUCHAR pOutBuffer
= NULL
;
1792 PNDIS_PACKET pNdisPacket
;
1794 UCHAR DlsPTK
[80]; // Due to dirver can not get PTK, use proprietary PTK
1796 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]));
1799 MAKE_802_3_HEADER(Header802_3
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, EAPOL
);
1801 // Zero message body
1802 NdisZeroMemory(&Packet
, sizeof(Packet
));
1803 Packet
.ProVer
= EAPOL_VER
;
1804 Packet
.ProType
= EAPOLKey
;
1805 Packet
.Body_Len
[1] = sizeof(KEY_DESCRIPTER
) - MAX_LEN_OF_RSNIE
+ 6 + MAC_ADDR_LEN
; // data field contain KDE and Peer MAC address
1807 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1808 if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPAPSK
))
1810 Packet
.KeyDesc
.Type
= WPA1_KEY_DESC
;
1812 else if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2PSK
))
1814 Packet
.KeyDesc
.Type
= WPA2_KEY_DESC
;
1817 // Key descriptor version
1818 Packet
.KeyDesc
.KeyInfo
.KeyDescVer
=
1819 (((pAd
->StaCfg
.PairCipher
== Ndis802_11Encryption3Enabled
) || (pAd
->StaCfg
.GroupCipher
== Ndis802_11Encryption3Enabled
)) ? (DESC_TYPE_AES
) : (DESC_TYPE_TKIP
));
1821 Packet
.KeyDesc
.KeyInfo
.KeyMic
= 1;
1822 Packet
.KeyDesc
.KeyInfo
.Secure
= 1;
1824 Packet
.KeyDesc
.KeyDataLen
[1] = 12;
1826 // use our own OUI to distinguish proprietary with standard.
1827 Packet
.KeyDesc
.KeyData
[0] = 0xDD;
1828 Packet
.KeyDesc
.KeyData
[1] = 0x0A;
1829 Packet
.KeyDesc
.KeyData
[2] = 0x00;
1830 Packet
.KeyDesc
.KeyData
[3] = 0x0C;
1831 Packet
.KeyDesc
.KeyData
[4] = 0x43;
1832 Packet
.KeyDesc
.KeyData
[5] = 0x03;
1833 NdisMoveMemory(&Packet
.KeyDesc
.KeyData
[6], pDA
, MAC_ADDR_LEN
);
1835 NdisMoveMemory(Packet
.KeyDesc
.ReplayCounter
, pAd
->StaCfg
.DlsReplayCounter
, LEN_KEY_DESC_REPLAY
);
1837 // Allocate buffer for transmitting message
1838 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
);
1839 if (NStatus
!= NDIS_STATUS_SUCCESS
)
1842 // Prepare EAPOL frame for MIC calculation
1843 // Be careful, only EAPOL frame is counted for MIC calculation
1844 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1845 Packet
.Body_Len
[1] + 4, &Packet
,
1848 // use proprietary PTK
1849 NdisZeroMemory(temp
, 64);
1850 NdisMoveMemory(temp
, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1851 WpaDerivePTK(pAd
, temp
, temp
, pAd
->CommonCfg
.Bssid
, temp
, pAd
->CurrentAddress
, DlsPTK
, LEN_PTK
);
1854 if (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption3Enabled
)
1857 NdisZeroMemory(digest
, sizeof(digest
));
1858 HMAC_SHA1(DlsPTK
, LEN_EAP_MICK
, pOutBuffer
, FrameLen
, digest
, SHA1_DIGEST_SIZE
);
1859 NdisMoveMemory(Packet
.KeyDesc
.KeyMic
, digest
, LEN_KEY_DESC_MIC
);
1863 NdisZeroMemory(Mic
, sizeof(Mic
));
1864 HMAC_MD5(DlsPTK
, LEN_EAP_MICK
, pOutBuffer
, FrameLen
, Mic
, MD5_DIGEST_SIZE
);
1865 NdisMoveMemory(Packet
.KeyDesc
.KeyMic
, Mic
, LEN_KEY_DESC_MIC
);
1868 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1869 sizeof(Header802_3
), Header802_3
,
1870 Packet
.Body_Len
[1] + 4, &Packet
,
1873 NStatus
= RTMPAllocateNdisPacket(pAd
, &pNdisPacket
, NULL
, 0, pOutBuffer
, FrameLen
);
1874 if (NStatus
== NDIS_STATUS_SUCCESS
)
1876 RTMP_SET_PACKET_WCID(pNdisPacket
, BSSID_WCID
);
1877 STASendPacket(pAd
, pNdisPacket
);
1878 RTMPDeQueuePacket(pAd
, FALSE
, NUM_OF_TX_RING
, MAX_TX_PROCESS
);
1881 MlmeFreeMemory(pAd
, pOutBuffer
);
1883 DBGPRINT(RT_DEBUG_TRACE
, ("RTMPSendSTAKeyHandShake- Send STAKey Message-2 (NStatus=%x, FrameLen=%ld)\n", NStatus
, FrameLen
));
1888 VOID
DlsTimeoutAction(
1889 IN PVOID SystemSpecific1
,
1890 IN PVOID FunctionContext
,
1891 IN PVOID SystemSpecific2
,
1892 IN PVOID SystemSpecific3
)
1894 MLME_DLS_REQ_STRUCT MlmeDlsReq
;
1896 PRT_802_11_DLS pDLS
= (PRT_802_11_DLS
)FunctionContext
;
1897 PRTMP_ADAPTER pAd
= pDLS
->pAd
;
1899 DBGPRINT(RT_DEBUG_TRACE
, ("DlsTimeout - Tear down DLS links (%02x:%02x:%02x:%02x:%02x:%02x)\n",
1900 pDLS
->MacAddr
[0], pDLS
->MacAddr
[1], pDLS
->MacAddr
[2], pDLS
->MacAddr
[3], pDLS
->MacAddr
[4], pDLS
->MacAddr
[5]));
1902 if ((pDLS
) && (pDLS
->Valid
))
1904 reason
= REASON_QOS_REQUEST_TIMEOUT
;
1905 pDLS
->Valid
= FALSE
;
1906 pDLS
->Status
= DLS_NONE
;
1907 DlsParmFill(pAd
, &MlmeDlsReq
, pDLS
, reason
);
1908 MlmeEnqueue(pAd
, DLS_STATE_MACHINE
, MT2_MLME_DLS_TEAR_DOWN
, sizeof(MLME_DLS_REQ_STRUCT
), &MlmeDlsReq
);
1909 RTMP_MLME_HANDLER(pAd
);
1914 ================================================================
1915 Description : because DLS and CLI share the same WCID table in ASIC.
1916 Mesh entry also insert to pAd->MacTab.content[]. Such is marked as ValidAsDls = TRUE.
1917 Also fills the pairwise key.
1918 Because front MAX_AID_BA entries have direct mapping to BAEntry, which is only used as CLI. So we insert Dls
1919 from index MAX_AID_BA.
1920 ================================================================
1922 MAC_TABLE_ENTRY
*MacTableInsertDlsEntry(
1923 IN PRTMP_ADAPTER pAd
,
1925 IN UINT DlsEntryIdx
)
1927 PMAC_TABLE_ENTRY pEntry
= NULL
;
1929 DBGPRINT(RT_DEBUG_TRACE
, ("====> MacTableInsertDlsEntry\n"));
1931 if (pAd
->MacTab
.Size
>= MAX_LEN_OF_MAC_TABLE
)
1936 if((pEntry
= DlsEntryTableLookup(pAd
, pAddr
, TRUE
)) != NULL
)
1939 // allocate one MAC entry
1940 pEntry
= MacTableInsertEntry(pAd
, pAddr
, DlsEntryIdx
+ MIN_NET_DEVICE_FOR_DLS
, TRUE
);
1943 pAd
->StaCfg
.DLSEntry
[DlsEntryIdx
].MacTabMatchWCID
= pEntry
->Aid
;
1944 pEntry
->MatchDlsEntryIdx
= DlsEntryIdx
;
1945 pEntry
->AuthMode
= pAd
->StaCfg
.AuthMode
;
1946 pEntry
->WepStatus
= pAd
->StaCfg
.WepStatus
;
1947 pEntry
->PortSecured
= WPA_802_1X_PORT_SECURED
;
1949 DBGPRINT(RT_DEBUG_TRACE
, ("MacTableInsertDlsEntry - allocate entry #%d, Total= %d\n",pEntry
->Aid
, pAd
->MacTab
.Size
));
1951 // If legacy WEP is used, set pair-wise cipherAlg into WCID attribute table for this entry
1952 if ((pEntry
->ValidAsDls
) && (pAd
->StaCfg
.WepStatus
== Ndis802_11WEPEnabled
))
1955 UCHAR CipherAlg
= 0;
1957 KeyIdx
= pAd
->StaCfg
.DefaultKeyId
;
1959 CipherAlg
= pAd
->SharedKey
[BSS0
][KeyIdx
].CipherAlg
;
1961 RTMPAddWcidAttributeEntry(pAd
,
1963 pAd
->StaCfg
.DefaultKeyId
,
1964 pAd
->SharedKey
[BSS0
][pAd
->StaCfg
.DefaultKeyId
].CipherAlg
,
1972 DBGPRINT(RT_DEBUG_TRACE
, ("<==== MacTableInsertDlsEntry\n"));
1979 ==========================================================================
1981 Delete all Mesh Entry in pAd->MacTab
1982 ==========================================================================
1984 BOOLEAN
MacTableDeleteDlsEntry(
1985 IN PRTMP_ADAPTER pAd
,
1989 DBGPRINT(RT_DEBUG_TRACE
, ("====> MacTableDeleteDlsEntry\n"));
1991 if (!VALID_WCID(wcid
))
1994 MacTableDeleteEntry(pAd
, wcid
, pAddr
);
1996 DBGPRINT(RT_DEBUG_TRACE
, ("<==== MacTableDeleteDlsEntry\n"));
2001 MAC_TABLE_ENTRY
*DlsEntryTableLookup(
2002 IN PRTMP_ADAPTER pAd
,
2004 IN BOOLEAN bResetIdelCount
)
2007 MAC_TABLE_ENTRY
*pEntry
= NULL
;
2009 RTMP_SEM_LOCK(&pAd
->MacTabLock
);
2010 HashIdx
= MAC_ADDR_HASH_INDEX(pAddr
);
2011 pEntry
= pAd
->MacTab
.Hash
[HashIdx
];
2015 if ((pEntry
->ValidAsDls
== TRUE
)
2016 && MAC_ADDR_EQUAL(pEntry
->Addr
, pAddr
))
2019 pEntry
->NoDataIdleCount
= 0;
2023 pEntry
= pEntry
->pNext
;
2026 RTMP_SEM_UNLOCK(&pAd
->MacTabLock
);
2030 MAC_TABLE_ENTRY
*DlsEntryTableLookupByWcid(
2031 IN PRTMP_ADAPTER pAd
,
2034 IN BOOLEAN bResetIdelCount
)
2037 PMAC_TABLE_ENTRY pCurEntry
= NULL
;
2038 PMAC_TABLE_ENTRY pEntry
= NULL
;
2040 if (!VALID_WCID(wcid
))
2043 RTMP_SEM_LOCK(&pAd
->MacTabLock
);
2047 pCurEntry
= &pAd
->MacTab
.Content
[wcid
];
2050 if ((pCurEntry
) && (pCurEntry
->ValidAsDls
== TRUE
))
2052 DLsIndex
= pCurEntry
->MatchDlsEntryIdx
;
2055 if (DLsIndex
== 0xff)
2058 if (MAC_ADDR_EQUAL(pCurEntry
->Addr
, pAddr
))
2061 pCurEntry
->NoDataIdleCount
= 0;
2067 RTMP_SEM_UNLOCK(&pAd
->MacTabLock
);
2072 INT
Set_DlsEntryInfo_Display_Proc(
2073 IN PRTMP_ADAPTER pAd
,
2078 DBGPRINT(RT_DEBUG_OFF
, ("\n%-19s%-8s\n", "MAC", "TIMEOUT\n"));
2079 for (i
=0; i
<MAX_NUM_OF_DLS_ENTRY
; i
++)
2081 if ((pAd
->StaCfg
.DLSEntry
[i
].Valid
) && (pAd
->StaCfg
.DLSEntry
[i
].Status
== DLS_FINISH
))
2083 PMAC_TABLE_ENTRY pEntry
= &pAd
->MacTab
.Content
[pAd
->StaCfg
.DLSEntry
[i
].MacTabMatchWCID
];
2085 DBGPRINT(RT_DEBUG_OFF
, ("%02x:%02x:%02x:%02x:%02x:%02x ",
2086 pAd
->StaCfg
.DLSEntry
[i
].MacAddr
[0], pAd
->StaCfg
.DLSEntry
[i
].MacAddr
[1], pAd
->StaCfg
.DLSEntry
[i
].MacAddr
[2],
2087 pAd
->StaCfg
.DLSEntry
[i
].MacAddr
[3], pAd
->StaCfg
.DLSEntry
[i
].MacAddr
[4], pAd
->StaCfg
.DLSEntry
[i
].MacAddr
[5]));
2088 DBGPRINT(RT_DEBUG_OFF
, ("%-8d\n", pAd
->StaCfg
.DLSEntry
[i
].TimeOut
));
2090 DBGPRINT(RT_DEBUG_OFF
, ("\n"));
2091 DBGPRINT(RT_DEBUG_OFF
, ("\n%-19s%-4s%-4s%-4s%-4s%-7s%-7s%-7s","MAC", "AID", "BSS", "PSM", "WMM", "RSSI0", "RSSI1", "RSSI2"));
2092 #ifdef DOT11_N_SUPPORT
2093 DBGPRINT(RT_DEBUG_OFF
, ("%-8s%-10s%-6s%-6s%-6s%-6s", "MIMOPS", "PhMd", "BW", "MCS", "SGI", "STBC"));
2094 #endif // DOT11_N_SUPPORT //
2095 DBGPRINT(RT_DEBUG_OFF
, ("\n%02X:%02X:%02X:%02X:%02X:%02X ",
2096 pEntry
->Addr
[0], pEntry
->Addr
[1], pEntry
->Addr
[2],
2097 pEntry
->Addr
[3], pEntry
->Addr
[4], pEntry
->Addr
[5]));
2098 DBGPRINT(RT_DEBUG_OFF
, ("%-4d", (int)pEntry
->Aid
));
2099 DBGPRINT(RT_DEBUG_OFF
, ("%-4d", (int)pEntry
->apidx
));
2100 DBGPRINT(RT_DEBUG_OFF
, ("%-4d", (int)pEntry
->PsMode
));
2101 DBGPRINT(RT_DEBUG_OFF
, ("%-4d", (int)CLIENT_STATUS_TEST_FLAG(pEntry
, fCLIENT_STATUS_WMM_CAPABLE
)));
2102 DBGPRINT(RT_DEBUG_OFF
, ("%-7d", pEntry
->RssiSample
.AvgRssi0
));
2103 DBGPRINT(RT_DEBUG_OFF
, ("%-7d", pEntry
->RssiSample
.AvgRssi1
));
2104 DBGPRINT(RT_DEBUG_OFF
, ("%-7d", pEntry
->RssiSample
.AvgRssi2
));
2105 #ifdef DOT11_N_SUPPORT
2106 DBGPRINT(RT_DEBUG_OFF
, ("%-8d", (int)pEntry
->MmpsMode
));
2107 DBGPRINT(RT_DEBUG_OFF
, ("%-10s", GetPhyMode(pEntry
->HTPhyMode
.field
.MODE
)));
2108 DBGPRINT(RT_DEBUG_OFF
, ("%-6s", GetBW(pEntry
->HTPhyMode
.field
.BW
)));
2109 DBGPRINT(RT_DEBUG_OFF
, ("%-6d", pEntry
->HTPhyMode
.field
.MCS
));
2110 DBGPRINT(RT_DEBUG_OFF
, ("%-6d", pEntry
->HTPhyMode
.field
.ShortGI
));
2111 DBGPRINT(RT_DEBUG_OFF
, ("%-6d", pEntry
->HTPhyMode
.field
.STBC
));
2112 #endif // DOT11_N_SUPPORT //
2113 DBGPRINT(RT_DEBUG_OFF
, ("%-10d, %d, %d%%\n", pEntry
->DebugFIFOCount
, pEntry
->DebugTxCount
,
2114 (pEntry
->DebugTxCount
) ? ((pEntry
->DebugTxCount
-pEntry
->DebugFIFOCount
)*100/pEntry
->DebugTxCount
) : 0));
2115 DBGPRINT(RT_DEBUG_OFF
, ("\n"));
2123 INT
Set_DlsAddEntry_Proc(
2124 IN PRTMP_ADAPTER pAd
,
2127 UCHAR mac
[MAC_ADDR_LEN
];
2130 STRING sepValue
[] = ":", DASH
= '-';
2134 if(strlen(arg
) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and timeout value in decimal format.
2137 token
= strchr(arg
, DASH
);
2138 if ((token
!= NULL
) && (strlen(token
)>1))
2140 Timeout
= (USHORT
) simple_strtol((token
+1), 0, 10);
2143 for (i
= 0, token
= rstrtok(arg
, &sepValue
[0]); token
; token
= rstrtok(NULL
, &sepValue
[0]), i
++)
2145 if((strlen(token
) != 2) || (!isxdigit(*token
)) || (!isxdigit(*(token
+1))))
2147 AtoH(token
, (&mac
[i
]), 1);
2152 DBGPRINT(RT_DEBUG_OFF
, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%d", mac
[0], mac
[1],
2153 mac
[2], mac
[3], mac
[4], mac
[5], (int)Timeout
));
2155 NdisZeroMemory(&Dls
, sizeof(RT_802_11_DLS
));
2156 Dls
.TimeOut
= Timeout
;
2157 COPY_MAC_ADDR(Dls
.MacAddr
, mac
);
2161 MLME_CNTL_STATE_MACHINE
,
2162 RT_OID_802_11_SET_DLS_PARAM
,
2163 sizeof(RT_802_11_DLS
),
2173 INT
Set_DlsTearDownEntry_Proc(
2174 IN PRTMP_ADAPTER pAd
,
2177 UCHAR macAddr
[MAC_ADDR_LEN
];
2182 if(strlen(arg
) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
2185 for (i
=0, value
= rstrtok(arg
,":"); value
; value
= rstrtok(NULL
,":"))
2187 if((strlen(value
) != 2) || (!isxdigit(*value
)) || (!isxdigit(*(value
+1))) )
2188 return FALSE
; //Invalid
2190 AtoH(value
, &macAddr
[i
++], 2);
2193 DBGPRINT(RT_DEBUG_OFF
, ("\n%02x:%02x:%02x:%02x:%02x:%02x", macAddr
[0], macAddr
[1],
2194 macAddr
[2], macAddr
[3], macAddr
[4], macAddr
[5]));
2196 NdisZeroMemory(&Dls
, sizeof(RT_802_11_DLS
));
2197 COPY_MAC_ADDR(Dls
.MacAddr
, macAddr
);
2201 MLME_CNTL_STATE_MACHINE
,
2202 RT_OID_802_11_SET_DLS_PARAM
,
2203 sizeof(RT_802_11_DLS
),