• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26 
27     Module Name:
28 	action.c
29 
30     Abstract:
31     Handle association related requests either from WSTA or from local MLME
32 
33     Revision History:
34     Who         When          What
35     --------    ----------    ----------------------------------------------
36 	Jan Lee		2006	  	created for rt2860
37  */
38 
39 #include "../rt_config.h"
40 #include "action.h"
41 
42 
43 static VOID ReservedAction(
44 	IN PRTMP_ADAPTER pAd,
45 	IN MLME_QUEUE_ELEM *Elem);
46 
47 /*
48     ==========================================================================
49     Description:
50         association state machine init, including state transition and timer init
51     Parameters:
52         S - pointer to the association state machine
53     Note:
54         The state machine looks like the following
55 
56                                     ASSOC_IDLE
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     ==========================================================================
63  */
ActionStateMachineInit(IN PRTMP_ADAPTER pAd,IN STATE_MACHINE * S,OUT STATE_MACHINE_FUNC Trans[])64 VOID ActionStateMachineInit(
65     IN	PRTMP_ADAPTER	pAd,
66     IN  STATE_MACHINE *S,
67     OUT STATE_MACHINE_FUNC Trans[])
68 {
69 	StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_ACT_STATE, MAX_ACT_MSG, (STATE_MACHINE_FUNC)Drop, ACT_IDLE, ACT_MACHINE_BASE);
70 
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);
73 
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 //
78 
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 //
86 
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);
89 
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);
93 }
94 
95 #ifdef DOT11_N_SUPPORT
MlmeADDBAAction(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)96 VOID MlmeADDBAAction(
97     IN PRTMP_ADAPTER pAd,
98     IN MLME_QUEUE_ELEM *Elem)
99 
100 {
101 	MLME_ADDBA_REQ_STRUCT *pInfo;
102 	UCHAR           Addr[6];
103 	PUCHAR         pOutBuffer = NULL;
104 	NDIS_STATUS     NStatus;
105 	ULONG		Idx;
106 	FRAME_ADDBA_REQ  Frame;
107 	ULONG		FrameLen;
108 	BA_ORI_ENTRY			*pBAEntry = NULL;
109 
110 	pInfo = (MLME_ADDBA_REQ_STRUCT *)Elem->Msg;
111 	NdisZeroMemory(&Frame, sizeof(FRAME_ADDBA_REQ));
112 
113 	if(MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr))
114 	{
115 		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
116 		if(NStatus != NDIS_STATUS_SUCCESS)
117 		{
118 			DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeADDBAAction() allocate memory failed \n"));
119 			return;
120 		}
121 		// 1. find entry
122 		Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
123 		if (Idx == 0)
124 		{
125 			MlmeFreeMemory(pAd, pOutBuffer);
126 			DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() can't find BAOriEntry \n"));
127 			return;
128 		}
129 		else
130 		{
131 			pBAEntry =&pAd->BATable.BAOriEntry[Idx];
132 		}
133 
134 #ifdef CONFIG_STA_SUPPORT
135 		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
136 		{
137 			if (ADHOC_ON(pAd))
138 				ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
139 			else
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);
143 			else
144 #endif // QOS_DLS_SUPPORT //
145 				ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pInfo->pAddr);
146 
147 		}
148 #endif // CONFIG_STA_SUPPORT //
149 
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];
160 
161 		*(USHORT *)(&Frame.BaParm) = cpu2le16(*(USHORT *)(&Frame.BaParm));
162 		Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue);
163 		Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word);
164 
165 		MakeOutgoingFrame(pOutBuffer,		   &FrameLen,
166 		              sizeof(FRAME_ADDBA_REQ), &Frame,
167 		              END_OF_ARGS);
168 		MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
169 		MlmeFreeMemory(pAd, pOutBuffer);
170 
171 		DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x,  FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize));
172     }
173 }
174 
175 /*
176     ==========================================================================
177     Description:
178         send DELBA and delete BaEntry if any
179     Parametrs:
180         Elem - MLME message MLME_DELBA_REQ_STRUCT
181 
182 	IRQL = DISPATCH_LEVEL
183 
184     ==========================================================================
185  */
MlmeDELBAAction(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)186 VOID MlmeDELBAAction(
187     IN PRTMP_ADAPTER pAd,
188     IN MLME_QUEUE_ELEM *Elem)
189 {
190 	MLME_DELBA_REQ_STRUCT *pInfo;
191 	PUCHAR         pOutBuffer = NULL;
192 	PUCHAR		   pOutBuffer2 = NULL;
193 	NDIS_STATUS     NStatus;
194 	ULONG		Idx;
195 	FRAME_DELBA_REQ  Frame;
196 	ULONG		FrameLen;
197 	FRAME_BAR	FrameBar;
198 
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));
203 
204 	if(MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen))
205 	{
206 		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
207 		if(NStatus != NDIS_STATUS_SUCCESS)
208 		{
209 			DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
210 			return;
211 		}
212 
213 		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2);  //Get an unused nonpaged memory
214 		if(NStatus != NDIS_STATUS_SUCCESS)
215 		{
216 			MlmeFreeMemory(pAd, pOutBuffer);
217 			DBGPRINT(RT_DEBUG_ERROR, ("BA - MlmeDELBAAction() allocate memory failed 2. \n"));
218 			return;
219 		}
220 
221 		// SEND BAR (Send BAR to refresh peer reordering buffer.)
222 		Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
223 
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 //
228 
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.
235 
236 		MakeOutgoingFrame(pOutBuffer2,				&FrameLen,
237 					  sizeof(FRAME_BAR),	  &FrameBar,
238 					  END_OF_ARGS);
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"));
242 
243 		// SEND DELBA FRAME
244 		FrameLen = 0;
245 #ifdef CONFIG_STA_SUPPORT
246 		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
247 		{
248 			if (ADHOC_ON(pAd))
249 				ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
250 			else
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);
254 			else
255 #endif // QOS_DLS_SUPPORT //
256 				ActHeaderInit(pAd, &Frame.Hdr,  pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[pInfo->Wcid].Addr);
257 		}
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);
266 
267 		MakeOutgoingFrame(pOutBuffer,               &FrameLen,
268 		              sizeof(FRAME_DELBA_REQ),    &Frame,
269 		              END_OF_ARGS);
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));
273     	}
274 }
275 #endif // DOT11_N_SUPPORT //
276 
MlmeQOSAction(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)277 VOID MlmeQOSAction(
278     IN PRTMP_ADAPTER pAd,
279     IN MLME_QUEUE_ELEM *Elem)
280 {
281 }
282 
MlmeDLSAction(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)283 VOID MlmeDLSAction(
284     IN PRTMP_ADAPTER pAd,
285     IN MLME_QUEUE_ELEM *Elem)
286 {
287 }
288 
MlmeInvalidAction(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)289 VOID MlmeInvalidAction(
290     IN PRTMP_ADAPTER pAd,
291     IN MLME_QUEUE_ELEM *Elem)
292 {
293 	//PUCHAR		   pOutBuffer = NULL;
294 	//Return the receiving frame except the MSB of category filed set to 1.  7.3.1.11
295 }
296 
PeerQOSAction(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)297 VOID PeerQOSAction(
298 	IN PRTMP_ADAPTER pAd,
299 	IN MLME_QUEUE_ELEM *Elem)
300 {
301 }
302 
303 #ifdef QOS_DLS_SUPPORT
PeerDLSAction(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)304 VOID PeerDLSAction(
305 	IN PRTMP_ADAPTER pAd,
306 	IN MLME_QUEUE_ELEM *Elem)
307 {
308 	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
309 
310 	switch(Action)
311 	{
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 //
317 			break;
318 
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 //
324 			break;
325 
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 //
331 			break;
332 	}
333 }
334 #endif // QOS_DLS_SUPPORT //
335 
336 #ifdef DOT11_N_SUPPORT
PeerBAAction(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)337 VOID PeerBAAction(
338 	IN PRTMP_ADAPTER pAd,
339 	IN MLME_QUEUE_ELEM *Elem)
340 {
341 	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
342 
343 	switch(Action)
344 	{
345 		case ADDBA_REQ:
346 			PeerAddBAReqAction(pAd,Elem);
347 			break;
348 		case ADDBA_RESP:
349 			PeerAddBARspAction(pAd,Elem);
350 			break;
351 		case DELBA:
352 			PeerDelBAAction(pAd,Elem);
353 			break;
354 	}
355 }
356 
357 
358 #ifdef DOT11N_DRAFT3
359 
360 #ifdef CONFIG_STA_SUPPORT
StaPublicAction(IN PRTMP_ADAPTER pAd,IN UCHAR Bss2040Coexist)361 VOID StaPublicAction(
362 	IN PRTMP_ADAPTER pAd,
363 	IN UCHAR Bss2040Coexist)
364 {
365 	BSS_2040_COEXIST_IE		BssCoexist;
366 	MLME_SCAN_REQ_STRUCT			ScanReq;
367 
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)))
371 	{
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;
380 	}
381 }
382 
383 
384 /*
385 Description : Build Intolerant Channel Rerpot from Trigger event table.
386 return : how many bytes copied.
387 */
BuildIntolerantChannelRep(IN PRTMP_ADAPTER pAd,IN PUCHAR pDest)388 ULONG BuildIntolerantChannelRep(
389 	IN	PRTMP_ADAPTER	pAd,
390 	IN    PUCHAR  pDest)
391 {
392 	ULONG			FrameLen = 0;
393 	ULONG			ReadOffset = 0;
394 	UCHAR			i;
395 	UCHAR			LastRegClass = 0xff;
396 	PUCHAR			pLen;
397 
398 	for ( i = 0;i < MAX_TRIGGER_EVENT;i++)
399 	{
400 		if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid == TRUE)
401 		{
402 			if (pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass == LastRegClass)
403 			{
404 				*(pDest + ReadOffset) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
405 				*pLen++;
406 				ReadOffset++;
407 				FrameLen++;
408 			}
409 			else
410 			{
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;
417 				FrameLen += 4;
418 				ReadOffset += 4;
419 			}
420 
421 		}
422 	}
423 	return FrameLen;
424 }
425 
426 
427 /*
428 Description : Send 20/40 BSS Coexistence Action frame If one trigger event is triggered.
429 */
Send2040CoexistAction(IN PRTMP_ADAPTER pAd,IN UCHAR Wcid,IN BOOLEAN bAddIntolerantCha)430 VOID Send2040CoexistAction(
431 	IN	PRTMP_ADAPTER	pAd,
432 	IN    UCHAR  Wcid,
433 	IN	BOOLEAN	bAddIntolerantCha)
434 {
435 	PUCHAR			pOutBuffer = NULL;
436 	NDIS_STATUS 	NStatus;
437 	FRAME_ACTION_HDR	Frame;
438 	ULONG			FrameLen;
439 	ULONG			IntolerantChaRepLen;
440 
441 	IntolerantChaRepLen = 0;
442 	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
443 	if(NStatus != NDIS_STATUS_SUCCESS)
444 	{
445 		DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction() allocate memory failed \n"));
446 		return;
447 	}
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;
451 
452 	MakeOutgoingFrame(pOutBuffer,				&FrameLen,
453 				  sizeof(FRAME_ACTION_HDR),	  &Frame,
454 				  END_OF_ARGS);
455 
456 	*(pOutBuffer + FrameLen) = pAd->CommonCfg.BSSCoexist2040.word;
457 	FrameLen++;
458 
459 	if (bAddIntolerantCha == TRUE)
460 		IntolerantChaRepLen = BuildIntolerantChannelRep(pAd, pOutBuffer + FrameLen);
461 
462 	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen + IntolerantChaRepLen);
463 	DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction( BSSCoexist2040 = 0x%x )  \n", pAd->CommonCfg.BSSCoexist2040.word));
464 
465 }
466 
467 
468 /*
469 	==========================================================================
470 	Description:
471 	After scan, Update 20/40 BSS Coexistence IE and send out.
472 	According to 802.11n D3.03 11.14.10
473 
474 	Parameters:
475 	==========================================================================
476  */
Update2040CoexistFrameAndNotify(IN PRTMP_ADAPTER pAd,IN UCHAR Wcid,IN BOOLEAN bAddIntolerantCha)477 VOID Update2040CoexistFrameAndNotify(
478 	IN	PRTMP_ADAPTER	pAd,
479 	IN    UCHAR  Wcid,
480 	IN	BOOLEAN	bAddIntolerantCha)
481 {
482 	BSS_2040_COEXIST_IE	OldValue;
483 
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;
487 
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)
492 	{
493 		Send2040CoexistAction(pAd, Wcid, bAddIntolerantCha);
494 	}
495 }
496 #endif // CONFIG_STA_SUPPORT //
497 
498 
ChannelSwitchSanityCheck(IN PRTMP_ADAPTER pAd,IN UCHAR Wcid,IN UCHAR NewChannel,IN UCHAR Secondary)499 BOOLEAN ChannelSwitchSanityCheck(
500 	IN	PRTMP_ADAPTER	pAd,
501 	IN    UCHAR  Wcid,
502 	IN    UCHAR  NewChannel,
503 	IN    UCHAR  Secondary)
504 {
505 	UCHAR		i;
506 
507 	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
508 		return FALSE;
509 
510 	if ((NewChannel > 7) && (Secondary == 1))
511 		return FALSE;
512 
513 	if ((NewChannel < 5) && (Secondary == 3))
514 		return FALSE;
515 
516 	// 0. Check if new channel is in the channellist.
517 	for (i = 0;i < pAd->ChannelListNum;i++)
518 	{
519 		if (pAd->ChannelList[i].Channel == NewChannel)
520 		{
521 			break;
522 		}
523 	}
524 
525 	if (i == pAd->ChannelListNum)
526 		return FALSE;
527 
528 	return TRUE;
529 }
530 
531 
ChannelSwitchAction(IN PRTMP_ADAPTER pAd,IN UCHAR Wcid,IN UCHAR NewChannel,IN UCHAR Secondary)532 VOID ChannelSwitchAction(
533 	IN	PRTMP_ADAPTER	pAd,
534 	IN    UCHAR  Wcid,
535 	IN    UCHAR  NewChannel,
536 	IN    UCHAR  Secondary)
537 {
538 	UCHAR		BBPValue = 0;
539 	ULONG		MACValue;
540 
541 	DBGPRINT(RT_DEBUG_TRACE,("SPECTRUM - ChannelSwitchAction(NewChannel = %d , Secondary = %d)  \n", NewChannel, Secondary));
542 
543 	if (ChannelSwitchSanityCheck(pAd, Wcid, NewChannel, Secondary) == FALSE)
544 		return;
545 
546 	// 1.  Switches to BW = 20.
547 	if (Secondary == 0)
548 	{
549 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
550 		BBPValue&= (~0x18);
551 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
552 		if (pAd->MACVersion == 0x28600100)
553 		{
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" ));
558 		}
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" ));
566 	}
567 	// 1.  Switches to BW = 40 And Station supports BW = 40.
568 	else if (((Secondary == 1) || (Secondary == 3)) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1))
569 	{
570 		pAd->CommonCfg.Channel = NewChannel;
571 
572 		if (Secondary == 1)
573 		{
574 			// Secondary above.
575 			pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
576 			RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
577 			MACValue &= 0xfe;
578 			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
579 			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
580 			BBPValue&= (~0x18);
581 			BBPValue|= (0x10);
582 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
583 			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
584 			BBPValue&= (~0x20);
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 ));
587 		}
588 		else
589 		{
590 			// Secondary below.
591 			pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
592 			RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
593 			MACValue &= 0xfe;
594 			MACValue |= 0x1;
595 			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
596 			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
597 			BBPValue&= (~0x18);
598 			BBPValue|= (0x10);
599 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
600 			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
601 			BBPValue&= (~0x20);
602 			BBPValue|= (0x20);
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 ));
605 		}
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;
610 	}
611 }
612 #endif // DOT11N_DRAFT3 //
613 #endif // DOT11_N_SUPPORT //
614 
PeerPublicAction(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)615 VOID PeerPublicAction(
616 	IN PRTMP_ADAPTER pAd,
617 	IN MLME_QUEUE_ELEM *Elem)
618 {
619 #ifdef DOT11N_DRAFT3
620 	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
621 #endif // DOT11N_DRAFT3 //
622 
623 	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
624 		return;
625 
626 #ifdef DOT11N_DRAFT3
627 	switch(Action)
628 	{
629 		case ACTION_BSS_2040_COEXIST:	// Format defined in IEEE 7.4.7a.1 in 11n Draf3.03
630 			{
631 				//UCHAR	BssCoexist;
632 				BSS_2040_COEXIST_ELEMENT		*pCoexistInfo;
633 				BSS_2040_COEXIST_IE 			*pBssCoexistIe;
634 				BSS_2040_INTOLERANT_CH_REPORT	*pIntolerantReport = NULL;
635 
636 				if (Elem->MsgLen <= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT)) )
637 				{
638 					DBGPRINT(RT_DEBUG_ERROR, ("ACTION - 20/40 BSS Coexistence Management Frame length too short! len = %ld!\n", Elem->MsgLen));
639 					break;
640 				}
641 				DBGPRINT(RT_DEBUG_TRACE, ("ACTION - 20/40 BSS Coexistence Management action----> \n"));
642 				hex_dump("CoexistenceMgmtFrame", Elem->Msg, Elem->MsgLen);
643 
644 
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)))
648 				{
649 					pIntolerantReport = (BSS_2040_INTOLERANT_CH_REPORT *)((PUCHAR)pCoexistInfo + sizeof(BSS_2040_COEXIST_ELEMENT));
650 				}
651 				//hex_dump("IntolerantReport ", (PUCHAR)pIntolerantReport, sizeof(BSS_2040_INTOLERANT_CH_REPORT));
652 
653 				pBssCoexistIe = (BSS_2040_COEXIST_IE *)(&pCoexistInfo->BssCoexistIe);
654 
655 #ifdef CONFIG_STA_SUPPORT
656 				IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
657 				{
658 					if (INFRA_ON(pAd))
659 					{
660 						StaPublicAction(pAd, pCoexistInfo);
661 					}
662 				}
663 #endif // CONFIG_STA_SUPPORT //
664 
665 			}
666 			break;
667 	}
668 
669 #endif // DOT11N_DRAFT3 //
670 
671 }
672 
673 
ReservedAction(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)674 static VOID ReservedAction(
675 	IN PRTMP_ADAPTER pAd,
676 	IN MLME_QUEUE_ELEM *Elem)
677 {
678 	UCHAR Category;
679 
680 	if (Elem->MsgLen <= LENGTH_802_11)
681 	{
682 		return;
683 	}
684 
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);
688 }
689 
PeerRMAction(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)690 VOID PeerRMAction(
691 	IN PRTMP_ADAPTER pAd,
692 	IN MLME_QUEUE_ELEM *Elem)
693 
694 {
695 	return;
696 }
697 
698 #ifdef DOT11_N_SUPPORT
respond_ht_information_exchange_action(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)699 static VOID respond_ht_information_exchange_action(
700 	IN PRTMP_ADAPTER pAd,
701 	IN MLME_QUEUE_ELEM *Elem)
702 {
703 	PUCHAR			pOutBuffer = NULL;
704 	NDIS_STATUS		NStatus;
705 	ULONG			FrameLen;
706 	FRAME_HT_INFO	HTINFOframe, *pFrame;
707 	UCHAR   		*pAddr;
708 
709 
710 	// 2. Always send back ADDBA Response
711 	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	 //Get an unused nonpaged memory
712 
713 	if (NStatus != NDIS_STATUS_SUCCESS)
714 	{
715 		DBGPRINT(RT_DEBUG_TRACE,("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
716 		return;
717 	}
718 
719 	// get RA
720 	pFrame = (FRAME_HT_INFO *) &Elem->Msg[0];
721 	pAddr = pFrame->Hdr.Addr2;
722 
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)
727 	{
728 		if (ADHOC_ON(pAd))
729 			ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
730 		else
731 			ActHeaderInit(pAd, &HTINFOframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
732 	}
733 #endif // CONFIG_STA_SUPPORT //
734 
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;
740 
741 	MakeOutgoingFrame(pOutBuffer,					&FrameLen,
742 					  sizeof(FRAME_HT_INFO),	&HTINFOframe,
743 					  END_OF_ARGS);
744 
745 	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
746 	MlmeFreeMemory(pAd, pOutBuffer);
747 }
748 
749 
750 #ifdef DOT11N_DRAFT3
SendNotifyBWActionFrame(IN PRTMP_ADAPTER pAd,IN UCHAR Wcid,IN UCHAR apidx)751 VOID SendNotifyBWActionFrame(
752 	IN PRTMP_ADAPTER pAd,
753 	IN UCHAR  Wcid,
754 	IN UCHAR apidx)
755 {
756 	PUCHAR			pOutBuffer = NULL;
757 	NDIS_STATUS 	NStatus;
758 	FRAME_ACTION_HDR	Frame;
759 	ULONG			FrameLen;
760 	PUCHAR			pAddr1;
761 
762 
763 	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
764 	if(NStatus != NDIS_STATUS_SUCCESS)
765 	{
766 		DBGPRINT(RT_DEBUG_ERROR,("ACT - SendNotifyBWAction() allocate memory failed \n"));
767 		return;
768 	}
769 
770 	if (Wcid == MCAST_WCID)
771 		pAddr1 = &BROADCAST_ADDR[0];
772 	else
773 		pAddr1 = pAd->MacTab.Content[Wcid].Addr;
774 	ActHeaderInit(pAd, &Frame.Hdr, pAddr1, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
775 
776 	Frame.Category = CATEGORY_HT;
777 	Frame.Action = NOTIFY_BW_ACTION;
778 
779 	MakeOutgoingFrame(pOutBuffer,				&FrameLen,
780 				  sizeof(FRAME_ACTION_HDR),	  &Frame,
781 				  END_OF_ARGS);
782 
783 	*(pOutBuffer + FrameLen) = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
784 	FrameLen++;
785 
786 
787 	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
788 	DBGPRINT(RT_DEBUG_TRACE,("ACT - SendNotifyBWAction(NotifyBW= %d)!\n", pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth));
789 
790 }
791 #endif // DOT11N_DRAFT3 //
792 
793 
PeerHTAction(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM * Elem)794 VOID PeerHTAction(
795 	IN PRTMP_ADAPTER pAd,
796 	IN MLME_QUEUE_ELEM *Elem)
797 {
798 	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
799 
800 	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
801 		return;
802 
803 	switch(Action)
804 	{
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)
809 			{
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] ));
815 				break;
816 			}
817 #endif // CONFIG_STA_SUPPORT //
818 
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;
821 
822 			break;
823 
824 		case SMPS_ACTION:
825 			// 7.3.1.25
826  			DBGPRINT(RT_DEBUG_TRACE,("ACTION - SMPS action----> \n"));
827 			if (((Elem->Msg[LENGTH_802_11+2]&0x1) == 0))
828 			{
829 				pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
830 			}
831 			else if (((Elem->Msg[LENGTH_802_11+2]&0x2) == 0))
832 			{
833 				pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
834 			}
835 			else
836 			{
837 				pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
838 			}
839 
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.
842 			break;
843 
844 		case SETPCO_ACTION:
845 			break;
846 
847 		case MIMO_CHA_MEASURE_ACTION:
848 			break;
849 
850 		case HT_INFO_EXCHANGE:
851 			{
852 				HT_INFORMATION_OCTET	*pHT_info;
853 
854 				pHT_info = (HT_INFORMATION_OCTET *) &Elem->Msg[LENGTH_802_11+2];
855     				// 7.4.8.10
856     				DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Information Exchange action----> \n"));
857     				if (pHT_info->Request)
858     				{
859     					respond_ht_information_exchange_action(pAd, Elem);
860     				}
861 			}
862     			break;
863 	}
864 }
865 
866 
867 /*
868 	==========================================================================
869 	Description:
870 		Retry sending ADDBA Reqest.
871 
872 	IRQL = DISPATCH_LEVEL
873 
874 	Parametrs:
875 	p8023Header: if this is already 802.3 format, p8023Header is NULL
876 
877 	Return	: TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
878 				FALSE , then continue indicaterx at this moment.
879 	==========================================================================
880  */
ORIBATimerTimeout(IN PRTMP_ADAPTER pAd)881 VOID ORIBATimerTimeout(
882 	IN	PRTMP_ADAPTER	pAd)
883 {
884 	MAC_TABLE_ENTRY	*pEntry;
885 	INT			i, total;
886 //	FRAME_BAR			FrameBar;
887 //	ULONG			FrameLen;
888 //	NDIS_STATUS 	NStatus;
889 //	PUCHAR			pOutBuffer = NULL;
890 //	USHORT			Sequence;
891 	UCHAR			TID;
892 
893 #ifdef RALINK_ATE
894 	if (ATE_ON(pAd))
895 		return;
896 #endif // RALINK_ATE //
897 
898 	total = pAd->MacTab.Size * NUM_OF_TID;
899 
900 	for (i = 1; ((i <MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)) ; i++)
901 	{
902 		if  (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done)
903 		{
904 			pEntry = &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].Wcid];
905 			TID = pAd->BATable.BAOriEntry[i].TID;
906 
907 			ASSERT(pAd->BATable.BAOriEntry[i].Wcid < MAX_LEN_OF_MAC_TABLE);
908 		}
909 		total --;
910 	}
911 }
912 
913 
SendRefreshBAR(IN PRTMP_ADAPTER pAd,IN MAC_TABLE_ENTRY * pEntry)914 VOID SendRefreshBAR(
915 	IN	PRTMP_ADAPTER	pAd,
916 	IN	MAC_TABLE_ENTRY	*pEntry)
917 {
918 	FRAME_BAR		FrameBar;
919 	ULONG			FrameLen;
920 	NDIS_STATUS 	NStatus;
921 	PUCHAR			pOutBuffer = NULL;
922 	USHORT			Sequence;
923 	UCHAR			i, TID;
924 	USHORT			idx;
925 	BA_ORI_ENTRY	*pBAEntry;
926 
927 	for (i = 0; i <NUM_OF_TID; i++)
928 	{
929 		idx = pEntry->BAOriWcidArray[i];
930 		if (idx == 0)
931 		{
932 			continue;
933 		}
934 		pBAEntry = &pAd->BATable.BAOriEntry[idx];
935 
936 		if  (pBAEntry->ORI_BA_Status == Originator_Done)
937 		{
938 			TID = pBAEntry->TID;
939 
940 			ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE);
941 
942 			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
943 			if(NStatus != NDIS_STATUS_SUCCESS)
944 			{
945 				DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
946 				return;
947 			}
948 
949 			Sequence = pEntry->TxSeq[TID];
950 
951 
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 //
956 
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.
960 
961 			MakeOutgoingFrame(pOutBuffer,				&FrameLen,
962 							  sizeof(FRAME_BAR),	  &FrameBar,
963 							  END_OF_ARGS);
964 			//if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET)))
965 			if (1)	// Now we always send BAR.
966 			{
967 				//MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen);
968 				MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
969 			}
970 			MlmeFreeMemory(pAd, pOutBuffer);
971 		}
972 	}
973 }
974 #endif // DOT11_N_SUPPORT //
975 
ActHeaderInit(IN PRTMP_ADAPTER pAd,IN OUT PHEADER_802_11 pHdr80211,IN PUCHAR Addr1,IN PUCHAR Addr2,IN PUCHAR Addr3)976 VOID ActHeaderInit(
977     IN	PRTMP_ADAPTER	pAd,
978     IN OUT PHEADER_802_11 pHdr80211,
979     IN PUCHAR Addr1,
980     IN PUCHAR Addr2,
981     IN PUCHAR Addr3)
982 {
983     NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
984     pHdr80211->FC.Type = BTYPE_MGMT;
985     pHdr80211->FC.SubType = SUBTYPE_ACTION;
986 
987     COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
988 	COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
989     COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
990 }
991 
BarHeaderInit(IN PRTMP_ADAPTER pAd,IN OUT PFRAME_BAR pCntlBar,IN PUCHAR pDA,IN PUCHAR pSA)992 VOID BarHeaderInit(
993 	IN	PRTMP_ADAPTER	pAd,
994 	IN OUT PFRAME_BAR pCntlBar,
995 	IN PUCHAR pDA,
996 	IN PUCHAR pSA)
997 {
998 //	USHORT	Duration;
999 
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;
1006 
1007 
1008 	pCntlBar->Duration = 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(FRAME_BA));
1009 
1010 	COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
1011 	COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
1012 }
1013 
1014 
1015 /*
1016 	==========================================================================
1017 	Description:
1018 		Insert Category and action code into the action frame.
1019 
1020 	Parametrs:
1021 		1. frame buffer pointer.
1022 		2. frame length.
1023 		3. category code of the frame.
1024 		4. action code of the frame.
1025 
1026 	Return	: None.
1027 	==========================================================================
1028  */
InsertActField(IN PRTMP_ADAPTER pAd,OUT PUCHAR pFrameBuf,OUT PULONG pFrameLen,IN UINT8 Category,IN UINT8 ActCode)1029 VOID InsertActField(
1030 	IN PRTMP_ADAPTER pAd,
1031 	OUT PUCHAR pFrameBuf,
1032 	OUT PULONG pFrameLen,
1033 	IN UINT8 Category,
1034 	IN UINT8 ActCode)
1035 {
1036 	ULONG TempLen;
1037 
1038 	MakeOutgoingFrame(	pFrameBuf,		&TempLen,
1039 						1,				&Category,
1040 						1,				&ActCode,
1041 						END_OF_ARGS);
1042 
1043 	*pFrameLen = *pFrameLen + TempLen;
1044 
1045 	return;
1046 }
1047