PageRenderTime 603ms CodeModel.GetById 21ms RepoModel.GetById 2ms app.codeStats 0ms

/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2
C | 676 lines | 489 code | 82 blank | 105 comment | 61 complexity | 7b2713b4ae1e031c177843bf0d4259ef MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1. /*
  2. * This file is created to process BA Action Frame. According to 802.11 spec,
  3. * there are 3 BA action types at all. And as BA is related to TS, this part
  4. * need some struture defined in QOS side code. Also TX RX is going to be
  5. * resturctured, so how to send ADDBAREQ ADDBARSP and DELBA packet is still
  6. * on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue.
  7. */
  8. #include "ieee80211.h"
  9. #include "rtl819x_BA.h"
  10. /*
  11. * Activate BA entry. And if Time is nozero, start timer.
  12. */
  13. void ActivateBAEntry(struct ieee80211_device* ieee, PBA_RECORD pBA, u16 Time)
  14. {
  15. pBA->bValid = true;
  16. if(Time != 0)
  17. mod_timer(&pBA->Timer, jiffies + MSECS(Time));
  18. }
  19. /*
  20. * deactivate BA entry, including its timer.
  21. */
  22. void DeActivateBAEntry( struct ieee80211_device* ieee, PBA_RECORD pBA)
  23. {
  24. pBA->bValid = false;
  25. del_timer_sync(&pBA->Timer);
  26. }
  27. /*
  28. * deactivete BA entry in Tx Ts, and send DELBA.
  29. */
  30. u8 TxTsDeleteBA( struct ieee80211_device* ieee, PTX_TS_RECORD pTxTs)
  31. {
  32. PBA_RECORD pAdmittedBa = &pTxTs->TxAdmittedBARecord; //These two BA entries must exist in TS structure
  33. PBA_RECORD pPendingBa = &pTxTs->TxPendingBARecord;
  34. u8 bSendDELBA = false;
  35. // Delete pending BA
  36. if(pPendingBa->bValid)
  37. {
  38. DeActivateBAEntry(ieee, pPendingBa);
  39. bSendDELBA = true;
  40. }
  41. // Delete admitted BA
  42. if(pAdmittedBa->bValid)
  43. {
  44. DeActivateBAEntry(ieee, pAdmittedBa);
  45. bSendDELBA = true;
  46. }
  47. return bSendDELBA;
  48. }
  49. /*
  50. * deactivete BA entry in Tx Ts, and send DELBA.
  51. */
  52. u8 RxTsDeleteBA( struct ieee80211_device* ieee, PRX_TS_RECORD pRxTs)
  53. {
  54. PBA_RECORD pBa = &pRxTs->RxAdmittedBARecord;
  55. u8 bSendDELBA = false;
  56. if(pBa->bValid)
  57. {
  58. DeActivateBAEntry(ieee, pBa);
  59. bSendDELBA = true;
  60. }
  61. return bSendDELBA;
  62. }
  63. /*
  64. * reset BA entry
  65. */
  66. void ResetBaEntry( PBA_RECORD pBA)
  67. {
  68. pBA->bValid = false;
  69. pBA->BaParamSet.shortData = 0;
  70. pBA->BaTimeoutValue = 0;
  71. pBA->DialogToken = 0;
  72. pBA->BaStartSeqCtrl.ShortData = 0;
  73. }
  74. /*
  75. * construct ADDBAREQ and ADDBARSP frame here together.
  76. * return constructed skb to xmit
  77. */
  78. static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, PBA_RECORD pBA, u16 StatusCode, u8 type)
  79. {
  80. struct sk_buff *skb = NULL;
  81. struct ieee80211_hdr_3addr* BAReq = NULL;
  82. u8* tag = NULL;
  83. u16 tmp = 0;
  84. u16 len = ieee->tx_headroom + 9;
  85. //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2))
  86. IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__, type, Dst, ieee->dev);
  87. if (pBA == NULL||ieee == NULL)
  88. {
  89. IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
  90. return NULL;
  91. }
  92. skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME
  93. if (skb == NULL)
  94. {
  95. IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
  96. return NULL;
  97. }
  98. memset(skb->data, 0, sizeof( struct ieee80211_hdr_3addr)); //I wonder whether it's necessary. Apparently kernel will not do it when alloc a skb.
  99. skb_reserve(skb, ieee->tx_headroom);
  100. BAReq = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr));
  101. memcpy(BAReq->addr1, Dst, ETH_ALEN);
  102. memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN);
  103. memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN);
  104. BAReq->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
  105. //tag += sizeof( struct ieee80211_hdr_3addr); //move to action field
  106. tag = (u8*)skb_put(skb, 9);
  107. *tag ++= ACT_CAT_BA;
  108. *tag ++= type;
  109. // Dialog Token
  110. *tag ++= pBA->DialogToken;
  111. if (ACT_ADDBARSP == type)
  112. {
  113. // Status Code
  114. printk("=====>to send ADDBARSP\n");
  115. tmp = cpu_to_le16(StatusCode);
  116. memcpy(tag, (u8*)&tmp, 2);
  117. tag += 2;
  118. }
  119. // BA Parameter Set
  120. tmp = cpu_to_le16(pBA->BaParamSet.shortData);
  121. memcpy(tag, (u8*)&tmp, 2);
  122. tag += 2;
  123. // BA Timeout Value
  124. tmp = cpu_to_le16(pBA->BaTimeoutValue);
  125. memcpy(tag, (u8*)&tmp, 2);
  126. tag += 2;
  127. if (ACT_ADDBAREQ == type)
  128. {
  129. // BA Start SeqCtrl
  130. memcpy(tag,(u8*)&(pBA->BaStartSeqCtrl), 2);
  131. tag += 2;
  132. }
  133. IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
  134. return skb;
  135. //return NULL;
  136. }
  137. /*
  138. * construct DELBA frame
  139. */
  140. static struct sk_buff* ieee80211_DELBA(
  141. struct ieee80211_device* ieee,
  142. u8* dst,
  143. PBA_RECORD pBA,
  144. TR_SELECT TxRxSelect,
  145. u16 ReasonCode
  146. )
  147. {
  148. DELBA_PARAM_SET DelbaParamSet;
  149. struct sk_buff *skb = NULL;
  150. struct ieee80211_hdr_3addr* Delba = NULL;
  151. u8* tag = NULL;
  152. u16 tmp = 0;
  153. //len = head len + DELBA Parameter Set(2) + Reason Code(2)
  154. u16 len = 6 + ieee->tx_headroom;
  155. if (net_ratelimit())
  156. IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__, ReasonCode, dst);
  157. memset(&DelbaParamSet, 0, 2);
  158. DelbaParamSet.field.Initiator = (TxRxSelect==TX_DIR)?1:0;
  159. DelbaParamSet.field.TID = pBA->BaParamSet.field.TID;
  160. skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME
  161. if (skb == NULL)
  162. {
  163. IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
  164. return NULL;
  165. }
  166. // memset(skb->data, 0, len+sizeof( struct ieee80211_hdr_3addr));
  167. skb_reserve(skb, ieee->tx_headroom);
  168. Delba = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr));
  169. memcpy(Delba->addr1, dst, ETH_ALEN);
  170. memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN);
  171. memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN);
  172. Delba->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
  173. tag = (u8*)skb_put(skb, 6);
  174. *tag ++= ACT_CAT_BA;
  175. *tag ++= ACT_DELBA;
  176. // DELBA Parameter Set
  177. tmp = cpu_to_le16(DelbaParamSet.shortData);
  178. memcpy(tag, (u8*)&tmp, 2);
  179. tag += 2;
  180. // Reason Code
  181. tmp = cpu_to_le16(ReasonCode);
  182. memcpy(tag, (u8*)&tmp, 2);
  183. tag += 2;
  184. IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
  185. if (net_ratelimit())
  186. IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "<=====%s()\n", __FUNCTION__);
  187. return skb;
  188. }
  189. /*
  190. * send ADDBAReq frame out
  191. * If any possible, please hide pBA in ieee.
  192. * And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
  193. */
  194. void ieee80211_send_ADDBAReq(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA)
  195. {
  196. struct sk_buff *skb = NULL;
  197. skb = ieee80211_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); //construct ACT_ADDBAREQ frames so set statuscode zero.
  198. if (skb)
  199. {
  200. softmac_mgmt_xmit(skb, ieee);
  201. //add statistic needed here.
  202. //and skb will be freed in softmac_mgmt_xmit(), so omit all dev_kfree_skb_any() outside softmac_mgmt_xmit()
  203. //WB
  204. }
  205. else
  206. {
  207. IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
  208. }
  209. }
  210. /*
  211. * send ADDBARSP frame out
  212. * If any possible, please hide pBA in ieee.
  213. * And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
  214. */
  215. void ieee80211_send_ADDBARsp(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, u16 StatusCode)
  216. {
  217. struct sk_buff *skb = NULL;
  218. skb = ieee80211_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); //construct ACT_ADDBARSP frames
  219. if (skb)
  220. {
  221. softmac_mgmt_xmit(skb, ieee);
  222. //same above
  223. }
  224. else
  225. {
  226. IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
  227. }
  228. }
  229. /*
  230. * send ADDBARSP frame out
  231. * If any possible, please hide pBA in ieee.
  232. * And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
  233. */
  234. void ieee80211_send_DELBA(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, TR_SELECT TxRxSelect, u16 ReasonCode)
  235. {
  236. struct sk_buff *skb = NULL;
  237. skb = ieee80211_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode); //construct ACT_ADDBARSP frames
  238. if (skb)
  239. {
  240. softmac_mgmt_xmit(skb, ieee);
  241. //same above
  242. }
  243. else
  244. {
  245. IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
  246. }
  247. return ;
  248. }
  249. int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
  250. {
  251. struct ieee80211_hdr_3addr* req = NULL;
  252. u16 rc = 0;
  253. u8 * dst = NULL, *pDialogToken = NULL, *tag = NULL;
  254. PBA_RECORD pBA = NULL;
  255. PBA_PARAM_SET pBaParamSet = NULL;
  256. u16* pBaTimeoutVal = NULL;
  257. PSEQUENCE_CONTROL pBaStartSeqCtrl = NULL;
  258. PRX_TS_RECORD pTS = NULL;
  259. if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
  260. {
  261. IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9));
  262. return -1;
  263. }
  264. IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
  265. req = ( struct ieee80211_hdr_3addr*) skb->data;
  266. tag = (u8*)req;
  267. dst = (u8*)(&req->addr2[0]);
  268. tag += sizeof( struct ieee80211_hdr_3addr);
  269. pDialogToken = tag + 2; //category+action
  270. pBaParamSet = (PBA_PARAM_SET)(tag + 3); //+DialogToken
  271. pBaTimeoutVal = (u16*)(tag + 5);
  272. pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
  273. printk("====================>rx ADDBAREQ from :%pM\n", dst);
  274. //some other capability is not ready now.
  275. if( (ieee->current_network.qos_data.active == 0) ||
  276. (ieee->pHTInfo->bCurrentHTSupport == false)) //||
  277. // (ieee->pStaQos->bEnableRxImmBA == false) )
  278. {
  279. rc = ADDBA_STATUS_REFUSED;
  280. IEEE80211_DEBUG(IEEE80211_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);
  281. goto OnADDBAReq_Fail;
  282. }
  283. // Search for related traffic stream.
  284. // If there is no matched TS, reject the ADDBA request.
  285. if( !GetTs(
  286. ieee,
  287. (PTS_COMMON_INFO*)(&pTS),
  288. dst,
  289. (u8)(pBaParamSet->field.TID),
  290. RX_DIR,
  291. true) )
  292. {
  293. rc = ADDBA_STATUS_REFUSED;
  294. IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __FUNCTION__);
  295. goto OnADDBAReq_Fail;
  296. }
  297. pBA = &pTS->RxAdmittedBARecord;
  298. // To Determine the ADDBA Req content
  299. // We can do much more check here, including BufferSize, AMSDU_Support, Policy, StartSeqCtrl...
  300. // I want to check StartSeqCtrl to make sure when we start aggregation!!!
  301. //
  302. if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED)
  303. {
  304. rc = ADDBA_STATUS_INVALID_PARAM;
  305. IEEE80211_DEBUG(IEEE80211_DL_ERR, "BA Policy is not correct in %s()\n", __FUNCTION__);
  306. goto OnADDBAReq_Fail;
  307. }
  308. // Admit the ADDBA Request
  309. //
  310. DeActivateBAEntry(ieee, pBA);
  311. pBA->DialogToken = *pDialogToken;
  312. pBA->BaParamSet = *pBaParamSet;
  313. pBA->BaTimeoutValue = *pBaTimeoutVal;
  314. pBA->BaStartSeqCtrl = *pBaStartSeqCtrl;
  315. //for half N mode we only aggregate 1 frame
  316. if (ieee->GetHalfNmodeSupportByAPsHandler(ieee))
  317. pBA->BaParamSet.field.BufferSize = 1;
  318. else
  319. pBA->BaParamSet.field.BufferSize = 32;
  320. ActivateBAEntry(ieee, pBA, pBA->BaTimeoutValue);
  321. ieee80211_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS);
  322. // End of procedure.
  323. return 0;
  324. OnADDBAReq_Fail:
  325. {
  326. BA_RECORD BA;
  327. BA.BaParamSet = *pBaParamSet;
  328. BA.BaTimeoutValue = *pBaTimeoutVal;
  329. BA.DialogToken = *pDialogToken;
  330. BA.BaParamSet.field.BAPolicy = BA_POLICY_IMMEDIATE;
  331. ieee80211_send_ADDBARsp(ieee, dst, &BA, rc);
  332. return 0; //we send RSP out.
  333. }
  334. }
  335. int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb)
  336. {
  337. struct ieee80211_hdr_3addr* rsp = NULL;
  338. PBA_RECORD pPendingBA, pAdmittedBA;
  339. PTX_TS_RECORD pTS = NULL;
  340. u8* dst = NULL, *pDialogToken = NULL, *tag = NULL;
  341. u16* pStatusCode = NULL, *pBaTimeoutVal = NULL;
  342. PBA_PARAM_SET pBaParamSet = NULL;
  343. u16 ReasonCode;
  344. if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
  345. {
  346. IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9));
  347. return -1;
  348. }
  349. rsp = ( struct ieee80211_hdr_3addr*)skb->data;
  350. tag = (u8*)rsp;
  351. dst = (u8*)(&rsp->addr2[0]);
  352. tag += sizeof( struct ieee80211_hdr_3addr);
  353. pDialogToken = tag + 2;
  354. pStatusCode = (u16*)(tag + 3);
  355. pBaParamSet = (PBA_PARAM_SET)(tag + 5);
  356. pBaTimeoutVal = (u16*)(tag + 7);
  357. // Check the capability
  358. // Since we can always receive A-MPDU, we just check if it is under HT mode.
  359. if( ieee->current_network.qos_data.active == 0 ||
  360. ieee->pHTInfo->bCurrentHTSupport == false ||
  361. ieee->pHTInfo->bCurrentAMPDUEnable == false )
  362. {
  363. IEEE80211_DEBUG(IEEE80211_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);
  364. ReasonCode = DELBA_REASON_UNKNOWN_BA;
  365. goto OnADDBARsp_Reject;
  366. }
  367. //
  368. // Search for related TS.
  369. // If there is no TS found, we wil reject ADDBA Rsp by sending DELBA frame.
  370. //
  371. if (!GetTs(
  372. ieee,
  373. (PTS_COMMON_INFO*)(&pTS),
  374. dst,
  375. (u8)(pBaParamSet->field.TID),
  376. TX_DIR,
  377. false) )
  378. {
  379. IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __FUNCTION__);
  380. ReasonCode = DELBA_REASON_UNKNOWN_BA;
  381. goto OnADDBARsp_Reject;
  382. }
  383. pTS->bAddBaReqInProgress = false;
  384. pPendingBA = &pTS->TxPendingBARecord;
  385. pAdmittedBA = &pTS->TxAdmittedBARecord;
  386. //
  387. // Check if related BA is waiting for setup.
  388. // If not, reject by sending DELBA frame.
  389. //
  390. if((pAdmittedBA->bValid==true))
  391. {
  392. // Since BA is already setup, we ignore all other ADDBA Response.
  393. IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n");
  394. return -1;
  395. }
  396. else if((pPendingBA->bValid == false) ||(*pDialogToken != pPendingBA->DialogToken))
  397. {
  398. IEEE80211_DEBUG(IEEE80211_DL_ERR, "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n");
  399. ReasonCode = DELBA_REASON_UNKNOWN_BA;
  400. goto OnADDBARsp_Reject;
  401. }
  402. else
  403. {
  404. IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", *pStatusCode);
  405. DeActivateBAEntry(ieee, pPendingBA);
  406. }
  407. if(*pStatusCode == ADDBA_STATUS_SUCCESS)
  408. {
  409. //
  410. // Determine ADDBA Rsp content here.
  411. // We can compare the value of BA parameter set that Peer returned and Self sent.
  412. // If it is OK, then admitted. Or we can send DELBA to cancel BA mechanism.
  413. //
  414. if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED)
  415. {
  416. // Since this is a kind of ADDBA failed, we delay next ADDBA process.
  417. pTS->bAddBaReqDelayed = true;
  418. DeActivateBAEntry(ieee, pAdmittedBA);
  419. ReasonCode = DELBA_REASON_END_BA;
  420. goto OnADDBARsp_Reject;
  421. }
  422. //
  423. // Admitted condition
  424. //
  425. pAdmittedBA->DialogToken = *pDialogToken;
  426. pAdmittedBA->BaTimeoutValue = *pBaTimeoutVal;
  427. pAdmittedBA->BaStartSeqCtrl = pPendingBA->BaStartSeqCtrl;
  428. pAdmittedBA->BaParamSet = *pBaParamSet;
  429. DeActivateBAEntry(ieee, pAdmittedBA);
  430. ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal);
  431. }
  432. else
  433. {
  434. // Delay next ADDBA process.
  435. pTS->bAddBaReqDelayed = true;
  436. }
  437. // End of procedure
  438. return 0;
  439. OnADDBARsp_Reject:
  440. {
  441. BA_RECORD BA;
  442. BA.BaParamSet = *pBaParamSet;
  443. ieee80211_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode);
  444. return 0;
  445. }
  446. }
  447. int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb)
  448. {
  449. struct ieee80211_hdr_3addr* delba = NULL;
  450. PDELBA_PARAM_SET pDelBaParamSet = NULL;
  451. u16* pReasonCode = NULL;
  452. u8* dst = NULL;
  453. if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6)
  454. {
  455. IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6));
  456. return -1;
  457. }
  458. if(ieee->current_network.qos_data.active == 0 ||
  459. ieee->pHTInfo->bCurrentHTSupport == false )
  460. {
  461. IEEE80211_DEBUG(IEEE80211_DL_ERR, "received DELBA while QOS or HT is not supported(%d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
  462. return -1;
  463. }
  464. IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
  465. delba = ( struct ieee80211_hdr_3addr*)skb->data;
  466. dst = (u8*)(&delba->addr2[0]);
  467. delba += sizeof( struct ieee80211_hdr_3addr);
  468. pDelBaParamSet = (PDELBA_PARAM_SET)(delba+2);
  469. pReasonCode = (u16*)(delba+4);
  470. if(pDelBaParamSet->field.Initiator == 1)
  471. {
  472. PRX_TS_RECORD pRxTs;
  473. if( !GetTs(
  474. ieee,
  475. (PTS_COMMON_INFO*)&pRxTs,
  476. dst,
  477. (u8)pDelBaParamSet->field.TID,
  478. RX_DIR,
  479. false) )
  480. {
  481. IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS for RXTS in %s()\n", __FUNCTION__);
  482. return -1;
  483. }
  484. RxTsDeleteBA(ieee, pRxTs);
  485. }
  486. else
  487. {
  488. PTX_TS_RECORD pTxTs;
  489. if(!GetTs(
  490. ieee,
  491. (PTS_COMMON_INFO*)&pTxTs,
  492. dst,
  493. (u8)pDelBaParamSet->field.TID,
  494. TX_DIR,
  495. false) )
  496. {
  497. IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS for TXTS in %s()\n", __FUNCTION__);
  498. return -1;
  499. }
  500. pTxTs->bUsingBa = false;
  501. pTxTs->bAddBaReqInProgress = false;
  502. pTxTs->bAddBaReqDelayed = false;
  503. del_timer_sync(&pTxTs->TsAddBaTimer);
  504. //PlatformCancelTimer(Adapter, &pTxTs->TsAddBaTimer);
  505. TxTsDeleteBA(ieee, pTxTs);
  506. }
  507. return 0;
  508. }
  509. /* ADDBA initiate. This can only be called by TX side. */
  510. void
  511. TsInitAddBA(
  512. struct ieee80211_device* ieee,
  513. PTX_TS_RECORD pTS,
  514. u8 Policy,
  515. u8 bOverwritePending
  516. )
  517. {
  518. PBA_RECORD pBA = &pTS->TxPendingBARecord;
  519. if(pBA->bValid==true && bOverwritePending==false)
  520. return;
  521. // Set parameters to "Pending" variable set
  522. DeActivateBAEntry(ieee, pBA);
  523. pBA->DialogToken++; // DialogToken: Only keep the latest dialog token
  524. pBA->BaParamSet.field.AMSDU_Support = 0; // Do not support A-MSDU with A-MPDU now!!
  525. pBA->BaParamSet.field.BAPolicy = Policy; // Policy: Delayed or Immediate
  526. pBA->BaParamSet.field.TID = pTS->TsCommonInfo.TSpec.f.TSInfo.field.ucTSID; // TID
  527. // BufferSize: This need to be set according to A-MPDU vector
  528. pBA->BaParamSet.field.BufferSize = 32; // BufferSize: This need to be set according to A-MPDU vector
  529. pBA->BaTimeoutValue = 0; // Timeout value: Set 0 to disable Timer
  530. pBA->BaStartSeqCtrl.field.SeqNum = (pTS->TxCurSeq + 3) % 4096; // Block Ack will start after 3 packets later.
  531. ActivateBAEntry(ieee, pBA, BA_SETUP_TIMEOUT);
  532. ieee80211_send_ADDBAReq(ieee, pTS->TsCommonInfo.Addr, pBA);
  533. }
  534. void
  535. TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect)
  536. {
  537. if(TxRxSelect == TX_DIR)
  538. {
  539. PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)pTsCommonInfo;
  540. if(TxTsDeleteBA(ieee, pTxTs))
  541. ieee80211_send_DELBA(
  542. ieee,
  543. pTsCommonInfo->Addr,
  544. (pTxTs->TxAdmittedBARecord.bValid)?(&pTxTs->TxAdmittedBARecord):(&pTxTs->TxPendingBARecord),
  545. TxRxSelect,
  546. DELBA_REASON_END_BA);
  547. }
  548. else if(TxRxSelect == RX_DIR)
  549. {
  550. PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)pTsCommonInfo;
  551. if(RxTsDeleteBA(ieee, pRxTs))
  552. ieee80211_send_DELBA(
  553. ieee,
  554. pTsCommonInfo->Addr,
  555. &pRxTs->RxAdmittedBARecord,
  556. TxRxSelect,
  557. DELBA_REASON_END_BA );
  558. }
  559. }
  560. /*
  561. * BA setup timer
  562. * acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
  563. */
  564. void BaSetupTimeOut(unsigned long data)
  565. {
  566. PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data;
  567. pTxTs->bAddBaReqInProgress = false;
  568. pTxTs->bAddBaReqDelayed = true;
  569. pTxTs->TxPendingBARecord.bValid = false;
  570. }
  571. void TxBaInactTimeout(unsigned long data)
  572. {
  573. PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data;
  574. struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[pTxTs->num]);
  575. TxTsDeleteBA(ieee, pTxTs);
  576. ieee80211_send_DELBA(
  577. ieee,
  578. pTxTs->TsCommonInfo.Addr,
  579. &pTxTs->TxAdmittedBARecord,
  580. TX_DIR,
  581. DELBA_REASON_TIMEOUT);
  582. }
  583. void RxBaInactTimeout(unsigned long data)
  584. {
  585. PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)data;
  586. struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]);
  587. RxTsDeleteBA(ieee, pRxTs);
  588. ieee80211_send_DELBA(
  589. ieee,
  590. pRxTs->TsCommonInfo.Addr,
  591. &pRxTs->RxAdmittedBARecord,
  592. RX_DIR,
  593. DELBA_REASON_TIMEOUT);
  594. }