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