Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Data transmitting implementation.
0004  *
0005  * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
0006  * Copyright (c) 2010, ST-Ericsson
0007  */
0008 #include <net/mac80211.h>
0009 #include <linux/etherdevice.h>
0010 
0011 #include "data_tx.h"
0012 #include "wfx.h"
0013 #include "bh.h"
0014 #include "sta.h"
0015 #include "queue.h"
0016 #include "debug.h"
0017 #include "traces.h"
0018 #include "hif_tx_mib.h"
0019 
0020 static int wfx_get_hw_rate(struct wfx_dev *wdev, const struct ieee80211_tx_rate *rate)
0021 {
0022     struct ieee80211_supported_band *band;
0023 
0024     if (rate->idx < 0)
0025         return -1;
0026     if (rate->flags & IEEE80211_TX_RC_MCS) {
0027         if (rate->idx > 7) {
0028             WARN(1, "wrong rate->idx value: %d", rate->idx);
0029             return -1;
0030         }
0031         return rate->idx + 14;
0032     }
0033     /* The device only support 2GHz, else band information should be retrieved from
0034      * ieee80211_tx_info
0035      */
0036     band = wdev->hw->wiphy->bands[NL80211_BAND_2GHZ];
0037     if (rate->idx >= band->n_bitrates) {
0038         WARN(1, "wrong rate->idx value: %d", rate->idx);
0039         return -1;
0040     }
0041     return band->bitrates[rate->idx].hw_value;
0042 }
0043 
0044 /* TX policy cache implementation */
0045 
0046 static void wfx_tx_policy_build(struct wfx_vif *wvif, struct wfx_tx_policy *policy,
0047                 struct ieee80211_tx_rate *rates)
0048 {
0049     struct wfx_dev *wdev = wvif->wdev;
0050     int i, rateid;
0051     u8 count;
0052 
0053     WARN(rates[0].idx < 0, "invalid rate policy");
0054     memset(policy, 0, sizeof(*policy));
0055     for (i = 0; i < IEEE80211_TX_MAX_RATES; ++i) {
0056         if (rates[i].idx < 0)
0057             break;
0058         WARN_ON(rates[i].count > 15);
0059         rateid = wfx_get_hw_rate(wdev, &rates[i]);
0060         /* Pack two values in each byte of policy->rates */
0061         count = rates[i].count;
0062         if (rateid % 2)
0063             count <<= 4;
0064         policy->rates[rateid / 2] |= count;
0065     }
0066 }
0067 
0068 static bool wfx_tx_policy_is_equal(const struct wfx_tx_policy *a, const struct wfx_tx_policy *b)
0069 {
0070     return !memcmp(a->rates, b->rates, sizeof(a->rates));
0071 }
0072 
0073 static int wfx_tx_policy_find(struct wfx_tx_policy_cache *cache, struct wfx_tx_policy *wanted)
0074 {
0075     struct wfx_tx_policy *it;
0076 
0077     list_for_each_entry(it, &cache->used, link)
0078         if (wfx_tx_policy_is_equal(wanted, it))
0079             return it - cache->cache;
0080     list_for_each_entry(it, &cache->free, link)
0081         if (wfx_tx_policy_is_equal(wanted, it))
0082             return it - cache->cache;
0083     return -1;
0084 }
0085 
0086 static void wfx_tx_policy_use(struct wfx_tx_policy_cache *cache, struct wfx_tx_policy *entry)
0087 {
0088     ++entry->usage_count;
0089     list_move(&entry->link, &cache->used);
0090 }
0091 
0092 static int wfx_tx_policy_release(struct wfx_tx_policy_cache *cache, struct wfx_tx_policy *entry)
0093 {
0094     int ret = --entry->usage_count;
0095 
0096     if (!ret)
0097         list_move(&entry->link, &cache->free);
0098     return ret;
0099 }
0100 
0101 static int wfx_tx_policy_get(struct wfx_vif *wvif, struct ieee80211_tx_rate *rates, bool *renew)
0102 {
0103     int idx;
0104     struct wfx_tx_policy_cache *cache = &wvif->tx_policy_cache;
0105     struct wfx_tx_policy wanted;
0106     struct wfx_tx_policy *entry;
0107 
0108     wfx_tx_policy_build(wvif, &wanted, rates);
0109 
0110     spin_lock_bh(&cache->lock);
0111     if (list_empty(&cache->free)) {
0112         WARN(1, "unable to get a valid Tx policy");
0113         spin_unlock_bh(&cache->lock);
0114         return HIF_TX_RETRY_POLICY_INVALID;
0115     }
0116     idx = wfx_tx_policy_find(cache, &wanted);
0117     if (idx >= 0) {
0118         *renew = false;
0119     } else {
0120         /* If policy is not found create a new one using the oldest entry in "free" list */
0121         *renew = true;
0122         entry = list_entry(cache->free.prev, struct wfx_tx_policy, link);
0123         memcpy(entry->rates, wanted.rates, sizeof(entry->rates));
0124         entry->uploaded = false;
0125         entry->usage_count = 0;
0126         idx = entry - cache->cache;
0127     }
0128     wfx_tx_policy_use(cache, &cache->cache[idx]);
0129     if (list_empty(&cache->free))
0130         ieee80211_stop_queues(wvif->wdev->hw);
0131     spin_unlock_bh(&cache->lock);
0132     return idx;
0133 }
0134 
0135 static void wfx_tx_policy_put(struct wfx_vif *wvif, int idx)
0136 {
0137     int usage, locked;
0138     struct wfx_tx_policy_cache *cache = &wvif->tx_policy_cache;
0139 
0140     if (idx == HIF_TX_RETRY_POLICY_INVALID)
0141         return;
0142     spin_lock_bh(&cache->lock);
0143     locked = list_empty(&cache->free);
0144     usage = wfx_tx_policy_release(cache, &cache->cache[idx]);
0145     if (locked && !usage)
0146         ieee80211_wake_queues(wvif->wdev->hw);
0147     spin_unlock_bh(&cache->lock);
0148 }
0149 
0150 static int wfx_tx_policy_upload(struct wfx_vif *wvif)
0151 {
0152     struct wfx_tx_policy *policies = wvif->tx_policy_cache.cache;
0153     u8 tmp_rates[12];
0154     int i, is_used;
0155 
0156     do {
0157         spin_lock_bh(&wvif->tx_policy_cache.lock);
0158         for (i = 0; i < ARRAY_SIZE(wvif->tx_policy_cache.cache); ++i) {
0159             is_used = memzcmp(policies[i].rates, sizeof(policies[i].rates));
0160             if (!policies[i].uploaded && is_used)
0161                 break;
0162         }
0163         if (i < ARRAY_SIZE(wvif->tx_policy_cache.cache)) {
0164             policies[i].uploaded = true;
0165             memcpy(tmp_rates, policies[i].rates, sizeof(tmp_rates));
0166             spin_unlock_bh(&wvif->tx_policy_cache.lock);
0167             wfx_hif_set_tx_rate_retry_policy(wvif, i, tmp_rates);
0168         } else {
0169             spin_unlock_bh(&wvif->tx_policy_cache.lock);
0170         }
0171     } while (i < ARRAY_SIZE(wvif->tx_policy_cache.cache));
0172     return 0;
0173 }
0174 
0175 void wfx_tx_policy_upload_work(struct work_struct *work)
0176 {
0177     struct wfx_vif *wvif = container_of(work, struct wfx_vif, tx_policy_upload_work);
0178 
0179     wfx_tx_policy_upload(wvif);
0180     wfx_tx_unlock(wvif->wdev);
0181 }
0182 
0183 void wfx_tx_policy_init(struct wfx_vif *wvif)
0184 {
0185     struct wfx_tx_policy_cache *cache = &wvif->tx_policy_cache;
0186     int i;
0187 
0188     memset(cache, 0, sizeof(*cache));
0189 
0190     spin_lock_init(&cache->lock);
0191     INIT_LIST_HEAD(&cache->used);
0192     INIT_LIST_HEAD(&cache->free);
0193 
0194     for (i = 0; i < ARRAY_SIZE(cache->cache); ++i)
0195         list_add(&cache->cache[i].link, &cache->free);
0196 }
0197 
0198 /* Tx implementation */
0199 
0200 static bool wfx_is_action_back(struct ieee80211_hdr *hdr)
0201 {
0202     struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)hdr;
0203 
0204     if (!ieee80211_is_action(mgmt->frame_control))
0205         return false;
0206     if (mgmt->u.action.category != WLAN_CATEGORY_BACK)
0207         return false;
0208     return true;
0209 }
0210 
0211 static u8 wfx_tx_get_link_id(struct wfx_vif *wvif, struct ieee80211_sta *sta,
0212                  struct ieee80211_hdr *hdr)
0213 {
0214     struct wfx_sta_priv *sta_priv = sta ? (struct wfx_sta_priv *)&sta->drv_priv : NULL;
0215     struct ieee80211_vif *vif = wvif_to_vif(wvif);
0216     const u8 *da = ieee80211_get_DA(hdr);
0217 
0218     if (sta_priv && sta_priv->link_id)
0219         return sta_priv->link_id;
0220     if (vif->type != NL80211_IFTYPE_AP)
0221         return 0;
0222     if (is_multicast_ether_addr(da))
0223         return 0;
0224     return HIF_LINK_ID_NOT_ASSOCIATED;
0225 }
0226 
0227 static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates)
0228 {
0229     int i;
0230     bool finished;
0231 
0232     /* Firmware is not able to mix rates with different flags */
0233     for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
0234         if (rates[0].flags & IEEE80211_TX_RC_SHORT_GI)
0235             rates[i].flags |= IEEE80211_TX_RC_SHORT_GI;
0236         if (!(rates[0].flags & IEEE80211_TX_RC_SHORT_GI))
0237             rates[i].flags &= ~IEEE80211_TX_RC_SHORT_GI;
0238         if (!(rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS))
0239             rates[i].flags &= ~IEEE80211_TX_RC_USE_RTS_CTS;
0240     }
0241 
0242     /* Sort rates and remove duplicates */
0243     do {
0244         finished = true;
0245         for (i = 0; i < IEEE80211_TX_MAX_RATES - 1; i++) {
0246             if (rates[i + 1].idx == rates[i].idx &&
0247                 rates[i].idx != -1) {
0248                 rates[i].count += rates[i + 1].count;
0249                 if (rates[i].count > 15)
0250                     rates[i].count = 15;
0251                 rates[i + 1].idx = -1;
0252                 rates[i + 1].count = 0;
0253 
0254                 finished = false;
0255             }
0256             if (rates[i + 1].idx > rates[i].idx) {
0257                 swap(rates[i + 1], rates[i]);
0258                 finished = false;
0259             }
0260         }
0261     } while (!finished);
0262     /* Ensure that MCS0 or 1Mbps is present at the end of the retry list */
0263     for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
0264         if (rates[i].idx == 0)
0265             break;
0266         if (rates[i].idx == -1) {
0267             rates[i].idx = 0;
0268             rates[i].count = 8; /* == hw->max_rate_tries */
0269             rates[i].flags = rates[i - 1].flags & IEEE80211_TX_RC_MCS;
0270             break;
0271         }
0272     }
0273     /* All retries use long GI */
0274     for (i = 1; i < IEEE80211_TX_MAX_RATES; i++)
0275         rates[i].flags &= ~IEEE80211_TX_RC_SHORT_GI;
0276 }
0277 
0278 static u8 wfx_tx_get_retry_policy_id(struct wfx_vif *wvif, struct ieee80211_tx_info *tx_info)
0279 {
0280     bool tx_policy_renew = false;
0281     u8 ret;
0282 
0283     ret = wfx_tx_policy_get(wvif, tx_info->driver_rates, &tx_policy_renew);
0284     if (ret == HIF_TX_RETRY_POLICY_INVALID)
0285         dev_warn(wvif->wdev->dev, "unable to get a valid Tx policy");
0286 
0287     if (tx_policy_renew) {
0288         wfx_tx_lock(wvif->wdev);
0289         if (!schedule_work(&wvif->tx_policy_upload_work))
0290             wfx_tx_unlock(wvif->wdev);
0291     }
0292     return ret;
0293 }
0294 
0295 static int wfx_tx_get_frame_format(struct ieee80211_tx_info *tx_info)
0296 {
0297     if (!(tx_info->driver_rates[0].flags & IEEE80211_TX_RC_MCS))
0298         return HIF_FRAME_FORMAT_NON_HT;
0299     else if (!(tx_info->driver_rates[0].flags & IEEE80211_TX_RC_GREEN_FIELD))
0300         return HIF_FRAME_FORMAT_MIXED_FORMAT_HT;
0301     else
0302         return HIF_FRAME_FORMAT_GF_HT_11N;
0303 }
0304 
0305 static int wfx_tx_get_icv_len(struct ieee80211_key_conf *hw_key)
0306 {
0307     int mic_space;
0308 
0309     if (!hw_key)
0310         return 0;
0311     if (hw_key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
0312         return 0;
0313     mic_space = (hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) ? 8 : 0;
0314     return hw_key->icv_len + mic_space;
0315 }
0316 
0317 static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta, struct sk_buff *skb)
0318 {
0319     struct wfx_hif_msg *hif_msg;
0320     struct wfx_hif_req_tx *req;
0321     struct wfx_tx_priv *tx_priv;
0322     struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
0323     struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
0324     struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
0325     int queue_id = skb_get_queue_mapping(skb);
0326     size_t offset = (size_t)skb->data & 3;
0327     int wmsg_len = sizeof(struct wfx_hif_msg) + sizeof(struct wfx_hif_req_tx) + offset;
0328 
0329     WARN(queue_id >= IEEE80211_NUM_ACS, "unsupported queue_id");
0330     wfx_tx_fixup_rates(tx_info->driver_rates);
0331 
0332     /* From now tx_info->control is unusable */
0333     memset(tx_info->rate_driver_data, 0, sizeof(struct wfx_tx_priv));
0334     /* Fill tx_priv */
0335     tx_priv = (struct wfx_tx_priv *)tx_info->rate_driver_data;
0336     tx_priv->icv_size = wfx_tx_get_icv_len(hw_key);
0337 
0338     /* Fill hif_msg */
0339     WARN(skb_headroom(skb) < wmsg_len, "not enough space in skb");
0340     WARN(offset & 1, "attempt to transmit an unaligned frame");
0341     skb_put(skb, tx_priv->icv_size);
0342     skb_push(skb, wmsg_len);
0343     memset(skb->data, 0, wmsg_len);
0344     hif_msg = (struct wfx_hif_msg *)skb->data;
0345     hif_msg->len = cpu_to_le16(skb->len);
0346     hif_msg->id = HIF_REQ_ID_TX;
0347     hif_msg->interface = wvif->id;
0348     if (skb->len > le16_to_cpu(wvif->wdev->hw_caps.size_inp_ch_buf)) {
0349         dev_warn(wvif->wdev->dev,
0350              "requested frame size (%d) is larger than maximum supported (%d)\n",
0351              skb->len, le16_to_cpu(wvif->wdev->hw_caps.size_inp_ch_buf));
0352         skb_pull(skb, wmsg_len);
0353         return -EIO;
0354     }
0355 
0356     /* Fill tx request */
0357     req = (struct wfx_hif_req_tx *)hif_msg->body;
0358     /* packet_id just need to be unique on device. 32bits are more than necessary for that task,
0359      * so we take advantage of it to add some extra data for debug.
0360      */
0361     req->packet_id = atomic_add_return(1, &wvif->wdev->packet_id) & 0xFFFF;
0362     req->packet_id |= IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)) << 16;
0363     req->packet_id |= queue_id << 28;
0364 
0365     req->fc_offset = offset;
0366     /* Queue index are inverted between firmware and Linux */
0367     req->queue_id = 3 - queue_id;
0368     req->peer_sta_id = wfx_tx_get_link_id(wvif, sta, hdr);
0369     req->retry_policy_index = wfx_tx_get_retry_policy_id(wvif, tx_info);
0370     req->frame_format = wfx_tx_get_frame_format(tx_info);
0371     if (tx_info->driver_rates[0].flags & IEEE80211_TX_RC_SHORT_GI)
0372         req->short_gi = 1;
0373     if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)
0374         req->after_dtim = 1;
0375 
0376     /* Auxiliary operations */
0377     wfx_tx_queues_put(wvif, skb);
0378     if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)
0379         schedule_work(&wvif->update_tim_work);
0380     wfx_bh_request_tx(wvif->wdev);
0381     return 0;
0382 }
0383 
0384 void wfx_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb)
0385 {
0386     struct wfx_dev *wdev = hw->priv;
0387     struct wfx_vif *wvif;
0388     struct ieee80211_sta *sta = control ? control->sta : NULL;
0389     struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
0390     struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
0391     size_t driver_data_room = sizeof_field(struct ieee80211_tx_info, rate_driver_data);
0392 
0393     BUILD_BUG_ON_MSG(sizeof(struct wfx_tx_priv) > driver_data_room,
0394              "struct tx_priv is too large");
0395     WARN(skb->next || skb->prev, "skb is already member of a list");
0396     /* control.vif can be NULL for injected frames */
0397     if (tx_info->control.vif)
0398         wvif = (struct wfx_vif *)tx_info->control.vif->drv_priv;
0399     else
0400         wvif = wvif_iterate(wdev, NULL);
0401     if (WARN_ON(!wvif))
0402         goto drop;
0403     /* Because of TX_AMPDU_SETUP_IN_HW, mac80211 does not try to send any BlockAck session
0404      * management frame. The check below exist just in case.
0405      */
0406     if (wfx_is_action_back(hdr)) {
0407         dev_info(wdev->dev, "drop BA action\n");
0408         goto drop;
0409     }
0410     if (wfx_tx_inner(wvif, sta, skb))
0411         goto drop;
0412 
0413     return;
0414 
0415 drop:
0416     ieee80211_tx_status_irqsafe(wdev->hw, skb);
0417 }
0418 
0419 static void wfx_skb_dtor(struct wfx_vif *wvif, struct sk_buff *skb)
0420 {
0421     struct wfx_hif_msg *hif = (struct wfx_hif_msg *)skb->data;
0422     struct wfx_hif_req_tx *req = (struct wfx_hif_req_tx *)hif->body;
0423     unsigned int offset = sizeof(struct wfx_hif_msg) + sizeof(struct wfx_hif_req_tx) +
0424                   req->fc_offset;
0425 
0426     if (!wvif) {
0427         pr_warn("vif associated with the skb does not exist anymore\n");
0428         return;
0429     }
0430     wfx_tx_policy_put(wvif, req->retry_policy_index);
0431     skb_pull(skb, offset);
0432     ieee80211_tx_status_irqsafe(wvif->wdev->hw, skb);
0433 }
0434 
0435 static void wfx_tx_fill_rates(struct wfx_dev *wdev, struct ieee80211_tx_info *tx_info,
0436                   const struct wfx_hif_cnf_tx *arg)
0437 {
0438     struct ieee80211_tx_rate *rate;
0439     int tx_count;
0440     int i;
0441 
0442     tx_count = arg->ack_failures;
0443     if (!arg->status || arg->ack_failures)
0444         tx_count += 1; /* Also report success */
0445     for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
0446         rate = &tx_info->status.rates[i];
0447         if (rate->idx < 0)
0448             break;
0449         if (tx_count < rate->count && arg->status == HIF_STATUS_TX_FAIL_RETRIES &&
0450             arg->ack_failures)
0451             dev_dbg(wdev->dev, "all retries were not consumed: %d != %d\n",
0452                 rate->count, tx_count);
0453         if (tx_count <= rate->count && tx_count &&
0454             arg->txed_rate != wfx_get_hw_rate(wdev, rate))
0455             dev_dbg(wdev->dev, "inconsistent tx_info rates: %d != %d\n",
0456                 arg->txed_rate, wfx_get_hw_rate(wdev, rate));
0457         if (tx_count > rate->count) {
0458             tx_count -= rate->count;
0459         } else if (!tx_count) {
0460             rate->count = 0;
0461             rate->idx = -1;
0462         } else {
0463             rate->count = tx_count;
0464             tx_count = 0;
0465         }
0466     }
0467     if (tx_count)
0468         dev_dbg(wdev->dev, "%d more retries than expected\n", tx_count);
0469 }
0470 
0471 void wfx_tx_confirm_cb(struct wfx_dev *wdev, const struct wfx_hif_cnf_tx *arg)
0472 {
0473     const struct wfx_tx_priv *tx_priv;
0474     struct ieee80211_tx_info *tx_info;
0475     struct wfx_vif *wvif;
0476     struct sk_buff *skb;
0477 
0478     skb = wfx_pending_get(wdev, arg->packet_id);
0479     if (!skb) {
0480         dev_warn(wdev->dev, "received unknown packet_id (%#.8x) from chip\n",
0481              arg->packet_id);
0482         return;
0483     }
0484     tx_info = IEEE80211_SKB_CB(skb);
0485     tx_priv = wfx_skb_tx_priv(skb);
0486     wvif = wdev_to_wvif(wdev, ((struct wfx_hif_msg *)skb->data)->interface);
0487     WARN_ON(!wvif);
0488     if (!wvif)
0489         return;
0490 
0491     /* Note that wfx_pending_get_pkt_us_delay() get data from tx_info */
0492     _trace_tx_stats(arg, skb, wfx_pending_get_pkt_us_delay(wdev, skb));
0493     wfx_tx_fill_rates(wdev, tx_info, arg);
0494     skb_trim(skb, skb->len - tx_priv->icv_size);
0495 
0496     /* From now, you can touch to tx_info->status, but do not touch to tx_priv anymore */
0497     /* FIXME: use ieee80211_tx_info_clear_status() */
0498     memset(tx_info->rate_driver_data, 0, sizeof(tx_info->rate_driver_data));
0499     memset(tx_info->pad, 0, sizeof(tx_info->pad));
0500 
0501     if (!arg->status) {
0502         tx_info->status.tx_time = le32_to_cpu(arg->media_delay) -
0503                       le32_to_cpu(arg->tx_queue_delay);
0504         if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
0505             tx_info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
0506         else
0507             tx_info->flags |= IEEE80211_TX_STAT_ACK;
0508     } else if (arg->status == HIF_STATUS_TX_FAIL_REQUEUE) {
0509         WARN(!arg->requeue, "incoherent status and result_flags");
0510         if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
0511             wvif->after_dtim_tx_allowed = false; /* DTIM period elapsed */
0512             schedule_work(&wvif->update_tim_work);
0513         }
0514         tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
0515     }
0516     wfx_skb_dtor(wvif, skb);
0517 }
0518 
0519 static void wfx_flush_vif(struct wfx_vif *wvif, u32 queues, struct sk_buff_head *dropped)
0520 {
0521     struct wfx_queue *queue;
0522     int i;
0523 
0524     for (i = 0; i < IEEE80211_NUM_ACS; i++) {
0525         if (!(BIT(i) & queues))
0526             continue;
0527         queue = &wvif->tx_queue[i];
0528         if (dropped)
0529             wfx_tx_queue_drop(wvif, queue, dropped);
0530     }
0531     if (wvif->wdev->chip_frozen)
0532         return;
0533     for (i = 0; i < IEEE80211_NUM_ACS; i++) {
0534         if (!(BIT(i) & queues))
0535             continue;
0536         queue = &wvif->tx_queue[i];
0537         if (wait_event_timeout(wvif->wdev->tx_dequeue, wfx_tx_queue_empty(wvif, queue),
0538                        msecs_to_jiffies(1000)) <= 0)
0539             dev_warn(wvif->wdev->dev, "frames queued while flushing tx queues?");
0540     }
0541 }
0542 
0543 void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 queues, bool drop)
0544 {
0545     struct wfx_dev *wdev = hw->priv;
0546     struct sk_buff_head dropped;
0547     struct wfx_vif *wvif;
0548     struct wfx_hif_msg *hif;
0549     struct sk_buff *skb;
0550 
0551     skb_queue_head_init(&dropped);
0552     if (vif) {
0553         wvif = (struct wfx_vif *)vif->drv_priv;
0554         wfx_flush_vif(wvif, queues, drop ? &dropped : NULL);
0555     } else {
0556         wvif = NULL;
0557         while ((wvif = wvif_iterate(wdev, wvif)) != NULL)
0558             wfx_flush_vif(wvif, queues, drop ? &dropped : NULL);
0559     }
0560     wfx_tx_flush(wdev);
0561     if (wdev->chip_frozen)
0562         wfx_pending_drop(wdev, &dropped);
0563     while ((skb = skb_dequeue(&dropped)) != NULL) {
0564         hif = (struct wfx_hif_msg *)skb->data;
0565         wvif = wdev_to_wvif(wdev, hif->interface);
0566         ieee80211_tx_info_clear_status(IEEE80211_SKB_CB(skb));
0567         wfx_skb_dtor(wvif, skb);
0568     }
0569 }