Staging: rt2860: remove CONFIG_STA_SUPPORT ifdefs
[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
76 #ifdef DOT11_N_SUPPORT
77         StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE, (STATE_MACHINE_FUNC)PeerBAAction);
78         StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE, (STATE_MACHINE_FUNC)PeerHTAction);
79         StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE, (STATE_MACHINE_FUNC)MlmeADDBAAction);
80         StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
81         StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
82 #endif // DOT11_N_SUPPORT //
83
84         StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE, (STATE_MACHINE_FUNC)PeerPublicAction);
85         StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE, (STATE_MACHINE_FUNC)PeerRMAction);
86
87         StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE, (STATE_MACHINE_FUNC)MlmeQOSAction);
88         StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE, (STATE_MACHINE_FUNC)MlmeDLSAction);
89         StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID, (STATE_MACHINE_FUNC)MlmeInvalidAction);
90 }
91
92 #ifdef DOT11_N_SUPPORT
93 VOID MlmeADDBAAction(
94     IN PRTMP_ADAPTER pAd,
95     IN MLME_QUEUE_ELEM *Elem)
96
97 {
98         MLME_ADDBA_REQ_STRUCT *pInfo;
99         UCHAR           Addr[6];
100         PUCHAR         pOutBuffer = NULL;
101         NDIS_STATUS     NStatus;
102         ULONG           Idx;
103         FRAME_ADDBA_REQ  Frame;
104         ULONG           FrameLen;
105         BA_ORI_ENTRY                    *pBAEntry = NULL;
106
107         pInfo = (MLME_ADDBA_REQ_STRUCT *)Elem->Msg;
108         NdisZeroMemory(&Frame, sizeof(FRAME_ADDBA_REQ));
109
110         if(MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr))
111         {
112                 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
113                 if(NStatus != NDIS_STATUS_SUCCESS)
114                 {
115                         DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeADDBAAction() allocate memory failed \n"));
116                         return;
117                 }
118                 // 1. find entry
119                 Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
120                 if (Idx == 0)
121                 {
122                         MlmeFreeMemory(pAd, pOutBuffer);
123                         DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() can't find BAOriEntry \n"));
124                         return;
125                 }
126                 else
127                 {
128                         pBAEntry =&pAd->BATable.BAOriEntry[Idx];
129                 }
130
131                 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
132                 {
133                         if (ADHOC_ON(pAd))
134                                 ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
135                         else
136                                 ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pInfo->pAddr);
137                 }
138
139                 Frame.Category = CATEGORY_BA;
140                 Frame.Action = ADDBA_REQ;
141                 Frame.BaParm.AMSDUSupported = 0;
142                 Frame.BaParm.BAPolicy = IMMED_BA;
143                 Frame.BaParm.TID = pInfo->TID;
144                 Frame.BaParm.BufSize = pInfo->BaBufSize;
145                 Frame.Token = pInfo->Token;
146                 Frame.TimeOutValue = pInfo->TimeOutValue;
147                 Frame.BaStartSeq.field.FragNum = 0;
148                 Frame.BaStartSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID];
149
150                 *(USHORT *)(&Frame.BaParm) = cpu2le16(*(USHORT *)(&Frame.BaParm));
151                 Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue);
152                 Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word);
153
154                 MakeOutgoingFrame(pOutBuffer,              &FrameLen,
155                               sizeof(FRAME_ADDBA_REQ), &Frame,
156                               END_OF_ARGS);
157                 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
158                 MlmeFreeMemory(pAd, pOutBuffer);
159
160                 DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x,  FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize));
161     }
162 }
163
164 /*
165     ==========================================================================
166     Description:
167         send DELBA and delete BaEntry if any
168     Parametrs:
169         Elem - MLME message MLME_DELBA_REQ_STRUCT
170
171         IRQL = DISPATCH_LEVEL
172
173     ==========================================================================
174  */
175 VOID MlmeDELBAAction(
176     IN PRTMP_ADAPTER pAd,
177     IN MLME_QUEUE_ELEM *Elem)
178 {
179         MLME_DELBA_REQ_STRUCT *pInfo;
180         PUCHAR         pOutBuffer = NULL;
181         PUCHAR             pOutBuffer2 = NULL;
182         NDIS_STATUS     NStatus;
183         ULONG           Idx;
184         FRAME_DELBA_REQ  Frame;
185         ULONG           FrameLen;
186         FRAME_BAR       FrameBar;
187
188         pInfo = (MLME_DELBA_REQ_STRUCT *)Elem->Msg;
189         // must send back DELBA
190         NdisZeroMemory(&Frame, sizeof(FRAME_DELBA_REQ));
191         DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator));
192
193         if(MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen))
194         {
195                 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
196                 if(NStatus != NDIS_STATUS_SUCCESS)
197                 {
198                         DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
199                         return;
200                 }
201
202                 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2);  //Get an unused nonpaged memory
203                 if(NStatus != NDIS_STATUS_SUCCESS)
204                 {
205                         MlmeFreeMemory(pAd, pOutBuffer);
206                         DBGPRINT(RT_DEBUG_ERROR, ("BA - MlmeDELBAAction() allocate memory failed 2. \n"));
207                         return;
208                 }
209
210                 // SEND BAR (Send BAR to refresh peer reordering buffer.)
211                 Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
212
213                 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
214                         BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress);
215
216                 FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL funciton.
217                 FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; // make sure sequence not clear in DEL funciton.
218                 FrameBar.BarControl.TID = pInfo->TID; // make sure sequence not clear in DEL funciton.
219                 FrameBar.BarControl.ACKPolicy = IMMED_BA; // make sure sequence not clear in DEL funciton.
220                 FrameBar.BarControl.Compressed = 1; // make sure sequence not clear in DEL funciton.
221                 FrameBar.BarControl.MTID = 0; // make sure sequence not clear in DEL funciton.
222
223                 MakeOutgoingFrame(pOutBuffer2,                          &FrameLen,
224                                           sizeof(FRAME_BAR),      &FrameBar,
225                                           END_OF_ARGS);
226                 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
227                 MlmeFreeMemory(pAd, pOutBuffer2);
228                 DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
229
230                 // SEND DELBA FRAME
231                 FrameLen = 0;
232
233                 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
234                 {
235                         if (ADHOC_ON(pAd))
236                                 ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
237                         else
238                                 ActHeaderInit(pAd, &Frame.Hdr,  pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[pInfo->Wcid].Addr);
239                 }
240
241                 Frame.Category = CATEGORY_BA;
242                 Frame.Action = DELBA;
243                 Frame.DelbaParm.Initiator = pInfo->Initiator;
244                 Frame.DelbaParm.TID = pInfo->TID;
245                 Frame.ReasonCode = 39; // Time Out
246                 *(USHORT *)(&Frame.DelbaParm) = cpu2le16(*(USHORT *)(&Frame.DelbaParm));
247                 Frame.ReasonCode = cpu2le16(Frame.ReasonCode);
248
249                 MakeOutgoingFrame(pOutBuffer,               &FrameLen,
250                               sizeof(FRAME_DELBA_REQ),    &Frame,
251                               END_OF_ARGS);
252                 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
253                 MlmeFreeMemory(pAd, pOutBuffer);
254                 DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator));
255         }
256 }
257 #endif // DOT11_N_SUPPORT //
258
259 VOID MlmeQOSAction(
260     IN PRTMP_ADAPTER pAd,
261     IN MLME_QUEUE_ELEM *Elem)
262 {
263 }
264
265 VOID MlmeDLSAction(
266     IN PRTMP_ADAPTER pAd,
267     IN MLME_QUEUE_ELEM *Elem)
268 {
269 }
270
271 VOID MlmeInvalidAction(
272     IN PRTMP_ADAPTER pAd,
273     IN MLME_QUEUE_ELEM *Elem)
274 {
275         //PUCHAR                   pOutBuffer = NULL;
276         //Return the receiving frame except the MSB of category filed set to 1.  7.3.1.11
277 }
278
279 VOID PeerQOSAction(
280         IN PRTMP_ADAPTER pAd,
281         IN MLME_QUEUE_ELEM *Elem)
282 {
283 }
284
285 #ifdef DOT11_N_SUPPORT
286 VOID PeerBAAction(
287         IN PRTMP_ADAPTER pAd,
288         IN MLME_QUEUE_ELEM *Elem)
289 {
290         UCHAR   Action = Elem->Msg[LENGTH_802_11+1];
291
292         switch(Action)
293         {
294                 case ADDBA_REQ:
295                         PeerAddBAReqAction(pAd,Elem);
296                         break;
297                 case ADDBA_RESP:
298                         PeerAddBARspAction(pAd,Elem);
299                         break;
300                 case DELBA:
301                         PeerDelBAAction(pAd,Elem);
302                         break;
303         }
304 }
305 #endif // DOT11_N_SUPPORT //
306
307 VOID PeerPublicAction(
308         IN PRTMP_ADAPTER pAd,
309         IN MLME_QUEUE_ELEM *Elem)
310 {
311         if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
312                 return;
313 }
314
315
316 static VOID ReservedAction(
317         IN PRTMP_ADAPTER pAd,
318         IN MLME_QUEUE_ELEM *Elem)
319 {
320         UCHAR Category;
321
322         if (Elem->MsgLen <= LENGTH_802_11)
323         {
324                 return;
325         }
326
327         Category = Elem->Msg[LENGTH_802_11];
328         DBGPRINT(RT_DEBUG_TRACE,("Rcv reserved category(%d) Action Frame\n", Category));
329         hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen);
330 }
331
332 VOID PeerRMAction(
333         IN PRTMP_ADAPTER pAd,
334         IN MLME_QUEUE_ELEM *Elem)
335
336 {
337         return;
338 }
339
340 #ifdef DOT11_N_SUPPORT
341 static VOID respond_ht_information_exchange_action(
342         IN PRTMP_ADAPTER pAd,
343         IN MLME_QUEUE_ELEM *Elem)
344 {
345         PUCHAR                  pOutBuffer = NULL;
346         NDIS_STATUS             NStatus;
347         ULONG                   FrameLen;
348         FRAME_HT_INFO   HTINFOframe, *pFrame;
349         UCHAR                   *pAddr;
350
351
352         // 2. Always send back ADDBA Response
353         NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
354
355         if (NStatus != NDIS_STATUS_SUCCESS)
356         {
357                 DBGPRINT(RT_DEBUG_TRACE,("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
358                 return;
359         }
360
361         // get RA
362         pFrame = (FRAME_HT_INFO *) &Elem->Msg[0];
363         pAddr = pFrame->Hdr.Addr2;
364
365         NdisZeroMemory(&HTINFOframe, sizeof(FRAME_HT_INFO));
366         // 2-1. Prepare ADDBA Response frame.
367         IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
368         {
369                 if (ADHOC_ON(pAd))
370                         ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
371                 else
372                         ActHeaderInit(pAd, &HTINFOframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
373         }
374
375         HTINFOframe.Category = CATEGORY_HT;
376         HTINFOframe.Action = HT_INFO_EXCHANGE;
377         HTINFOframe.HT_Info.Request = 0;
378         HTINFOframe.HT_Info.Forty_MHz_Intolerant = pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant;
379         HTINFOframe.HT_Info.STA_Channel_Width    = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
380
381         MakeOutgoingFrame(pOutBuffer,                                   &FrameLen,
382                                           sizeof(FRAME_HT_INFO),        &HTINFOframe,
383                                           END_OF_ARGS);
384
385         MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
386         MlmeFreeMemory(pAd, pOutBuffer);
387 }
388
389 VOID PeerHTAction(
390         IN PRTMP_ADAPTER pAd,
391         IN MLME_QUEUE_ELEM *Elem)
392 {
393         UCHAR   Action = Elem->Msg[LENGTH_802_11+1];
394
395         if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
396                 return;
397
398         switch(Action)
399         {
400                 case NOTIFY_BW_ACTION:
401                         DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Notify Channel bandwidth action----> \n"));
402
403                         if(pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
404                         {
405                                 // Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps
406                                 // sending BW_Notify Action frame, and cause us to linkup and linkdown.
407                                 // In legacy mode, don't need to parse HT action frame.
408                                 DBGPRINT(RT_DEBUG_TRACE,("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
409                                                                 Elem->Msg[LENGTH_802_11+2] ));
410                                 break;
411                         }
412
413                         if (Elem->Msg[LENGTH_802_11+2] == 0)    // 7.4.8.2. if value is 1, keep the same as supported channel bandwidth.
414                                 pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0;
415
416                         break;
417                 case SMPS_ACTION:
418                         // 7.3.1.25
419                         DBGPRINT(RT_DEBUG_TRACE,("ACTION - SMPS action----> \n"));
420                         if (((Elem->Msg[LENGTH_802_11+2]&0x1) == 0))
421                         {
422                                 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
423                         }
424                         else if (((Elem->Msg[LENGTH_802_11+2]&0x2) == 0))
425                         {
426                                 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
427                         }
428                         else
429                         {
430                                 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
431                         }
432
433                         DBGPRINT(RT_DEBUG_TRACE,("Aid(%d) MIMO PS = %d\n", Elem->Wcid, pAd->MacTab.Content[Elem->Wcid].MmpsMode));
434                         // rt2860c : add something for smps change.
435                         break;
436
437                 case SETPCO_ACTION:
438                         break;
439                 case MIMO_CHA_MEASURE_ACTION:
440                         break;
441                 case HT_INFO_EXCHANGE:
442                         {
443                                 HT_INFORMATION_OCTET    *pHT_info;
444
445                                 pHT_info = (HT_INFORMATION_OCTET *) &Elem->Msg[LENGTH_802_11+2];
446                                 // 7.4.8.10
447                                 DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Information Exchange action----> \n"));
448                                 if (pHT_info->Request)
449                                 {
450                                         respond_ht_information_exchange_action(pAd, Elem);
451                                 }
452                         }
453                         break;
454         }
455 }
456
457
458 /*
459         ==========================================================================
460         Description:
461                 Retry sending ADDBA Reqest.
462
463         IRQL = DISPATCH_LEVEL
464
465         Parametrs:
466         p8023Header: if this is already 802.3 format, p8023Header is NULL
467
468         Return  : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
469                                 FALSE , then continue indicaterx at this moment.
470         ==========================================================================
471  */
472 VOID ORIBATimerTimeout(
473         IN      PRTMP_ADAPTER   pAd)
474 {
475         MAC_TABLE_ENTRY *pEntry;
476         INT                     i, total;
477         UCHAR                   TID;
478
479         total = pAd->MacTab.Size * NUM_OF_TID;
480
481         for (i = 1; ((i <MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)) ; i++)
482         {
483                 if  (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done)
484                 {
485                         pEntry = &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].Wcid];
486                         TID = pAd->BATable.BAOriEntry[i].TID;
487
488                         ASSERT(pAd->BATable.BAOriEntry[i].Wcid < MAX_LEN_OF_MAC_TABLE);
489                 }
490                 total --;
491         }
492 }
493
494
495 VOID SendRefreshBAR(
496         IN      PRTMP_ADAPTER   pAd,
497         IN      MAC_TABLE_ENTRY *pEntry)
498 {
499         FRAME_BAR               FrameBar;
500         ULONG                   FrameLen;
501         NDIS_STATUS     NStatus;
502         PUCHAR                  pOutBuffer = NULL;
503         USHORT                  Sequence;
504         UCHAR                   i, TID;
505         USHORT                  idx;
506         BA_ORI_ENTRY    *pBAEntry;
507
508         for (i = 0; i <NUM_OF_TID; i++)
509         {
510                 idx = pEntry->BAOriWcidArray[i];
511                 if (idx == 0)
512                 {
513                         continue;
514                 }
515                 pBAEntry = &pAd->BATable.BAOriEntry[idx];
516
517                 if  (pBAEntry->ORI_BA_Status == Originator_Done)
518                 {
519                         TID = pBAEntry->TID;
520
521                         ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE);
522
523                         NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
524                         if(NStatus != NDIS_STATUS_SUCCESS)
525                         {
526                                 DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
527                                 return;
528                         }
529
530                         Sequence = pEntry->TxSeq[TID];
531
532                         IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
533                                 BarHeaderInit(pAd, &FrameBar, pEntry->Addr, pAd->CurrentAddress);
534
535                         FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
536                         FrameBar.StartingSeq.field.StartSeq = Sequence; // make sure sequence not clear in DEL funciton.
537                         FrameBar.BarControl.TID = TID; // make sure sequence not clear in DEL funciton.
538
539                         MakeOutgoingFrame(pOutBuffer,                           &FrameLen,
540                                                           sizeof(FRAME_BAR),      &FrameBar,
541                                                           END_OF_ARGS);
542                         if (1)  // Now we always send BAR.
543                         {
544                                 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
545                         }
546                         MlmeFreeMemory(pAd, pOutBuffer);
547                 }
548         }
549 }
550 #endif // DOT11_N_SUPPORT //
551
552 VOID ActHeaderInit(
553     IN  PRTMP_ADAPTER   pAd,
554     IN OUT PHEADER_802_11 pHdr80211,
555     IN PUCHAR Addr1,
556     IN PUCHAR Addr2,
557     IN PUCHAR Addr3)
558 {
559     NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
560     pHdr80211->FC.Type = BTYPE_MGMT;
561     pHdr80211->FC.SubType = SUBTYPE_ACTION;
562
563     COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
564         COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
565     COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
566 }
567
568 VOID BarHeaderInit(
569         IN      PRTMP_ADAPTER   pAd,
570         IN OUT PFRAME_BAR pCntlBar,
571         IN PUCHAR pDA,
572         IN PUCHAR pSA)
573 {
574         NdisZeroMemory(pCntlBar, sizeof(FRAME_BAR));
575         pCntlBar->FC.Type = BTYPE_CNTL;
576         pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ;
577         pCntlBar->BarControl.MTID = 0;
578         pCntlBar->BarControl.Compressed = 1;
579         pCntlBar->BarControl.ACKPolicy = 0;
580
581
582         pCntlBar->Duration = 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(FRAME_BA));
583
584         COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
585         COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
586 }
587
588
589 /*
590         ==========================================================================
591         Description:
592                 Insert Category and action code into the action frame.
593
594         Parametrs:
595                 1. frame buffer pointer.
596                 2. frame length.
597                 3. category code of the frame.
598                 4. action code of the frame.
599
600         Return  : None.
601         ==========================================================================
602  */
603 VOID InsertActField(
604         IN PRTMP_ADAPTER pAd,
605         OUT PUCHAR pFrameBuf,
606         OUT PULONG pFrameLen,
607         IN UINT8 Category,
608         IN UINT8 ActCode)
609 {
610         ULONG TempLen;
611
612         MakeOutgoingFrame(      pFrameBuf,              &TempLen,
613                                                 1,                              &Category,
614                                                 1,                              &ActCode,
615                                                 END_OF_ARGS);
616
617         *pFrameLen = *pFrameLen + TempLen;
618
619         return;
620 }