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 association related requests either from WSTA or from local MLME
35 -------- ---------- ----------------------------------------------
36 Jan Lee 2006 created for rt2860
39 #include "../rt_config.h"
40 #include "../action.h"
43 static VOID
ReservedAction(
45 IN MLME_QUEUE_ELEM
*Elem
);
49 ==========================================================================
51 association state machine init, including state transition and timer init
53 S - pointer to the association state machine
55 The state machine looks like the following
58 MT2_MLME_DISASSOC_REQ mlme_disassoc_req_action
59 MT2_PEER_DISASSOC_REQ peer_disassoc_action
60 MT2_PEER_ASSOC_REQ drop
61 MT2_PEER_REASSOC_REQ drop
62 MT2_CLS3ERR cls3err_action
63 ==========================================================================
65 VOID
ActionStateMachineInit(
68 OUT STATE_MACHINE_FUNC Trans
[])
70 StateMachineInit(S
, (STATE_MACHINE_FUNC
*)Trans
, MAX_ACT_STATE
, MAX_ACT_MSG
, (STATE_MACHINE_FUNC
)Drop
, ACT_IDLE
, ACT_MACHINE_BASE
);
72 StateMachineSetAction(S
, ACT_IDLE
, MT2_PEER_SPECTRUM_CATE
, (STATE_MACHINE_FUNC
)PeerSpectrumAction
);
73 StateMachineSetAction(S
, ACT_IDLE
, MT2_PEER_QOS_CATE
, (STATE_MACHINE_FUNC
)PeerQOSAction
);
75 StateMachineSetAction(S
, ACT_IDLE
, MT2_PEER_DLS_CATE
, (STATE_MACHINE_FUNC
)ReservedAction
);
76 #ifdef QOS_DLS_SUPPORT
77 StateMachineSetAction(S
, ACT_IDLE
, MT2_PEER_DLS_CATE
, (STATE_MACHINE_FUNC
)PeerDLSAction
);
78 #endif // QOS_DLS_SUPPORT //
80 #ifdef DOT11_N_SUPPORT
81 StateMachineSetAction(S
, ACT_IDLE
, MT2_PEER_BA_CATE
, (STATE_MACHINE_FUNC
)PeerBAAction
);
82 StateMachineSetAction(S
, ACT_IDLE
, MT2_PEER_HT_CATE
, (STATE_MACHINE_FUNC
)PeerHTAction
);
83 StateMachineSetAction(S
, ACT_IDLE
, MT2_MLME_ADD_BA_CATE
, (STATE_MACHINE_FUNC
)MlmeADDBAAction
);
84 StateMachineSetAction(S
, ACT_IDLE
, MT2_MLME_ORI_DELBA_CATE
, (STATE_MACHINE_FUNC
)MlmeDELBAAction
);
85 StateMachineSetAction(S
, ACT_IDLE
, MT2_MLME_REC_DELBA_CATE
, (STATE_MACHINE_FUNC
)MlmeDELBAAction
);
86 #endif // DOT11_N_SUPPORT //
88 StateMachineSetAction(S
, ACT_IDLE
, MT2_PEER_PUBLIC_CATE
, (STATE_MACHINE_FUNC
)PeerPublicAction
);
89 StateMachineSetAction(S
, ACT_IDLE
, MT2_PEER_RM_CATE
, (STATE_MACHINE_FUNC
)PeerRMAction
);
91 StateMachineSetAction(S
, ACT_IDLE
, MT2_MLME_QOS_CATE
, (STATE_MACHINE_FUNC
)MlmeQOSAction
);
92 StateMachineSetAction(S
, ACT_IDLE
, MT2_MLME_DLS_CATE
, (STATE_MACHINE_FUNC
)MlmeDLSAction
);
93 StateMachineSetAction(S
, ACT_IDLE
, MT2_ACT_INVALID
, (STATE_MACHINE_FUNC
)MlmeInvalidAction
);
98 #ifdef DOT11_N_SUPPORT
100 IN PRTMP_ADAPTER pAd
,
101 IN MLME_QUEUE_ELEM
*Elem
)
104 MLME_ADDBA_REQ_STRUCT
*pInfo
;
106 PUCHAR pOutBuffer
= NULL
;
109 FRAME_ADDBA_REQ Frame
;
111 BA_ORI_ENTRY
*pBAEntry
= NULL
;
113 pInfo
= (MLME_ADDBA_REQ_STRUCT
*)Elem
->Msg
;
114 NdisZeroMemory(&Frame
, sizeof(FRAME_ADDBA_REQ
));
116 if(MlmeAddBAReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, Addr
))
118 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
119 if(NStatus
!= NDIS_STATUS_SUCCESS
)
121 DBGPRINT(RT_DEBUG_TRACE
,("BA - MlmeADDBAAction() allocate memory failed \n"));
125 Idx
= pAd
->MacTab
.Content
[pInfo
->Wcid
].BAOriWcidArray
[pInfo
->TID
];
128 MlmeFreeMemory(pAd
, pOutBuffer
);
129 DBGPRINT(RT_DEBUG_ERROR
,("BA - MlmeADDBAAction() can't find BAOriEntry \n"));
134 pBAEntry
=&pAd
->BATable
.BAOriEntry
[Idx
];
137 #ifdef CONFIG_STA_SUPPORT
138 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
141 ActHeaderInit(pAd
, &Frame
.Hdr
, pInfo
->pAddr
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
143 #ifdef QOS_DLS_SUPPORT
144 if (pAd
->MacTab
.Content
[pInfo
->Wcid
].ValidAsDls
)
145 ActHeaderInit(pAd
, &Frame
.Hdr
, pInfo
->pAddr
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
147 #endif // QOS_DLS_SUPPORT //
148 ActHeaderInit(pAd
, &Frame
.Hdr
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, pInfo
->pAddr
);
151 #endif // CONFIG_STA_SUPPORT //
153 Frame
.Category
= CATEGORY_BA
;
154 Frame
.Action
= ADDBA_REQ
;
155 Frame
.BaParm
.AMSDUSupported
= 0;
156 Frame
.BaParm
.BAPolicy
= IMMED_BA
;
157 Frame
.BaParm
.TID
= pInfo
->TID
;
158 Frame
.BaParm
.BufSize
= pInfo
->BaBufSize
;
159 Frame
.Token
= pInfo
->Token
;
160 Frame
.TimeOutValue
= pInfo
->TimeOutValue
;
161 Frame
.BaStartSeq
.field
.FragNum
= 0;
162 Frame
.BaStartSeq
.field
.StartSeq
= pAd
->MacTab
.Content
[pInfo
->Wcid
].TxSeq
[pInfo
->TID
];
164 *(USHORT
*)(&Frame
.BaParm
) = cpu2le16(*(USHORT
*)(&Frame
.BaParm
));
165 Frame
.TimeOutValue
= cpu2le16(Frame
.TimeOutValue
);
166 Frame
.BaStartSeq
.word
= cpu2le16(Frame
.BaStartSeq
.word
);
168 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
169 sizeof(FRAME_ADDBA_REQ
), &Frame
,
172 MiniportMMRequest(pAd
, (MGMT_USE_QUEUE_FLAG
| MapUserPriorityToAccessCategory
[pInfo
->TID
]), pOutBuffer
, FrameLen
);
174 MlmeFreeMemory(pAd
, pOutBuffer
);
176 DBGPRINT(RT_DEBUG_TRACE
, ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", Frame
.BaStartSeq
.field
.StartSeq
, FrameLen
, Frame
.BaParm
.BufSize
));
181 ==========================================================================
183 send DELBA and delete BaEntry if any
185 Elem - MLME message MLME_DELBA_REQ_STRUCT
187 IRQL = DISPATCH_LEVEL
189 ==========================================================================
191 VOID
MlmeDELBAAction(
192 IN PRTMP_ADAPTER pAd
,
193 IN MLME_QUEUE_ELEM
*Elem
)
195 MLME_DELBA_REQ_STRUCT
*pInfo
;
196 PUCHAR pOutBuffer
= NULL
;
197 PUCHAR pOutBuffer2
= NULL
;
200 FRAME_DELBA_REQ Frame
;
204 pInfo
= (MLME_DELBA_REQ_STRUCT
*)Elem
->Msg
;
205 // must send back DELBA
206 NdisZeroMemory(&Frame
, sizeof(FRAME_DELBA_REQ
));
207 DBGPRINT(RT_DEBUG_TRACE
, ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo
->Initiator
));
209 if(MlmeDelBAReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
))
211 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
212 if(NStatus
!= NDIS_STATUS_SUCCESS
)
214 DBGPRINT(RT_DEBUG_ERROR
,("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
218 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer2
); //Get an unused nonpaged memory
219 if(NStatus
!= NDIS_STATUS_SUCCESS
)
221 MlmeFreeMemory(pAd
, pOutBuffer
);
222 DBGPRINT(RT_DEBUG_ERROR
, ("BA - MlmeDELBAAction() allocate memory failed 2. \n"));
226 // SEND BAR (Send BAR to refresh peer reordering buffer.)
227 Idx
= pAd
->MacTab
.Content
[pInfo
->Wcid
].BAOriWcidArray
[pInfo
->TID
];
229 #ifdef CONFIG_STA_SUPPORT
230 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
231 BarHeaderInit(pAd
, &FrameBar
, pAd
->MacTab
.Content
[pInfo
->Wcid
].Addr
, pAd
->CurrentAddress
);
232 #endif // CONFIG_STA_SUPPORT //
234 FrameBar
.StartingSeq
.field
.FragNum
= 0; // make sure sequence not clear in DEL funciton.
235 FrameBar
.StartingSeq
.field
.StartSeq
= pAd
->MacTab
.Content
[pInfo
->Wcid
].TxSeq
[pInfo
->TID
]; // make sure sequence not clear in DEL funciton.
236 FrameBar
.BarControl
.TID
= pInfo
->TID
; // make sure sequence not clear in DEL funciton.
237 FrameBar
.BarControl
.ACKPolicy
= IMMED_BA
; // make sure sequence not clear in DEL funciton.
238 FrameBar
.BarControl
.Compressed
= 1; // make sure sequence not clear in DEL funciton.
239 FrameBar
.BarControl
.MTID
= 0; // make sure sequence not clear in DEL funciton.
241 MakeOutgoingFrame(pOutBuffer2
, &FrameLen
,
242 sizeof(FRAME_BAR
), &FrameBar
,
244 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer2
, FrameLen
);
245 MlmeFreeMemory(pAd
, pOutBuffer2
);
246 DBGPRINT(RT_DEBUG_TRACE
,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
250 #ifdef CONFIG_STA_SUPPORT
251 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
254 ActHeaderInit(pAd
, &Frame
.Hdr
, pAd
->MacTab
.Content
[pInfo
->Wcid
].Addr
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
256 #ifdef QOS_DLS_SUPPORT
257 if (pAd
->MacTab
.Content
[pInfo
->Wcid
].ValidAsDls
)
258 ActHeaderInit(pAd
, &Frame
.Hdr
, pAd
->MacTab
.Content
[pInfo
->Wcid
].Addr
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
260 #endif // QOS_DLS_SUPPORT //
261 ActHeaderInit(pAd
, &Frame
.Hdr
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, pAd
->MacTab
.Content
[pInfo
->Wcid
].Addr
);
263 #endif // CONFIG_STA_SUPPORT //
264 Frame
.Category
= CATEGORY_BA
;
265 Frame
.Action
= DELBA
;
266 Frame
.DelbaParm
.Initiator
= pInfo
->Initiator
;
267 Frame
.DelbaParm
.TID
= pInfo
->TID
;
268 Frame
.ReasonCode
= 39; // Time Out
269 *(USHORT
*)(&Frame
.DelbaParm
) = cpu2le16(*(USHORT
*)(&Frame
.DelbaParm
));
270 Frame
.ReasonCode
= cpu2le16(Frame
.ReasonCode
);
272 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
273 sizeof(FRAME_DELBA_REQ
), &Frame
,
275 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
);
276 MlmeFreeMemory(pAd
, pOutBuffer
);
277 DBGPRINT(RT_DEBUG_TRACE
, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo
->Initiator
));
280 #endif // DOT11_N_SUPPORT //
283 IN PRTMP_ADAPTER pAd
,
284 IN MLME_QUEUE_ELEM
*Elem
)
289 IN PRTMP_ADAPTER pAd
,
290 IN MLME_QUEUE_ELEM
*Elem
)
294 VOID
MlmeInvalidAction(
295 IN PRTMP_ADAPTER pAd
,
296 IN MLME_QUEUE_ELEM
*Elem
)
298 //PUCHAR pOutBuffer = NULL;
299 //Return the receiving frame except the MSB of category filed set to 1. 7.3.1.11
303 IN PRTMP_ADAPTER pAd
,
304 IN MLME_QUEUE_ELEM
*Elem
)
308 #ifdef QOS_DLS_SUPPORT
310 IN PRTMP_ADAPTER pAd
,
311 IN MLME_QUEUE_ELEM
*Elem
)
313 UCHAR Action
= Elem
->Msg
[LENGTH_802_11
+1];
317 case ACTION_DLS_REQUEST
:
318 #ifdef CONFIG_STA_SUPPORT
319 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
320 PeerDlsReqAction(pAd
, Elem
);
321 #endif // CONFIG_STA_SUPPORT //
324 case ACTION_DLS_RESPONSE
:
325 #ifdef CONFIG_STA_SUPPORT
326 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
327 PeerDlsRspAction(pAd
, Elem
);
328 #endif // CONFIG_STA_SUPPORT //
331 case ACTION_DLS_TEARDOWN
:
332 #ifdef CONFIG_STA_SUPPORT
333 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
334 PeerDlsTearDownAction(pAd
, Elem
);
335 #endif // CONFIG_STA_SUPPORT //
339 #endif // QOS_DLS_SUPPORT //
343 #ifdef DOT11_N_SUPPORT
345 IN PRTMP_ADAPTER pAd
,
346 IN MLME_QUEUE_ELEM
*Elem
)
348 UCHAR Action
= Elem
->Msg
[LENGTH_802_11
+1];
353 PeerAddBAReqAction(pAd
,Elem
);
356 PeerAddBARspAction(pAd
,Elem
);
359 PeerDelBAAction(pAd
,Elem
);
367 #ifdef CONFIG_STA_SUPPORT
368 VOID
StaPublicAction(
369 IN PRTMP_ADAPTER pAd
,
370 IN UCHAR Bss2040Coexist
)
372 BSS_2040_COEXIST_IE BssCoexist
;
373 MLME_SCAN_REQ_STRUCT ScanReq
;
375 BssCoexist
.word
= Bss2040Coexist
;
376 // AP asks Station to return a 20/40 BSS Coexistence mgmt frame. So we first starts a scan, then send back 20/40 BSS Coexistence mgmt frame
377 if ((BssCoexist
.field
.InfoReq
== 1) && (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_SCAN_2040
)))
379 // Clear record first. After scan , will update those bit and send back to transmiter.
380 pAd
->CommonCfg
.BSSCoexist2040
.field
.InfoReq
= 1;
381 pAd
->CommonCfg
.BSSCoexist2040
.field
.Intolerant40
= 0;
382 pAd
->CommonCfg
.BSSCoexist2040
.field
.BSS20WidthReq
= 0;
383 // Fill out stuff for scan request
384 ScanParmFill(pAd
, &ScanReq
, ZeroSsid
, 0, BSS_ANY
, SCAN_2040_BSS_COEXIST
);
385 MlmeEnqueue(pAd
, SYNC_STATE_MACHINE
, MT2_MLME_SCAN_REQ
, sizeof(MLME_SCAN_REQ_STRUCT
), &ScanReq
);
386 pAd
->Mlme
.CntlMachine
.CurrState
= CNTL_WAIT_OID_LIST_SCAN
;
392 Description : Build Intolerant Channel Rerpot from Trigger event table.
393 return : how many bytes copied.
395 ULONG
BuildIntolerantChannelRep(
396 IN PRTMP_ADAPTER pAd
,
400 ULONG ReadOffset
= 0;
402 UCHAR LastRegClass
= 0xff;
405 for ( i
= 0;i
< MAX_TRIGGER_EVENT
;i
++)
407 if (pAd
->CommonCfg
.TriggerEventTab
.EventA
[i
].bValid
== TRUE
)
409 if (pAd
->CommonCfg
.TriggerEventTab
.EventA
[i
].RegClass
== LastRegClass
)
411 *(pDest
+ ReadOffset
) = (UCHAR
)pAd
->CommonCfg
.TriggerEventTab
.EventA
[i
].Channel
;
418 *(pDest
+ ReadOffset
) = IE_2040_BSS_INTOLERANT_REPORT
; // IE
419 *(pDest
+ ReadOffset
+ 1) = 2; // Len = RegClass byte + channel byte.
420 pLen
= pDest
+ ReadOffset
+ 1;
421 LastRegClass
= pAd
->CommonCfg
.TriggerEventTab
.EventA
[i
].RegClass
;
422 *(pDest
+ ReadOffset
+ 2) = LastRegClass
; // Len = RegClass byte + channel byte.
423 *(pDest
+ ReadOffset
+ 3) = (UCHAR
)pAd
->CommonCfg
.TriggerEventTab
.EventA
[i
].Channel
;
435 Description : Send 20/40 BSS Coexistence Action frame If one trigger event is triggered.
437 VOID
Send2040CoexistAction(
438 IN PRTMP_ADAPTER pAd
,
440 IN BOOLEAN bAddIntolerantCha
)
442 PUCHAR pOutBuffer
= NULL
;
444 FRAME_ACTION_HDR Frame
;
446 ULONG IntolerantChaRepLen
;
448 IntolerantChaRepLen
= 0;
449 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
450 if(NStatus
!= NDIS_STATUS_SUCCESS
)
452 DBGPRINT(RT_DEBUG_ERROR
,("ACT - Send2040CoexistAction() allocate memory failed \n"));
455 ActHeaderInit(pAd
, &Frame
.Hdr
, pAd
->MacTab
.Content
[Wcid
].Addr
, pAd
->CommonCfg
.Bssid
);
456 Frame
.Category
= CATEGORY_PUBLIC
;
457 Frame
.Action
= ACTION_BSS_2040_COEXIST
;
459 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
460 sizeof(FRAME_ACTION_HDR
), &Frame
,
463 *(pOutBuffer
+ FrameLen
) = pAd
->CommonCfg
.BSSCoexist2040
.word
;
466 if (bAddIntolerantCha
== TRUE
)
467 IntolerantChaRepLen
= BuildIntolerantChannelRep(pAd
, pOutBuffer
+ FrameLen
);
469 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
+ IntolerantChaRepLen
);
470 DBGPRINT(RT_DEBUG_ERROR
,("ACT - Send2040CoexistAction( BSSCoexist2040 = 0x%x ) \n", pAd
->CommonCfg
.BSSCoexist2040
.word
));
476 ==========================================================================
478 After scan, Update 20/40 BSS Coexistence IE and send out.
479 According to 802.11n D3.03 11.14.10
482 ==========================================================================
484 VOID
Update2040CoexistFrameAndNotify(
485 IN PRTMP_ADAPTER pAd
,
487 IN BOOLEAN bAddIntolerantCha
)
489 BSS_2040_COEXIST_IE OldValue
;
491 OldValue
.word
= pAd
->CommonCfg
.BSSCoexist2040
.word
;
492 if ((pAd
->CommonCfg
.TriggerEventTab
.EventANo
> 0) || (pAd
->CommonCfg
.TriggerEventTab
.EventBCountDown
> 0))
493 pAd
->CommonCfg
.BSSCoexist2040
.field
.BSS20WidthReq
= 1;
495 // Need to check !!!!
496 // How STA will set Intolerant40 if implementation dependent. Now we don't set this bit first.!!!!!
497 // So Only check BSS20WidthReq change.
498 if (OldValue
.field
.BSS20WidthReq
!= pAd
->CommonCfg
.BSSCoexist2040
.field
.BSS20WidthReq
)
500 Send2040CoexistAction(pAd
, Wcid
, bAddIntolerantCha
);
503 #endif // CONFIG_STA_SUPPORT //
506 BOOLEAN
ChannelSwitchSanityCheck(
507 IN PRTMP_ADAPTER pAd
,
514 if (Wcid
>= MAX_LEN_OF_MAC_TABLE
)
517 if ((NewChannel
> 7) && (Secondary
== 1))
520 if ((NewChannel
< 5) && (Secondary
== 3))
523 // 0. Check if new channel is in the channellist.
524 for (i
= 0;i
< pAd
->ChannelListNum
;i
++)
526 if (pAd
->ChannelList
[i
].Channel
== NewChannel
)
532 if (i
== pAd
->ChannelListNum
)
539 VOID
ChannelSwitchAction(
540 IN PRTMP_ADAPTER pAd
,
548 DBGPRINT(RT_DEBUG_TRACE
,("SPECTRUM - ChannelSwitchAction(NewChannel = %d , Secondary = %d) \n", NewChannel
, Secondary
));
550 if (ChannelSwitchSanityCheck(pAd
, Wcid
, NewChannel
, Secondary
) == FALSE
)
553 // 1. Switches to BW = 20.
556 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
558 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
559 if (pAd
->MACVersion
== 0x28600100)
561 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R69
, 0x16);
562 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R70
, 0x08);
563 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R73
, 0x11);
564 DBGPRINT(RT_DEBUG_TRACE
, ("!!!rt2860C !!! \n" ));
566 pAd
->CommonCfg
.BBPCurrentBW
= BW_20
;
567 pAd
->CommonCfg
.Channel
= NewChannel
;
568 pAd
->CommonCfg
.CentralChannel
= pAd
->CommonCfg
.Channel
;
569 AsicSwitchChannel(pAd
, pAd
->CommonCfg
.Channel
,FALSE
);
570 AsicLockChannel(pAd
, pAd
->CommonCfg
.Channel
);
571 pAd
->MacTab
.Content
[Wcid
].HTPhyMode
.field
.BW
= 0;
572 DBGPRINT(RT_DEBUG_TRACE
, ("!!!20MHz !!! \n" ));
574 // 1. Switches to BW = 40 And Station supports BW = 40.
575 else if (((Secondary
== 1) || (Secondary
== 3)) && (pAd
->CommonCfg
.HtCapability
.HtCapInfo
.ChannelWidth
== 1))
577 pAd
->CommonCfg
.Channel
= NewChannel
;
582 pAd
->CommonCfg
.CentralChannel
= pAd
->CommonCfg
.Channel
+ 2;
583 RTMP_IO_READ32(pAd
, TX_BAND_CFG
, &MACValue
);
585 RTMP_IO_WRITE32(pAd
, TX_BAND_CFG
, MACValue
);
586 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
589 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
590 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R3
, &BBPValue
);
592 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, BBPValue
);
593 DBGPRINT(RT_DEBUG_TRACE
, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd
->CommonCfg
.CentralChannel
));
598 pAd
->CommonCfg
.CentralChannel
= pAd
->CommonCfg
.Channel
- 2;
599 RTMP_IO_READ32(pAd
, TX_BAND_CFG
, &MACValue
);
602 RTMP_IO_WRITE32(pAd
, TX_BAND_CFG
, MACValue
);
603 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
606 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
607 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R3
, &BBPValue
);
610 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, BBPValue
);
611 DBGPRINT(RT_DEBUG_TRACE
, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd
->CommonCfg
.CentralChannel
));
613 pAd
->CommonCfg
.BBPCurrentBW
= BW_40
;
614 AsicSwitchChannel(pAd
, pAd
->CommonCfg
.CentralChannel
, FALSE
);
615 AsicLockChannel(pAd
, pAd
->CommonCfg
.CentralChannel
);
616 pAd
->MacTab
.Content
[Wcid
].HTPhyMode
.field
.BW
= 1;
619 #endif // DOT11N_DRAFT3 //
620 #endif // DOT11_N_SUPPORT //
622 VOID
PeerPublicAction(
623 IN PRTMP_ADAPTER pAd
,
624 IN MLME_QUEUE_ELEM
*Elem
)
626 #ifdef DOT11_N_SUPPORT
628 UCHAR Action
= Elem
->Msg
[LENGTH_802_11
+1];
629 #endif // DOT11N_DRAFT3 //
630 #endif // DOT11_N_SUPPORT //
631 if (Elem
->Wcid
>= MAX_LEN_OF_MAC_TABLE
)
634 #ifdef DOT11_N_SUPPORT
638 case ACTION_BSS_2040_COEXIST
: // Format defined in IEEE 7.4.7a.1 in 11n Draf3.03
641 BSS_2040_COEXIST_ELEMENT
*pCoexistInfo
;
642 BSS_2040_COEXIST_IE
*pBssCoexistIe
;
643 BSS_2040_INTOLERANT_CH_REPORT
*pIntolerantReport
= NULL
;
645 if (Elem
->MsgLen
<= (LENGTH_802_11
+ sizeof(BSS_2040_COEXIST_ELEMENT
)) )
647 DBGPRINT(RT_DEBUG_ERROR
, ("ACTION - 20/40 BSS Coexistence Management Frame length too short! len = %ld!\n", Elem
->MsgLen
));
650 DBGPRINT(RT_DEBUG_TRACE
, ("ACTION - 20/40 BSS Coexistence Management action----> \n"));
651 hex_dump("CoexistenceMgmtFrame", Elem
->Msg
, Elem
->MsgLen
);
654 pCoexistInfo
= (BSS_2040_COEXIST_ELEMENT
*) &Elem
->Msg
[LENGTH_802_11
+2];
655 //hex_dump("CoexistInfo", (PUCHAR)pCoexistInfo, sizeof(BSS_2040_COEXIST_ELEMENT));
656 if (Elem
->MsgLen
>= (LENGTH_802_11
+ sizeof(BSS_2040_COEXIST_ELEMENT
) + sizeof(BSS_2040_INTOLERANT_CH_REPORT
)))
658 pIntolerantReport
= (BSS_2040_INTOLERANT_CH_REPORT
*)((PUCHAR
)pCoexistInfo
+ sizeof(BSS_2040_COEXIST_ELEMENT
));
660 //hex_dump("IntolerantReport ", (PUCHAR)pIntolerantReport, sizeof(BSS_2040_INTOLERANT_CH_REPORT));
662 pBssCoexistIe
= (BSS_2040_COEXIST_IE
*)(&pCoexistInfo
->BssCoexistIe
);
664 #ifdef CONFIG_STA_SUPPORT
665 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
669 StaPublicAction(pAd
, pCoexistInfo
);
672 #endif // CONFIG_STA_SUPPORT //
678 #endif // DOT11N_DRAFT3 //
679 #endif // DOT11_N_SUPPORT //
684 static VOID
ReservedAction(
685 IN PRTMP_ADAPTER pAd
,
686 IN MLME_QUEUE_ELEM
*Elem
)
690 if (Elem
->MsgLen
<= LENGTH_802_11
)
695 Category
= Elem
->Msg
[LENGTH_802_11
];
696 DBGPRINT(RT_DEBUG_TRACE
,("Rcv reserved category(%d) Action Frame\n", Category
));
697 hex_dump("Reserved Action Frame", &Elem
->Msg
[0], Elem
->MsgLen
);
701 IN PRTMP_ADAPTER pAd
,
702 IN MLME_QUEUE_ELEM
*Elem
)
708 #ifdef DOT11_N_SUPPORT
709 static VOID
respond_ht_information_exchange_action(
710 IN PRTMP_ADAPTER pAd
,
711 IN MLME_QUEUE_ELEM
*Elem
)
713 PUCHAR pOutBuffer
= NULL
;
716 FRAME_HT_INFO HTINFOframe
, *pFrame
;
720 // 2. Always send back ADDBA Response
721 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
723 if (NStatus
!= NDIS_STATUS_SUCCESS
)
725 DBGPRINT(RT_DEBUG_TRACE
,("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
730 pFrame
= (FRAME_HT_INFO
*) &Elem
->Msg
[0];
731 pAddr
= pFrame
->Hdr
.Addr2
;
733 NdisZeroMemory(&HTINFOframe
, sizeof(FRAME_HT_INFO
));
734 // 2-1. Prepare ADDBA Response frame.
735 #ifdef CONFIG_STA_SUPPORT
736 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
739 ActHeaderInit(pAd
, &HTINFOframe
.Hdr
, pAddr
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
741 ActHeaderInit(pAd
, &HTINFOframe
.Hdr
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, pAddr
);
743 #endif // CONFIG_STA_SUPPORT //
745 HTINFOframe
.Category
= CATEGORY_HT
;
746 HTINFOframe
.Action
= HT_INFO_EXCHANGE
;
747 HTINFOframe
.HT_Info
.Request
= 0;
748 HTINFOframe
.HT_Info
.Forty_MHz_Intolerant
= pAd
->CommonCfg
.HtCapability
.HtCapInfo
.Forty_Mhz_Intolerant
;
749 HTINFOframe
.HT_Info
.STA_Channel_Width
= pAd
->CommonCfg
.AddHTInfo
.AddHtInfo
.RecomWidth
;
751 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
752 sizeof(FRAME_HT_INFO
), &HTINFOframe
,
755 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
);
756 MlmeFreeMemory(pAd
, pOutBuffer
);
761 VOID
SendNotifyBWActionFrame(
762 IN PRTMP_ADAPTER pAd
,
766 PUCHAR pOutBuffer
= NULL
;
768 FRAME_ACTION_HDR Frame
;
773 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
774 if(NStatus
!= NDIS_STATUS_SUCCESS
)
776 DBGPRINT(RT_DEBUG_ERROR
,("ACT - SendNotifyBWAction() allocate memory failed \n"));
780 if (Wcid
== MCAST_WCID
)
781 pAddr1
= &BROADCAST_ADDR
[0];
783 pAddr1
= pAd
->MacTab
.Content
[Wcid
].Addr
;
784 ActHeaderInit(pAd
, &Frame
.Hdr
, pAddr1
, pAd
->ApCfg
.MBSSID
[apidx
].Bssid
, pAd
->ApCfg
.MBSSID
[apidx
].Bssid
);
786 Frame
.Category
= CATEGORY_HT
;
787 Frame
.Action
= NOTIFY_BW_ACTION
;
789 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
790 sizeof(FRAME_ACTION_HDR
), &Frame
,
793 *(pOutBuffer
+ FrameLen
) = pAd
->CommonCfg
.AddHTInfo
.AddHtInfo
.RecomWidth
;
797 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
);
798 DBGPRINT(RT_DEBUG_TRACE
,("ACT - SendNotifyBWAction(NotifyBW= %d)!\n", pAd
->CommonCfg
.AddHTInfo
.AddHtInfo
.RecomWidth
));
801 #endif // DOT11N_DRAFT3 //
805 IN PRTMP_ADAPTER pAd
,
806 IN MLME_QUEUE_ELEM
*Elem
)
808 UCHAR Action
= Elem
->Msg
[LENGTH_802_11
+1];
810 if (Elem
->Wcid
>= MAX_LEN_OF_MAC_TABLE
)
815 case NOTIFY_BW_ACTION
:
816 DBGPRINT(RT_DEBUG_TRACE
,("ACTION - HT Notify Channel bandwidth action----> \n"));
817 #ifdef CONFIG_STA_SUPPORT
818 if(pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
== FALSE
)
820 // Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps
821 // sending BW_Notify Action frame, and cause us to linkup and linkdown.
822 // In legacy mode, don't need to parse HT action frame.
823 DBGPRINT(RT_DEBUG_TRACE
,("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
824 Elem
->Msg
[LENGTH_802_11
+2] ));
827 #endif // CONFIG_STA_SUPPORT //
829 if (Elem
->Msg
[LENGTH_802_11
+2] == 0) // 7.4.8.2. if value is 1, keep the same as supported channel bandwidth.
830 pAd
->MacTab
.Content
[Elem
->Wcid
].HTPhyMode
.field
.BW
= 0;
836 DBGPRINT(RT_DEBUG_TRACE
,("ACTION - SMPS action----> \n"));
837 if (((Elem
->Msg
[LENGTH_802_11
+2]&0x1) == 0))
839 pAd
->MacTab
.Content
[Elem
->Wcid
].MmpsMode
= MMPS_ENABLE
;
841 else if (((Elem
->Msg
[LENGTH_802_11
+2]&0x2) == 0))
843 pAd
->MacTab
.Content
[Elem
->Wcid
].MmpsMode
= MMPS_STATIC
;
847 pAd
->MacTab
.Content
[Elem
->Wcid
].MmpsMode
= MMPS_DYNAMIC
;
850 DBGPRINT(RT_DEBUG_TRACE
,("Aid(%d) MIMO PS = %d\n", Elem
->Wcid
, pAd
->MacTab
.Content
[Elem
->Wcid
].MmpsMode
));
851 // rt2860c : add something for smps change.
857 case MIMO_CHA_MEASURE_ACTION
:
860 case HT_INFO_EXCHANGE
:
862 HT_INFORMATION_OCTET
*pHT_info
;
864 pHT_info
= (HT_INFORMATION_OCTET
*) &Elem
->Msg
[LENGTH_802_11
+2];
866 DBGPRINT(RT_DEBUG_TRACE
,("ACTION - HT Information Exchange action----> \n"));
867 if (pHT_info
->Request
)
869 respond_ht_information_exchange_action(pAd
, Elem
);
878 ==========================================================================
880 Retry sending ADDBA Reqest.
882 IRQL = DISPATCH_LEVEL
885 p8023Header: if this is already 802.3 format, p8023Header is NULL
887 Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
888 FALSE , then continue indicaterx at this moment.
889 ==========================================================================
891 VOID
ORIBATimerTimeout(
892 IN PRTMP_ADAPTER pAd
)
894 MAC_TABLE_ENTRY
*pEntry
;
896 // FRAME_BAR FrameBar;
898 // NDIS_STATUS NStatus;
899 // PUCHAR pOutBuffer = NULL;
906 #endif // RALINK_ATE //
908 total
= pAd
->MacTab
.Size
* NUM_OF_TID
;
910 for (i
= 1; ((i
<MAX_LEN_OF_BA_ORI_TABLE
) && (total
> 0)) ; i
++)
912 if (pAd
->BATable
.BAOriEntry
[i
].ORI_BA_Status
== Originator_Done
)
914 pEntry
= &pAd
->MacTab
.Content
[pAd
->BATable
.BAOriEntry
[i
].Wcid
];
915 TID
= pAd
->BATable
.BAOriEntry
[i
].TID
;
917 ASSERT(pAd
->BATable
.BAOriEntry
[i
].Wcid
< MAX_LEN_OF_MAC_TABLE
);
925 IN PRTMP_ADAPTER pAd
,
926 IN MAC_TABLE_ENTRY
*pEntry
)
931 PUCHAR pOutBuffer
= NULL
;
935 BA_ORI_ENTRY
*pBAEntry
;
937 for (i
= 0; i
<NUM_OF_TID
; i
++)
939 idx
= pEntry
->BAOriWcidArray
[i
];
944 pBAEntry
= &pAd
->BATable
.BAOriEntry
[idx
];
946 if (pBAEntry
->ORI_BA_Status
== Originator_Done
)
950 ASSERT(pBAEntry
->Wcid
< MAX_LEN_OF_MAC_TABLE
);
952 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
953 if(NStatus
!= NDIS_STATUS_SUCCESS
)
955 DBGPRINT(RT_DEBUG_ERROR
,("BA - MlmeADDBAAction() allocate memory failed \n"));
959 Sequence
= pEntry
->TxSeq
[TID
];
962 #ifdef CONFIG_STA_SUPPORT
963 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
964 BarHeaderInit(pAd
, &FrameBar
, pEntry
->Addr
, pAd
->CurrentAddress
);
965 #endif // CONFIG_STA_SUPPORT //
967 FrameBar
.StartingSeq
.field
.FragNum
= 0; // make sure sequence not clear in DEL function.
968 FrameBar
.StartingSeq
.field
.StartSeq
= Sequence
; // make sure sequence not clear in DEL funciton.
969 FrameBar
.BarControl
.TID
= TID
; // make sure sequence not clear in DEL funciton.
971 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
972 sizeof(FRAME_BAR
), &FrameBar
,
974 //if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET)))
975 if (1) // Now we always send BAR.
977 //MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen);
978 MiniportMMRequest(pAd
, (MGMT_USE_QUEUE_FLAG
| MapUserPriorityToAccessCategory
[TID
]), pOutBuffer
, FrameLen
);
981 MlmeFreeMemory(pAd
, pOutBuffer
);
985 #endif // DOT11_N_SUPPORT //
988 IN PRTMP_ADAPTER pAd
,
989 IN OUT PHEADER_802_11 pHdr80211
,
994 NdisZeroMemory(pHdr80211
, sizeof(HEADER_802_11
));
995 pHdr80211
->FC
.Type
= BTYPE_MGMT
;
996 pHdr80211
->FC
.SubType
= SUBTYPE_ACTION
;
998 COPY_MAC_ADDR(pHdr80211
->Addr1
, Addr1
);
999 COPY_MAC_ADDR(pHdr80211
->Addr2
, Addr2
);
1000 COPY_MAC_ADDR(pHdr80211
->Addr3
, Addr3
);
1004 IN PRTMP_ADAPTER pAd
,
1005 IN OUT PFRAME_BAR pCntlBar
,
1011 NdisZeroMemory(pCntlBar
, sizeof(FRAME_BAR
));
1012 pCntlBar
->FC
.Type
= BTYPE_CNTL
;
1013 pCntlBar
->FC
.SubType
= SUBTYPE_BLOCK_ACK_REQ
;
1014 pCntlBar
->BarControl
.MTID
= 0;
1015 pCntlBar
->BarControl
.Compressed
= 1;
1016 pCntlBar
->BarControl
.ACKPolicy
= 0;
1019 pCntlBar
->Duration
= 16 + RTMPCalcDuration(pAd
, RATE_1
, sizeof(FRAME_BA
));
1021 COPY_MAC_ADDR(pCntlBar
->Addr1
, pDA
);
1022 COPY_MAC_ADDR(pCntlBar
->Addr2
, pSA
);
1027 ==========================================================================
1029 Insert Category and action code into the action frame.
1032 1. frame buffer pointer.
1034 3. category code of the frame.
1035 4. action code of the frame.
1038 ==========================================================================
1040 VOID
InsertActField(
1041 IN PRTMP_ADAPTER pAd
,
1042 OUT PUCHAR pFrameBuf
,
1043 OUT PULONG pFrameLen
,
1049 MakeOutgoingFrame( pFrameBuf
, &TempLen
,
1054 *pFrameLen
= *pFrameLen
+ TempLen
;