]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/rt3090/common/action.c
Staging: add rt3090 wireless driver
[mv-sheeva.git] / drivers / staging / rt3090 / common / action.c
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     ==========================================================================
50     Description:
51         association state machine init, including state transition and timer init
52     Parameters:
53         S - pointer to the association state machine
54     Note:
55         The state machine looks like the following
56
57                                     ASSOC_IDLE
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     ==========================================================================
64  */
65 VOID ActionStateMachineInit(
66     IN  PRTMP_ADAPTER   pAd,
67     IN  STATE_MACHINE *S,
68     OUT STATE_MACHINE_FUNC Trans[])
69 {
70         StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_ACT_STATE, MAX_ACT_MSG, (STATE_MACHINE_FUNC)Drop, ACT_IDLE, ACT_MACHINE_BASE);
71
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);
74
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 //
79
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 //
87
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);
90
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);
94
95
96 }
97
98 #ifdef DOT11_N_SUPPORT
99 VOID MlmeADDBAAction(
100     IN PRTMP_ADAPTER pAd,
101     IN MLME_QUEUE_ELEM *Elem)
102
103 {
104         MLME_ADDBA_REQ_STRUCT *pInfo;
105         UCHAR           Addr[6];
106         PUCHAR         pOutBuffer = NULL;
107         NDIS_STATUS     NStatus;
108         ULONG           Idx;
109         FRAME_ADDBA_REQ  Frame;
110         ULONG           FrameLen;
111         BA_ORI_ENTRY                    *pBAEntry = NULL;
112
113         pInfo = (MLME_ADDBA_REQ_STRUCT *)Elem->Msg;
114         NdisZeroMemory(&Frame, sizeof(FRAME_ADDBA_REQ));
115
116         if(MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr))
117         {
118                 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
119                 if(NStatus != NDIS_STATUS_SUCCESS)
120                 {
121                         DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeADDBAAction() allocate memory failed \n"));
122                         return;
123                 }
124                 // 1. find entry
125                 Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
126                 if (Idx == 0)
127                 {
128                         MlmeFreeMemory(pAd, pOutBuffer);
129                         DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() can't find BAOriEntry \n"));
130                         return;
131                 }
132                 else
133                 {
134                         pBAEntry =&pAd->BATable.BAOriEntry[Idx];
135                 }
136
137 #ifdef CONFIG_STA_SUPPORT
138                 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
139                 {
140                         if (ADHOC_ON(pAd))
141                                 ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
142                         else
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);
146                         else
147 #endif // QOS_DLS_SUPPORT //
148                         ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pInfo->pAddr);
149
150                 }
151 #endif // CONFIG_STA_SUPPORT //
152
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];
163
164                 *(USHORT *)(&Frame.BaParm) = cpu2le16(*(USHORT *)(&Frame.BaParm));
165                 Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue);
166                 Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word);
167
168                 MakeOutgoingFrame(pOutBuffer,              &FrameLen,
169                               sizeof(FRAME_ADDBA_REQ), &Frame,
170                               END_OF_ARGS);
171
172                 MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG | MapUserPriorityToAccessCategory[pInfo->TID]), pOutBuffer, FrameLen);
173
174                 MlmeFreeMemory(pAd, pOutBuffer);
175
176                 DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x,  FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize));
177     }
178 }
179
180 /*
181     ==========================================================================
182     Description:
183         send DELBA and delete BaEntry if any
184     Parametrs:
185         Elem - MLME message MLME_DELBA_REQ_STRUCT
186
187         IRQL = DISPATCH_LEVEL
188
189     ==========================================================================
190  */
191 VOID MlmeDELBAAction(
192     IN PRTMP_ADAPTER pAd,
193     IN MLME_QUEUE_ELEM *Elem)
194 {
195         MLME_DELBA_REQ_STRUCT *pInfo;
196         PUCHAR         pOutBuffer = NULL;
197         PUCHAR             pOutBuffer2 = NULL;
198         NDIS_STATUS     NStatus;
199         ULONG           Idx;
200         FRAME_DELBA_REQ  Frame;
201         ULONG           FrameLen;
202         FRAME_BAR       FrameBar;
203
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));
208
209         if(MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen))
210         {
211                 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
212                 if(NStatus != NDIS_STATUS_SUCCESS)
213                 {
214                         DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
215                         return;
216                 }
217
218                 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2);  //Get an unused nonpaged memory
219                 if(NStatus != NDIS_STATUS_SUCCESS)
220                 {
221                         MlmeFreeMemory(pAd, pOutBuffer);
222                         DBGPRINT(RT_DEBUG_ERROR, ("BA - MlmeDELBAAction() allocate memory failed 2. \n"));
223                         return;
224                 }
225
226                 // SEND BAR (Send BAR to refresh peer reordering buffer.)
227                 Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
228
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 //
233
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.
240
241                 MakeOutgoingFrame(pOutBuffer2,                          &FrameLen,
242                                           sizeof(FRAME_BAR),      &FrameBar,
243                                           END_OF_ARGS);
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"));
247
248                 // SEND DELBA FRAME
249                 FrameLen = 0;
250 #ifdef CONFIG_STA_SUPPORT
251                 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
252                 {
253                         if (ADHOC_ON(pAd))
254                                 ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
255                         else
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);
259                         else
260 #endif // QOS_DLS_SUPPORT //
261                         ActHeaderInit(pAd, &Frame.Hdr,  pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[pInfo->Wcid].Addr);
262                 }
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);
271
272                 MakeOutgoingFrame(pOutBuffer,               &FrameLen,
273                               sizeof(FRAME_DELBA_REQ),    &Frame,
274                               END_OF_ARGS);
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));
278         }
279 }
280 #endif // DOT11_N_SUPPORT //
281
282 VOID MlmeQOSAction(
283     IN PRTMP_ADAPTER pAd,
284     IN MLME_QUEUE_ELEM *Elem)
285 {
286 }
287
288 VOID MlmeDLSAction(
289     IN PRTMP_ADAPTER pAd,
290     IN MLME_QUEUE_ELEM *Elem)
291 {
292 }
293
294 VOID MlmeInvalidAction(
295     IN PRTMP_ADAPTER pAd,
296     IN MLME_QUEUE_ELEM *Elem)
297 {
298         //PUCHAR                   pOutBuffer = NULL;
299         //Return the receiving frame except the MSB of category filed set to 1.  7.3.1.11
300 }
301
302 VOID PeerQOSAction(
303         IN PRTMP_ADAPTER pAd,
304         IN MLME_QUEUE_ELEM *Elem)
305 {
306 }
307
308 #ifdef QOS_DLS_SUPPORT
309 VOID PeerDLSAction(
310         IN PRTMP_ADAPTER pAd,
311         IN MLME_QUEUE_ELEM *Elem)
312 {
313         UCHAR   Action = Elem->Msg[LENGTH_802_11+1];
314
315         switch(Action)
316         {
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 //
322                         break;
323
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 //
329                         break;
330
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 //
336                         break;
337         }
338 }
339 #endif // QOS_DLS_SUPPORT //
340
341
342
343 #ifdef DOT11_N_SUPPORT
344 VOID PeerBAAction(
345         IN PRTMP_ADAPTER pAd,
346         IN MLME_QUEUE_ELEM *Elem)
347 {
348         UCHAR   Action = Elem->Msg[LENGTH_802_11+1];
349
350         switch(Action)
351         {
352                 case ADDBA_REQ:
353                         PeerAddBAReqAction(pAd,Elem);
354                         break;
355                 case ADDBA_RESP:
356                         PeerAddBARspAction(pAd,Elem);
357                         break;
358                 case DELBA:
359                         PeerDelBAAction(pAd,Elem);
360                         break;
361         }
362 }
363
364
365 #ifdef DOT11N_DRAFT3
366
367 #ifdef CONFIG_STA_SUPPORT
368 VOID StaPublicAction(
369         IN PRTMP_ADAPTER pAd,
370         IN UCHAR Bss2040Coexist)
371 {
372         BSS_2040_COEXIST_IE             BssCoexist;
373         MLME_SCAN_REQ_STRUCT                    ScanReq;
374
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)))
378         {
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;
387         }
388 }
389
390
391 /*
392 Description : Build Intolerant Channel Rerpot from Trigger event table.
393 return : how many bytes copied.
394 */
395 ULONG BuildIntolerantChannelRep(
396         IN      PRTMP_ADAPTER   pAd,
397         IN    PUCHAR  pDest)
398 {
399         ULONG                   FrameLen = 0;
400         ULONG                   ReadOffset = 0;
401         UCHAR                   i;
402         UCHAR                   LastRegClass = 0xff;
403         PUCHAR                  pLen;
404
405         for ( i = 0;i < MAX_TRIGGER_EVENT;i++)
406         {
407                 if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid == TRUE)
408                 {
409                         if (pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass == LastRegClass)
410                         {
411                                 *(pDest + ReadOffset) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
412                                 *pLen++;
413                                 ReadOffset++;
414                                 FrameLen++;
415                         }
416                         else
417                         {
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;
424                                 FrameLen += 4;
425                                 ReadOffset += 4;
426                         }
427
428                 }
429         }
430         return FrameLen;
431 }
432
433
434 /*
435 Description : Send 20/40 BSS Coexistence Action frame If one trigger event is triggered.
436 */
437 VOID Send2040CoexistAction(
438         IN      PRTMP_ADAPTER   pAd,
439         IN    UCHAR  Wcid,
440         IN      BOOLEAN bAddIntolerantCha)
441 {
442         PUCHAR                  pOutBuffer = NULL;
443         NDIS_STATUS     NStatus;
444         FRAME_ACTION_HDR        Frame;
445         ULONG                   FrameLen;
446         ULONG                   IntolerantChaRepLen;
447
448         IntolerantChaRepLen = 0;
449         NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
450         if(NStatus != NDIS_STATUS_SUCCESS)
451         {
452                 DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction() allocate memory failed \n"));
453                 return;
454         }
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;
458
459         MakeOutgoingFrame(pOutBuffer,                           &FrameLen,
460                                   sizeof(FRAME_ACTION_HDR),       &Frame,
461                                   END_OF_ARGS);
462
463         *(pOutBuffer + FrameLen) = pAd->CommonCfg.BSSCoexist2040.word;
464         FrameLen++;
465
466         if (bAddIntolerantCha == TRUE)
467                 IntolerantChaRepLen = BuildIntolerantChannelRep(pAd, pOutBuffer + FrameLen);
468
469         MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen + IntolerantChaRepLen);
470         DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction( BSSCoexist2040 = 0x%x )  \n", pAd->CommonCfg.BSSCoexist2040.word));
471
472 }
473
474
475 /*
476         ==========================================================================
477         Description:
478         After scan, Update 20/40 BSS Coexistence IE and send out.
479         According to 802.11n D3.03 11.14.10
480
481         Parameters:
482         ==========================================================================
483  */
484 VOID Update2040CoexistFrameAndNotify(
485         IN      PRTMP_ADAPTER   pAd,
486         IN    UCHAR  Wcid,
487         IN      BOOLEAN bAddIntolerantCha)
488 {
489         BSS_2040_COEXIST_IE     OldValue;
490
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;
494
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)
499         {
500                 Send2040CoexistAction(pAd, Wcid, bAddIntolerantCha);
501         }
502 }
503 #endif // CONFIG_STA_SUPPORT //
504
505
506 BOOLEAN ChannelSwitchSanityCheck(
507         IN      PRTMP_ADAPTER   pAd,
508         IN    UCHAR  Wcid,
509         IN    UCHAR  NewChannel,
510         IN    UCHAR  Secondary)
511 {
512         UCHAR           i;
513
514         if (Wcid >= MAX_LEN_OF_MAC_TABLE)
515                 return FALSE;
516
517         if ((NewChannel > 7) && (Secondary == 1))
518                 return FALSE;
519
520         if ((NewChannel < 5) && (Secondary == 3))
521                 return FALSE;
522
523         // 0. Check if new channel is in the channellist.
524         for (i = 0;i < pAd->ChannelListNum;i++)
525         {
526                 if (pAd->ChannelList[i].Channel == NewChannel)
527                 {
528                         break;
529                 }
530         }
531
532         if (i == pAd->ChannelListNum)
533                 return FALSE;
534
535         return TRUE;
536 }
537
538
539 VOID ChannelSwitchAction(
540         IN      PRTMP_ADAPTER   pAd,
541         IN    UCHAR  Wcid,
542         IN    UCHAR  NewChannel,
543         IN    UCHAR  Secondary)
544 {
545         UCHAR           BBPValue = 0;
546         ULONG           MACValue;
547
548         DBGPRINT(RT_DEBUG_TRACE,("SPECTRUM - ChannelSwitchAction(NewChannel = %d , Secondary = %d)  \n", NewChannel, Secondary));
549
550         if (ChannelSwitchSanityCheck(pAd, Wcid, NewChannel, Secondary) == FALSE)
551                 return;
552
553         // 1.  Switches to BW = 20.
554         if (Secondary == 0)
555         {
556                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
557                 BBPValue&= (~0x18);
558                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
559                 if (pAd->MACVersion == 0x28600100)
560                 {
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" ));
565                 }
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" ));
573         }
574         // 1.  Switches to BW = 40 And Station supports BW = 40.
575         else if (((Secondary == 1) || (Secondary == 3)) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1))
576         {
577                 pAd->CommonCfg.Channel = NewChannel;
578
579                 if (Secondary == 1)
580                 {
581                         // Secondary above.
582                         pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
583                         RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
584                         MACValue &= 0xfe;
585                         RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
586                         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
587                         BBPValue&= (~0x18);
588                         BBPValue|= (0x10);
589                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
590                         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
591                         BBPValue&= (~0x20);
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 ));
594                 }
595                 else
596                 {
597                         // Secondary below.
598                         pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
599                         RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
600                         MACValue &= 0xfe;
601                         MACValue |= 0x1;
602                         RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
603                         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
604                         BBPValue&= (~0x18);
605                         BBPValue|= (0x10);
606                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
607                         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
608                         BBPValue&= (~0x20);
609                         BBPValue|= (0x20);
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 ));
612                 }
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;
617         }
618 }
619 #endif // DOT11N_DRAFT3 //
620 #endif // DOT11_N_SUPPORT //
621
622 VOID PeerPublicAction(
623         IN PRTMP_ADAPTER pAd,
624         IN MLME_QUEUE_ELEM *Elem)
625 {
626 #ifdef DOT11_N_SUPPORT
627 #ifdef DOT11N_DRAFT3
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)
632                 return;
633
634 #ifdef DOT11_N_SUPPORT
635 #ifdef DOT11N_DRAFT3
636         switch(Action)
637         {
638                 case ACTION_BSS_2040_COEXIST:   // Format defined in IEEE 7.4.7a.1 in 11n Draf3.03
639                         {
640                                 //UCHAR BssCoexist;
641                                 BSS_2040_COEXIST_ELEMENT                *pCoexistInfo;
642                                 BSS_2040_COEXIST_IE                     *pBssCoexistIe;
643                                 BSS_2040_INTOLERANT_CH_REPORT   *pIntolerantReport = NULL;
644
645                                 if (Elem->MsgLen <= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT)) )
646                                 {
647                                         DBGPRINT(RT_DEBUG_ERROR, ("ACTION - 20/40 BSS Coexistence Management Frame length too short! len = %ld!\n", Elem->MsgLen));
648                                         break;
649                                 }
650                                 DBGPRINT(RT_DEBUG_TRACE, ("ACTION - 20/40 BSS Coexistence Management action----> \n"));
651                                 hex_dump("CoexistenceMgmtFrame", Elem->Msg, Elem->MsgLen);
652
653
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)))
657                                 {
658                                         pIntolerantReport = (BSS_2040_INTOLERANT_CH_REPORT *)((PUCHAR)pCoexistInfo + sizeof(BSS_2040_COEXIST_ELEMENT));
659                                 }
660                                 //hex_dump("IntolerantReport ", (PUCHAR)pIntolerantReport, sizeof(BSS_2040_INTOLERANT_CH_REPORT));
661
662                                 pBssCoexistIe = (BSS_2040_COEXIST_IE *)(&pCoexistInfo->BssCoexistIe);
663
664 #ifdef CONFIG_STA_SUPPORT
665                                 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
666                                 {
667                                         if (INFRA_ON(pAd))
668                                         {
669                                                 StaPublicAction(pAd, pCoexistInfo);
670                                         }
671                                 }
672 #endif // CONFIG_STA_SUPPORT //
673
674                         }
675                         break;
676         }
677
678 #endif // DOT11N_DRAFT3 //
679 #endif // DOT11_N_SUPPORT //
680
681 }
682
683
684 static VOID ReservedAction(
685         IN PRTMP_ADAPTER pAd,
686         IN MLME_QUEUE_ELEM *Elem)
687 {
688         UCHAR Category;
689
690         if (Elem->MsgLen <= LENGTH_802_11)
691         {
692                 return;
693         }
694
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);
698 }
699
700 VOID PeerRMAction(
701         IN PRTMP_ADAPTER pAd,
702         IN MLME_QUEUE_ELEM *Elem)
703
704 {
705         return;
706 }
707
708 #ifdef DOT11_N_SUPPORT
709 static VOID respond_ht_information_exchange_action(
710         IN PRTMP_ADAPTER pAd,
711         IN MLME_QUEUE_ELEM *Elem)
712 {
713         PUCHAR                  pOutBuffer = NULL;
714         NDIS_STATUS             NStatus;
715         ULONG                   FrameLen;
716         FRAME_HT_INFO   HTINFOframe, *pFrame;
717         UCHAR                   *pAddr;
718
719
720         // 2. Always send back ADDBA Response
721         NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
722
723         if (NStatus != NDIS_STATUS_SUCCESS)
724         {
725                 DBGPRINT(RT_DEBUG_TRACE,("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
726                 return;
727         }
728
729         // get RA
730         pFrame = (FRAME_HT_INFO *) &Elem->Msg[0];
731         pAddr = pFrame->Hdr.Addr2;
732
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)
737         {
738                 if (ADHOC_ON(pAd))
739                         ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
740                 else
741                 ActHeaderInit(pAd, &HTINFOframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
742         }
743 #endif // CONFIG_STA_SUPPORT //
744
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;
750
751         MakeOutgoingFrame(pOutBuffer,                                   &FrameLen,
752                                           sizeof(FRAME_HT_INFO),        &HTINFOframe,
753                                           END_OF_ARGS);
754
755         MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
756         MlmeFreeMemory(pAd, pOutBuffer);
757 }
758
759
760 #ifdef DOT11N_DRAFT3
761 VOID SendNotifyBWActionFrame(
762         IN PRTMP_ADAPTER pAd,
763         IN UCHAR  Wcid,
764         IN UCHAR apidx)
765 {
766         PUCHAR                  pOutBuffer = NULL;
767         NDIS_STATUS     NStatus;
768         FRAME_ACTION_HDR        Frame;
769         ULONG                   FrameLen;
770         PUCHAR                  pAddr1;
771
772
773         NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
774         if(NStatus != NDIS_STATUS_SUCCESS)
775         {
776                 DBGPRINT(RT_DEBUG_ERROR,("ACT - SendNotifyBWAction() allocate memory failed \n"));
777                 return;
778         }
779
780         if (Wcid == MCAST_WCID)
781                 pAddr1 = &BROADCAST_ADDR[0];
782         else
783                 pAddr1 = pAd->MacTab.Content[Wcid].Addr;
784         ActHeaderInit(pAd, &Frame.Hdr, pAddr1, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
785
786         Frame.Category = CATEGORY_HT;
787         Frame.Action = NOTIFY_BW_ACTION;
788
789         MakeOutgoingFrame(pOutBuffer,                           &FrameLen,
790                                   sizeof(FRAME_ACTION_HDR),       &Frame,
791                                   END_OF_ARGS);
792
793         *(pOutBuffer + FrameLen) = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
794         FrameLen++;
795
796
797         MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
798         DBGPRINT(RT_DEBUG_TRACE,("ACT - SendNotifyBWAction(NotifyBW= %d)!\n", pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth));
799
800 }
801 #endif // DOT11N_DRAFT3 //
802
803
804 VOID PeerHTAction(
805         IN PRTMP_ADAPTER pAd,
806         IN MLME_QUEUE_ELEM *Elem)
807 {
808         UCHAR   Action = Elem->Msg[LENGTH_802_11+1];
809
810         if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
811                 return;
812
813         switch(Action)
814         {
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)
819                         {
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] ));
825                                 break;
826                         }
827 #endif // CONFIG_STA_SUPPORT //
828
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;
831
832                         break;
833
834                 case SMPS_ACTION:
835                         // 7.3.1.25
836                         DBGPRINT(RT_DEBUG_TRACE,("ACTION - SMPS action----> \n"));
837                         if (((Elem->Msg[LENGTH_802_11+2]&0x1) == 0))
838                         {
839                                 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
840                         }
841                         else if (((Elem->Msg[LENGTH_802_11+2]&0x2) == 0))
842                         {
843                                 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
844                         }
845                         else
846                         {
847                                 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
848                         }
849
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.
852                         break;
853
854                 case SETPCO_ACTION:
855                         break;
856
857                 case MIMO_CHA_MEASURE_ACTION:
858                         break;
859
860                 case HT_INFO_EXCHANGE:
861                         {
862                                 HT_INFORMATION_OCTET    *pHT_info;
863
864                                 pHT_info = (HT_INFORMATION_OCTET *) &Elem->Msg[LENGTH_802_11+2];
865                                 // 7.4.8.10
866                                 DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Information Exchange action----> \n"));
867                                 if (pHT_info->Request)
868                                 {
869                                         respond_ht_information_exchange_action(pAd, Elem);
870                                 }
871                         }
872                 break;
873         }
874 }
875
876
877 /*
878         ==========================================================================
879         Description:
880                 Retry sending ADDBA Reqest.
881
882         IRQL = DISPATCH_LEVEL
883
884         Parametrs:
885         p8023Header: if this is already 802.3 format, p8023Header is NULL
886
887         Return  : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
888                                 FALSE , then continue indicaterx at this moment.
889         ==========================================================================
890  */
891 VOID ORIBATimerTimeout(
892         IN      PRTMP_ADAPTER   pAd)
893 {
894         MAC_TABLE_ENTRY *pEntry;
895         INT                     i, total;
896 //      FRAME_BAR                       FrameBar;
897 //      ULONG                   FrameLen;
898 //      NDIS_STATUS     NStatus;
899 //      PUCHAR                  pOutBuffer = NULL;
900 //      USHORT                  Sequence;
901         UCHAR                   TID;
902
903 #ifdef RALINK_ATE
904         if (ATE_ON(pAd))
905                 return;
906 #endif // RALINK_ATE //
907
908         total = pAd->MacTab.Size * NUM_OF_TID;
909
910         for (i = 1; ((i <MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)) ; i++)
911         {
912                 if  (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done)
913                 {
914                         pEntry = &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].Wcid];
915                         TID = pAd->BATable.BAOriEntry[i].TID;
916
917                         ASSERT(pAd->BATable.BAOriEntry[i].Wcid < MAX_LEN_OF_MAC_TABLE);
918                 }
919                 total --;
920         }
921 }
922
923
924 VOID SendRefreshBAR(
925         IN      PRTMP_ADAPTER   pAd,
926         IN      MAC_TABLE_ENTRY *pEntry)
927 {
928         FRAME_BAR               FrameBar;
929         ULONG                   FrameLen;
930         NDIS_STATUS     NStatus;
931         PUCHAR                  pOutBuffer = NULL;
932         USHORT                  Sequence;
933         UCHAR                   i, TID;
934         USHORT                  idx;
935         BA_ORI_ENTRY    *pBAEntry;
936
937         for (i = 0; i <NUM_OF_TID; i++)
938         {
939                 idx = pEntry->BAOriWcidArray[i];
940                 if (idx == 0)
941                 {
942                         continue;
943                 }
944                 pBAEntry = &pAd->BATable.BAOriEntry[idx];
945
946                 if  (pBAEntry->ORI_BA_Status == Originator_Done)
947                 {
948                         TID = pBAEntry->TID;
949
950                         ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE);
951
952                         NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
953                         if(NStatus != NDIS_STATUS_SUCCESS)
954                         {
955                                 DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
956                                 return;
957                         }
958
959                         Sequence = pEntry->TxSeq[TID];
960
961
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 //
966
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.
970
971                         MakeOutgoingFrame(pOutBuffer,                           &FrameLen,
972                                                           sizeof(FRAME_BAR),      &FrameBar,
973                                                           END_OF_ARGS);
974                         //if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET)))
975                         if (1)  // Now we always send BAR.
976                         {
977                                 //MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen);
978                                 MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG | MapUserPriorityToAccessCategory[TID]), pOutBuffer, FrameLen);
979
980                         }
981                         MlmeFreeMemory(pAd, pOutBuffer);
982                 }
983         }
984 }
985 #endif // DOT11_N_SUPPORT //
986
987 VOID ActHeaderInit(
988     IN  PRTMP_ADAPTER   pAd,
989     IN OUT PHEADER_802_11 pHdr80211,
990     IN PUCHAR Addr1,
991     IN PUCHAR Addr2,
992     IN PUCHAR Addr3)
993 {
994     NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
995     pHdr80211->FC.Type = BTYPE_MGMT;
996     pHdr80211->FC.SubType = SUBTYPE_ACTION;
997
998     COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
999         COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
1000     COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
1001 }
1002
1003 VOID BarHeaderInit(
1004         IN      PRTMP_ADAPTER   pAd,
1005         IN OUT PFRAME_BAR pCntlBar,
1006         IN PUCHAR pDA,
1007         IN PUCHAR pSA)
1008 {
1009 //      USHORT  Duration;
1010
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;
1017
1018
1019         pCntlBar->Duration = 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(FRAME_BA));
1020
1021         COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
1022         COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
1023 }
1024
1025
1026 /*
1027         ==========================================================================
1028         Description:
1029                 Insert Category and action code into the action frame.
1030
1031         Parametrs:
1032                 1. frame buffer pointer.
1033                 2. frame length.
1034                 3. category code of the frame.
1035                 4. action code of the frame.
1036
1037         Return  : None.
1038         ==========================================================================
1039  */
1040 VOID InsertActField(
1041         IN PRTMP_ADAPTER pAd,
1042         OUT PUCHAR pFrameBuf,
1043         OUT PULONG pFrameLen,
1044         IN UINT8 Category,
1045         IN UINT8 ActCode)
1046 {
1047         ULONG TempLen;
1048
1049         MakeOutgoingFrame(      pFrameBuf,              &TempLen,
1050                                                 1,                              &Category,
1051                                                 1,                              &ActCode,
1052                                                 END_OF_ARGS);
1053
1054         *pFrameLen = *pFrameLen + TempLen;
1055
1056         return;
1057 }