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