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