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