rtl819x_BAProc.c 16 KB

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