Staging: rt2860: remove dead RALINK_ATE code
[linux-2.6] / drivers / staging / rt2860 / 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     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  */
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
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  */
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 #ifdef CONFIG_STA_SUPPORT
224                 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
225                         BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress);
226 #endif // CONFIG_STA_SUPPORT //
227
228                 FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL funciton.
229                 FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; // make sure sequence not clear in DEL funciton.
230                 FrameBar.BarControl.TID = pInfo->TID; // make sure sequence not clear in DEL funciton.
231                 FrameBar.BarControl.ACKPolicy = IMMED_BA; // make sure sequence not clear in DEL funciton.
232                 FrameBar.BarControl.Compressed = 1; // make sure sequence not clear in DEL funciton.
233                 FrameBar.BarControl.MTID = 0; // make sure sequence not clear in DEL funciton.
234
235                 MakeOutgoingFrame(pOutBuffer2,                          &FrameLen,
236                                           sizeof(FRAME_BAR),      &FrameBar,
237                                           END_OF_ARGS);
238                 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
239                 MlmeFreeMemory(pAd, pOutBuffer2);
240                 DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
241
242                 // SEND DELBA FRAME
243                 FrameLen = 0;
244 #ifdef CONFIG_STA_SUPPORT
245                 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
246                 {
247                         if (ADHOC_ON(pAd))
248                                 ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
249                         else
250 #ifdef QOS_DLS_SUPPORT
251                         if (pAd->MacTab.Content[pInfo->Wcid].ValidAsDls)
252                                 ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
253                         else
254 #endif // QOS_DLS_SUPPORT //
255                                 ActHeaderInit(pAd, &Frame.Hdr,  pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[pInfo->Wcid].Addr);
256                 }
257 #endif // CONFIG_STA_SUPPORT //
258                 Frame.Category = CATEGORY_BA;
259                 Frame.Action = DELBA;
260                 Frame.DelbaParm.Initiator = pInfo->Initiator;
261                 Frame.DelbaParm.TID = pInfo->TID;
262                 Frame.ReasonCode = 39; // Time Out
263                 *(USHORT *)(&Frame.DelbaParm) = cpu2le16(*(USHORT *)(&Frame.DelbaParm));
264                 Frame.ReasonCode = cpu2le16(Frame.ReasonCode);
265
266                 MakeOutgoingFrame(pOutBuffer,               &FrameLen,
267                               sizeof(FRAME_DELBA_REQ),    &Frame,
268                               END_OF_ARGS);
269                 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
270                 MlmeFreeMemory(pAd, pOutBuffer);
271                 DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator));
272         }
273 }
274 #endif // DOT11_N_SUPPORT //
275
276 VOID MlmeQOSAction(
277     IN PRTMP_ADAPTER pAd,
278     IN MLME_QUEUE_ELEM *Elem)
279 {
280 }
281
282 VOID MlmeDLSAction(
283     IN PRTMP_ADAPTER pAd,
284     IN MLME_QUEUE_ELEM *Elem)
285 {
286 }
287
288 VOID MlmeInvalidAction(
289     IN PRTMP_ADAPTER pAd,
290     IN MLME_QUEUE_ELEM *Elem)
291 {
292         //PUCHAR                   pOutBuffer = NULL;
293         //Return the receiving frame except the MSB of category filed set to 1.  7.3.1.11
294 }
295
296 VOID PeerQOSAction(
297         IN PRTMP_ADAPTER pAd,
298         IN MLME_QUEUE_ELEM *Elem)
299 {
300 }
301
302 #ifdef QOS_DLS_SUPPORT
303 VOID PeerDLSAction(
304         IN PRTMP_ADAPTER pAd,
305         IN MLME_QUEUE_ELEM *Elem)
306 {
307         UCHAR   Action = Elem->Msg[LENGTH_802_11+1];
308
309         switch(Action)
310         {
311                 case ACTION_DLS_REQUEST:
312 #ifdef CONFIG_STA_SUPPORT
313                         IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
314                         PeerDlsReqAction(pAd, Elem);
315 #endif // CONFIG_STA_SUPPORT //
316                         break;
317
318                 case ACTION_DLS_RESPONSE:
319 #ifdef CONFIG_STA_SUPPORT
320                         IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
321                         PeerDlsRspAction(pAd, Elem);
322 #endif // CONFIG_STA_SUPPORT //
323                         break;
324
325                 case ACTION_DLS_TEARDOWN:
326 #ifdef CONFIG_STA_SUPPORT
327                         IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
328                         PeerDlsTearDownAction(pAd, Elem);
329 #endif // CONFIG_STA_SUPPORT //
330                         break;
331         }
332 }
333 #endif // QOS_DLS_SUPPORT //
334
335 #ifdef DOT11_N_SUPPORT
336 VOID PeerBAAction(
337         IN PRTMP_ADAPTER pAd,
338         IN MLME_QUEUE_ELEM *Elem)
339 {
340         UCHAR   Action = Elem->Msg[LENGTH_802_11+1];
341
342         switch(Action)
343         {
344                 case ADDBA_REQ:
345                         PeerAddBAReqAction(pAd,Elem);
346                         break;
347                 case ADDBA_RESP:
348                         PeerAddBARspAction(pAd,Elem);
349                         break;
350                 case DELBA:
351                         PeerDelBAAction(pAd,Elem);
352                         break;
353         }
354 }
355
356
357 #ifdef DOT11N_DRAFT3
358
359 #ifdef CONFIG_STA_SUPPORT
360 VOID StaPublicAction(
361         IN PRTMP_ADAPTER pAd,
362         IN UCHAR Bss2040Coexist)
363 {
364         BSS_2040_COEXIST_IE             BssCoexist;
365         MLME_SCAN_REQ_STRUCT                    ScanReq;
366
367         BssCoexist.word = Bss2040Coexist;
368         // 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
369         if ((BssCoexist.field.InfoReq == 1) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040)))
370         {
371                 // Clear record first.  After scan , will update those bit and send back to transmiter.
372                 pAd->CommonCfg.BSSCoexist2040.field.InfoReq = 1;
373                 pAd->CommonCfg.BSSCoexist2040.field.Intolerant40 = 0;
374                 pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 0;
375                 // Fill out stuff for scan request
376                 ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_2040_BSS_COEXIST);
377                 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
378                 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
379         }
380 }
381
382
383 /*
384 Description : Build Intolerant Channel Rerpot from Trigger event table.
385 return : how many bytes copied.
386 */
387 ULONG BuildIntolerantChannelRep(
388         IN      PRTMP_ADAPTER   pAd,
389         IN    PUCHAR  pDest)
390 {
391         ULONG                   FrameLen = 0;
392         ULONG                   ReadOffset = 0;
393         UCHAR                   i;
394         UCHAR                   LastRegClass = 0xff;
395         PUCHAR                  pLen;
396
397         for ( i = 0;i < MAX_TRIGGER_EVENT;i++)
398         {
399                 if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid == TRUE)
400                 {
401                         if (pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass == LastRegClass)
402                         {
403                                 *(pDest + ReadOffset) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
404                                 *pLen++;
405                                 ReadOffset++;
406                                 FrameLen++;
407                         }
408                         else
409                         {
410                                 *(pDest + ReadOffset) = IE_2040_BSS_INTOLERANT_REPORT;  // IE
411                                 *(pDest + ReadOffset + 1) = 2;  // Len = RegClass byte + channel byte.
412                                 pLen = pDest + ReadOffset + 1;
413                                 LastRegClass = pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass;
414                                 *(pDest + ReadOffset + 2) = LastRegClass;       // Len = RegClass byte + channel byte.
415                                 *(pDest + ReadOffset + 3) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
416                                 FrameLen += 4;
417                                 ReadOffset += 4;
418                         }
419
420                 }
421         }
422         return FrameLen;
423 }
424
425
426 /*
427 Description : Send 20/40 BSS Coexistence Action frame If one trigger event is triggered.
428 */
429 VOID Send2040CoexistAction(
430         IN      PRTMP_ADAPTER   pAd,
431         IN    UCHAR  Wcid,
432         IN      BOOLEAN bAddIntolerantCha)
433 {
434         PUCHAR                  pOutBuffer = NULL;
435         NDIS_STATUS     NStatus;
436         FRAME_ACTION_HDR        Frame;
437         ULONG                   FrameLen;
438         ULONG                   IntolerantChaRepLen;
439
440         IntolerantChaRepLen = 0;
441         NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
442         if(NStatus != NDIS_STATUS_SUCCESS)
443         {
444                 DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction() allocate memory failed \n"));
445                 return;
446         }
447         ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[Wcid].Addr, pAd->CommonCfg.Bssid);
448         Frame.Category = CATEGORY_PUBLIC;
449         Frame.Action = ACTION_BSS_2040_COEXIST;
450
451         MakeOutgoingFrame(pOutBuffer,                           &FrameLen,
452                                   sizeof(FRAME_ACTION_HDR),       &Frame,
453                                   END_OF_ARGS);
454
455         *(pOutBuffer + FrameLen) = pAd->CommonCfg.BSSCoexist2040.word;
456         FrameLen++;
457
458         if (bAddIntolerantCha == TRUE)
459                 IntolerantChaRepLen = BuildIntolerantChannelRep(pAd, pOutBuffer + FrameLen);
460
461         MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen + IntolerantChaRepLen);
462         DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction( BSSCoexist2040 = 0x%x )  \n", pAd->CommonCfg.BSSCoexist2040.word));
463
464 }
465
466
467 /*
468         ==========================================================================
469         Description:
470         After scan, Update 20/40 BSS Coexistence IE and send out.
471         According to 802.11n D3.03 11.14.10
472
473         Parameters:
474         ==========================================================================
475  */
476 VOID Update2040CoexistFrameAndNotify(
477         IN      PRTMP_ADAPTER   pAd,
478         IN    UCHAR  Wcid,
479         IN      BOOLEAN bAddIntolerantCha)
480 {
481         BSS_2040_COEXIST_IE     OldValue;
482
483         OldValue.word = pAd->CommonCfg.BSSCoexist2040.word;
484         if ((pAd->CommonCfg.TriggerEventTab.EventANo > 0) || (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0))
485                 pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 1;
486
487         // Need to check !!!!
488         // How STA will set Intolerant40 if implementation dependent. Now we don't set this bit first.!!!!!
489         // So Only check BSS20WidthReq change.
490         if (OldValue.field.BSS20WidthReq != pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq)
491         {
492                 Send2040CoexistAction(pAd, Wcid, bAddIntolerantCha);
493         }
494 }
495 #endif // CONFIG_STA_SUPPORT //
496
497
498 BOOLEAN ChannelSwitchSanityCheck(
499         IN      PRTMP_ADAPTER   pAd,
500         IN    UCHAR  Wcid,
501         IN    UCHAR  NewChannel,
502         IN    UCHAR  Secondary)
503 {
504         UCHAR           i;
505
506         if (Wcid >= MAX_LEN_OF_MAC_TABLE)
507                 return FALSE;
508
509         if ((NewChannel > 7) && (Secondary == 1))
510                 return FALSE;
511
512         if ((NewChannel < 5) && (Secondary == 3))
513                 return FALSE;
514
515         // 0. Check if new channel is in the channellist.
516         for (i = 0;i < pAd->ChannelListNum;i++)
517         {
518                 if (pAd->ChannelList[i].Channel == NewChannel)
519                 {
520                         break;
521                 }
522         }
523
524         if (i == pAd->ChannelListNum)
525                 return FALSE;
526
527         return TRUE;
528 }
529
530
531 VOID ChannelSwitchAction(
532         IN      PRTMP_ADAPTER   pAd,
533         IN    UCHAR  Wcid,
534         IN    UCHAR  NewChannel,
535         IN    UCHAR  Secondary)
536 {
537         UCHAR           BBPValue = 0;
538         ULONG           MACValue;
539
540         DBGPRINT(RT_DEBUG_TRACE,("SPECTRUM - ChannelSwitchAction(NewChannel = %d , Secondary = %d)  \n", NewChannel, Secondary));
541
542         if (ChannelSwitchSanityCheck(pAd, Wcid, NewChannel, Secondary) == FALSE)
543                 return;
544
545         // 1.  Switches to BW = 20.
546         if (Secondary == 0)
547         {
548                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
549                 BBPValue&= (~0x18);
550                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
551                 if (pAd->MACVersion == 0x28600100)
552                 {
553                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
554                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
555                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
556                         DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
557                 }
558                 pAd->CommonCfg.BBPCurrentBW = BW_20;
559                 pAd->CommonCfg.Channel = NewChannel;
560                 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
561                 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel,FALSE);
562                 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
563                 pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 0;
564                 DBGPRINT(RT_DEBUG_TRACE, ("!!!20MHz   !!! \n" ));
565         }
566         // 1.  Switches to BW = 40 And Station supports BW = 40.
567         else if (((Secondary == 1) || (Secondary == 3)) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1))
568         {
569                 pAd->CommonCfg.Channel = NewChannel;
570
571                 if (Secondary == 1)
572                 {
573                         // Secondary above.
574                         pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
575                         RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
576                         MACValue &= 0xfe;
577                         RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
578                         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
579                         BBPValue&= (~0x18);
580                         BBPValue|= (0x10);
581                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
582                         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
583                         BBPValue&= (~0x20);
584                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
585                         DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
586                 }
587                 else
588                 {
589                         // Secondary below.
590                         pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
591                         RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
592                         MACValue &= 0xfe;
593                         MACValue |= 0x1;
594                         RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
595                         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
596                         BBPValue&= (~0x18);
597                         BBPValue|= (0x10);
598                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
599                         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
600                         BBPValue&= (~0x20);
601                         BBPValue|= (0x20);
602                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
603                         DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
604                 }
605                 pAd->CommonCfg.BBPCurrentBW = BW_40;
606                 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
607                 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
608                 pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 1;
609         }
610 }
611 #endif // DOT11N_DRAFT3 //
612 #endif // DOT11_N_SUPPORT //
613
614 VOID PeerPublicAction(
615         IN PRTMP_ADAPTER pAd,
616         IN MLME_QUEUE_ELEM *Elem)
617 {
618 #ifdef DOT11N_DRAFT3
619         UCHAR   Action = Elem->Msg[LENGTH_802_11+1];
620 #endif // DOT11N_DRAFT3 //
621
622         if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
623                 return;
624
625 #ifdef DOT11N_DRAFT3
626         switch(Action)
627         {
628                 case ACTION_BSS_2040_COEXIST:   // Format defined in IEEE 7.4.7a.1 in 11n Draf3.03
629                         {
630                                 //UCHAR BssCoexist;
631                                 BSS_2040_COEXIST_ELEMENT                *pCoexistInfo;
632                                 BSS_2040_COEXIST_IE                     *pBssCoexistIe;
633                                 BSS_2040_INTOLERANT_CH_REPORT   *pIntolerantReport = NULL;
634
635                                 if (Elem->MsgLen <= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT)) )
636                                 {
637                                         DBGPRINT(RT_DEBUG_ERROR, ("ACTION - 20/40 BSS Coexistence Management Frame length too short! len = %ld!\n", Elem->MsgLen));
638                                         break;
639                                 }
640                                 DBGPRINT(RT_DEBUG_TRACE, ("ACTION - 20/40 BSS Coexistence Management action----> \n"));
641                                 hex_dump("CoexistenceMgmtFrame", Elem->Msg, Elem->MsgLen);
642
643
644                                 pCoexistInfo = (BSS_2040_COEXIST_ELEMENT *) &Elem->Msg[LENGTH_802_11+2];
645                                 //hex_dump("CoexistInfo", (PUCHAR)pCoexistInfo, sizeof(BSS_2040_COEXIST_ELEMENT));
646                                 if (Elem->MsgLen >= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT) + sizeof(BSS_2040_INTOLERANT_CH_REPORT)))
647                                 {
648                                         pIntolerantReport = (BSS_2040_INTOLERANT_CH_REPORT *)((PUCHAR)pCoexistInfo + sizeof(BSS_2040_COEXIST_ELEMENT));
649                                 }
650                                 //hex_dump("IntolerantReport ", (PUCHAR)pIntolerantReport, sizeof(BSS_2040_INTOLERANT_CH_REPORT));
651
652                                 pBssCoexistIe = (BSS_2040_COEXIST_IE *)(&pCoexistInfo->BssCoexistIe);
653
654 #ifdef CONFIG_STA_SUPPORT
655                                 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
656                                 {
657                                         if (INFRA_ON(pAd))
658                                         {
659                                                 StaPublicAction(pAd, pCoexistInfo);
660                                         }
661                                 }
662 #endif // CONFIG_STA_SUPPORT //
663
664                         }
665                         break;
666         }
667
668 #endif // DOT11N_DRAFT3 //
669
670 }
671
672
673 static VOID ReservedAction(
674         IN PRTMP_ADAPTER pAd,
675         IN MLME_QUEUE_ELEM *Elem)
676 {
677         UCHAR Category;
678
679         if (Elem->MsgLen <= LENGTH_802_11)
680         {
681                 return;
682         }
683
684         Category = Elem->Msg[LENGTH_802_11];
685         DBGPRINT(RT_DEBUG_TRACE,("Rcv reserved category(%d) Action Frame\n", Category));
686         hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen);
687 }
688
689 VOID PeerRMAction(
690         IN PRTMP_ADAPTER pAd,
691         IN MLME_QUEUE_ELEM *Elem)
692
693 {
694         return;
695 }
696
697 #ifdef DOT11_N_SUPPORT
698 static VOID respond_ht_information_exchange_action(
699         IN PRTMP_ADAPTER pAd,
700         IN MLME_QUEUE_ELEM *Elem)
701 {
702         PUCHAR                  pOutBuffer = NULL;
703         NDIS_STATUS             NStatus;
704         ULONG                   FrameLen;
705         FRAME_HT_INFO   HTINFOframe, *pFrame;
706         UCHAR                   *pAddr;
707
708
709         // 2. Always send back ADDBA Response
710         NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
711
712         if (NStatus != NDIS_STATUS_SUCCESS)
713         {
714                 DBGPRINT(RT_DEBUG_TRACE,("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
715                 return;
716         }
717
718         // get RA
719         pFrame = (FRAME_HT_INFO *) &Elem->Msg[0];
720         pAddr = pFrame->Hdr.Addr2;
721
722         NdisZeroMemory(&HTINFOframe, sizeof(FRAME_HT_INFO));
723         // 2-1. Prepare ADDBA Response frame.
724 #ifdef CONFIG_STA_SUPPORT
725         IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
726         {
727                 if (ADHOC_ON(pAd))
728                         ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
729                 else
730                         ActHeaderInit(pAd, &HTINFOframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
731         }
732 #endif // CONFIG_STA_SUPPORT //
733
734         HTINFOframe.Category = CATEGORY_HT;
735         HTINFOframe.Action = HT_INFO_EXCHANGE;
736         HTINFOframe.HT_Info.Request = 0;
737         HTINFOframe.HT_Info.Forty_MHz_Intolerant = pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant;
738         HTINFOframe.HT_Info.STA_Channel_Width    = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
739
740         MakeOutgoingFrame(pOutBuffer,                                   &FrameLen,
741                                           sizeof(FRAME_HT_INFO),        &HTINFOframe,
742                                           END_OF_ARGS);
743
744         MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
745         MlmeFreeMemory(pAd, pOutBuffer);
746 }
747
748
749 #ifdef DOT11N_DRAFT3
750 VOID SendNotifyBWActionFrame(
751         IN PRTMP_ADAPTER pAd,
752         IN UCHAR  Wcid,
753         IN UCHAR apidx)
754 {
755         PUCHAR                  pOutBuffer = NULL;
756         NDIS_STATUS     NStatus;
757         FRAME_ACTION_HDR        Frame;
758         ULONG                   FrameLen;
759         PUCHAR                  pAddr1;
760
761
762         NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
763         if(NStatus != NDIS_STATUS_SUCCESS)
764         {
765                 DBGPRINT(RT_DEBUG_ERROR,("ACT - SendNotifyBWAction() allocate memory failed \n"));
766                 return;
767         }
768
769         if (Wcid == MCAST_WCID)
770                 pAddr1 = &BROADCAST_ADDR[0];
771         else
772                 pAddr1 = pAd->MacTab.Content[Wcid].Addr;
773         ActHeaderInit(pAd, &Frame.Hdr, pAddr1, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
774
775         Frame.Category = CATEGORY_HT;
776         Frame.Action = NOTIFY_BW_ACTION;
777
778         MakeOutgoingFrame(pOutBuffer,                           &FrameLen,
779                                   sizeof(FRAME_ACTION_HDR),       &Frame,
780                                   END_OF_ARGS);
781
782         *(pOutBuffer + FrameLen) = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
783         FrameLen++;
784
785
786         MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
787         DBGPRINT(RT_DEBUG_TRACE,("ACT - SendNotifyBWAction(NotifyBW= %d)!\n", pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth));
788
789 }
790 #endif // DOT11N_DRAFT3 //
791
792
793 VOID PeerHTAction(
794         IN PRTMP_ADAPTER pAd,
795         IN MLME_QUEUE_ELEM *Elem)
796 {
797         UCHAR   Action = Elem->Msg[LENGTH_802_11+1];
798
799         if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
800                 return;
801
802         switch(Action)
803         {
804                 case NOTIFY_BW_ACTION:
805                         DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Notify Channel bandwidth action----> \n"));
806 #ifdef CONFIG_STA_SUPPORT
807                         if(pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
808                         {
809                                 // Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps
810                                 // sending BW_Notify Action frame, and cause us to linkup and linkdown.
811                                 // In legacy mode, don't need to parse HT action frame.
812                                 DBGPRINT(RT_DEBUG_TRACE,("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
813                                                                 Elem->Msg[LENGTH_802_11+2] ));
814                                 break;
815                         }
816 #endif // CONFIG_STA_SUPPORT //
817
818                         if (Elem->Msg[LENGTH_802_11+2] == 0)    // 7.4.8.2. if value is 1, keep the same as supported channel bandwidth.
819                                 pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0;
820
821                         break;
822                 case SMPS_ACTION:
823                         // 7.3.1.25
824                         DBGPRINT(RT_DEBUG_TRACE,("ACTION - SMPS action----> \n"));
825                         if (((Elem->Msg[LENGTH_802_11+2]&0x1) == 0))
826                         {
827                                 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
828                         }
829                         else if (((Elem->Msg[LENGTH_802_11+2]&0x2) == 0))
830                         {
831                                 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
832                         }
833                         else
834                         {
835                                 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
836                         }
837
838                         DBGPRINT(RT_DEBUG_TRACE,("Aid(%d) MIMO PS = %d\n", Elem->Wcid, pAd->MacTab.Content[Elem->Wcid].MmpsMode));
839                         // rt2860c : add something for smps change.
840                         break;
841
842                 case SETPCO_ACTION:
843                         break;
844                 case MIMO_CHA_MEASURE_ACTION:
845                         break;
846                 case HT_INFO_EXCHANGE:
847                         {
848                                 HT_INFORMATION_OCTET    *pHT_info;
849
850                                 pHT_info = (HT_INFORMATION_OCTET *) &Elem->Msg[LENGTH_802_11+2];
851                                 // 7.4.8.10
852                                 DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Information Exchange action----> \n"));
853                                 if (pHT_info->Request)
854                                 {
855                                         respond_ht_information_exchange_action(pAd, Elem);
856                                 }
857                         }
858                         break;
859         }
860 }
861
862
863 /*
864         ==========================================================================
865         Description:
866                 Retry sending ADDBA Reqest.
867
868         IRQL = DISPATCH_LEVEL
869
870         Parametrs:
871         p8023Header: if this is already 802.3 format, p8023Header is NULL
872
873         Return  : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
874                                 FALSE , then continue indicaterx at this moment.
875         ==========================================================================
876  */
877 VOID ORIBATimerTimeout(
878         IN      PRTMP_ADAPTER   pAd)
879 {
880         MAC_TABLE_ENTRY *pEntry;
881         INT                     i, total;
882         UCHAR                   TID;
883
884         total = pAd->MacTab.Size * NUM_OF_TID;
885
886         for (i = 1; ((i <MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)) ; i++)
887         {
888                 if  (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done)
889                 {
890                         pEntry = &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].Wcid];
891                         TID = pAd->BATable.BAOriEntry[i].TID;
892
893                         ASSERT(pAd->BATable.BAOriEntry[i].Wcid < MAX_LEN_OF_MAC_TABLE);
894                 }
895                 total --;
896         }
897 }
898
899
900 VOID SendRefreshBAR(
901         IN      PRTMP_ADAPTER   pAd,
902         IN      MAC_TABLE_ENTRY *pEntry)
903 {
904         FRAME_BAR               FrameBar;
905         ULONG                   FrameLen;
906         NDIS_STATUS     NStatus;
907         PUCHAR                  pOutBuffer = NULL;
908         USHORT                  Sequence;
909         UCHAR                   i, TID;
910         USHORT                  idx;
911         BA_ORI_ENTRY    *pBAEntry;
912
913         for (i = 0; i <NUM_OF_TID; i++)
914         {
915                 idx = pEntry->BAOriWcidArray[i];
916                 if (idx == 0)
917                 {
918                         continue;
919                 }
920                 pBAEntry = &pAd->BATable.BAOriEntry[idx];
921
922                 if  (pBAEntry->ORI_BA_Status == Originator_Done)
923                 {
924                         TID = pBAEntry->TID;
925
926                         ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE);
927
928                         NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
929                         if(NStatus != NDIS_STATUS_SUCCESS)
930                         {
931                                 DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
932                                 return;
933                         }
934
935                         Sequence = pEntry->TxSeq[TID];
936 #ifdef CONFIG_STA_SUPPORT
937                         IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
938                                 BarHeaderInit(pAd, &FrameBar, pEntry->Addr, pAd->CurrentAddress);
939 #endif // CONFIG_STA_SUPPORT //
940
941                         FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
942                         FrameBar.StartingSeq.field.StartSeq = Sequence; // make sure sequence not clear in DEL funciton.
943                         FrameBar.BarControl.TID = TID; // make sure sequence not clear in DEL funciton.
944
945                         MakeOutgoingFrame(pOutBuffer,                           &FrameLen,
946                                                           sizeof(FRAME_BAR),      &FrameBar,
947                                                           END_OF_ARGS);
948                         if (1)  // Now we always send BAR.
949                         {
950                                 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
951                         }
952                         MlmeFreeMemory(pAd, pOutBuffer);
953                 }
954         }
955 }
956 #endif // DOT11_N_SUPPORT //
957
958 VOID ActHeaderInit(
959     IN  PRTMP_ADAPTER   pAd,
960     IN OUT PHEADER_802_11 pHdr80211,
961     IN PUCHAR Addr1,
962     IN PUCHAR Addr2,
963     IN PUCHAR Addr3)
964 {
965     NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
966     pHdr80211->FC.Type = BTYPE_MGMT;
967     pHdr80211->FC.SubType = SUBTYPE_ACTION;
968
969     COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
970         COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
971     COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
972 }
973
974 VOID BarHeaderInit(
975         IN      PRTMP_ADAPTER   pAd,
976         IN OUT PFRAME_BAR pCntlBar,
977         IN PUCHAR pDA,
978         IN PUCHAR pSA)
979 {
980         NdisZeroMemory(pCntlBar, sizeof(FRAME_BAR));
981         pCntlBar->FC.Type = BTYPE_CNTL;
982         pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ;
983         pCntlBar->BarControl.MTID = 0;
984         pCntlBar->BarControl.Compressed = 1;
985         pCntlBar->BarControl.ACKPolicy = 0;
986
987
988         pCntlBar->Duration = 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(FRAME_BA));
989
990         COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
991         COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
992 }
993
994
995 /*
996         ==========================================================================
997         Description:
998                 Insert Category and action code into the action frame.
999
1000         Parametrs:
1001                 1. frame buffer pointer.
1002                 2. frame length.
1003                 3. category code of the frame.
1004                 4. action code of the frame.
1005
1006         Return  : None.
1007         ==========================================================================
1008  */
1009 VOID InsertActField(
1010         IN PRTMP_ADAPTER pAd,
1011         OUT PUCHAR pFrameBuf,
1012         OUT PULONG pFrameLen,
1013         IN UINT8 Category,
1014         IN UINT8 ActCode)
1015 {
1016         ULONG TempLen;
1017
1018         MakeOutgoingFrame(      pFrameBuf,              &TempLen,
1019                                                 1,                              &Category,
1020                                                 1,                              &ActCode,
1021                                                 END_OF_ARGS);
1022
1023         *pFrameLen = *pFrameLen + TempLen;
1024
1025         return;
1026 }