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"
43 static VOID
ReservedAction(
45 IN MLME_QUEUE_ELEM
*Elem
);
48 ==========================================================================
50 association state machine init, including state transition and timer init
52 S - pointer to the association state machine
54 The state machine looks like the following
57 MT2_MLME_DISASSOC_REQ mlme_disassoc_req_action
58 MT2_PEER_DISASSOC_REQ peer_disassoc_action
59 MT2_PEER_ASSOC_REQ drop
60 MT2_PEER_REASSOC_REQ drop
61 MT2_CLS3ERR cls3err_action
62 ==========================================================================
64 VOID
ActionStateMachineInit(
67 OUT STATE_MACHINE_FUNC Trans
[])
69 StateMachineInit(S
, (STATE_MACHINE_FUNC
*)Trans
, MAX_ACT_STATE
, MAX_ACT_MSG
, (STATE_MACHINE_FUNC
)Drop
, ACT_IDLE
, ACT_MACHINE_BASE
);
71 StateMachineSetAction(S
, ACT_IDLE
, MT2_PEER_SPECTRUM_CATE
, (STATE_MACHINE_FUNC
)PeerSpectrumAction
);
72 StateMachineSetAction(S
, ACT_IDLE
, MT2_PEER_QOS_CATE
, (STATE_MACHINE_FUNC
)PeerQOSAction
);
74 StateMachineSetAction(S
, ACT_IDLE
, MT2_PEER_DLS_CATE
, (STATE_MACHINE_FUNC
)ReservedAction
);
75 #ifdef QOS_DLS_SUPPORT
76 StateMachineSetAction(S
, ACT_IDLE
, MT2_PEER_DLS_CATE
, (STATE_MACHINE_FUNC
)PeerDLSAction
);
77 #endif // QOS_DLS_SUPPORT //
79 #ifdef DOT11_N_SUPPORT
80 StateMachineSetAction(S
, ACT_IDLE
, MT2_PEER_BA_CATE
, (STATE_MACHINE_FUNC
)PeerBAAction
);
81 StateMachineSetAction(S
, ACT_IDLE
, MT2_PEER_HT_CATE
, (STATE_MACHINE_FUNC
)PeerHTAction
);
82 StateMachineSetAction(S
, ACT_IDLE
, MT2_MLME_ADD_BA_CATE
, (STATE_MACHINE_FUNC
)MlmeADDBAAction
);
83 StateMachineSetAction(S
, ACT_IDLE
, MT2_MLME_ORI_DELBA_CATE
, (STATE_MACHINE_FUNC
)MlmeDELBAAction
);
84 StateMachineSetAction(S
, ACT_IDLE
, MT2_MLME_REC_DELBA_CATE
, (STATE_MACHINE_FUNC
)MlmeDELBAAction
);
85 #endif // DOT11_N_SUPPORT //
87 StateMachineSetAction(S
, ACT_IDLE
, MT2_PEER_PUBLIC_CATE
, (STATE_MACHINE_FUNC
)PeerPublicAction
);
88 StateMachineSetAction(S
, ACT_IDLE
, MT2_PEER_RM_CATE
, (STATE_MACHINE_FUNC
)PeerRMAction
);
90 StateMachineSetAction(S
, ACT_IDLE
, MT2_MLME_QOS_CATE
, (STATE_MACHINE_FUNC
)MlmeQOSAction
);
91 StateMachineSetAction(S
, ACT_IDLE
, MT2_MLME_DLS_CATE
, (STATE_MACHINE_FUNC
)MlmeDLSAction
);
92 StateMachineSetAction(S
, ACT_IDLE
, MT2_ACT_INVALID
, (STATE_MACHINE_FUNC
)MlmeInvalidAction
);
95 #ifdef DOT11_N_SUPPORT
98 IN MLME_QUEUE_ELEM
*Elem
)
101 MLME_ADDBA_REQ_STRUCT
*pInfo
;
103 PUCHAR pOutBuffer
= NULL
;
106 FRAME_ADDBA_REQ Frame
;
108 BA_ORI_ENTRY
*pBAEntry
= NULL
;
110 pInfo
= (MLME_ADDBA_REQ_STRUCT
*)Elem
->Msg
;
111 NdisZeroMemory(&Frame
, sizeof(FRAME_ADDBA_REQ
));
113 if(MlmeAddBAReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, Addr
))
115 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
116 if(NStatus
!= NDIS_STATUS_SUCCESS
)
118 DBGPRINT(RT_DEBUG_TRACE
,("BA - MlmeADDBAAction() allocate memory failed \n"));
122 Idx
= pAd
->MacTab
.Content
[pInfo
->Wcid
].BAOriWcidArray
[pInfo
->TID
];
125 MlmeFreeMemory(pAd
, pOutBuffer
);
126 DBGPRINT(RT_DEBUG_ERROR
,("BA - MlmeADDBAAction() can't find BAOriEntry \n"));
131 pBAEntry
=&pAd
->BATable
.BAOriEntry
[Idx
];
134 #ifdef CONFIG_STA_SUPPORT
135 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
138 ActHeaderInit(pAd
, &Frame
.Hdr
, pInfo
->pAddr
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
140 #ifdef QOS_DLS_SUPPORT
141 if (pAd
->MacTab
.Content
[pInfo
->Wcid
].ValidAsDls
)
142 ActHeaderInit(pAd
, &Frame
.Hdr
, pInfo
->pAddr
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
144 #endif // QOS_DLS_SUPPORT //
145 ActHeaderInit(pAd
, &Frame
.Hdr
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, pInfo
->pAddr
);
148 #endif // CONFIG_STA_SUPPORT //
150 Frame
.Category
= CATEGORY_BA
;
151 Frame
.Action
= ADDBA_REQ
;
152 Frame
.BaParm
.AMSDUSupported
= 0;
153 Frame
.BaParm
.BAPolicy
= IMMED_BA
;
154 Frame
.BaParm
.TID
= pInfo
->TID
;
155 Frame
.BaParm
.BufSize
= pInfo
->BaBufSize
;
156 Frame
.Token
= pInfo
->Token
;
157 Frame
.TimeOutValue
= pInfo
->TimeOutValue
;
158 Frame
.BaStartSeq
.field
.FragNum
= 0;
159 Frame
.BaStartSeq
.field
.StartSeq
= pAd
->MacTab
.Content
[pInfo
->Wcid
].TxSeq
[pInfo
->TID
];
161 *(USHORT
*)(&Frame
.BaParm
) = cpu2le16(*(USHORT
*)(&Frame
.BaParm
));
162 Frame
.TimeOutValue
= cpu2le16(Frame
.TimeOutValue
);
163 Frame
.BaStartSeq
.word
= cpu2le16(Frame
.BaStartSeq
.word
);
165 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
166 sizeof(FRAME_ADDBA_REQ
), &Frame
,
168 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
);
169 MlmeFreeMemory(pAd
, pOutBuffer
);
171 DBGPRINT(RT_DEBUG_TRACE
, ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", Frame
.BaStartSeq
.field
.StartSeq
, FrameLen
, Frame
.BaParm
.BufSize
));
176 ==========================================================================
178 send DELBA and delete BaEntry if any
180 Elem - MLME message MLME_DELBA_REQ_STRUCT
182 IRQL = DISPATCH_LEVEL
184 ==========================================================================
186 VOID
MlmeDELBAAction(
187 IN PRTMP_ADAPTER pAd
,
188 IN MLME_QUEUE_ELEM
*Elem
)
190 MLME_DELBA_REQ_STRUCT
*pInfo
;
191 PUCHAR pOutBuffer
= NULL
;
192 PUCHAR pOutBuffer2
= NULL
;
195 FRAME_DELBA_REQ Frame
;
199 pInfo
= (MLME_DELBA_REQ_STRUCT
*)Elem
->Msg
;
200 // must send back DELBA
201 NdisZeroMemory(&Frame
, sizeof(FRAME_DELBA_REQ
));
202 DBGPRINT(RT_DEBUG_TRACE
, ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo
->Initiator
));
204 if(MlmeDelBAReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
))
206 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
207 if(NStatus
!= NDIS_STATUS_SUCCESS
)
209 DBGPRINT(RT_DEBUG_ERROR
,("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
213 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer2
); //Get an unused nonpaged memory
214 if(NStatus
!= NDIS_STATUS_SUCCESS
)
216 MlmeFreeMemory(pAd
, pOutBuffer
);
217 DBGPRINT(RT_DEBUG_ERROR
, ("BA - MlmeDELBAAction() allocate memory failed 2. \n"));
221 // SEND BAR (Send BAR to refresh peer reordering buffer.)
222 Idx
= pAd
->MacTab
.Content
[pInfo
->Wcid
].BAOriWcidArray
[pInfo
->TID
];
224 #ifdef CONFIG_STA_SUPPORT
225 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
226 BarHeaderInit(pAd
, &FrameBar
, pAd
->MacTab
.Content
[pInfo
->Wcid
].Addr
, pAd
->CurrentAddress
);
227 #endif // CONFIG_STA_SUPPORT //
229 FrameBar
.StartingSeq
.field
.FragNum
= 0; // make sure sequence not clear in DEL funciton.
230 FrameBar
.StartingSeq
.field
.StartSeq
= pAd
->MacTab
.Content
[pInfo
->Wcid
].TxSeq
[pInfo
->TID
]; // make sure sequence not clear in DEL funciton.
231 FrameBar
.BarControl
.TID
= pInfo
->TID
; // make sure sequence not clear in DEL funciton.
232 FrameBar
.BarControl
.ACKPolicy
= IMMED_BA
; // make sure sequence not clear in DEL funciton.
233 FrameBar
.BarControl
.Compressed
= 1; // make sure sequence not clear in DEL funciton.
234 FrameBar
.BarControl
.MTID
= 0; // make sure sequence not clear in DEL funciton.
236 MakeOutgoingFrame(pOutBuffer2
, &FrameLen
,
237 sizeof(FRAME_BAR
), &FrameBar
,
239 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer2
, FrameLen
);
240 MlmeFreeMemory(pAd
, pOutBuffer2
);
241 DBGPRINT(RT_DEBUG_TRACE
,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
245 #ifdef CONFIG_STA_SUPPORT
246 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
249 ActHeaderInit(pAd
, &Frame
.Hdr
, pAd
->MacTab
.Content
[pInfo
->Wcid
].Addr
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
251 #ifdef QOS_DLS_SUPPORT
252 if (pAd
->MacTab
.Content
[pInfo
->Wcid
].ValidAsDls
)
253 ActHeaderInit(pAd
, &Frame
.Hdr
, pAd
->MacTab
.Content
[pInfo
->Wcid
].Addr
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
255 #endif // QOS_DLS_SUPPORT //
256 ActHeaderInit(pAd
, &Frame
.Hdr
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, pAd
->MacTab
.Content
[pInfo
->Wcid
].Addr
);
258 #endif // CONFIG_STA_SUPPORT //
259 Frame
.Category
= CATEGORY_BA
;
260 Frame
.Action
= DELBA
;
261 Frame
.DelbaParm
.Initiator
= pInfo
->Initiator
;
262 Frame
.DelbaParm
.TID
= pInfo
->TID
;
263 Frame
.ReasonCode
= 39; // Time Out
264 *(USHORT
*)(&Frame
.DelbaParm
) = cpu2le16(*(USHORT
*)(&Frame
.DelbaParm
));
265 Frame
.ReasonCode
= cpu2le16(Frame
.ReasonCode
);
267 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
268 sizeof(FRAME_DELBA_REQ
), &Frame
,
270 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
);
271 MlmeFreeMemory(pAd
, pOutBuffer
);
272 DBGPRINT(RT_DEBUG_TRACE
, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo
->Initiator
));
275 #endif // DOT11_N_SUPPORT //
278 IN PRTMP_ADAPTER pAd
,
279 IN MLME_QUEUE_ELEM
*Elem
)
284 IN PRTMP_ADAPTER pAd
,
285 IN MLME_QUEUE_ELEM
*Elem
)
289 VOID
MlmeInvalidAction(
290 IN PRTMP_ADAPTER pAd
,
291 IN MLME_QUEUE_ELEM
*Elem
)
293 //PUCHAR pOutBuffer = NULL;
294 //Return the receiving frame except the MSB of category filed set to 1. 7.3.1.11
298 IN PRTMP_ADAPTER pAd
,
299 IN MLME_QUEUE_ELEM
*Elem
)
303 #ifdef QOS_DLS_SUPPORT
305 IN PRTMP_ADAPTER pAd
,
306 IN MLME_QUEUE_ELEM
*Elem
)
308 UCHAR Action
= Elem
->Msg
[LENGTH_802_11
+1];
312 case ACTION_DLS_REQUEST
:
313 #ifdef CONFIG_STA_SUPPORT
314 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
315 PeerDlsReqAction(pAd
, Elem
);
316 #endif // CONFIG_STA_SUPPORT //
319 case ACTION_DLS_RESPONSE
:
320 #ifdef CONFIG_STA_SUPPORT
321 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
322 PeerDlsRspAction(pAd
, Elem
);
323 #endif // CONFIG_STA_SUPPORT //
326 case ACTION_DLS_TEARDOWN
:
327 #ifdef CONFIG_STA_SUPPORT
328 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
329 PeerDlsTearDownAction(pAd
, Elem
);
330 #endif // CONFIG_STA_SUPPORT //
334 #endif // QOS_DLS_SUPPORT //
336 #ifdef DOT11_N_SUPPORT
338 IN PRTMP_ADAPTER pAd
,
339 IN MLME_QUEUE_ELEM
*Elem
)
341 UCHAR Action
= Elem
->Msg
[LENGTH_802_11
+1];
346 PeerAddBAReqAction(pAd
,Elem
);
349 PeerAddBARspAction(pAd
,Elem
);
352 PeerDelBAAction(pAd
,Elem
);
360 #ifdef CONFIG_STA_SUPPORT
361 VOID
StaPublicAction(
362 IN PRTMP_ADAPTER pAd
,
363 IN UCHAR Bss2040Coexist
)
365 BSS_2040_COEXIST_IE BssCoexist
;
366 MLME_SCAN_REQ_STRUCT ScanReq
;
368 BssCoexist
.word
= Bss2040Coexist
;
369 // 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
370 if ((BssCoexist
.field
.InfoReq
== 1) && (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_SCAN_2040
)))
372 // Clear record first. After scan , will update those bit and send back to transmiter.
373 pAd
->CommonCfg
.BSSCoexist2040
.field
.InfoReq
= 1;
374 pAd
->CommonCfg
.BSSCoexist2040
.field
.Intolerant40
= 0;
375 pAd
->CommonCfg
.BSSCoexist2040
.field
.BSS20WidthReq
= 0;
376 // Fill out stuff for scan request
377 ScanParmFill(pAd
, &ScanReq
, ZeroSsid
, 0, BSS_ANY
, SCAN_2040_BSS_COEXIST
);
378 MlmeEnqueue(pAd
, SYNC_STATE_MACHINE
, MT2_MLME_SCAN_REQ
, sizeof(MLME_SCAN_REQ_STRUCT
), &ScanReq
);
379 pAd
->Mlme
.CntlMachine
.CurrState
= CNTL_WAIT_OID_LIST_SCAN
;
385 Description : Build Intolerant Channel Rerpot from Trigger event table.
386 return : how many bytes copied.
388 ULONG
BuildIntolerantChannelRep(
389 IN PRTMP_ADAPTER pAd
,
393 ULONG ReadOffset
= 0;
395 UCHAR LastRegClass
= 0xff;
398 for ( i
= 0;i
< MAX_TRIGGER_EVENT
;i
++)
400 if (pAd
->CommonCfg
.TriggerEventTab
.EventA
[i
].bValid
== TRUE
)
402 if (pAd
->CommonCfg
.TriggerEventTab
.EventA
[i
].RegClass
== LastRegClass
)
404 *(pDest
+ ReadOffset
) = (UCHAR
)pAd
->CommonCfg
.TriggerEventTab
.EventA
[i
].Channel
;
411 *(pDest
+ ReadOffset
) = IE_2040_BSS_INTOLERANT_REPORT
; // IE
412 *(pDest
+ ReadOffset
+ 1) = 2; // Len = RegClass byte + channel byte.
413 pLen
= pDest
+ ReadOffset
+ 1;
414 LastRegClass
= pAd
->CommonCfg
.TriggerEventTab
.EventA
[i
].RegClass
;
415 *(pDest
+ ReadOffset
+ 2) = LastRegClass
; // Len = RegClass byte + channel byte.
416 *(pDest
+ ReadOffset
+ 3) = (UCHAR
)pAd
->CommonCfg
.TriggerEventTab
.EventA
[i
].Channel
;
428 Description : Send 20/40 BSS Coexistence Action frame If one trigger event is triggered.
430 VOID
Send2040CoexistAction(
431 IN PRTMP_ADAPTER pAd
,
433 IN BOOLEAN bAddIntolerantCha
)
435 PUCHAR pOutBuffer
= NULL
;
437 FRAME_ACTION_HDR Frame
;
439 ULONG IntolerantChaRepLen
;
441 IntolerantChaRepLen
= 0;
442 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
443 if(NStatus
!= NDIS_STATUS_SUCCESS
)
445 DBGPRINT(RT_DEBUG_ERROR
,("ACT - Send2040CoexistAction() allocate memory failed \n"));
448 ActHeaderInit(pAd
, &Frame
.Hdr
, pAd
->MacTab
.Content
[Wcid
].Addr
, pAd
->CommonCfg
.Bssid
);
449 Frame
.Category
= CATEGORY_PUBLIC
;
450 Frame
.Action
= ACTION_BSS_2040_COEXIST
;
452 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
453 sizeof(FRAME_ACTION_HDR
), &Frame
,
456 *(pOutBuffer
+ FrameLen
) = pAd
->CommonCfg
.BSSCoexist2040
.word
;
459 if (bAddIntolerantCha
== TRUE
)
460 IntolerantChaRepLen
= BuildIntolerantChannelRep(pAd
, pOutBuffer
+ FrameLen
);
462 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
+ IntolerantChaRepLen
);
463 DBGPRINT(RT_DEBUG_ERROR
,("ACT - Send2040CoexistAction( BSSCoexist2040 = 0x%x ) \n", pAd
->CommonCfg
.BSSCoexist2040
.word
));
469 ==========================================================================
471 After scan, Update 20/40 BSS Coexistence IE and send out.
472 According to 802.11n D3.03 11.14.10
475 ==========================================================================
477 VOID
Update2040CoexistFrameAndNotify(
478 IN PRTMP_ADAPTER pAd
,
480 IN BOOLEAN bAddIntolerantCha
)
482 BSS_2040_COEXIST_IE OldValue
;
484 OldValue
.word
= pAd
->CommonCfg
.BSSCoexist2040
.word
;
485 if ((pAd
->CommonCfg
.TriggerEventTab
.EventANo
> 0) || (pAd
->CommonCfg
.TriggerEventTab
.EventBCountDown
> 0))
486 pAd
->CommonCfg
.BSSCoexist2040
.field
.BSS20WidthReq
= 1;
488 // Need to check !!!!
489 // How STA will set Intolerant40 if implementation dependent. Now we don't set this bit first.!!!!!
490 // So Only check BSS20WidthReq change.
491 if (OldValue
.field
.BSS20WidthReq
!= pAd
->CommonCfg
.BSSCoexist2040
.field
.BSS20WidthReq
)
493 Send2040CoexistAction(pAd
, Wcid
, bAddIntolerantCha
);
496 #endif // CONFIG_STA_SUPPORT //
499 BOOLEAN
ChannelSwitchSanityCheck(
500 IN PRTMP_ADAPTER pAd
,
507 if (Wcid
>= MAX_LEN_OF_MAC_TABLE
)
510 if ((NewChannel
> 7) && (Secondary
== 1))
513 if ((NewChannel
< 5) && (Secondary
== 3))
516 // 0. Check if new channel is in the channellist.
517 for (i
= 0;i
< pAd
->ChannelListNum
;i
++)
519 if (pAd
->ChannelList
[i
].Channel
== NewChannel
)
525 if (i
== pAd
->ChannelListNum
)
532 VOID
ChannelSwitchAction(
533 IN PRTMP_ADAPTER pAd
,
541 DBGPRINT(RT_DEBUG_TRACE
,("SPECTRUM - ChannelSwitchAction(NewChannel = %d , Secondary = %d) \n", NewChannel
, Secondary
));
543 if (ChannelSwitchSanityCheck(pAd
, Wcid
, NewChannel
, Secondary
) == FALSE
)
546 // 1. Switches to BW = 20.
549 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
551 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
552 if (pAd
->MACVersion
== 0x28600100)
554 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R69
, 0x16);
555 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R70
, 0x08);
556 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R73
, 0x11);
557 DBGPRINT(RT_DEBUG_TRACE
, ("!!!rt2860C !!! \n" ));
559 pAd
->CommonCfg
.BBPCurrentBW
= BW_20
;
560 pAd
->CommonCfg
.Channel
= NewChannel
;
561 pAd
->CommonCfg
.CentralChannel
= pAd
->CommonCfg
.Channel
;
562 AsicSwitchChannel(pAd
, pAd
->CommonCfg
.Channel
,FALSE
);
563 AsicLockChannel(pAd
, pAd
->CommonCfg
.Channel
);
564 pAd
->MacTab
.Content
[Wcid
].HTPhyMode
.field
.BW
= 0;
565 DBGPRINT(RT_DEBUG_TRACE
, ("!!!20MHz !!! \n" ));
567 // 1. Switches to BW = 40 And Station supports BW = 40.
568 else if (((Secondary
== 1) || (Secondary
== 3)) && (pAd
->CommonCfg
.HtCapability
.HtCapInfo
.ChannelWidth
== 1))
570 pAd
->CommonCfg
.Channel
= NewChannel
;
575 pAd
->CommonCfg
.CentralChannel
= pAd
->CommonCfg
.Channel
+ 2;
576 RTMP_IO_READ32(pAd
, TX_BAND_CFG
, &MACValue
);
578 RTMP_IO_WRITE32(pAd
, TX_BAND_CFG
, MACValue
);
579 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
582 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
583 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R3
, &BBPValue
);
585 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, BBPValue
);
586 DBGPRINT(RT_DEBUG_TRACE
, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd
->CommonCfg
.CentralChannel
));
591 pAd
->CommonCfg
.CentralChannel
= pAd
->CommonCfg
.Channel
- 2;
592 RTMP_IO_READ32(pAd
, TX_BAND_CFG
, &MACValue
);
595 RTMP_IO_WRITE32(pAd
, TX_BAND_CFG
, MACValue
);
596 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
599 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
600 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R3
, &BBPValue
);
603 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, BBPValue
);
604 DBGPRINT(RT_DEBUG_TRACE
, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd
->CommonCfg
.CentralChannel
));
606 pAd
->CommonCfg
.BBPCurrentBW
= BW_40
;
607 AsicSwitchChannel(pAd
, pAd
->CommonCfg
.CentralChannel
, FALSE
);
608 AsicLockChannel(pAd
, pAd
->CommonCfg
.CentralChannel
);
609 pAd
->MacTab
.Content
[Wcid
].HTPhyMode
.field
.BW
= 1;
612 #endif // DOT11N_DRAFT3 //
613 #endif // DOT11_N_SUPPORT //
615 VOID
PeerPublicAction(
616 IN PRTMP_ADAPTER pAd
,
617 IN MLME_QUEUE_ELEM
*Elem
)
620 UCHAR Action
= Elem
->Msg
[LENGTH_802_11
+1];
621 #endif // DOT11N_DRAFT3 //
623 if (Elem
->Wcid
>= MAX_LEN_OF_MAC_TABLE
)
629 case ACTION_BSS_2040_COEXIST
: // Format defined in IEEE 7.4.7a.1 in 11n Draf3.03
632 BSS_2040_COEXIST_ELEMENT
*pCoexistInfo
;
633 BSS_2040_COEXIST_IE
*pBssCoexistIe
;
634 BSS_2040_INTOLERANT_CH_REPORT
*pIntolerantReport
= NULL
;
636 if (Elem
->MsgLen
<= (LENGTH_802_11
+ sizeof(BSS_2040_COEXIST_ELEMENT
)) )
638 DBGPRINT(RT_DEBUG_ERROR
, ("ACTION - 20/40 BSS Coexistence Management Frame length too short! len = %ld!\n", Elem
->MsgLen
));
641 DBGPRINT(RT_DEBUG_TRACE
, ("ACTION - 20/40 BSS Coexistence Management action----> \n"));
642 hex_dump("CoexistenceMgmtFrame", Elem
->Msg
, Elem
->MsgLen
);
645 pCoexistInfo
= (BSS_2040_COEXIST_ELEMENT
*) &Elem
->Msg
[LENGTH_802_11
+2];
646 //hex_dump("CoexistInfo", (PUCHAR)pCoexistInfo, sizeof(BSS_2040_COEXIST_ELEMENT));
647 if (Elem
->MsgLen
>= (LENGTH_802_11
+ sizeof(BSS_2040_COEXIST_ELEMENT
) + sizeof(BSS_2040_INTOLERANT_CH_REPORT
)))
649 pIntolerantReport
= (BSS_2040_INTOLERANT_CH_REPORT
*)((PUCHAR
)pCoexistInfo
+ sizeof(BSS_2040_COEXIST_ELEMENT
));
651 //hex_dump("IntolerantReport ", (PUCHAR)pIntolerantReport, sizeof(BSS_2040_INTOLERANT_CH_REPORT));
653 pBssCoexistIe
= (BSS_2040_COEXIST_IE
*)(&pCoexistInfo
->BssCoexistIe
);
655 #ifdef CONFIG_STA_SUPPORT
656 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
660 StaPublicAction(pAd
, pCoexistInfo
);
663 #endif // CONFIG_STA_SUPPORT //
669 #endif // DOT11N_DRAFT3 //
674 static VOID
ReservedAction(
675 IN PRTMP_ADAPTER pAd
,
676 IN MLME_QUEUE_ELEM
*Elem
)
680 if (Elem
->MsgLen
<= LENGTH_802_11
)
685 Category
= Elem
->Msg
[LENGTH_802_11
];
686 DBGPRINT(RT_DEBUG_TRACE
,("Rcv reserved category(%d) Action Frame\n", Category
));
687 hex_dump("Reserved Action Frame", &Elem
->Msg
[0], Elem
->MsgLen
);
691 IN PRTMP_ADAPTER pAd
,
692 IN MLME_QUEUE_ELEM
*Elem
)
698 #ifdef DOT11_N_SUPPORT
699 static VOID
respond_ht_information_exchange_action(
700 IN PRTMP_ADAPTER pAd
,
701 IN MLME_QUEUE_ELEM
*Elem
)
703 PUCHAR pOutBuffer
= NULL
;
706 FRAME_HT_INFO HTINFOframe
, *pFrame
;
710 // 2. Always send back ADDBA Response
711 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
713 if (NStatus
!= NDIS_STATUS_SUCCESS
)
715 DBGPRINT(RT_DEBUG_TRACE
,("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
720 pFrame
= (FRAME_HT_INFO
*) &Elem
->Msg
[0];
721 pAddr
= pFrame
->Hdr
.Addr2
;
723 NdisZeroMemory(&HTINFOframe
, sizeof(FRAME_HT_INFO
));
724 // 2-1. Prepare ADDBA Response frame.
725 #ifdef CONFIG_STA_SUPPORT
726 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
729 ActHeaderInit(pAd
, &HTINFOframe
.Hdr
, pAddr
, pAd
->CurrentAddress
, pAd
->CommonCfg
.Bssid
);
731 ActHeaderInit(pAd
, &HTINFOframe
.Hdr
, pAd
->CommonCfg
.Bssid
, pAd
->CurrentAddress
, pAddr
);
733 #endif // CONFIG_STA_SUPPORT //
735 HTINFOframe
.Category
= CATEGORY_HT
;
736 HTINFOframe
.Action
= HT_INFO_EXCHANGE
;
737 HTINFOframe
.HT_Info
.Request
= 0;
738 HTINFOframe
.HT_Info
.Forty_MHz_Intolerant
= pAd
->CommonCfg
.HtCapability
.HtCapInfo
.Forty_Mhz_Intolerant
;
739 HTINFOframe
.HT_Info
.STA_Channel_Width
= pAd
->CommonCfg
.AddHTInfo
.AddHtInfo
.RecomWidth
;
741 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
742 sizeof(FRAME_HT_INFO
), &HTINFOframe
,
745 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
);
746 MlmeFreeMemory(pAd
, pOutBuffer
);
751 VOID
SendNotifyBWActionFrame(
752 IN PRTMP_ADAPTER pAd
,
756 PUCHAR pOutBuffer
= NULL
;
758 FRAME_ACTION_HDR Frame
;
763 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
764 if(NStatus
!= NDIS_STATUS_SUCCESS
)
766 DBGPRINT(RT_DEBUG_ERROR
,("ACT - SendNotifyBWAction() allocate memory failed \n"));
770 if (Wcid
== MCAST_WCID
)
771 pAddr1
= &BROADCAST_ADDR
[0];
773 pAddr1
= pAd
->MacTab
.Content
[Wcid
].Addr
;
774 ActHeaderInit(pAd
, &Frame
.Hdr
, pAddr1
, pAd
->ApCfg
.MBSSID
[apidx
].Bssid
, pAd
->ApCfg
.MBSSID
[apidx
].Bssid
);
776 Frame
.Category
= CATEGORY_HT
;
777 Frame
.Action
= NOTIFY_BW_ACTION
;
779 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
780 sizeof(FRAME_ACTION_HDR
), &Frame
,
783 *(pOutBuffer
+ FrameLen
) = pAd
->CommonCfg
.AddHTInfo
.AddHtInfo
.RecomWidth
;
787 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
);
788 DBGPRINT(RT_DEBUG_TRACE
,("ACT - SendNotifyBWAction(NotifyBW= %d)!\n", pAd
->CommonCfg
.AddHTInfo
.AddHtInfo
.RecomWidth
));
791 #endif // DOT11N_DRAFT3 //
795 IN PRTMP_ADAPTER pAd
,
796 IN MLME_QUEUE_ELEM
*Elem
)
798 UCHAR Action
= Elem
->Msg
[LENGTH_802_11
+1];
800 if (Elem
->Wcid
>= MAX_LEN_OF_MAC_TABLE
)
805 case NOTIFY_BW_ACTION
:
806 DBGPRINT(RT_DEBUG_TRACE
,("ACTION - HT Notify Channel bandwidth action----> \n"));
807 #ifdef CONFIG_STA_SUPPORT
808 if(pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
== FALSE
)
810 // Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps
811 // sending BW_Notify Action frame, and cause us to linkup and linkdown.
812 // In legacy mode, don't need to parse HT action frame.
813 DBGPRINT(RT_DEBUG_TRACE
,("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
814 Elem
->Msg
[LENGTH_802_11
+2] ));
817 #endif // CONFIG_STA_SUPPORT //
819 if (Elem
->Msg
[LENGTH_802_11
+2] == 0) // 7.4.8.2. if value is 1, keep the same as supported channel bandwidth.
820 pAd
->MacTab
.Content
[Elem
->Wcid
].HTPhyMode
.field
.BW
= 0;
826 DBGPRINT(RT_DEBUG_TRACE
,("ACTION - SMPS action----> \n"));
827 if (((Elem
->Msg
[LENGTH_802_11
+2]&0x1) == 0))
829 pAd
->MacTab
.Content
[Elem
->Wcid
].MmpsMode
= MMPS_ENABLE
;
831 else if (((Elem
->Msg
[LENGTH_802_11
+2]&0x2) == 0))
833 pAd
->MacTab
.Content
[Elem
->Wcid
].MmpsMode
= MMPS_STATIC
;
837 pAd
->MacTab
.Content
[Elem
->Wcid
].MmpsMode
= MMPS_DYNAMIC
;
840 DBGPRINT(RT_DEBUG_TRACE
,("Aid(%d) MIMO PS = %d\n", Elem
->Wcid
, pAd
->MacTab
.Content
[Elem
->Wcid
].MmpsMode
));
841 // rt2860c : add something for smps change.
847 case MIMO_CHA_MEASURE_ACTION
:
850 case HT_INFO_EXCHANGE
:
852 HT_INFORMATION_OCTET
*pHT_info
;
854 pHT_info
= (HT_INFORMATION_OCTET
*) &Elem
->Msg
[LENGTH_802_11
+2];
856 DBGPRINT(RT_DEBUG_TRACE
,("ACTION - HT Information Exchange action----> \n"));
857 if (pHT_info
->Request
)
859 respond_ht_information_exchange_action(pAd
, Elem
);
868 ==========================================================================
870 Retry sending ADDBA Reqest.
872 IRQL = DISPATCH_LEVEL
875 p8023Header: if this is already 802.3 format, p8023Header is NULL
877 Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
878 FALSE , then continue indicaterx at this moment.
879 ==========================================================================
881 VOID
ORIBATimerTimeout(
882 IN PRTMP_ADAPTER pAd
)
884 MAC_TABLE_ENTRY
*pEntry
;
886 // FRAME_BAR FrameBar;
888 // NDIS_STATUS NStatus;
889 // PUCHAR pOutBuffer = NULL;
896 #endif // RALINK_ATE //
898 total
= pAd
->MacTab
.Size
* NUM_OF_TID
;
900 for (i
= 1; ((i
<MAX_LEN_OF_BA_ORI_TABLE
) && (total
> 0)) ; i
++)
902 if (pAd
->BATable
.BAOriEntry
[i
].ORI_BA_Status
== Originator_Done
)
904 pEntry
= &pAd
->MacTab
.Content
[pAd
->BATable
.BAOriEntry
[i
].Wcid
];
905 TID
= pAd
->BATable
.BAOriEntry
[i
].TID
;
907 ASSERT(pAd
->BATable
.BAOriEntry
[i
].Wcid
< MAX_LEN_OF_MAC_TABLE
);
915 IN PRTMP_ADAPTER pAd
,
916 IN MAC_TABLE_ENTRY
*pEntry
)
921 PUCHAR pOutBuffer
= NULL
;
925 BA_ORI_ENTRY
*pBAEntry
;
927 for (i
= 0; i
<NUM_OF_TID
; i
++)
929 idx
= pEntry
->BAOriWcidArray
[i
];
934 pBAEntry
= &pAd
->BATable
.BAOriEntry
[idx
];
936 if (pBAEntry
->ORI_BA_Status
== Originator_Done
)
940 ASSERT(pBAEntry
->Wcid
< MAX_LEN_OF_MAC_TABLE
);
942 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
943 if(NStatus
!= NDIS_STATUS_SUCCESS
)
945 DBGPRINT(RT_DEBUG_ERROR
,("BA - MlmeADDBAAction() allocate memory failed \n"));
949 Sequence
= pEntry
->TxSeq
[TID
];
952 #ifdef CONFIG_STA_SUPPORT
953 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
954 BarHeaderInit(pAd
, &FrameBar
, pEntry
->Addr
, pAd
->CurrentAddress
);
955 #endif // CONFIG_STA_SUPPORT //
957 FrameBar
.StartingSeq
.field
.FragNum
= 0; // make sure sequence not clear in DEL function.
958 FrameBar
.StartingSeq
.field
.StartSeq
= Sequence
; // make sure sequence not clear in DEL funciton.
959 FrameBar
.BarControl
.TID
= TID
; // make sure sequence not clear in DEL funciton.
961 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
962 sizeof(FRAME_BAR
), &FrameBar
,
964 //if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET)))
965 if (1) // Now we always send BAR.
967 //MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen);
968 MiniportMMRequest(pAd
, 0, pOutBuffer
, FrameLen
);
970 MlmeFreeMemory(pAd
, pOutBuffer
);
974 #endif // DOT11_N_SUPPORT //
977 IN PRTMP_ADAPTER pAd
,
978 IN OUT PHEADER_802_11 pHdr80211
,
983 NdisZeroMemory(pHdr80211
, sizeof(HEADER_802_11
));
984 pHdr80211
->FC
.Type
= BTYPE_MGMT
;
985 pHdr80211
->FC
.SubType
= SUBTYPE_ACTION
;
987 COPY_MAC_ADDR(pHdr80211
->Addr1
, Addr1
);
988 COPY_MAC_ADDR(pHdr80211
->Addr2
, Addr2
);
989 COPY_MAC_ADDR(pHdr80211
->Addr3
, Addr3
);
993 IN PRTMP_ADAPTER pAd
,
994 IN OUT PFRAME_BAR pCntlBar
,
1000 NdisZeroMemory(pCntlBar
, sizeof(FRAME_BAR
));
1001 pCntlBar
->FC
.Type
= BTYPE_CNTL
;
1002 pCntlBar
->FC
.SubType
= SUBTYPE_BLOCK_ACK_REQ
;
1003 pCntlBar
->BarControl
.MTID
= 0;
1004 pCntlBar
->BarControl
.Compressed
= 1;
1005 pCntlBar
->BarControl
.ACKPolicy
= 0;
1008 pCntlBar
->Duration
= 16 + RTMPCalcDuration(pAd
, RATE_1
, sizeof(FRAME_BA
));
1010 COPY_MAC_ADDR(pCntlBar
->Addr1
, pDA
);
1011 COPY_MAC_ADDR(pCntlBar
->Addr2
, pSA
);
1016 ==========================================================================
1018 Insert Category and action code into the action frame.
1021 1. frame buffer pointer.
1023 3. category code of the frame.
1024 4. action code of the frame.
1027 ==========================================================================
1029 VOID
InsertActField(
1030 IN PRTMP_ADAPTER pAd
,
1031 OUT PUCHAR pFrameBuf
,
1032 OUT PULONG pFrameLen
,
1038 MakeOutgoingFrame( pFrameBuf
, &TempLen
,
1043 *pFrameLen
= *pFrameLen
+ TempLen
;