1
/******************************************************************************
2
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
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
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
13
* The full GNU General Public License is included in this distribution in the
14
* file called LICENSE.
16
* Contact Information:
17
* wlanfae <wlanfae@realtek.com>
18
******************************************************************************/
20
#include "rtl819x_BA.h"
21
#ifdef RTK_DMP_PLATFORM
22
#include <linux/usb_setting.h>
25
void ActivateBAEntry(struct rtllib_device* ieee, PBA_RECORD pBA, u16 Time)
29
mod_timer(&pBA->Timer, jiffies + MSECS(Time));
32
void DeActivateBAEntry( struct rtllib_device* ieee, PBA_RECORD pBA)
35
del_timer_sync(&pBA->Timer);
37
u8 TxTsDeleteBA( struct rtllib_device* ieee, PTX_TS_RECORD pTxTs)
39
PBA_RECORD pAdmittedBa = &pTxTs->TxAdmittedBARecord;
40
PBA_RECORD pPendingBa = &pTxTs->TxPendingBARecord;
41
u8 bSendDELBA = false;
43
if(pPendingBa->bValid)
45
DeActivateBAEntry(ieee, pPendingBa);
49
if(pAdmittedBa->bValid)
51
DeActivateBAEntry(ieee, pAdmittedBa);
58
u8 RxTsDeleteBA( struct rtllib_device* ieee, PRX_TS_RECORD pRxTs)
60
PBA_RECORD pBa = &pRxTs->RxAdmittedBARecord;
61
u8 bSendDELBA = false;
65
DeActivateBAEntry(ieee, pBa);
72
void ResetBaEntry( PBA_RECORD pBA)
75
pBA->BaParamSet.shortData = 0;
76
pBA->BaTimeoutValue = 0;
78
pBA->BaStartSeqCtrl.ShortData = 0;
80
static struct sk_buff* rtllib_ADDBA(struct rtllib_device* ieee, u8* Dst, PBA_RECORD pBA, u16 StatusCode, u8 type)
82
struct sk_buff *skb = NULL;
83
struct rtllib_hdr_3addr* BAReq = NULL;
86
u16 len = ieee->tx_headroom + 9;
87
RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __FUNCTION__, type, MAC_ARG(Dst), ieee->dev);
88
if (pBA == NULL||ieee == NULL)
90
RTLLIB_DEBUG(RTLLIB_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
93
#ifdef USB_USE_ALIGNMENT
96
skb = dev_alloc_skb(len + sizeof( struct rtllib_hdr_3addr) + USB_512B_ALIGNMENT_SIZE);
98
skb = dev_alloc_skb(len + sizeof( struct rtllib_hdr_3addr));
102
RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
106
memset(skb->data, 0, sizeof( struct rtllib_hdr_3addr));
108
#ifdef USB_USE_ALIGNMENT
109
Tmpaddr = (u32)skb->data;
110
alignment = Tmpaddr & 0x1ff;
111
skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
114
skb_reserve(skb, ieee->tx_headroom);
116
BAReq = ( struct rtllib_hdr_3addr *) skb_put(skb,sizeof( struct rtllib_hdr_3addr));
118
memcpy(BAReq->addr1, Dst, ETH_ALEN);
119
memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN);
121
memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN);
123
BAReq->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT);
125
tag = (u8*)skb_put(skb, 9);
128
*tag ++= pBA->DialogToken;
130
if (ACT_ADDBARSP == type)
132
printk("====>to send ADDBARSP\n");
133
tmp = cpu_to_le16(StatusCode);
134
memcpy(tag, (u8*)&tmp, 2);
137
tmp = cpu_to_le16(pBA->BaParamSet.shortData);
138
memcpy(tag, (u8*)&tmp, 2);
140
tmp = cpu_to_le16(pBA->BaTimeoutValue);
141
memcpy(tag, (u8*)&tmp, 2);
144
if (ACT_ADDBAREQ == type)
146
memcpy(tag,(u8*)&(pBA->BaStartSeqCtrl), 2);
150
RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len);
154
static struct sk_buff* rtllib_DELBA(
155
struct rtllib_device* ieee,
158
TR_SELECT TxRxSelect,
162
DELBA_PARAM_SET DelbaParamSet;
163
struct sk_buff *skb = NULL;
164
struct rtllib_hdr_3addr* Delba = NULL;
167
u16 len = 6 + ieee->tx_headroom;
170
RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __FUNCTION__, ReasonCode, MAC_ARG(dst));
172
memset(&DelbaParamSet, 0, 2);
174
DelbaParamSet.field.Initiator = (TxRxSelect==TX_DIR)?1:0;
175
DelbaParamSet.field.TID = pBA->BaParamSet.field.TID;
177
#ifdef USB_USE_ALIGNMENT
180
skb = dev_alloc_skb(len + sizeof( struct rtllib_hdr_3addr) + USB_512B_ALIGNMENT_SIZE);
182
skb = dev_alloc_skb(len + sizeof( struct rtllib_hdr_3addr));
186
RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
190
#ifdef USB_USE_ALIGNMENT
191
Tmpaddr = (u32)skb->data;
192
alignment = Tmpaddr & 0x1ff;
193
skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
195
skb_reserve(skb, ieee->tx_headroom);
197
Delba = ( struct rtllib_hdr_3addr *) skb_put(skb,sizeof( struct rtllib_hdr_3addr));
199
memcpy(Delba->addr1, dst, ETH_ALEN);
200
memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN);
201
memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN);
202
Delba->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT);
204
tag = (u8*)skb_put(skb, 6);
209
tmp = cpu_to_le16(DelbaParamSet.shortData);
210
memcpy(tag, (u8*)&tmp, 2);
212
tmp = cpu_to_le16(ReasonCode);
213
memcpy(tag, (u8*)&tmp, 2);
216
RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len);
218
RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "<=====%s()\n", __FUNCTION__);
222
void rtllib_send_ADDBAReq(struct rtllib_device* ieee, u8* dst, PBA_RECORD pBA)
224
struct sk_buff *skb = NULL;
225
skb = rtllib_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ);
229
printk("====>to send ADDBAREQ!!!!!\n");
230
softmac_mgmt_xmit(skb, ieee);
234
RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
239
void rtllib_send_ADDBARsp(struct rtllib_device* ieee, u8* dst, PBA_RECORD pBA, u16 StatusCode)
241
struct sk_buff *skb = NULL;
242
skb = rtllib_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP);
245
softmac_mgmt_xmit(skb, ieee);
249
RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
256
void rtllib_send_DELBA(struct rtllib_device* ieee, u8* dst, PBA_RECORD pBA, TR_SELECT TxRxSelect, u16 ReasonCode)
258
struct sk_buff *skb = NULL;
259
skb = rtllib_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode);
262
softmac_mgmt_xmit(skb, ieee);
266
RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
271
int rtllib_rx_ADDBAReq( struct rtllib_device* ieee, struct sk_buff *skb)
273
struct rtllib_hdr_3addr* req = NULL;
275
u8 * dst = NULL, *pDialogToken = NULL, *tag = NULL;
276
PBA_RECORD pBA = NULL;
277
PBA_PARAM_SET pBaParamSet = NULL;
278
u16* pBaTimeoutVal = NULL;
279
PSEQUENCE_CONTROL pBaStartSeqCtrl = NULL;
280
PRX_TS_RECORD pTS = NULL;
282
if (skb->len < sizeof( struct rtllib_hdr_3addr) + 9)
284
RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in BAREQ(%d / %d)\n",(int)skb->len, (int)(sizeof( struct rtllib_hdr_3addr) + 9));
288
RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len);
290
req = ( struct rtllib_hdr_3addr*) skb->data;
292
dst = (u8*)(&req->addr2[0]);
293
tag += sizeof( struct rtllib_hdr_3addr);
294
pDialogToken = tag + 2;
295
pBaParamSet = (PBA_PARAM_SET)(tag + 3);
296
pBaTimeoutVal = (u16*)(tag + 5);
297
pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
299
printk("====>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst));
301
#ifdef _RTL8192_EXT_PATCH_
302
(ieee->current_network.qos_data.active == 0 && ieee->current_mesh_network.qos_data.active==0) ||
304
ieee->current_network.qos_data.active == 0 ||
306
(ieee->pHTInfo->bCurrentHTSupport == false) ||
307
(ieee->pHTInfo->IOTAction & HT_IOT_ACT_REJECT_ADDBA_REQ))
309
rc = ADDBA_STATUS_REFUSED;
310
RTLLIB_DEBUG(RTLLIB_DL_ERR, "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
311
goto OnADDBAReq_Fail;
315
(PTS_COMMON_INFO*)(&pTS),
317
(u8)(pBaParamSet->field.TID),
321
rc = ADDBA_STATUS_REFUSED;
322
RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS in %s()\n", __FUNCTION__);
323
goto OnADDBAReq_Fail;
325
pBA = &pTS->RxAdmittedBARecord;
327
if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED)
329
rc = ADDBA_STATUS_INVALID_PARAM;
330
RTLLIB_DEBUG(RTLLIB_DL_ERR, "BA Policy is not correct in %s()\n", __FUNCTION__);
331
goto OnADDBAReq_Fail;
335
rtllib_FlushRxTsPendingPkts(ieee, pTS);
337
DeActivateBAEntry(ieee, pBA);
338
pBA->DialogToken = *pDialogToken;
339
pBA->BaParamSet = *pBaParamSet;
340
pBA->BaTimeoutValue = *pBaTimeoutVal;
341
pBA->BaStartSeqCtrl = *pBaStartSeqCtrl;
343
if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)||
344
(ieee->pHTInfo->IOTAction & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT))
345
pBA->BaParamSet.field.BufferSize = 1;
347
pBA->BaParamSet.field.BufferSize = 32;
349
ActivateBAEntry(ieee, pBA, 0);
350
rtllib_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS);
357
BA.BaParamSet = *pBaParamSet;
358
BA.BaTimeoutValue = *pBaTimeoutVal;
359
BA.DialogToken = *pDialogToken;
360
BA.BaParamSet.field.BAPolicy = BA_POLICY_IMMEDIATE;
361
rtllib_send_ADDBARsp(ieee, dst, &BA, rc);
367
int rtllib_rx_ADDBARsp( struct rtllib_device* ieee, struct sk_buff *skb)
369
struct rtllib_hdr_3addr* rsp = NULL;
370
PBA_RECORD pPendingBA, pAdmittedBA;
371
PTX_TS_RECORD pTS = NULL;
372
u8* dst = NULL, *pDialogToken = NULL, *tag = NULL;
373
u16* pStatusCode = NULL, *pBaTimeoutVal = NULL;
374
PBA_PARAM_SET pBaParamSet = NULL;
377
if (skb->len < sizeof( struct rtllib_hdr_3addr) + 9)
379
RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in BARSP(%d / %d)\n", (int)skb->len, (int)(sizeof( struct rtllib_hdr_3addr) + 9));
382
rsp = ( struct rtllib_hdr_3addr*)skb->data;
384
dst = (u8*)(&rsp->addr2[0]);
385
tag += sizeof( struct rtllib_hdr_3addr);
386
pDialogToken = tag + 2;
387
pStatusCode = (u16*)(tag + 3);
388
pBaParamSet = (PBA_PARAM_SET)(tag + 5);
389
pBaTimeoutVal = (u16*)(tag + 7);
391
printk("====>rx ADDBARSP from :"MAC_FMT"\n", MAC_ARG(dst));
393
#ifdef _RTL8192_EXT_PATCH_
394
(ieee->current_network.qos_data.active == 0 && ieee->current_mesh_network.qos_data.active==0) ||
396
ieee->current_network.qos_data.active == 0 ||
398
ieee->pHTInfo->bCurrentHTSupport == false ||
399
ieee->pHTInfo->bCurrentAMPDUEnable == false )
401
RTLLIB_DEBUG(RTLLIB_DL_ERR, "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bCurrentAMPDUEnable);
402
ReasonCode = DELBA_REASON_UNKNOWN_BA;
403
goto OnADDBARsp_Reject;
409
(PTS_COMMON_INFO*)(&pTS),
411
(u8)(pBaParamSet->field.TID),
415
RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS in %s()\n", __FUNCTION__);
416
ReasonCode = DELBA_REASON_UNKNOWN_BA;
417
goto OnADDBARsp_Reject;
420
pTS->bAddBaReqInProgress = false;
421
pPendingBA = &pTS->TxPendingBARecord;
422
pAdmittedBA = &pTS->TxAdmittedBARecord;
425
if((pAdmittedBA->bValid==true))
427
RTLLIB_DEBUG(RTLLIB_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n");
430
else if((pPendingBA->bValid == false) ||(*pDialogToken != pPendingBA->DialogToken))
432
RTLLIB_DEBUG(RTLLIB_DL_ERR, "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n");
433
ReasonCode = DELBA_REASON_UNKNOWN_BA;
434
goto OnADDBARsp_Reject;
438
RTLLIB_DEBUG(RTLLIB_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", *pStatusCode);
439
DeActivateBAEntry(ieee, pPendingBA);
443
if(*pStatusCode == ADDBA_STATUS_SUCCESS)
445
if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED)
447
pTS->bAddBaReqDelayed = true;
448
DeActivateBAEntry(ieee, pAdmittedBA);
449
ReasonCode = DELBA_REASON_END_BA;
450
goto OnADDBARsp_Reject;
454
pAdmittedBA->DialogToken = *pDialogToken;
455
pAdmittedBA->BaTimeoutValue = *pBaTimeoutVal;
456
pAdmittedBA->BaStartSeqCtrl = pPendingBA->BaStartSeqCtrl;
457
pAdmittedBA->BaParamSet = *pBaParamSet;
458
DeActivateBAEntry(ieee, pAdmittedBA);
459
ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal);
461
pTS->bAddBaReqDelayed = true;
462
pTS->bDisable_AddBa = true;
463
ReasonCode = DELBA_REASON_END_BA;
464
goto OnADDBARsp_Reject;
472
BA.BaParamSet = *pBaParamSet;
473
rtllib_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode);
479
int rtllib_rx_DELBA(struct rtllib_device* ieee,struct sk_buff *skb)
481
struct rtllib_hdr_3addr* delba = NULL;
482
PDELBA_PARAM_SET pDelBaParamSet = NULL;
483
u16* pReasonCode = NULL;
486
if (skb->len < sizeof( struct rtllib_hdr_3addr) + 6)
488
RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in DELBA(%d / %d)\n", (int)skb->len, (int)(sizeof( struct rtllib_hdr_3addr) + 6));
493
#ifdef _RTL8192_EXT_PATCH_
494
(ieee->current_network.qos_data.active == 0 && ieee->current_mesh_network.qos_data.active==0) ||
496
ieee->current_network.qos_data.active == 0 ||
498
ieee->pHTInfo->bCurrentHTSupport == false )
500
RTLLIB_DEBUG(RTLLIB_DL_ERR, "received DELBA while QOS or HT is not supported(%d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
504
RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len);
505
delba = ( struct rtllib_hdr_3addr*)skb->data;
506
dst = (u8*)(&delba->addr2[0]);
507
delba += sizeof( struct rtllib_hdr_3addr);
508
pDelBaParamSet = (PDELBA_PARAM_SET)(delba+2);
509
pReasonCode = (u16*)(delba+4);
511
if(pDelBaParamSet->field.Initiator == 1)
517
(PTS_COMMON_INFO*)&pRxTs,
519
(u8)pDelBaParamSet->field.TID,
523
RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS for RXTS in %s().dsf:"MAC_FMT" TID:%d\n", __FUNCTION__, MAC_ARG(dst), (u8)pDelBaParamSet->field.TID);
527
RxTsDeleteBA(ieee, pRxTs);
535
(PTS_COMMON_INFO*)&pTxTs,
537
(u8)pDelBaParamSet->field.TID,
541
RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS for TXTS in %s()\n", __FUNCTION__);
545
pTxTs->bUsingBa = false;
546
pTxTs->bAddBaReqInProgress = false;
547
pTxTs->bAddBaReqDelayed = false;
548
del_timer_sync(&pTxTs->TsAddBaTimer);
549
TxTsDeleteBA(ieee, pTxTs);
556
struct rtllib_device* ieee,
562
PBA_RECORD pBA = &pTS->TxPendingBARecord;
564
if(pBA->bValid==true && bOverwritePending==false)
567
DeActivateBAEntry(ieee, pBA);
570
pBA->BaParamSet.field.AMSDU_Support = 0;
571
pBA->BaParamSet.field.BAPolicy = Policy;
572
pBA->BaParamSet.field.TID = pTS->TsCommonInfo.TSpec.f.TSInfo.field.ucTSID;
573
pBA->BaParamSet.field.BufferSize = 32;
574
pBA->BaTimeoutValue = 0;
575
pBA->BaStartSeqCtrl.field.SeqNum = (pTS->TxCurSeq + 3) % 4096;
577
ActivateBAEntry(ieee, pBA, BA_SETUP_TIMEOUT);
579
rtllib_send_ADDBAReq(ieee, pTS->TsCommonInfo.Addr, pBA);
583
TsInitDelBA( struct rtllib_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect)
586
if(TxRxSelect == TX_DIR)
588
PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)pTsCommonInfo;
590
if(TxTsDeleteBA(ieee, pTxTs))
594
(pTxTs->TxAdmittedBARecord.bValid)?(&pTxTs->TxAdmittedBARecord):(&pTxTs->TxPendingBARecord),
596
DELBA_REASON_END_BA);
598
else if(TxRxSelect == RX_DIR)
600
PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)pTsCommonInfo;
601
if(RxTsDeleteBA(ieee, pRxTs))
605
&pRxTs->RxAdmittedBARecord,
607
DELBA_REASON_END_BA );
610
void BaSetupTimeOut(unsigned long data)
612
PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data;
614
pTxTs->bAddBaReqInProgress = false;
615
pTxTs->bAddBaReqDelayed = true;
616
pTxTs->TxPendingBARecord.bValid = false;
619
void TxBaInactTimeout(unsigned long data)
621
PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data;
622
struct rtllib_device *ieee = container_of(pTxTs, struct rtllib_device, TxTsRecord[pTxTs->num]);
623
TxTsDeleteBA(ieee, pTxTs);
626
pTxTs->TsCommonInfo.Addr,
627
&pTxTs->TxAdmittedBARecord,
629
DELBA_REASON_TIMEOUT);
632
void RxBaInactTimeout(unsigned long data)
634
PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)data;
635
struct rtllib_device *ieee = container_of(pRxTs, struct rtllib_device, RxTsRecord[pRxTs->num]);
637
RxTsDeleteBA(ieee, pRxTs);
640
pRxTs->TsCommonInfo.Addr,
641
&pRxTs->RxAdmittedBARecord,
643
DELBA_REASON_TIMEOUT);