aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/wfx/data_tx.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2020-09-09 18:26:07 +0200
committerTakashi Iwai <tiwai@suse.de>2020-09-09 18:26:48 +0200
commit9ddb236f13594b34a12dacf69a5adca7a1aef35e (patch)
tree1dc1f6e54962a2e3ad3d56c894522cb4b1ddce93 /drivers/staging/wfx/data_tx.c
parentALSA: vx: vx_pcm: remove redundant assignment (diff)
parentALSA: hda/realtek - The Mic on a RedmiBook doesn't work (diff)
downloadlinux-dev-9ddb236f13594b34a12dacf69a5adca7a1aef35e.tar.xz
linux-dev-9ddb236f13594b34a12dacf69a5adca7a1aef35e.zip
Merge branch 'for-linus' into for-next
Back-merge to apply the tasklet conversion patches that are based on the already applied tasklet API changes on 5.9-rc4. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'drivers/staging/wfx/data_tx.c')
-rw-r--r--drivers/staging/wfx/data_tx.c127
1 files changed, 47 insertions, 80 deletions
diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c
index f042ef36b408..3acf4eb0214d 100644
--- a/drivers/staging/wfx/data_tx.c
+++ b/drivers/staging/wfx/data_tx.c
@@ -213,23 +213,6 @@ static bool ieee80211_is_action_back(struct ieee80211_hdr *hdr)
return true;
}
-static void wfx_tx_manage_pm(struct wfx_vif *wvif, struct ieee80211_hdr *hdr,
- struct wfx_tx_priv *tx_priv,
- struct ieee80211_sta *sta)
-{
- struct wfx_sta_priv *sta_priv;
- int tid = ieee80211_get_tid(hdr);
-
- if (sta) {
- tx_priv->has_sta = true;
- sta_priv = (struct wfx_sta_priv *)&sta->drv_priv;
- spin_lock_bh(&sta_priv->lock);
- sta_priv->buffered[tid]++;
- ieee80211_sta_set_buffered(sta, tid, true);
- spin_unlock_bh(&sta_priv->lock);
- }
-}
-
static u8 wfx_tx_get_link_id(struct wfx_vif *wvif, struct ieee80211_sta *sta,
struct ieee80211_hdr *hdr)
{
@@ -407,8 +390,7 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta,
req->tx_flags.retry_policy_index = wfx_tx_get_rate_id(wvif, tx_info);
// Auxiliary operations
- wfx_tx_manage_pm(wvif, hdr, tx_priv, sta);
- wfx_tx_queues_put(wvif->wdev, skb);
+ wfx_tx_queues_put(wvif, skb);
if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)
schedule_work(&wvif->update_tim_work);
wfx_bh_request_tx(wvif->wdev);
@@ -436,7 +418,8 @@ void wfx_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
wvif = wvif_iterate(wdev, NULL);
if (WARN_ON(!wvif))
goto drop;
- // FIXME: why?
+ // Because of TX_AMPDU_SETUP_IN_HW, mac80211 does not try to send any
+ // BlockAck session management frame. The check below exist just in case.
if (ieee80211_is_action_back(hdr)) {
dev_info(wdev->dev, "drop BA action\n");
goto drop;
@@ -450,37 +433,6 @@ drop:
ieee80211_tx_status_irqsafe(wdev->hw, skb);
}
-static struct ieee80211_hdr *wfx_skb_hdr80211(struct sk_buff *skb)
-{
- struct hif_msg *hif = (struct hif_msg *)skb->data;
- struct hif_req_tx *req = (struct hif_req_tx *)hif->body;
-
- return (struct ieee80211_hdr *)(req->frame + req->data_flags.fc_offset);
-}
-
-static void wfx_tx_update_sta(struct wfx_vif *wvif, struct ieee80211_hdr *hdr)
-{
- int tid = ieee80211_get_tid(hdr);
- struct wfx_sta_priv *sta_priv;
- struct ieee80211_sta *sta;
-
- rcu_read_lock(); // protect sta
- sta = ieee80211_find_sta(wvif->vif, hdr->addr1);
- if (sta) {
- sta_priv = (struct wfx_sta_priv *)&sta->drv_priv;
- spin_lock_bh(&sta_priv->lock);
- WARN(!sta_priv->buffered[tid], "inconsistent notification");
- sta_priv->buffered[tid]--;
- if (!sta_priv->buffered[tid])
- ieee80211_sta_set_buffered(sta, tid, false);
- spin_unlock_bh(&sta_priv->lock);
- } else {
- dev_dbg(wvif->wdev->dev, "%s: sta does not exist anymore\n",
- __func__);
- }
- rcu_read_unlock();
-}
-
static void wfx_skb_dtor(struct wfx_vif *wvif, struct sk_buff *skb)
{
struct hif_msg *hif = (struct hif_msg *)skb->data;
@@ -533,27 +485,29 @@ static void wfx_tx_fill_rates(struct wfx_dev *wdev,
dev_dbg(wdev->dev, "%d more retries than expected\n", tx_count);
}
-void wfx_tx_confirm_cb(struct wfx_vif *wvif, const struct hif_cnf_tx *arg)
+void wfx_tx_confirm_cb(struct wfx_dev *wdev, const struct hif_cnf_tx *arg)
{
struct ieee80211_tx_info *tx_info;
const struct wfx_tx_priv *tx_priv;
+ struct wfx_vif *wvif;
struct sk_buff *skb;
- skb = wfx_pending_get(wvif->wdev, arg->packet_id);
+ skb = wfx_pending_get(wdev, arg->packet_id);
if (!skb) {
- dev_warn(wvif->wdev->dev, "received unknown packet_id (%#.8x) from chip\n",
+ dev_warn(wdev->dev, "received unknown packet_id (%#.8x) from chip\n",
arg->packet_id);
return;
}
+ wvif = wdev_to_wvif(wdev, ((struct hif_msg *)skb->data)->interface);
+ WARN_ON(!wvif);
+ if (!wvif)
+ return;
tx_info = IEEE80211_SKB_CB(skb);
tx_priv = wfx_skb_tx_priv(skb);
- _trace_tx_stats(arg, skb,
- wfx_pending_get_pkt_us_delay(wvif->wdev, skb));
+ _trace_tx_stats(arg, skb, wfx_pending_get_pkt_us_delay(wdev, skb));
// You can touch to tx_priv, but don't touch to tx_info->status.
- wfx_tx_fill_rates(wvif->wdev, tx_info, arg);
- if (tx_priv->has_sta)
- wfx_tx_update_sta(wvif, wfx_skb_hdr80211(skb));
+ wfx_tx_fill_rates(wdev, tx_info, arg);
skb_trim(skb, skb->len - wfx_tx_get_icv_len(tx_priv->hw_key));
// From now, you can touch to tx_info->status, but do not touch to
@@ -582,45 +536,58 @@ void wfx_tx_confirm_cb(struct wfx_vif *wvif, const struct hif_cnf_tx *arg)
wfx_skb_dtor(wvif, skb);
}
-void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- u32 queues, bool drop)
+static void wfx_flush_vif(struct wfx_vif *wvif, u32 queues,
+ struct sk_buff_head *dropped)
{
- struct wfx_dev *wdev = hw->priv;
- struct sk_buff_head dropped;
struct wfx_queue *queue;
- struct wfx_vif *wvif;
- struct hif_msg *hif;
- struct sk_buff *skb;
- int vif_id = -1;
int i;
- if (vif)
- vif_id = ((struct wfx_vif *)vif->drv_priv)->id;
- skb_queue_head_init(&dropped);
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
if (!(BIT(i) & queues))
continue;
- queue = &wdev->tx_queue[i];
- if (drop)
- wfx_tx_queue_drop(wdev, queue, vif_id, &dropped);
- if (wdev->chip_frozen)
+ queue = &wvif->tx_queue[i];
+ if (dropped)
+ wfx_tx_queue_drop(wvif, queue, dropped);
+ }
+ if (wvif->wdev->chip_frozen)
+ return;
+ for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+ if (!(BIT(i) & queues))
continue;
- if (wait_event_timeout(wdev->tx_dequeue,
- wfx_tx_queue_empty(wdev, queue, vif_id),
+ queue = &wvif->tx_queue[i];
+ if (wait_event_timeout(wvif->wdev->tx_dequeue,
+ wfx_tx_queue_empty(wvif, queue),
msecs_to_jiffies(1000)) <= 0)
- dev_warn(wdev->dev,
+ dev_warn(wvif->wdev->dev,
"frames queued while flushing tx queues?");
}
+}
+
+void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ u32 queues, bool drop)
+{
+ struct wfx_dev *wdev = hw->priv;
+ struct sk_buff_head dropped;
+ struct wfx_vif *wvif;
+ struct hif_msg *hif;
+ struct sk_buff *skb;
+
+ skb_queue_head_init(&dropped);
+ if (vif) {
+ wvif = (struct wfx_vif *)vif->drv_priv;
+ wfx_flush_vif(wvif, queues, drop ? &dropped : NULL);
+ } else {
+ wvif = NULL;
+ while ((wvif = wvif_iterate(wdev, wvif)) != NULL)
+ wfx_flush_vif(wvif, queues, drop ? &dropped : NULL);
+ }
wfx_tx_flush(wdev);
if (wdev->chip_frozen)
wfx_pending_drop(wdev, &dropped);
while ((skb = skb_dequeue(&dropped)) != NULL) {
hif = (struct hif_msg *)skb->data;
wvif = wdev_to_wvif(wdev, hif->interface);
- if (wfx_skb_tx_priv(skb)->has_sta)
- wfx_tx_update_sta(wvif, wfx_skb_hdr80211(skb));
ieee80211_tx_info_clear_status(IEEE80211_SKB_CB(skb));
wfx_skb_dtor(wvif, skb);
}
}
-