linux/drivers/staging/rtl8192e/rtl819x_BAProc.c
<<
>>
Prefs
   1/******************************************************************************
   2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
   3 *
   4 * This program is distributed in the hope that it will be useful, but WITHOUT
   5 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   6 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   7 * more details.
   8 *
   9 * You should have received a copy of the GNU General Public License along with
  10 * this program; if not, write to the Free Software Foundation, Inc.,
  11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  12 *
  13 * The full GNU General Public License is included in this distribution in the
  14 * file called LICENSE.
  15 *
  16 * Contact Information:
  17 * wlanfae <wlanfae@realtek.com>
  18******************************************************************************/
  19#include "rtllib.h"
  20#include "rtl819x_BA.h"
  21
  22static void ActivateBAEntry(struct rtllib_device *ieee, struct ba_record *pBA,
  23                            u16 Time)
  24{
  25        pBA->bValid = true;
  26        if (Time != 0)
  27                mod_timer(&pBA->Timer, jiffies + MSECS(Time));
  28}
  29
  30static void DeActivateBAEntry(struct rtllib_device *ieee, struct ba_record *pBA)
  31{
  32        pBA->bValid = false;
  33        del_timer_sync(&pBA->Timer);
  34}
  35
  36static u8 TxTsDeleteBA(struct rtllib_device *ieee, struct tx_ts_record *pTxTs)
  37{
  38        struct ba_record *pAdmittedBa = &pTxTs->TxAdmittedBARecord;
  39        struct ba_record *pPendingBa = &pTxTs->TxPendingBARecord;
  40        u8 bSendDELBA = false;
  41
  42        if (pPendingBa->bValid) {
  43                DeActivateBAEntry(ieee, pPendingBa);
  44                bSendDELBA = true;
  45        }
  46
  47        if (pAdmittedBa->bValid) {
  48                DeActivateBAEntry(ieee, pAdmittedBa);
  49                bSendDELBA = true;
  50        }
  51        return bSendDELBA;
  52}
  53
  54static u8 RxTsDeleteBA(struct rtllib_device *ieee, struct rx_ts_record *pRxTs)
  55{
  56        struct ba_record *pBa = &pRxTs->RxAdmittedBARecord;
  57        u8                      bSendDELBA = false;
  58
  59        if (pBa->bValid) {
  60                DeActivateBAEntry(ieee, pBa);
  61                bSendDELBA = true;
  62        }
  63
  64        return bSendDELBA;
  65}
  66
  67void ResetBaEntry(struct ba_record *pBA)
  68{
  69        pBA->bValid                     = false;
  70        pBA->BaParamSet.shortData       = 0;
  71        pBA->BaTimeoutValue             = 0;
  72        pBA->DialogToken                = 0;
  73        pBA->BaStartSeqCtrl.ShortData   = 0;
  74}
  75static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst,
  76                                    struct ba_record *pBA,
  77                                    u16 StatusCode, u8 type)
  78{
  79        struct sk_buff *skb = NULL;
  80         struct rtllib_hdr_3addr *BAReq = NULL;
  81        u8 *tag = NULL;
  82        u16 tmp = 0;
  83        u16 len = ieee->tx_headroom + 9;
  84
  85        RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "========>%s(), frame(%d)"
  86                     " sentd to: %pM, ieee->dev:%p\n", __func__,
  87                     type, Dst, ieee->dev);
  88        if (pBA == NULL) {
  89                RTLLIB_DEBUG(RTLLIB_DL_ERR, "pBA is NULL\n");
  90                return NULL;
  91        }
  92        skb = dev_alloc_skb(len + sizeof(struct rtllib_hdr_3addr));
  93        if (skb == NULL) {
  94                RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
  95                return NULL;
  96        }
  97
  98        memset(skb->data, 0, sizeof(struct rtllib_hdr_3addr));
  99
 100        skb_reserve(skb, ieee->tx_headroom);
 101
 102        BAReq = (struct rtllib_hdr_3addr *)skb_put(skb,
 103                 sizeof(struct rtllib_hdr_3addr));
 104
 105        memcpy(BAReq->addr1, Dst, ETH_ALEN);
 106        memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN);
 107
 108        memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN);
 109        BAReq->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT);
 110
 111        tag = (u8 *)skb_put(skb, 9);
 112        *tag ++= ACT_CAT_BA;
 113        *tag ++= type;
 114        *tag ++= pBA->DialogToken;
 115
 116        if (ACT_ADDBARSP == type) {
 117                RT_TRACE(COMP_DBG, "====>to send ADDBARSP\n");
 118                tmp = cpu_to_le16(StatusCode);
 119                memcpy(tag, (u8 *)&tmp, 2);
 120                tag += 2;
 121        }
 122        tmp = cpu_to_le16(pBA->BaParamSet.shortData);
 123        memcpy(tag, (u8 *)&tmp, 2);
 124        tag += 2;
 125        tmp = cpu_to_le16(pBA->BaTimeoutValue);
 126        memcpy(tag, (u8 *)&tmp, 2);
 127        tag += 2;
 128
 129        if (ACT_ADDBAREQ == type) {
 130                memcpy(tag, (u8 *)&(pBA->BaStartSeqCtrl), 2);
 131                tag += 2;
 132        }
 133
 134        RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len);
 135        return skb;
 136}
 137
 138static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst,
 139                                    struct ba_record *pBA,
 140                                    enum tr_select TxRxSelect, u16 ReasonCode)
 141{
 142        union delba_param_set DelbaParamSet;
 143        struct sk_buff *skb = NULL;
 144         struct rtllib_hdr_3addr *Delba = NULL;
 145        u8 *tag = NULL;
 146        u16 tmp = 0;
 147        u16 len = 6 + ieee->tx_headroom;
 148
 149        if (net_ratelimit())
 150                RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA,
 151                             "========>%s(), Reason"
 152                             "Code(%d) sentd to: %pM\n", __func__,
 153                             ReasonCode, dst);
 154
 155        memset(&DelbaParamSet, 0, 2);
 156
 157        DelbaParamSet.field.Initiator = (TxRxSelect == TX_DIR) ? 1 : 0;
 158        DelbaParamSet.field.TID = pBA->BaParamSet.field.TID;
 159
 160        skb = dev_alloc_skb(len + sizeof(struct rtllib_hdr_3addr));
 161        if (skb == NULL) {
 162                RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
 163                return NULL;
 164        }
 165
 166        skb_reserve(skb, ieee->tx_headroom);
 167
 168        Delba = (struct rtllib_hdr_3addr *) skb_put(skb,
 169                 sizeof(struct rtllib_hdr_3addr));
 170
 171        memcpy(Delba->addr1, dst, ETH_ALEN);
 172        memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN);
 173        memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN);
 174        Delba->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT);
 175
 176        tag = (u8 *)skb_put(skb, 6);
 177
 178        *tag ++= ACT_CAT_BA;
 179        *tag ++= ACT_DELBA;
 180
 181        tmp = cpu_to_le16(DelbaParamSet.shortData);
 182        memcpy(tag, (u8 *)&tmp, 2);
 183        tag += 2;
 184        tmp = cpu_to_le16(ReasonCode);
 185        memcpy(tag, (u8 *)&tmp, 2);
 186        tag += 2;
 187
 188        RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len);
 189        if (net_ratelimit())
 190                RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "<=====%s()\n",
 191                             __func__);
 192        return skb;
 193}
 194
 195static void rtllib_send_ADDBAReq(struct rtllib_device *ieee, u8 *dst,
 196                                 struct ba_record *pBA)
 197{
 198        struct sk_buff *skb = NULL;
 199        skb = rtllib_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ);
 200
 201        if (skb) {
 202                RT_TRACE(COMP_DBG, "====>to send ADDBAREQ!!!!!\n");
 203                softmac_mgmt_xmit(skb, ieee);
 204        } else {
 205                RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in function"
 206                             " %s()\n", __func__);
 207        }
 208        return;
 209}
 210
 211static void rtllib_send_ADDBARsp(struct rtllib_device *ieee, u8 *dst,
 212                                 struct ba_record *pBA, u16 StatusCode)
 213{
 214        struct sk_buff *skb = NULL;
 215        skb = rtllib_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP);
 216        if (skb)
 217                softmac_mgmt_xmit(skb, ieee);
 218        else
 219                RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in function"
 220                             " %s()\n", __func__);
 221        return;
 222}
 223
 224static void rtllib_send_DELBA(struct rtllib_device *ieee, u8 *dst,
 225                              struct ba_record *pBA, enum tr_select TxRxSelect,
 226                              u16 ReasonCode)
 227{
 228        struct sk_buff *skb = NULL;
 229        skb = rtllib_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode);
 230        if (skb)
 231                softmac_mgmt_xmit(skb, ieee);
 232        else
 233                RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in func"
 234                             "tion %s()\n", __func__);
 235        return ;
 236}
 237
 238int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb)
 239{
 240        struct rtllib_hdr_3addr *req = NULL;
 241        u16 rc = 0;
 242        u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL;
 243        struct ba_record *pBA = NULL;
 244        union ba_param_set *pBaParamSet = NULL;
 245        u16 *pBaTimeoutVal = NULL;
 246        union sequence_control *pBaStartSeqCtrl = NULL;
 247        struct rx_ts_record *pTS = NULL;
 248
 249        if (skb->len < sizeof(struct rtllib_hdr_3addr) + 9) {
 250                RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in BAREQ(%d / "
 251                             "%d)\n", (int)skb->len,
 252                             (int)(sizeof(struct rtllib_hdr_3addr) + 9));
 253                return -1;
 254        }
 255
 256        RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len);
 257
 258        req = (struct rtllib_hdr_3addr *) skb->data;
 259        tag = (u8 *)req;
 260        dst = (u8 *)(&req->addr2[0]);
 261        tag += sizeof(struct rtllib_hdr_3addr);
 262        pDialogToken = tag + 2;
 263        pBaParamSet = (union ba_param_set *)(tag + 3);
 264        pBaTimeoutVal = (u16 *)(tag + 5);
 265        pBaStartSeqCtrl = (union sequence_control *)(req + 7);
 266
 267        RT_TRACE(COMP_DBG, "====>rx ADDBAREQ from : %pM\n", dst);
 268        if (ieee->current_network.qos_data.active == 0  ||
 269            (ieee->pHTInfo->bCurrentHTSupport == false) ||
 270            (ieee->pHTInfo->IOTAction & HT_IOT_ACT_REJECT_ADDBA_REQ)) {
 271                rc = ADDBA_STATUS_REFUSED;
 272                RTLLIB_DEBUG(RTLLIB_DL_ERR, "Failed to reply on ADDBA_REQ as "
 273                             "some capability is not ready(%d, %d)\n",
 274                             ieee->current_network.qos_data.active,
 275                             ieee->pHTInfo->bCurrentHTSupport);
 276                goto OnADDBAReq_Fail;
 277        }
 278        if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst,
 279            (u8)(pBaParamSet->field.TID), RX_DIR, true)) {
 280                rc = ADDBA_STATUS_REFUSED;
 281                RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS in %s()\n", __func__);
 282                goto OnADDBAReq_Fail;
 283        }
 284        pBA = &pTS->RxAdmittedBARecord;
 285
 286        if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) {
 287                rc = ADDBA_STATUS_INVALID_PARAM;
 288                RTLLIB_DEBUG(RTLLIB_DL_ERR, "BA Policy is not correct in "
 289                             "%s()\n", __func__);
 290                goto OnADDBAReq_Fail;
 291        }
 292
 293        rtllib_FlushRxTsPendingPkts(ieee, pTS);
 294
 295        DeActivateBAEntry(ieee, pBA);
 296        pBA->DialogToken = *pDialogToken;
 297        pBA->BaParamSet = *pBaParamSet;
 298        pBA->BaTimeoutValue = *pBaTimeoutVal;
 299        pBA->BaStartSeqCtrl = *pBaStartSeqCtrl;
 300
 301        if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev) ||
 302           (ieee->pHTInfo->IOTAction & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT))
 303                pBA->BaParamSet.field.BufferSize = 1;
 304        else
 305                pBA->BaParamSet.field.BufferSize = 32;
 306
 307        ActivateBAEntry(ieee, pBA, 0);
 308        rtllib_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS);
 309
 310        return 0;
 311
 312OnADDBAReq_Fail:
 313        {
 314                struct ba_record BA;
 315                BA.BaParamSet = *pBaParamSet;
 316                BA.BaTimeoutValue = *pBaTimeoutVal;
 317                BA.DialogToken = *pDialogToken;
 318                BA.BaParamSet.field.BAPolicy = BA_POLICY_IMMEDIATE;
 319                rtllib_send_ADDBARsp(ieee, dst, &BA, rc);
 320                return 0;
 321        }
 322}
 323
 324int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb)
 325{
 326         struct rtllib_hdr_3addr *rsp = NULL;
 327        struct ba_record *pPendingBA, *pAdmittedBA;
 328        struct tx_ts_record *pTS = NULL;
 329        u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL;
 330        u16 *pStatusCode = NULL, *pBaTimeoutVal = NULL;
 331        union ba_param_set *pBaParamSet = NULL;
 332        u16                     ReasonCode;
 333
 334        if (skb->len < sizeof(struct rtllib_hdr_3addr) + 9) {
 335                RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in BARSP(%d / "
 336                             "%d)\n", (int)skb->len,
 337                             (int)(sizeof(struct rtllib_hdr_3addr) + 9));
 338                return -1;
 339        }
 340        rsp = (struct rtllib_hdr_3addr *)skb->data;
 341        tag = (u8 *)rsp;
 342        dst = (u8 *)(&rsp->addr2[0]);
 343        tag += sizeof(struct rtllib_hdr_3addr);
 344        pDialogToken = tag + 2;
 345        pStatusCode = (u16 *)(tag + 3);
 346        pBaParamSet = (union ba_param_set *)(tag + 5);
 347        pBaTimeoutVal = (u16 *)(tag + 7);
 348
 349        RT_TRACE(COMP_DBG, "====>rx ADDBARSP from : %pM\n", dst);
 350        if (ieee->current_network.qos_data.active == 0  ||
 351            ieee->pHTInfo->bCurrentHTSupport == false ||
 352            ieee->pHTInfo->bCurrentAMPDUEnable == false) {
 353                RTLLIB_DEBUG(RTLLIB_DL_ERR, "reject to ADDBA_RSP as some capab"
 354                             "ility is not ready(%d, %d, %d)\n",
 355                             ieee->current_network.qos_data.active,
 356                             ieee->pHTInfo->bCurrentHTSupport,
 357                             ieee->pHTInfo->bCurrentAMPDUEnable);
 358                ReasonCode = DELBA_REASON_UNKNOWN_BA;
 359                goto OnADDBARsp_Reject;
 360        }
 361
 362
 363        if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst,
 364                   (u8)(pBaParamSet->field.TID), TX_DIR, false)) {
 365                RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS in %s()\n", __func__);
 366                ReasonCode = DELBA_REASON_UNKNOWN_BA;
 367                goto OnADDBARsp_Reject;
 368        }
 369
 370        pTS->bAddBaReqInProgress = false;
 371        pPendingBA = &pTS->TxPendingBARecord;
 372        pAdmittedBA = &pTS->TxAdmittedBARecord;
 373
 374
 375        if ((pAdmittedBA->bValid == true)) {
 376                RTLLIB_DEBUG(RTLLIB_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp."
 377                             " Drop because already admit it!\n");
 378                return -1;
 379        } else if ((pPendingBA->bValid == false) ||
 380                   (*pDialogToken != pPendingBA->DialogToken)) {
 381                RTLLIB_DEBUG(RTLLIB_DL_ERR,  "OnADDBARsp(): Recv ADDBA Rsp. "
 382                             "BA invalid, DELBA!\n");
 383                ReasonCode = DELBA_REASON_UNKNOWN_BA;
 384                goto OnADDBARsp_Reject;
 385        } else {
 386                RTLLIB_DEBUG(RTLLIB_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. BA "
 387                             "is admitted! Status code:%X\n", *pStatusCode);
 388                DeActivateBAEntry(ieee, pPendingBA);
 389        }
 390
 391
 392        if (*pStatusCode == ADDBA_STATUS_SUCCESS) {
 393                if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) {
 394                        pTS->bAddBaReqDelayed = true;
 395                        DeActivateBAEntry(ieee, pAdmittedBA);
 396                        ReasonCode = DELBA_REASON_END_BA;
 397                        goto OnADDBARsp_Reject;
 398                }
 399
 400
 401                pAdmittedBA->DialogToken = *pDialogToken;
 402                pAdmittedBA->BaTimeoutValue = *pBaTimeoutVal;
 403                pAdmittedBA->BaStartSeqCtrl = pPendingBA->BaStartSeqCtrl;
 404                pAdmittedBA->BaParamSet = *pBaParamSet;
 405                DeActivateBAEntry(ieee, pAdmittedBA);
 406                ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal);
 407        } else {
 408                pTS->bAddBaReqDelayed = true;
 409                pTS->bDisable_AddBa = true;
 410                ReasonCode = DELBA_REASON_END_BA;
 411                goto OnADDBARsp_Reject;
 412        }
 413
 414        return 0;
 415
 416OnADDBARsp_Reject:
 417        {
 418                struct ba_record BA;
 419                BA.BaParamSet = *pBaParamSet;
 420                rtllib_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode);
 421                return 0;
 422        }
 423}
 424
 425int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb)
 426{
 427         struct rtllib_hdr_3addr *delba = NULL;
 428        union delba_param_set *pDelBaParamSet = NULL;
 429        u16 *pReasonCode = NULL;
 430        u8 *dst = NULL;
 431
 432        if (skb->len < sizeof(struct rtllib_hdr_3addr) + 6) {
 433                RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in DELBA(%d /"
 434                             " %d)\n", (int)skb->len,
 435                             (int)(sizeof(struct rtllib_hdr_3addr) + 6));
 436                return -1;
 437        }
 438
 439        if (ieee->current_network.qos_data.active == 0  ||
 440                ieee->pHTInfo->bCurrentHTSupport == false) {
 441                RTLLIB_DEBUG(RTLLIB_DL_ERR, "received DELBA while QOS or HT "
 442                             "is not supported(%d, %d)\n",
 443                             ieee->current_network. qos_data.active,
 444                             ieee->pHTInfo->bCurrentHTSupport);
 445                return -1;
 446        }
 447
 448        RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len);
 449        delba = (struct rtllib_hdr_3addr *)skb->data;
 450        dst = (u8 *)(&delba->addr2[0]);
 451        delba += sizeof(struct rtllib_hdr_3addr);
 452        pDelBaParamSet = (union delba_param_set *)(delba+2);
 453        pReasonCode = (u16 *)(delba+4);
 454
 455        if (pDelBaParamSet->field.Initiator == 1) {
 456                struct rx_ts_record *pRxTs;
 457
 458                if (!GetTs(ieee, (struct ts_common_info **)&pRxTs, dst,
 459                    (u8)pDelBaParamSet->field.TID, RX_DIR, false)) {
 460                        RTLLIB_DEBUG(RTLLIB_DL_ERR,  "can't get TS for RXTS in "
 461                                     "%s().dst: %pM TID:%d\n", __func__, dst,
 462                                     (u8)pDelBaParamSet->field.TID);
 463                        return -1;
 464                }
 465
 466                RxTsDeleteBA(ieee, pRxTs);
 467        } else {
 468                struct tx_ts_record *pTxTs;
 469
 470                if (!GetTs(ieee, (struct ts_common_info **)&pTxTs, dst,
 471                           (u8)pDelBaParamSet->field.TID, TX_DIR, false)) {
 472                        RTLLIB_DEBUG(RTLLIB_DL_ERR,  "can't get TS for TXTS in "
 473                                     "%s()\n", __func__);
 474                        return -1;
 475                }
 476
 477                pTxTs->bUsingBa = false;
 478                pTxTs->bAddBaReqInProgress = false;
 479                pTxTs->bAddBaReqDelayed = false;
 480                del_timer_sync(&pTxTs->TsAddBaTimer);
 481                TxTsDeleteBA(ieee, pTxTs);
 482        }
 483        return 0;
 484}
 485
 486void TsInitAddBA(struct rtllib_device *ieee, struct tx_ts_record *pTS,
 487                 u8 Policy, u8  bOverwritePending)
 488{
 489        struct ba_record *pBA = &pTS->TxPendingBARecord;
 490
 491        if (pBA->bValid == true && bOverwritePending == false)
 492                return;
 493
 494        DeActivateBAEntry(ieee, pBA);
 495
 496        pBA->DialogToken++;
 497        pBA->BaParamSet.field.AMSDU_Support = 0;
 498        pBA->BaParamSet.field.BAPolicy = Policy;
 499        pBA->BaParamSet.field.TID =
 500                         pTS->TsCommonInfo.TSpec.f.TSInfo.field.ucTSID;
 501        pBA->BaParamSet.field.BufferSize = 32;
 502        pBA->BaTimeoutValue = 0;
 503        pBA->BaStartSeqCtrl.field.SeqNum = (pTS->TxCurSeq + 3) % 4096;
 504
 505        ActivateBAEntry(ieee, pBA, BA_SETUP_TIMEOUT);
 506
 507        rtllib_send_ADDBAReq(ieee, pTS->TsCommonInfo.Addr, pBA);
 508}
 509
 510void TsInitDelBA(struct rtllib_device *ieee,
 511                 struct ts_common_info *pTsCommonInfo,
 512                 enum tr_select TxRxSelect)
 513{
 514        if (TxRxSelect == TX_DIR) {
 515                struct tx_ts_record *pTxTs =
 516                         (struct tx_ts_record *)pTsCommonInfo;
 517
 518                if (TxTsDeleteBA(ieee, pTxTs))
 519                        rtllib_send_DELBA(ieee, pTsCommonInfo->Addr,
 520                                          (pTxTs->TxAdmittedBARecord.bValid) ?
 521                                         (&pTxTs->TxAdmittedBARecord) :
 522                                        (&pTxTs->TxPendingBARecord),
 523                                         TxRxSelect, DELBA_REASON_END_BA);
 524        } else if (TxRxSelect == RX_DIR) {
 525                struct rx_ts_record *pRxTs =
 526                                 (struct rx_ts_record *)pTsCommonInfo;
 527                if (RxTsDeleteBA(ieee, pRxTs))
 528                        rtllib_send_DELBA(ieee, pTsCommonInfo->Addr,
 529                                          &pRxTs->RxAdmittedBARecord,
 530                                          TxRxSelect, DELBA_REASON_END_BA);
 531        }
 532}
 533
 534void BaSetupTimeOut(unsigned long data)
 535{
 536        struct tx_ts_record *pTxTs = (struct tx_ts_record *)data;
 537
 538        pTxTs->bAddBaReqInProgress = false;
 539        pTxTs->bAddBaReqDelayed = true;
 540        pTxTs->TxPendingBARecord.bValid = false;
 541}
 542
 543void TxBaInactTimeout(unsigned long data)
 544{
 545        struct tx_ts_record *pTxTs = (struct tx_ts_record *)data;
 546        struct rtllib_device *ieee = container_of(pTxTs, struct rtllib_device,
 547                                     TxTsRecord[pTxTs->num]);
 548        TxTsDeleteBA(ieee, pTxTs);
 549        rtllib_send_DELBA(ieee, pTxTs->TsCommonInfo.Addr,
 550                          &pTxTs->TxAdmittedBARecord, TX_DIR,
 551                          DELBA_REASON_TIMEOUT);
 552}
 553
 554void RxBaInactTimeout(unsigned long data)
 555{
 556        struct rx_ts_record *pRxTs = (struct rx_ts_record *)data;
 557        struct rtllib_device *ieee = container_of(pRxTs, struct rtllib_device,
 558                                     RxTsRecord[pRxTs->num]);
 559
 560        RxTsDeleteBA(ieee, pRxTs);
 561        rtllib_send_DELBA(ieee, pRxTs->TsCommonInfo.Addr,
 562                          &pRxTs->RxAdmittedBARecord, RX_DIR,
 563                          DELBA_REASON_TIMEOUT);
 564        return ;
 565}
 566