rtl819x_BAProc.c revision 8cf33316817d8349fa3125584a0f4767b3e4b72d
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#include "rtl_core.h" 22 23void ActivateBAEntry(struct rtllib_device* ieee, struct ba_record *pBA, u16 Time) 24{ 25 pBA->bValid = true; 26 if (Time != 0) 27 mod_timer(&pBA->Timer, jiffies + MSECS(Time)); 28} 29 30void DeActivateBAEntry( struct rtllib_device* ieee, struct ba_record *pBA) 31{ 32 pBA->bValid = false; 33 del_timer_sync(&pBA->Timer); 34} 35u8 TxTsDeleteBA( struct rtllib_device* ieee, struct tx_ts_record *pTxTs) 36{ 37 struct ba_record *pAdmittedBa = &pTxTs->TxAdmittedBARecord; 38 struct ba_record *pPendingBa = &pTxTs->TxPendingBARecord; 39 u8 bSendDELBA = false; 40 41 if (pPendingBa->bValid) 42 { 43 DeActivateBAEntry(ieee, pPendingBa); 44 bSendDELBA = true; 45 } 46 47 if (pAdmittedBa->bValid) 48 { 49 DeActivateBAEntry(ieee, pAdmittedBa); 50 bSendDELBA = true; 51 } 52 53 return bSendDELBA; 54} 55 56u8 RxTsDeleteBA( struct rtllib_device* ieee, struct rx_ts_record *pRxTs) 57{ 58 struct ba_record *pBa = &pRxTs->RxAdmittedBARecord; 59 u8 bSendDELBA = false; 60 61 if (pBa->bValid) 62 { 63 DeActivateBAEntry(ieee, pBa); 64 bSendDELBA = true; 65 } 66 67 return bSendDELBA; 68} 69 70void 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} 78static struct sk_buff* rtllib_ADDBA(struct rtllib_device* ieee, u8* Dst, struct ba_record *pBA, u16 StatusCode, u8 type) 79{ 80 struct sk_buff *skb = NULL; 81 struct rtllib_hdr_3addr* BAReq = NULL; 82 u8* tag = NULL; 83 u16 tmp = 0; 84 u16 len = ieee->tx_headroom + 9; 85 RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __func__, type, MAC_ARG(Dst), ieee->dev); 86 if (pBA == NULL||ieee == NULL) 87 { 88 RTLLIB_DEBUG(RTLLIB_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee); 89 return NULL; 90 } 91 skb = dev_alloc_skb(len + sizeof( struct rtllib_hdr_3addr)); 92 if (skb == NULL) 93 { 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,sizeof( struct rtllib_hdr_3addr)); 103 104 memcpy(BAReq->addr1, Dst, ETH_ALEN); 105 memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN); 106 107 memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN); 108 BAReq->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT); 109 110 tag = (u8*)skb_put(skb, 9); 111 *tag ++= ACT_CAT_BA; 112 *tag ++= type; 113 *tag ++= pBA->DialogToken; 114 115 if (ACT_ADDBARSP == type) 116 { 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 { 131 memcpy(tag,(u8*)&(pBA->BaStartSeqCtrl), 2); 132 tag += 2; 133 } 134 135 RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); 136 return skb; 137} 138 139static struct sk_buff* rtllib_DELBA( 140 struct rtllib_device* ieee, 141 u8* dst, 142 struct ba_record *pBA, 143 TR_SELECT TxRxSelect, 144 u16 ReasonCode 145 ) 146{ 147 DELBA_PARAM_SET DelbaParamSet; 148 struct sk_buff *skb = NULL; 149 struct rtllib_hdr_3addr* Delba = NULL; 150 u8* tag = NULL; 151 u16 tmp = 0; 152 u16 len = 6 + ieee->tx_headroom; 153 154 if (net_ratelimit()) 155 RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __func__, ReasonCode, MAC_ARG(dst)); 156 157 memset(&DelbaParamSet, 0, 2); 158 159 DelbaParamSet.field.Initiator = (TxRxSelect==TX_DIR)?1:0; 160 DelbaParamSet.field.TID = pBA->BaParamSet.field.TID; 161 162 skb = dev_alloc_skb(len + sizeof( struct rtllib_hdr_3addr)); 163 if (skb == NULL) 164 { 165 RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc skb for ADDBA_REQ\n"); 166 return NULL; 167 } 168 169 skb_reserve(skb, ieee->tx_headroom); 170 171 Delba = ( struct rtllib_hdr_3addr *) skb_put(skb,sizeof( struct rtllib_hdr_3addr)); 172 173 memcpy(Delba->addr1, dst, ETH_ALEN); 174 memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN); 175 memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN); 176 Delba->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT); 177 178 tag = (u8*)skb_put(skb, 6); 179 180 *tag ++= ACT_CAT_BA; 181 *tag ++= ACT_DELBA; 182 183 tmp = cpu_to_le16(DelbaParamSet.shortData); 184 memcpy(tag, (u8*)&tmp, 2); 185 tag += 2; 186 tmp = cpu_to_le16(ReasonCode); 187 memcpy(tag, (u8*)&tmp, 2); 188 tag += 2; 189 190 RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); 191 if (net_ratelimit()) 192 RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "<=====%s()\n", __func__); 193 return skb; 194} 195 196void rtllib_send_ADDBAReq(struct rtllib_device* ieee, u8* dst, 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 %s()\n", __func__); 206 } 207 return; 208} 209 210void rtllib_send_ADDBARsp(struct rtllib_device* ieee, u8* dst, struct ba_record *pBA, u16 StatusCode) 211{ 212 struct sk_buff *skb = NULL; 213 skb = rtllib_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); 214 if (skb) 215 softmac_mgmt_xmit(skb, ieee); 216 else 217 RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in function %s()\n", __func__); 218 219 return; 220 221} 222 223void rtllib_send_DELBA(struct rtllib_device* ieee, u8* dst, struct ba_record *pBA, TR_SELECT TxRxSelect, u16 ReasonCode) 224{ 225 struct sk_buff *skb = NULL; 226 skb = rtllib_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode); 227 if (skb) 228 { 229 softmac_mgmt_xmit(skb, ieee); 230 } 231 else 232 { 233 RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in function %s()\n", __func__); 234 } 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 PBA_PARAM_SET pBaParamSet = NULL; 245 u16* pBaTimeoutVal = NULL; 246 PSEQUENCE_CONTROL pBaStartSeqCtrl = NULL; 247 struct rx_ts_record *pTS = NULL; 248 249 if (skb->len < sizeof( struct rtllib_hdr_3addr) + 9) 250 { 251 RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in BAREQ(%d / %d)\n",(int)skb->len, (int)(sizeof( struct rtllib_hdr_3addr) + 9)); 252 return -1; 253 } 254 255 RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); 256 257 req = ( struct rtllib_hdr_3addr*) skb->data; 258 tag = (u8*)req; 259 dst = (u8*)(&req->addr2[0]); 260 tag += sizeof( struct rtllib_hdr_3addr); 261 pDialogToken = tag + 2; 262 pBaParamSet = (PBA_PARAM_SET)(tag + 3); 263 pBaTimeoutVal = (u16*)(tag + 5); 264 pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7); 265 266 RT_TRACE(COMP_DBG, "====>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst)); 267 if (ieee->current_network.qos_data.active == 0 || 268 (ieee->pHTInfo->bCurrentHTSupport == false) || 269 (ieee->pHTInfo->IOTAction & HT_IOT_ACT_REJECT_ADDBA_REQ)) { 270 rc = ADDBA_STATUS_REFUSED; 271 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); 272 goto OnADDBAReq_Fail; 273 } 274 if (!GetTs( 275 ieee, 276 (struct ts_common_info **)(&pTS), 277 dst, 278 (u8)(pBaParamSet->field.TID), 279 RX_DIR, 280 true) ) 281 { 282 rc = ADDBA_STATUS_REFUSED; 283 RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS in %s()\n", __func__); 284 goto OnADDBAReq_Fail; 285 } 286 pBA = &pTS->RxAdmittedBARecord; 287 288 if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) 289 { 290 rc = ADDBA_STATUS_INVALID_PARAM; 291 RTLLIB_DEBUG(RTLLIB_DL_ERR, "BA Policy is not correct in %s()\n", __func__); 292 goto OnADDBAReq_Fail; 293 } 294 295 296 rtllib_FlushRxTsPendingPkts(ieee, pTS); 297 298 DeActivateBAEntry(ieee, pBA); 299 pBA->DialogToken = *pDialogToken; 300 pBA->BaParamSet = *pBaParamSet; 301 pBA->BaTimeoutValue = *pBaTimeoutVal; 302 pBA->BaStartSeqCtrl = *pBaStartSeqCtrl; 303 304 if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)|| 305 (ieee->pHTInfo->IOTAction & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT)) 306 pBA->BaParamSet.field.BufferSize = 1; 307 else 308 pBA->BaParamSet.field.BufferSize = 32; 309 310 ActivateBAEntry(ieee, pBA, 0); 311 rtllib_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS); 312 313 return 0; 314 315OnADDBAReq_Fail: 316 { 317 struct ba_record BA; 318 BA.BaParamSet = *pBaParamSet; 319 BA.BaTimeoutValue = *pBaTimeoutVal; 320 BA.DialogToken = *pDialogToken; 321 BA.BaParamSet.field.BAPolicy = BA_POLICY_IMMEDIATE; 322 rtllib_send_ADDBARsp(ieee, dst, &BA, rc); 323 return 0; 324 } 325 326} 327 328int rtllib_rx_ADDBARsp( struct rtllib_device* ieee, struct sk_buff *skb) 329{ 330 struct rtllib_hdr_3addr* rsp = NULL; 331 struct ba_record *pPendingBA, *pAdmittedBA; 332 struct tx_ts_record *pTS = NULL; 333 u8* dst = NULL, *pDialogToken = NULL, *tag = NULL; 334 u16* pStatusCode = NULL, *pBaTimeoutVal = NULL; 335 PBA_PARAM_SET pBaParamSet = NULL; 336 u16 ReasonCode; 337 338 if (skb->len < sizeof( struct rtllib_hdr_3addr) + 9) 339 { 340 RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in BARSP(%d / %d)\n", (int)skb->len, (int)(sizeof( struct rtllib_hdr_3addr) + 9)); 341 return -1; 342 } 343 rsp = ( struct rtllib_hdr_3addr*)skb->data; 344 tag = (u8*)rsp; 345 dst = (u8*)(&rsp->addr2[0]); 346 tag += sizeof( struct rtllib_hdr_3addr); 347 pDialogToken = tag + 2; 348 pStatusCode = (u16*)(tag + 3); 349 pBaParamSet = (PBA_PARAM_SET)(tag + 5); 350 pBaTimeoutVal = (u16*)(tag + 7); 351 352 RT_TRACE(COMP_DBG, "====>rx ADDBARSP from :"MAC_FMT"\n", MAC_ARG(dst)); 353 if ( 354 ieee->current_network.qos_data.active == 0 || 355 ieee->pHTInfo->bCurrentHTSupport == false || 356 ieee->pHTInfo->bCurrentAMPDUEnable == false ) 357 { 358 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); 359 ReasonCode = DELBA_REASON_UNKNOWN_BA; 360 goto OnADDBARsp_Reject; 361 } 362 363 364 if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, 365 (u8)(pBaParamSet->field.TID), TX_DIR, false)) { 366 RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS in %s()\n", __func__); 367 ReasonCode = DELBA_REASON_UNKNOWN_BA; 368 goto OnADDBARsp_Reject; 369 } 370 371 pTS->bAddBaReqInProgress = false; 372 pPendingBA = &pTS->TxPendingBARecord; 373 pAdmittedBA = &pTS->TxAdmittedBARecord; 374 375 376 if ((pAdmittedBA->bValid==true)) 377 { 378 RTLLIB_DEBUG(RTLLIB_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n"); 379 return -1; 380 } 381 else if ((pPendingBA->bValid == false) ||(*pDialogToken != pPendingBA->DialogToken)) 382 { 383 RTLLIB_DEBUG(RTLLIB_DL_ERR, "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n"); 384 ReasonCode = DELBA_REASON_UNKNOWN_BA; 385 goto OnADDBARsp_Reject; 386 } 387 else 388 { 389 RTLLIB_DEBUG(RTLLIB_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", *pStatusCode); 390 DeActivateBAEntry(ieee, pPendingBA); 391 } 392 393 394 if (*pStatusCode == ADDBA_STATUS_SUCCESS) 395 { 396 if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) 397 { 398 pTS->bAddBaReqDelayed = true; 399 DeActivateBAEntry(ieee, pAdmittedBA); 400 ReasonCode = DELBA_REASON_END_BA; 401 goto OnADDBARsp_Reject; 402 } 403 404 405 pAdmittedBA->DialogToken = *pDialogToken; 406 pAdmittedBA->BaTimeoutValue = *pBaTimeoutVal; 407 pAdmittedBA->BaStartSeqCtrl = pPendingBA->BaStartSeqCtrl; 408 pAdmittedBA->BaParamSet = *pBaParamSet; 409 DeActivateBAEntry(ieee, pAdmittedBA); 410 ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal); 411 } else { 412 pTS->bAddBaReqDelayed = true; 413 pTS->bDisable_AddBa = true; 414 ReasonCode = DELBA_REASON_END_BA; 415 goto OnADDBARsp_Reject; 416 } 417 418 return 0; 419 420OnADDBARsp_Reject: 421 { 422 struct ba_record BA; 423 BA.BaParamSet = *pBaParamSet; 424 rtllib_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode); 425 return 0; 426 } 427 428} 429 430int rtllib_rx_DELBA(struct rtllib_device* ieee,struct sk_buff *skb) 431{ 432 struct rtllib_hdr_3addr* delba = NULL; 433 PDELBA_PARAM_SET pDelBaParamSet = NULL; 434 u16* pReasonCode = NULL; 435 u8* dst = NULL; 436 437 if (skb->len < sizeof( struct rtllib_hdr_3addr) + 6) 438 { 439 RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in DELBA(%d / %d)\n", (int)skb->len, (int)(sizeof( struct rtllib_hdr_3addr) + 6)); 440 return -1; 441 } 442 443 if ( 444 ieee->current_network.qos_data.active == 0 || 445 ieee->pHTInfo->bCurrentHTSupport == false ) 446 { 447 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); 448 return -1; 449 } 450 451 RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); 452 delba = ( struct rtllib_hdr_3addr*)skb->data; 453 dst = (u8*)(&delba->addr2[0]); 454 delba += sizeof( struct rtllib_hdr_3addr); 455 pDelBaParamSet = (PDELBA_PARAM_SET)(delba+2); 456 pReasonCode = (u16*)(delba+4); 457 458 if (pDelBaParamSet->field.Initiator == 1) 459 { 460 struct rx_ts_record *pRxTs; 461 462 if ( !GetTs( 463 ieee, 464 (struct ts_common_info **)&pRxTs, 465 dst, 466 (u8)pDelBaParamSet->field.TID, 467 RX_DIR, 468 false) ) 469 { 470 RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS for RXTS in %s().dst:"MAC_FMT" TID:%d\n", __func__, MAC_ARG(dst), (u8)pDelBaParamSet->field.TID); 471 return -1; 472 } 473 474 RxTsDeleteBA(ieee, pRxTs); 475 } 476 else 477 { 478 struct tx_ts_record *pTxTs; 479 480 if (!GetTs( 481 ieee, 482 (struct ts_common_info **)&pTxTs, 483 dst, 484 (u8)pDelBaParamSet->field.TID, 485 TX_DIR, 486 false) ) 487 { 488 RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS for TXTS in %s()\n", __func__); 489 return -1; 490 } 491 492 pTxTs->bUsingBa = false; 493 pTxTs->bAddBaReqInProgress = false; 494 pTxTs->bAddBaReqDelayed = false; 495 del_timer_sync(&pTxTs->TsAddBaTimer); 496 TxTsDeleteBA(ieee, pTxTs); 497 } 498 return 0; 499} 500 501void 502TsInitAddBA( 503 struct rtllib_device* ieee, 504 struct tx_ts_record *pTS, 505 u8 Policy, 506 u8 bOverwritePending 507 ) 508{ 509 struct ba_record *pBA = &pTS->TxPendingBARecord; 510 511 if (pBA->bValid==true && bOverwritePending==false) 512 return; 513 514 DeActivateBAEntry(ieee, pBA); 515 516 pBA->DialogToken++; 517 pBA->BaParamSet.field.AMSDU_Support = 0; 518 pBA->BaParamSet.field.BAPolicy = Policy; 519 pBA->BaParamSet.field.TID = pTS->TsCommonInfo.TSpec.f.TSInfo.field.ucTSID; 520 pBA->BaParamSet.field.BufferSize = 32; 521 pBA->BaTimeoutValue = 0; 522 pBA->BaStartSeqCtrl.field.SeqNum = (pTS->TxCurSeq + 3) % 4096; 523 524 ActivateBAEntry(ieee, pBA, BA_SETUP_TIMEOUT); 525 526 rtllib_send_ADDBAReq(ieee, pTS->TsCommonInfo.Addr, pBA); 527} 528 529void 530TsInitDelBA( struct rtllib_device* ieee, struct ts_common_info *pTsCommonInfo, TR_SELECT TxRxSelect) 531{ 532 533 if (TxRxSelect == TX_DIR) 534 { 535 struct tx_ts_record *pTxTs = (struct tx_ts_record *)pTsCommonInfo; 536 537 if (TxTsDeleteBA(ieee, pTxTs)) 538 rtllib_send_DELBA( 539 ieee, 540 pTsCommonInfo->Addr, 541 (pTxTs->TxAdmittedBARecord.bValid)?(&pTxTs->TxAdmittedBARecord):(&pTxTs->TxPendingBARecord), 542 TxRxSelect, 543 DELBA_REASON_END_BA); 544 } 545 else if (TxRxSelect == RX_DIR) 546 { 547 struct rx_ts_record *pRxTs = (struct rx_ts_record *)pTsCommonInfo; 548 if (RxTsDeleteBA(ieee, pRxTs)) 549 rtllib_send_DELBA( 550 ieee, 551 pTsCommonInfo->Addr, 552 &pRxTs->RxAdmittedBARecord, 553 TxRxSelect, 554 DELBA_REASON_END_BA ); 555 } 556} 557void BaSetupTimeOut(unsigned long data) 558{ 559 struct tx_ts_record *pTxTs = (struct tx_ts_record *)data; 560 561 pTxTs->bAddBaReqInProgress = false; 562 pTxTs->bAddBaReqDelayed = true; 563 pTxTs->TxPendingBARecord.bValid = false; 564} 565 566void TxBaInactTimeout(unsigned long data) 567{ 568 struct tx_ts_record *pTxTs = (struct tx_ts_record *)data; 569 struct rtllib_device *ieee = container_of(pTxTs, struct rtllib_device, TxTsRecord[pTxTs->num]); 570 TxTsDeleteBA(ieee, pTxTs); 571 rtllib_send_DELBA( 572 ieee, 573 pTxTs->TsCommonInfo.Addr, 574 &pTxTs->TxAdmittedBARecord, 575 TX_DIR, 576 DELBA_REASON_TIMEOUT); 577} 578 579void RxBaInactTimeout(unsigned long data) 580{ 581 struct rx_ts_record *pRxTs = (struct rx_ts_record *)data; 582 struct rtllib_device *ieee = container_of(pRxTs, struct rtllib_device, RxTsRecord[pRxTs->num]); 583 584 RxTsDeleteBA(ieee, pRxTs); 585 rtllib_send_DELBA( 586 ieee, 587 pRxTs->TsCommonInfo.Addr, 588 &pRxTs->RxAdmittedBARecord, 589 RX_DIR, 590 DELBA_REASON_TIMEOUT); 591 return ; 592} 593