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