ht.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. /*
  2. * HT handling
  3. *
  4. * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
  5. * Copyright 2002-2005, Instant802 Networks, Inc.
  6. * Copyright 2005-2006, Devicescape Software, Inc.
  7. * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
  8. * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
  9. * Copyright 2007-2008, Intel Corporation
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License version 2 as
  13. * published by the Free Software Foundation.
  14. */
  15. #include <linux/ieee80211.h>
  16. #include <net/wireless.h>
  17. #include <net/mac80211.h>
  18. #include "ieee80211_i.h"
  19. #include "sta_info.h"
  20. #include "wme.h"
  21. int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
  22. struct ieee80211_ht_info *ht_info)
  23. {
  24. if (ht_info == NULL)
  25. return -EINVAL;
  26. memset(ht_info, 0, sizeof(*ht_info));
  27. if (ht_cap_ie) {
  28. u8 ampdu_info = ht_cap_ie->ampdu_params_info;
  29. ht_info->ht_supported = 1;
  30. ht_info->cap = le16_to_cpu(ht_cap_ie->cap_info);
  31. ht_info->ampdu_factor =
  32. ampdu_info & IEEE80211_HT_CAP_AMPDU_FACTOR;
  33. ht_info->ampdu_density =
  34. (ampdu_info & IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2;
  35. memcpy(ht_info->supp_mcs_set, ht_cap_ie->supp_mcs_set, 16);
  36. } else
  37. ht_info->ht_supported = 0;
  38. return 0;
  39. }
  40. int ieee80211_ht_addt_info_ie_to_ht_bss_info(
  41. struct ieee80211_ht_addt_info *ht_add_info_ie,
  42. struct ieee80211_ht_bss_info *bss_info)
  43. {
  44. if (bss_info == NULL)
  45. return -EINVAL;
  46. memset(bss_info, 0, sizeof(*bss_info));
  47. if (ht_add_info_ie) {
  48. u16 op_mode;
  49. op_mode = le16_to_cpu(ht_add_info_ie->operation_mode);
  50. bss_info->primary_channel = ht_add_info_ie->control_chan;
  51. bss_info->bss_cap = ht_add_info_ie->ht_param;
  52. bss_info->bss_op_mode = (u8)(op_mode & 0xff);
  53. }
  54. return 0;
  55. }
  56. void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, const u8 *da,
  57. u16 tid, u8 dialog_token, u16 start_seq_num,
  58. u16 agg_size, u16 timeout)
  59. {
  60. struct ieee80211_local *local = sdata->local;
  61. struct ieee80211_if_sta *ifsta = &sdata->u.sta;
  62. struct sk_buff *skb;
  63. struct ieee80211_mgmt *mgmt;
  64. u16 capab;
  65. skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
  66. if (!skb) {
  67. printk(KERN_ERR "%s: failed to allocate buffer "
  68. "for addba request frame\n", sdata->dev->name);
  69. return;
  70. }
  71. skb_reserve(skb, local->hw.extra_tx_headroom);
  72. mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
  73. memset(mgmt, 0, 24);
  74. memcpy(mgmt->da, da, ETH_ALEN);
  75. memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
  76. if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
  77. memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
  78. else
  79. memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
  80. mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
  81. IEEE80211_STYPE_ACTION);
  82. skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req));
  83. mgmt->u.action.category = WLAN_CATEGORY_BACK;
  84. mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
  85. mgmt->u.action.u.addba_req.dialog_token = dialog_token;
  86. capab = (u16)(1 << 1); /* bit 1 aggregation policy */
  87. capab |= (u16)(tid << 2); /* bit 5:2 TID number */
  88. capab |= (u16)(agg_size << 6); /* bit 15:6 max size of aggergation */
  89. mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
  90. mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout);
  91. mgmt->u.action.u.addba_req.start_seq_num =
  92. cpu_to_le16(start_seq_num << 4);
  93. ieee80211_sta_tx(sdata, skb, 0);
  94. }
  95. void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, const u8 *da, u16 tid,
  96. u16 initiator, u16 reason_code)
  97. {
  98. struct ieee80211_local *local = sdata->local;
  99. struct ieee80211_if_sta *ifsta = &sdata->u.sta;
  100. struct sk_buff *skb;
  101. struct ieee80211_mgmt *mgmt;
  102. u16 params;
  103. skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
  104. if (!skb) {
  105. printk(KERN_ERR "%s: failed to allocate buffer "
  106. "for delba frame\n", sdata->dev->name);
  107. return;
  108. }
  109. skb_reserve(skb, local->hw.extra_tx_headroom);
  110. mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
  111. memset(mgmt, 0, 24);
  112. memcpy(mgmt->da, da, ETH_ALEN);
  113. memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
  114. if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
  115. memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
  116. else
  117. memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
  118. mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
  119. IEEE80211_STYPE_ACTION);
  120. skb_put(skb, 1 + sizeof(mgmt->u.action.u.delba));
  121. mgmt->u.action.category = WLAN_CATEGORY_BACK;
  122. mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
  123. params = (u16)(initiator << 11); /* bit 11 initiator */
  124. params |= (u16)(tid << 12); /* bit 15:12 TID number */
  125. mgmt->u.action.u.delba.params = cpu_to_le16(params);
  126. mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code);
  127. ieee80211_sta_tx(sdata, skb, 0);
  128. }
  129. void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
  130. {
  131. struct ieee80211_local *local = sdata->local;
  132. struct sk_buff *skb;
  133. struct ieee80211_bar *bar;
  134. u16 bar_control = 0;
  135. skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom);
  136. if (!skb) {
  137. printk(KERN_ERR "%s: failed to allocate buffer for "
  138. "bar frame\n", sdata->dev->name);
  139. return;
  140. }
  141. skb_reserve(skb, local->hw.extra_tx_headroom);
  142. bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
  143. memset(bar, 0, sizeof(*bar));
  144. bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
  145. IEEE80211_STYPE_BACK_REQ);
  146. memcpy(bar->ra, ra, ETH_ALEN);
  147. memcpy(bar->ta, sdata->dev->dev_addr, ETH_ALEN);
  148. bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
  149. bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
  150. bar_control |= (u16)(tid << 12);
  151. bar->control = cpu_to_le16(bar_control);
  152. bar->start_seq_num = cpu_to_le16(ssn);
  153. ieee80211_sta_tx(sdata, skb, 0);
  154. }
  155. void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid,
  156. u16 initiator, u16 reason)
  157. {
  158. struct ieee80211_local *local = sdata->local;
  159. struct ieee80211_hw *hw = &local->hw;
  160. struct sta_info *sta;
  161. int ret, i;
  162. DECLARE_MAC_BUF(mac);
  163. rcu_read_lock();
  164. sta = sta_info_get(local, ra);
  165. if (!sta) {
  166. rcu_read_unlock();
  167. return;
  168. }
  169. /* check if TID is in operational state */
  170. spin_lock_bh(&sta->lock);
  171. if (sta->ampdu_mlme.tid_state_rx[tid]
  172. != HT_AGG_STATE_OPERATIONAL) {
  173. spin_unlock_bh(&sta->lock);
  174. rcu_read_unlock();
  175. return;
  176. }
  177. sta->ampdu_mlme.tid_state_rx[tid] =
  178. HT_AGG_STATE_REQ_STOP_BA_MSK |
  179. (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
  180. spin_unlock_bh(&sta->lock);
  181. /* stop HW Rx aggregation. ampdu_action existence
  182. * already verified in session init so we add the BUG_ON */
  183. BUG_ON(!local->ops->ampdu_action);
  184. #ifdef CONFIG_MAC80211_HT_DEBUG
  185. printk(KERN_DEBUG "Rx BA session stop requested for %s tid %u\n",
  186. print_mac(mac, ra), tid);
  187. #endif /* CONFIG_MAC80211_HT_DEBUG */
  188. ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP,
  189. ra, tid, NULL);
  190. if (ret)
  191. printk(KERN_DEBUG "HW problem - can not stop rx "
  192. "aggregation for tid %d\n", tid);
  193. /* shutdown timer has not expired */
  194. if (initiator != WLAN_BACK_TIMER)
  195. del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
  196. /* check if this is a self generated aggregation halt */
  197. if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER)
  198. ieee80211_send_delba(sdata, ra, tid, 0, reason);
  199. /* free the reordering buffer */
  200. for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) {
  201. if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) {
  202. /* release the reordered frames */
  203. dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]);
  204. sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--;
  205. sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL;
  206. }
  207. }
  208. /* free resources */
  209. kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf);
  210. kfree(sta->ampdu_mlme.tid_rx[tid]);
  211. sta->ampdu_mlme.tid_rx[tid] = NULL;
  212. sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE;
  213. rcu_read_unlock();
  214. }
  215. /*
  216. * After sending add Block Ack request we activated a timer until
  217. * add Block Ack response will arrive from the recipient.
  218. * If this timer expires sta_addba_resp_timer_expired will be executed.
  219. */
  220. void sta_addba_resp_timer_expired(unsigned long data)
  221. {
  222. /* not an elegant detour, but there is no choice as the timer passes
  223. * only one argument, and both sta_info and TID are needed, so init
  224. * flow in sta_info_create gives the TID as data, while the timer_to_id
  225. * array gives the sta through container_of */
  226. u16 tid = *(u8 *)data;
  227. struct sta_info *temp_sta = container_of((void *)data,
  228. struct sta_info, timer_to_tid[tid]);
  229. struct ieee80211_local *local = temp_sta->local;
  230. struct ieee80211_hw *hw = &local->hw;
  231. struct sta_info *sta;
  232. u8 *state;
  233. rcu_read_lock();
  234. sta = sta_info_get(local, temp_sta->addr);
  235. if (!sta) {
  236. rcu_read_unlock();
  237. return;
  238. }
  239. state = &sta->ampdu_mlme.tid_state_tx[tid];
  240. /* check if the TID waits for addBA response */
  241. spin_lock_bh(&sta->lock);
  242. if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
  243. spin_unlock_bh(&sta->lock);
  244. *state = HT_AGG_STATE_IDLE;
  245. #ifdef CONFIG_MAC80211_HT_DEBUG
  246. printk(KERN_DEBUG "timer expired on tid %d but we are not "
  247. "expecting addBA response there", tid);
  248. #endif
  249. goto timer_expired_exit;
  250. }
  251. #ifdef CONFIG_MAC80211_HT_DEBUG
  252. printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid);
  253. #endif
  254. /* go through the state check in stop_BA_session */
  255. *state = HT_AGG_STATE_OPERATIONAL;
  256. spin_unlock_bh(&sta->lock);
  257. ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid,
  258. WLAN_BACK_INITIATOR);
  259. timer_expired_exit:
  260. rcu_read_unlock();
  261. }
  262. void ieee80211_sta_tear_down_BA_sessions(struct ieee80211_sub_if_data *sdata, u8 *addr)
  263. {
  264. struct ieee80211_local *local = sdata->local;
  265. int i;
  266. for (i = 0; i < STA_TID_NUM; i++) {
  267. ieee80211_stop_tx_ba_session(&local->hw, addr, i,
  268. WLAN_BACK_INITIATOR);
  269. ieee80211_sta_stop_rx_ba_session(sdata, addr, i,
  270. WLAN_BACK_RECIPIENT,
  271. WLAN_REASON_QSTA_LEAVE_QBSS);
  272. }
  273. }
  274. int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
  275. {
  276. struct ieee80211_local *local = hw_to_local(hw);
  277. struct sta_info *sta;
  278. struct ieee80211_sub_if_data *sdata;
  279. u16 start_seq_num;
  280. u8 *state;
  281. int ret;
  282. DECLARE_MAC_BUF(mac);
  283. if (tid >= STA_TID_NUM)
  284. return -EINVAL;
  285. #ifdef CONFIG_MAC80211_HT_DEBUG
  286. printk(KERN_DEBUG "Open BA session requested for %s tid %u\n",
  287. print_mac(mac, ra), tid);
  288. #endif /* CONFIG_MAC80211_HT_DEBUG */
  289. rcu_read_lock();
  290. sta = sta_info_get(local, ra);
  291. if (!sta) {
  292. #ifdef CONFIG_MAC80211_HT_DEBUG
  293. printk(KERN_DEBUG "Could not find the station\n");
  294. #endif
  295. ret = -ENOENT;
  296. goto exit;
  297. }
  298. spin_lock_bh(&sta->lock);
  299. /* we have tried too many times, receiver does not want A-MPDU */
  300. if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
  301. ret = -EBUSY;
  302. goto err_unlock_sta;
  303. }
  304. state = &sta->ampdu_mlme.tid_state_tx[tid];
  305. /* check if the TID is not in aggregation flow already */
  306. if (*state != HT_AGG_STATE_IDLE) {
  307. #ifdef CONFIG_MAC80211_HT_DEBUG
  308. printk(KERN_DEBUG "BA request denied - session is not "
  309. "idle on tid %u\n", tid);
  310. #endif /* CONFIG_MAC80211_HT_DEBUG */
  311. ret = -EAGAIN;
  312. goto err_unlock_sta;
  313. }
  314. /* prepare A-MPDU MLME for Tx aggregation */
  315. sta->ampdu_mlme.tid_tx[tid] =
  316. kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
  317. if (!sta->ampdu_mlme.tid_tx[tid]) {
  318. #ifdef CONFIG_MAC80211_HT_DEBUG
  319. if (net_ratelimit())
  320. printk(KERN_ERR "allocate tx mlme to tid %d failed\n",
  321. tid);
  322. #endif
  323. ret = -ENOMEM;
  324. goto err_unlock_sta;
  325. }
  326. /* Tx timer */
  327. sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function =
  328. sta_addba_resp_timer_expired;
  329. sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data =
  330. (unsigned long)&sta->timer_to_tid[tid];
  331. init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
  332. /* create a new queue for this aggregation */
  333. ret = ieee80211_ht_agg_queue_add(local, sta, tid);
  334. /* case no queue is available to aggregation
  335. * don't switch to aggregation */
  336. if (ret) {
  337. #ifdef CONFIG_MAC80211_HT_DEBUG
  338. printk(KERN_DEBUG "BA request denied - queue unavailable for"
  339. " tid %d\n", tid);
  340. #endif /* CONFIG_MAC80211_HT_DEBUG */
  341. goto err_unlock_queue;
  342. }
  343. sdata = sta->sdata;
  344. /* Ok, the Addba frame hasn't been sent yet, but if the driver calls the
  345. * call back right away, it must see that the flow has begun */
  346. *state |= HT_ADDBA_REQUESTED_MSK;
  347. /* This is slightly racy because the queue isn't stopped */
  348. start_seq_num = sta->tid_seq[tid];
  349. if (local->ops->ampdu_action)
  350. ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START,
  351. ra, tid, &start_seq_num);
  352. if (ret) {
  353. /* No need to requeue the packets in the agg queue, since we
  354. * held the tx lock: no packet could be enqueued to the newly
  355. * allocated queue */
  356. ieee80211_ht_agg_queue_remove(local, sta, tid, 0);
  357. #ifdef CONFIG_MAC80211_HT_DEBUG
  358. printk(KERN_DEBUG "BA request denied - HW unavailable for"
  359. " tid %d\n", tid);
  360. #endif /* CONFIG_MAC80211_HT_DEBUG */
  361. *state = HT_AGG_STATE_IDLE;
  362. goto err_unlock_queue;
  363. }
  364. /* Will put all the packets in the new SW queue */
  365. ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
  366. spin_unlock_bh(&sta->lock);
  367. /* send an addBA request */
  368. sta->ampdu_mlme.dialog_token_allocator++;
  369. sta->ampdu_mlme.tid_tx[tid]->dialog_token =
  370. sta->ampdu_mlme.dialog_token_allocator;
  371. sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
  372. ieee80211_send_addba_request(sta->sdata, ra, tid,
  373. sta->ampdu_mlme.tid_tx[tid]->dialog_token,
  374. sta->ampdu_mlme.tid_tx[tid]->ssn,
  375. 0x40, 5000);
  376. /* activate the timer for the recipient's addBA response */
  377. sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
  378. jiffies + ADDBA_RESP_INTERVAL;
  379. add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
  380. #ifdef CONFIG_MAC80211_HT_DEBUG
  381. printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
  382. #endif
  383. goto exit;
  384. err_unlock_queue:
  385. kfree(sta->ampdu_mlme.tid_tx[tid]);
  386. sta->ampdu_mlme.tid_tx[tid] = NULL;
  387. ret = -EBUSY;
  388. err_unlock_sta:
  389. spin_unlock_bh(&sta->lock);
  390. exit:
  391. rcu_read_unlock();
  392. return ret;
  393. }
  394. EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
  395. int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
  396. u8 *ra, u16 tid,
  397. enum ieee80211_back_parties initiator)
  398. {
  399. struct ieee80211_local *local = hw_to_local(hw);
  400. struct sta_info *sta;
  401. u8 *state;
  402. int ret = 0;
  403. DECLARE_MAC_BUF(mac);
  404. if (tid >= STA_TID_NUM)
  405. return -EINVAL;
  406. rcu_read_lock();
  407. sta = sta_info_get(local, ra);
  408. if (!sta) {
  409. rcu_read_unlock();
  410. return -ENOENT;
  411. }
  412. /* check if the TID is in aggregation */
  413. state = &sta->ampdu_mlme.tid_state_tx[tid];
  414. spin_lock_bh(&sta->lock);
  415. if (*state != HT_AGG_STATE_OPERATIONAL) {
  416. ret = -ENOENT;
  417. goto stop_BA_exit;
  418. }
  419. #ifdef CONFIG_MAC80211_HT_DEBUG
  420. printk(KERN_DEBUG "Tx BA session stop requested for %s tid %u\n",
  421. print_mac(mac, ra), tid);
  422. #endif /* CONFIG_MAC80211_HT_DEBUG */
  423. ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]);
  424. *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
  425. (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
  426. if (local->ops->ampdu_action)
  427. ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_STOP,
  428. ra, tid, NULL);
  429. /* case HW denied going back to legacy */
  430. if (ret) {
  431. WARN_ON(ret != -EBUSY);
  432. *state = HT_AGG_STATE_OPERATIONAL;
  433. ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
  434. goto stop_BA_exit;
  435. }
  436. stop_BA_exit:
  437. spin_unlock_bh(&sta->lock);
  438. rcu_read_unlock();
  439. return ret;
  440. }
  441. EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
  442. void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
  443. {
  444. struct ieee80211_local *local = hw_to_local(hw);
  445. struct sta_info *sta;
  446. u8 *state;
  447. DECLARE_MAC_BUF(mac);
  448. if (tid >= STA_TID_NUM) {
  449. #ifdef CONFIG_MAC80211_HT_DEBUG
  450. printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
  451. tid, STA_TID_NUM);
  452. #endif
  453. return;
  454. }
  455. rcu_read_lock();
  456. sta = sta_info_get(local, ra);
  457. if (!sta) {
  458. rcu_read_unlock();
  459. #ifdef CONFIG_MAC80211_HT_DEBUG
  460. printk(KERN_DEBUG "Could not find station: %s\n",
  461. print_mac(mac, ra));
  462. #endif
  463. return;
  464. }
  465. state = &sta->ampdu_mlme.tid_state_tx[tid];
  466. spin_lock_bh(&sta->lock);
  467. if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
  468. #ifdef CONFIG_MAC80211_HT_DEBUG
  469. printk(KERN_DEBUG "addBA was not requested yet, state is %d\n",
  470. *state);
  471. #endif
  472. spin_unlock_bh(&sta->lock);
  473. rcu_read_unlock();
  474. return;
  475. }
  476. WARN_ON_ONCE(*state & HT_ADDBA_DRV_READY_MSK);
  477. *state |= HT_ADDBA_DRV_READY_MSK;
  478. if (*state == HT_AGG_STATE_OPERATIONAL) {
  479. #ifdef CONFIG_MAC80211_HT_DEBUG
  480. printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
  481. #endif
  482. ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
  483. }
  484. spin_unlock_bh(&sta->lock);
  485. rcu_read_unlock();
  486. }
  487. EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
  488. void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
  489. {
  490. struct ieee80211_local *local = hw_to_local(hw);
  491. struct sta_info *sta;
  492. u8 *state;
  493. int agg_queue;
  494. DECLARE_MAC_BUF(mac);
  495. if (tid >= STA_TID_NUM) {
  496. #ifdef CONFIG_MAC80211_HT_DEBUG
  497. printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
  498. tid, STA_TID_NUM);
  499. #endif
  500. return;
  501. }
  502. #ifdef CONFIG_MAC80211_HT_DEBUG
  503. printk(KERN_DEBUG "Stopping Tx BA session for %s tid %d\n",
  504. print_mac(mac, ra), tid);
  505. #endif /* CONFIG_MAC80211_HT_DEBUG */
  506. rcu_read_lock();
  507. sta = sta_info_get(local, ra);
  508. if (!sta) {
  509. #ifdef CONFIG_MAC80211_HT_DEBUG
  510. printk(KERN_DEBUG "Could not find station: %s\n",
  511. print_mac(mac, ra));
  512. #endif
  513. rcu_read_unlock();
  514. return;
  515. }
  516. state = &sta->ampdu_mlme.tid_state_tx[tid];
  517. /* NOTE: no need to use sta->lock in this state check, as
  518. * ieee80211_stop_tx_ba_session will let only one stop call to
  519. * pass through per sta/tid
  520. */
  521. if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
  522. #ifdef CONFIG_MAC80211_HT_DEBUG
  523. printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
  524. #endif
  525. rcu_read_unlock();
  526. return;
  527. }
  528. if (*state & HT_AGG_STATE_INITIATOR_MSK)
  529. ieee80211_send_delba(sta->sdata, ra, tid,
  530. WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
  531. agg_queue = sta->tid_to_tx_q[tid];
  532. ieee80211_ht_agg_queue_remove(local, sta, tid, 1);
  533. /* We just requeued the all the frames that were in the
  534. * removed queue, and since we might miss a softirq we do
  535. * netif_schedule_queue. ieee80211_wake_queue is not used
  536. * here as this queue is not necessarily stopped
  537. */
  538. netif_schedule_queue(netdev_get_tx_queue(local->mdev, agg_queue));
  539. spin_lock_bh(&sta->lock);
  540. *state = HT_AGG_STATE_IDLE;
  541. sta->ampdu_mlme.addba_req_num[tid] = 0;
  542. kfree(sta->ampdu_mlme.tid_tx[tid]);
  543. sta->ampdu_mlme.tid_tx[tid] = NULL;
  544. spin_unlock_bh(&sta->lock);
  545. rcu_read_unlock();
  546. }
  547. EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
  548. void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
  549. const u8 *ra, u16 tid)
  550. {
  551. struct ieee80211_local *local = hw_to_local(hw);
  552. struct ieee80211_ra_tid *ra_tid;
  553. struct sk_buff *skb = dev_alloc_skb(0);
  554. if (unlikely(!skb)) {
  555. #ifdef CONFIG_MAC80211_HT_DEBUG
  556. if (net_ratelimit())
  557. printk(KERN_WARNING "%s: Not enough memory, "
  558. "dropping start BA session", skb->dev->name);
  559. #endif
  560. return;
  561. }
  562. ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
  563. memcpy(&ra_tid->ra, ra, ETH_ALEN);
  564. ra_tid->tid = tid;
  565. skb->pkt_type = IEEE80211_ADDBA_MSG;
  566. skb_queue_tail(&local->skb_queue, skb);
  567. tasklet_schedule(&local->tasklet);
  568. }
  569. EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
  570. void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
  571. const u8 *ra, u16 tid)
  572. {
  573. struct ieee80211_local *local = hw_to_local(hw);
  574. struct ieee80211_ra_tid *ra_tid;
  575. struct sk_buff *skb = dev_alloc_skb(0);
  576. if (unlikely(!skb)) {
  577. #ifdef CONFIG_MAC80211_HT_DEBUG
  578. if (net_ratelimit())
  579. printk(KERN_WARNING "%s: Not enough memory, "
  580. "dropping stop BA session", skb->dev->name);
  581. #endif
  582. return;
  583. }
  584. ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
  585. memcpy(&ra_tid->ra, ra, ETH_ALEN);
  586. ra_tid->tid = tid;
  587. skb->pkt_type = IEEE80211_DELBA_MSG;
  588. skb_queue_tail(&local->skb_queue, skb);
  589. tasklet_schedule(&local->tasklet);
  590. }
  591. EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe);