data_tx.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Data transmitting implementation.
  4. *
  5. * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
  6. * Copyright (c) 2010, ST-Ericsson
  7. */
  8. #include <net/mac80211.h>
  9. #include <linux/etherdevice.h>
  10. #include "data_tx.h"
  11. #include "wfx.h"
  12. #include "bh.h"
  13. #include "sta.h"
  14. #include "queue.h"
  15. #include "debug.h"
  16. #include "traces.h"
  17. #include "hif_tx_mib.h"
  18. static int wfx_get_hw_rate(struct wfx_dev *wdev, const struct ieee80211_tx_rate *rate)
  19. {
  20. struct ieee80211_supported_band *band;
  21. if (rate->idx < 0)
  22. return -1;
  23. if (rate->flags & IEEE80211_TX_RC_MCS) {
  24. if (rate->idx > 7) {
  25. WARN(1, "wrong rate->idx value: %d", rate->idx);
  26. return -1;
  27. }
  28. return rate->idx + 14;
  29. }
  30. /* The device only support 2GHz, else band information should be retrieved from
  31. * ieee80211_tx_info
  32. */
  33. band = wdev->hw->wiphy->bands[NL80211_BAND_2GHZ];
  34. if (rate->idx >= band->n_bitrates) {
  35. WARN(1, "wrong rate->idx value: %d", rate->idx);
  36. return -1;
  37. }
  38. return band->bitrates[rate->idx].hw_value;
  39. }
  40. /* TX policy cache implementation */
  41. static void wfx_tx_policy_build(struct wfx_vif *wvif, struct wfx_tx_policy *policy,
  42. struct ieee80211_tx_rate *rates)
  43. {
  44. struct wfx_dev *wdev = wvif->wdev;
  45. int i, rateid;
  46. u8 count;
  47. WARN(rates[0].idx < 0, "invalid rate policy");
  48. memset(policy, 0, sizeof(*policy));
  49. for (i = 0; i < IEEE80211_TX_MAX_RATES; ++i) {
  50. if (rates[i].idx < 0)
  51. break;
  52. WARN_ON(rates[i].count > 15);
  53. rateid = wfx_get_hw_rate(wdev, &rates[i]);
  54. /* Pack two values in each byte of policy->rates */
  55. count = rates[i].count;
  56. if (rateid % 2)
  57. count <<= 4;
  58. policy->rates[rateid / 2] |= count;
  59. }
  60. }
  61. static bool wfx_tx_policy_is_equal(const struct wfx_tx_policy *a, const struct wfx_tx_policy *b)
  62. {
  63. return !memcmp(a->rates, b->rates, sizeof(a->rates));
  64. }
  65. static int wfx_tx_policy_find(struct wfx_tx_policy_cache *cache, struct wfx_tx_policy *wanted)
  66. {
  67. struct wfx_tx_policy *it;
  68. list_for_each_entry(it, &cache->used, link)
  69. if (wfx_tx_policy_is_equal(wanted, it))
  70. return it - cache->cache;
  71. list_for_each_entry(it, &cache->free, link)
  72. if (wfx_tx_policy_is_equal(wanted, it))
  73. return it - cache->cache;
  74. return -1;
  75. }
  76. static void wfx_tx_policy_use(struct wfx_tx_policy_cache *cache, struct wfx_tx_policy *entry)
  77. {
  78. ++entry->usage_count;
  79. list_move(&entry->link, &cache->used);
  80. }
  81. static int wfx_tx_policy_release(struct wfx_tx_policy_cache *cache, struct wfx_tx_policy *entry)
  82. {
  83. int ret = --entry->usage_count;
  84. if (!ret)
  85. list_move(&entry->link, &cache->free);
  86. return ret;
  87. }
  88. static int wfx_tx_policy_get(struct wfx_vif *wvif, struct ieee80211_tx_rate *rates, bool *renew)
  89. {
  90. int idx;
  91. struct wfx_tx_policy_cache *cache = &wvif->tx_policy_cache;
  92. struct wfx_tx_policy wanted;
  93. struct wfx_tx_policy *entry;
  94. wfx_tx_policy_build(wvif, &wanted, rates);
  95. spin_lock_bh(&cache->lock);
  96. if (list_empty(&cache->free)) {
  97. WARN(1, "unable to get a valid Tx policy");
  98. spin_unlock_bh(&cache->lock);
  99. return HIF_TX_RETRY_POLICY_INVALID;
  100. }
  101. idx = wfx_tx_policy_find(cache, &wanted);
  102. if (idx >= 0) {
  103. *renew = false;
  104. } else {
  105. /* If policy is not found create a new one using the oldest entry in "free" list */
  106. *renew = true;
  107. entry = list_entry(cache->free.prev, struct wfx_tx_policy, link);
  108. memcpy(entry->rates, wanted.rates, sizeof(entry->rates));
  109. entry->uploaded = false;
  110. entry->usage_count = 0;
  111. idx = entry - cache->cache;
  112. }
  113. wfx_tx_policy_use(cache, &cache->cache[idx]);
  114. if (list_empty(&cache->free))
  115. ieee80211_stop_queues(wvif->wdev->hw);
  116. spin_unlock_bh(&cache->lock);
  117. return idx;
  118. }
  119. static void wfx_tx_policy_put(struct wfx_vif *wvif, int idx)
  120. {
  121. int usage, locked;
  122. struct wfx_tx_policy_cache *cache = &wvif->tx_policy_cache;
  123. if (idx == HIF_TX_RETRY_POLICY_INVALID)
  124. return;
  125. spin_lock_bh(&cache->lock);
  126. locked = list_empty(&cache->free);
  127. usage = wfx_tx_policy_release(cache, &cache->cache[idx]);
  128. if (locked && !usage)
  129. ieee80211_wake_queues(wvif->wdev->hw);
  130. spin_unlock_bh(&cache->lock);
  131. }
  132. static int wfx_tx_policy_upload(struct wfx_vif *wvif)
  133. {
  134. struct wfx_tx_policy *policies = wvif->tx_policy_cache.cache;
  135. u8 tmp_rates[12];
  136. int i, is_used;
  137. do {
  138. spin_lock_bh(&wvif->tx_policy_cache.lock);
  139. for (i = 0; i < ARRAY_SIZE(wvif->tx_policy_cache.cache); ++i) {
  140. is_used = memzcmp(policies[i].rates, sizeof(policies[i].rates));
  141. if (!policies[i].uploaded && is_used)
  142. break;
  143. }
  144. if (i < ARRAY_SIZE(wvif->tx_policy_cache.cache)) {
  145. policies[i].uploaded = true;
  146. memcpy(tmp_rates, policies[i].rates, sizeof(tmp_rates));
  147. spin_unlock_bh(&wvif->tx_policy_cache.lock);
  148. wfx_hif_set_tx_rate_retry_policy(wvif, i, tmp_rates);
  149. } else {
  150. spin_unlock_bh(&wvif->tx_policy_cache.lock);
  151. }
  152. } while (i < ARRAY_SIZE(wvif->tx_policy_cache.cache));
  153. return 0;
  154. }
  155. void wfx_tx_policy_upload_work(struct work_struct *work)
  156. {
  157. struct wfx_vif *wvif = container_of(work, struct wfx_vif, tx_policy_upload_work);
  158. wfx_tx_policy_upload(wvif);
  159. wfx_tx_unlock(wvif->wdev);
  160. }
  161. void wfx_tx_policy_init(struct wfx_vif *wvif)
  162. {
  163. struct wfx_tx_policy_cache *cache = &wvif->tx_policy_cache;
  164. int i;
  165. memset(cache, 0, sizeof(*cache));
  166. spin_lock_init(&cache->lock);
  167. INIT_LIST_HEAD(&cache->used);
  168. INIT_LIST_HEAD(&cache->free);
  169. for (i = 0; i < ARRAY_SIZE(cache->cache); ++i)
  170. list_add(&cache->cache[i].link, &cache->free);
  171. }
  172. /* Tx implementation */
  173. static bool wfx_is_action_back(struct ieee80211_hdr *hdr)
  174. {
  175. struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)hdr;
  176. if (!ieee80211_is_action(mgmt->frame_control))
  177. return false;
  178. if (mgmt->u.action.category != WLAN_CATEGORY_BACK)
  179. return false;
  180. return true;
  181. }
  182. struct wfx_tx_priv *wfx_skb_tx_priv(struct sk_buff *skb)
  183. {
  184. struct ieee80211_tx_info *tx_info;
  185. if (!skb)
  186. return NULL;
  187. tx_info = IEEE80211_SKB_CB(skb);
  188. return (struct wfx_tx_priv *)tx_info->rate_driver_data;
  189. }
  190. struct wfx_hif_req_tx *wfx_skb_txreq(struct sk_buff *skb)
  191. {
  192. struct wfx_hif_msg *hif = (struct wfx_hif_msg *)skb->data;
  193. struct wfx_hif_req_tx *req = (struct wfx_hif_req_tx *)hif->body;
  194. return req;
  195. }
  196. struct wfx_vif *wfx_skb_wvif(struct wfx_dev *wdev, struct sk_buff *skb)
  197. {
  198. struct wfx_tx_priv *tx_priv = wfx_skb_tx_priv(skb);
  199. struct wfx_hif_msg *hif = (struct wfx_hif_msg *)skb->data;
  200. if (tx_priv->vif_id != hif->interface && hif->interface != 2) {
  201. dev_err(wdev->dev, "corrupted skb");
  202. return wdev_to_wvif(wdev, hif->interface);
  203. }
  204. return wdev_to_wvif(wdev, tx_priv->vif_id);
  205. }
  206. static u8 wfx_tx_get_link_id(struct wfx_vif *wvif, struct ieee80211_sta *sta,
  207. struct ieee80211_hdr *hdr)
  208. {
  209. struct wfx_sta_priv *sta_priv = sta ? (struct wfx_sta_priv *)&sta->drv_priv : NULL;
  210. struct ieee80211_vif *vif = wvif_to_vif(wvif);
  211. const u8 *da = ieee80211_get_DA(hdr);
  212. if (sta_priv && sta_priv->link_id)
  213. return sta_priv->link_id;
  214. if (vif->type != NL80211_IFTYPE_AP)
  215. return 0;
  216. if (is_multicast_ether_addr(da))
  217. return 0;
  218. return HIF_LINK_ID_NOT_ASSOCIATED;
  219. }
  220. static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates)
  221. {
  222. bool has_rate0 = false;
  223. int i, j;
  224. for (i = 1, j = 1; j < IEEE80211_TX_MAX_RATES; j++) {
  225. if (rates[j].idx == -1)
  226. break;
  227. /* The device use the rates in descending order, whatever the request from minstrel.
  228. * We have to trade off here. Most important is to respect the primary rate
  229. * requested by minstrel. So, we drops the entries with rate higher than the
  230. * previous.
  231. */
  232. if (rates[j].idx >= rates[i - 1].idx) {
  233. rates[i - 1].count += rates[j].count;
  234. rates[i - 1].count = min_t(u16, 15, rates[i - 1].count);
  235. } else {
  236. memcpy(rates + i, rates + j, sizeof(rates[i]));
  237. if (rates[i].idx == 0)
  238. has_rate0 = true;
  239. /* The device apply Short GI only on the first rate */
  240. rates[i].flags &= ~IEEE80211_TX_RC_SHORT_GI;
  241. i++;
  242. }
  243. }
  244. /* Ensure that MCS0 or 1Mbps is present at the end of the retry list */
  245. if (!has_rate0 && i < IEEE80211_TX_MAX_RATES) {
  246. rates[i].idx = 0;
  247. rates[i].count = 8; /* == hw->max_rate_tries */
  248. rates[i].flags = rates[0].flags & IEEE80211_TX_RC_MCS;
  249. i++;
  250. }
  251. for (; i < IEEE80211_TX_MAX_RATES; i++) {
  252. memset(rates + i, 0, sizeof(rates[i]));
  253. rates[i].idx = -1;
  254. }
  255. }
  256. static u8 wfx_tx_get_retry_policy_id(struct wfx_vif *wvif, struct ieee80211_tx_info *tx_info)
  257. {
  258. bool tx_policy_renew = false;
  259. u8 ret;
  260. ret = wfx_tx_policy_get(wvif, tx_info->driver_rates, &tx_policy_renew);
  261. if (ret == HIF_TX_RETRY_POLICY_INVALID)
  262. dev_warn(wvif->wdev->dev, "unable to get a valid Tx policy");
  263. if (tx_policy_renew) {
  264. wfx_tx_lock(wvif->wdev);
  265. if (!schedule_work(&wvif->tx_policy_upload_work))
  266. wfx_tx_unlock(wvif->wdev);
  267. }
  268. return ret;
  269. }
  270. static int wfx_tx_get_frame_format(struct ieee80211_tx_info *tx_info)
  271. {
  272. if (!(tx_info->driver_rates[0].flags & IEEE80211_TX_RC_MCS))
  273. return HIF_FRAME_FORMAT_NON_HT;
  274. else if (!(tx_info->driver_rates[0].flags & IEEE80211_TX_RC_GREEN_FIELD))
  275. return HIF_FRAME_FORMAT_MIXED_FORMAT_HT;
  276. else
  277. return HIF_FRAME_FORMAT_GF_HT_11N;
  278. }
  279. static int wfx_tx_get_icv_len(struct ieee80211_key_conf *hw_key)
  280. {
  281. int mic_space;
  282. if (!hw_key)
  283. return 0;
  284. if (hw_key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
  285. return 0;
  286. mic_space = (hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) ? 8 : 0;
  287. return hw_key->icv_len + mic_space;
  288. }
  289. static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta, struct sk_buff *skb)
  290. {
  291. struct wfx_hif_msg *hif_msg;
  292. struct wfx_hif_req_tx *req;
  293. struct wfx_tx_priv *tx_priv;
  294. struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
  295. struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
  296. struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
  297. int queue_id = skb_get_queue_mapping(skb);
  298. size_t offset = (size_t)skb->data & 3;
  299. int wmsg_len = sizeof(struct wfx_hif_msg) + sizeof(struct wfx_hif_req_tx) + offset;
  300. WARN(queue_id >= IEEE80211_NUM_ACS, "unsupported queue_id");
  301. wfx_tx_fixup_rates(tx_info->driver_rates);
  302. /* From now tx_info->control is unusable */
  303. memset(tx_info->rate_driver_data, 0, sizeof(struct wfx_tx_priv));
  304. /* Fill tx_priv */
  305. tx_priv = (struct wfx_tx_priv *)tx_info->rate_driver_data;
  306. tx_priv->icv_size = wfx_tx_get_icv_len(hw_key);
  307. tx_priv->vif_id = wvif->id;
  308. /* Fill hif_msg */
  309. WARN(skb_headroom(skb) < wmsg_len, "not enough space in skb");
  310. WARN(offset & 1, "attempt to transmit an unaligned frame");
  311. skb_put(skb, tx_priv->icv_size);
  312. skb_push(skb, wmsg_len);
  313. memset(skb->data, 0, wmsg_len);
  314. hif_msg = (struct wfx_hif_msg *)skb->data;
  315. hif_msg->len = cpu_to_le16(skb->len);
  316. hif_msg->id = HIF_REQ_ID_TX;
  317. if (tx_info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
  318. hif_msg->interface = 2;
  319. else
  320. hif_msg->interface = wvif->id;
  321. if (skb->len > le16_to_cpu(wvif->wdev->hw_caps.size_inp_ch_buf)) {
  322. dev_warn(wvif->wdev->dev,
  323. "requested frame size (%d) is larger than maximum supported (%d)\n",
  324. skb->len, le16_to_cpu(wvif->wdev->hw_caps.size_inp_ch_buf));
  325. skb_pull(skb, wmsg_len);
  326. return -EIO;
  327. }
  328. /* Fill tx request */
  329. req = (struct wfx_hif_req_tx *)hif_msg->body;
  330. /* packet_id just need to be unique on device. 32bits are more than necessary for that task,
  331. * so we take advantage of it to add some extra data for debug.
  332. */
  333. req->packet_id = atomic_add_return(1, &wvif->wdev->packet_id) & 0xFFFF;
  334. req->packet_id |= IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)) << 16;
  335. req->packet_id |= queue_id << 28;
  336. req->fc_offset = offset;
  337. /* Queue index are inverted between firmware and Linux */
  338. req->queue_id = 3 - queue_id;
  339. if (tx_info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
  340. req->peer_sta_id = HIF_LINK_ID_NOT_ASSOCIATED;
  341. req->retry_policy_index = HIF_TX_RETRY_POLICY_INVALID;
  342. req->frame_format = HIF_FRAME_FORMAT_NON_HT;
  343. } else {
  344. req->peer_sta_id = wfx_tx_get_link_id(wvif, sta, hdr);
  345. req->retry_policy_index = wfx_tx_get_retry_policy_id(wvif, tx_info);
  346. req->frame_format = wfx_tx_get_frame_format(tx_info);
  347. }
  348. if (tx_info->driver_rates[0].flags & IEEE80211_TX_RC_SHORT_GI)
  349. req->short_gi = 1;
  350. if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)
  351. req->after_dtim = 1;
  352. /* Auxiliary operations */
  353. wfx_tx_queues_put(wvif, skb);
  354. if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)
  355. schedule_work(&wvif->update_tim_work);
  356. wfx_bh_request_tx(wvif->wdev);
  357. return 0;
  358. }
  359. void wfx_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb)
  360. {
  361. struct wfx_dev *wdev = hw->priv;
  362. struct wfx_vif *wvif;
  363. struct ieee80211_sta *sta = control ? control->sta : NULL;
  364. struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
  365. struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
  366. size_t driver_data_room = sizeof_field(struct ieee80211_tx_info, rate_driver_data);
  367. BUILD_BUG_ON_MSG(sizeof(struct wfx_tx_priv) > driver_data_room,
  368. "struct tx_priv is too large");
  369. WARN(skb->next || skb->prev, "skb is already member of a list");
  370. /* control.vif can be NULL for injected frames */
  371. if (tx_info->control.vif)
  372. wvif = (struct wfx_vif *)tx_info->control.vif->drv_priv;
  373. else
  374. wvif = wvif_iterate(wdev, NULL);
  375. if (WARN_ON(!wvif))
  376. goto drop;
  377. /* Because of TX_AMPDU_SETUP_IN_HW, mac80211 does not try to send any BlockAck session
  378. * management frame. The check below exist just in case.
  379. */
  380. if (wfx_is_action_back(hdr)) {
  381. dev_info(wdev->dev, "drop BA action\n");
  382. goto drop;
  383. }
  384. if (wfx_tx_inner(wvif, sta, skb))
  385. goto drop;
  386. return;
  387. drop:
  388. ieee80211_tx_status_irqsafe(wdev->hw, skb);
  389. }
  390. static void wfx_skb_dtor(struct wfx_vif *wvif, struct sk_buff *skb)
  391. {
  392. struct wfx_hif_msg *hif = (struct wfx_hif_msg *)skb->data;
  393. struct wfx_hif_req_tx *req = (struct wfx_hif_req_tx *)hif->body;
  394. unsigned int offset = sizeof(struct wfx_hif_msg) + sizeof(struct wfx_hif_req_tx) +
  395. req->fc_offset;
  396. if (!wvif) {
  397. pr_warn("vif associated with the skb does not exist anymore\n");
  398. return;
  399. }
  400. wfx_tx_policy_put(wvif, req->retry_policy_index);
  401. skb_pull(skb, offset);
  402. ieee80211_tx_status_irqsafe(wvif->wdev->hw, skb);
  403. }
  404. static void wfx_tx_fill_rates(struct wfx_dev *wdev, struct ieee80211_tx_info *tx_info,
  405. const struct wfx_hif_cnf_tx *arg)
  406. {
  407. struct ieee80211_tx_rate *rate;
  408. int tx_count;
  409. int i;
  410. tx_count = arg->ack_failures;
  411. if (!arg->status || arg->ack_failures)
  412. tx_count += 1; /* Also report success */
  413. for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
  414. rate = &tx_info->status.rates[i];
  415. if (rate->idx < 0)
  416. break;
  417. if (tx_count < rate->count && arg->status == HIF_STATUS_TX_FAIL_RETRIES &&
  418. arg->ack_failures)
  419. dev_dbg(wdev->dev, "all retries were not consumed: %d != %d\n",
  420. rate->count, tx_count);
  421. if (tx_count <= rate->count && tx_count &&
  422. arg->txed_rate != wfx_get_hw_rate(wdev, rate))
  423. dev_dbg(wdev->dev, "inconsistent tx_info rates: %d != %d\n",
  424. arg->txed_rate, wfx_get_hw_rate(wdev, rate));
  425. if (tx_count > rate->count) {
  426. tx_count -= rate->count;
  427. } else if (!tx_count) {
  428. rate->count = 0;
  429. rate->idx = -1;
  430. } else {
  431. rate->count = tx_count;
  432. tx_count = 0;
  433. }
  434. }
  435. if (tx_count)
  436. dev_dbg(wdev->dev, "%d more retries than expected\n", tx_count);
  437. }
  438. void wfx_tx_confirm_cb(struct wfx_dev *wdev, const struct wfx_hif_cnf_tx *arg)
  439. {
  440. const struct wfx_tx_priv *tx_priv;
  441. struct ieee80211_tx_info *tx_info;
  442. struct wfx_vif *wvif;
  443. struct sk_buff *skb;
  444. skb = wfx_pending_get(wdev, arg->packet_id);
  445. if (!skb) {
  446. dev_warn(wdev->dev, "received unknown packet_id (%#.8x) from chip\n",
  447. arg->packet_id);
  448. return;
  449. }
  450. tx_info = IEEE80211_SKB_CB(skb);
  451. tx_priv = wfx_skb_tx_priv(skb);
  452. wvif = wfx_skb_wvif(wdev, skb);
  453. WARN_ON(!wvif);
  454. if (!wvif)
  455. return;
  456. /* Note that wfx_pending_get_pkt_us_delay() get data from tx_info */
  457. _trace_tx_stats(arg, skb, wfx_pending_get_pkt_us_delay(wdev, skb));
  458. wfx_tx_fill_rates(wdev, tx_info, arg);
  459. skb_trim(skb, skb->len - tx_priv->icv_size);
  460. /* From now, you can touch to tx_info->status, but do not touch to tx_priv anymore */
  461. /* FIXME: use ieee80211_tx_info_clear_status() */
  462. memset(tx_info->rate_driver_data, 0, sizeof(tx_info->rate_driver_data));
  463. memset(tx_info->pad, 0, sizeof(tx_info->pad));
  464. if (!arg->status) {
  465. tx_info->status.tx_time = le32_to_cpu(arg->media_delay) -
  466. le32_to_cpu(arg->tx_queue_delay);
  467. if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
  468. tx_info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
  469. else
  470. tx_info->flags |= IEEE80211_TX_STAT_ACK;
  471. } else if (arg->status == HIF_STATUS_TX_FAIL_REQUEUE) {
  472. WARN(!arg->requeue, "incoherent status and result_flags");
  473. if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
  474. wvif->after_dtim_tx_allowed = false; /* DTIM period elapsed */
  475. schedule_work(&wvif->update_tim_work);
  476. }
  477. tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
  478. }
  479. wfx_skb_dtor(wvif, skb);
  480. }
  481. static void wfx_flush_vif(struct wfx_vif *wvif, u32 queues, struct sk_buff_head *dropped)
  482. {
  483. struct wfx_queue *queue;
  484. int i;
  485. for (i = 0; i < IEEE80211_NUM_ACS; i++) {
  486. if (!(BIT(i) & queues))
  487. continue;
  488. queue = &wvif->tx_queue[i];
  489. if (dropped)
  490. wfx_tx_queue_drop(wvif, queue, dropped);
  491. }
  492. if (wvif->wdev->chip_frozen)
  493. return;
  494. for (i = 0; i < IEEE80211_NUM_ACS; i++) {
  495. if (!(BIT(i) & queues))
  496. continue;
  497. queue = &wvif->tx_queue[i];
  498. if (wait_event_timeout(wvif->wdev->tx_dequeue, wfx_tx_queue_empty(wvif, queue),
  499. msecs_to_jiffies(1000)) <= 0)
  500. dev_warn(wvif->wdev->dev, "frames queued while flushing tx queues?");
  501. }
  502. }
  503. void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 queues, bool drop)
  504. {
  505. struct wfx_dev *wdev = hw->priv;
  506. struct sk_buff_head dropped;
  507. struct wfx_vif *wvif;
  508. struct sk_buff *skb;
  509. skb_queue_head_init(&dropped);
  510. if (vif) {
  511. wvif = (struct wfx_vif *)vif->drv_priv;
  512. wfx_flush_vif(wvif, queues, drop ? &dropped : NULL);
  513. } else {
  514. wvif = NULL;
  515. while ((wvif = wvif_iterate(wdev, wvif)) != NULL)
  516. wfx_flush_vif(wvif, queues, drop ? &dropped : NULL);
  517. }
  518. wfx_tx_flush(wdev);
  519. if (wdev->chip_frozen)
  520. wfx_pending_drop(wdev, &dropped);
  521. while ((skb = skb_dequeue(&dropped)) != NULL) {
  522. wvif = wfx_skb_wvif(wdev, skb);
  523. ieee80211_tx_info_clear_status(IEEE80211_SKB_CB(skb));
  524. wfx_skb_dtor(wvif, skb);
  525. }
  526. }