ath9k: fix setting up tx99 with a monitor mode interface
authorFelix Fietkau <nbd@nbd.name>
Mon, 20 Aug 2018 09:40:48 +0000 (11:40 +0200)
committerJo-Philipp Wich <jo@mein.io>
Tue, 18 Dec 2018 16:47:49 +0000 (17:47 +0100)
Signed-off-by: Felix Fietkau <nbd@nbd.name>
(backported from d9792152fdc7f18229274b82b5d8664d22b36d2c)

package/kernel/mac80211/patches/381-ath9k-fix-tx99-with-monitor-mode-interface.patch [new file with mode: 0644]

diff --git a/package/kernel/mac80211/patches/381-ath9k-fix-tx99-with-monitor-mode-interface.patch b/package/kernel/mac80211/patches/381-ath9k-fix-tx99-with-monitor-mode-interface.patch
new file mode 100644 (file)
index 0000000..777b734
--- /dev/null
@@ -0,0 +1,92 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Mon, 20 Aug 2018 11:35:05 +0200
+Subject: [PATCH] ath9k: fix tx99 with monitor mode interface
+
+Tx99 is typically configured via a monitor mode interface, which does
+not get added to the driver as a vif. Since the code currently expects
+a configured virtual interface for tx99, enabling tx99 via debugfs fails.
+Since the vif is not needed anyway, remove all checks for it.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -1074,7 +1074,6 @@ struct ath_softc {
+       struct ath_spec_scan_priv spec_priv;
+-      struct ieee80211_vif *tx99_vif;
+       struct sk_buff *tx99_skb;
+       bool tx99_state;
+       s16 tx99_power;
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -1251,15 +1251,10 @@ static int ath9k_add_interface(struct ie
+       struct ath_vif *avp = (void *)vif->drv_priv;
+       struct ath_node *an = &avp->mcast_node;
+-      mutex_lock(&sc->mutex);
++      if (IS_ENABLED(CPTCFG_ATH9K_TX99))
++              return -EOPNOTSUPP;
+-      if (IS_ENABLED(CPTCFG_ATH9K_TX99)) {
+-              if (sc->cur_chan->nvifs >= 1) {
+-                      mutex_unlock(&sc->mutex);
+-                      return -EOPNOTSUPP;
+-              }
+-              sc->tx99_vif = vif;
+-      }
++      mutex_lock(&sc->mutex);
+       ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type);
+       sc->cur_chan->nvifs++;
+@@ -1342,7 +1337,6 @@ static void ath9k_remove_interface(struc
+       ath9k_p2p_remove_vif(sc, vif);
+       sc->cur_chan->nvifs--;
+-      sc->tx99_vif = NULL;
+       if (!ath9k_is_chanctx_enabled())
+               list_del(&avp->list);
+--- a/drivers/net/wireless/ath/ath9k/tx99.c
++++ b/drivers/net/wireless/ath/ath9k/tx99.c
+@@ -54,12 +54,6 @@ static struct sk_buff *ath9k_build_tx99_
+       struct ieee80211_hdr *hdr;
+       struct ieee80211_tx_info *tx_info;
+       struct sk_buff *skb;
+-      struct ath_vif *avp;
+-
+-      if (!sc->tx99_vif)
+-              return NULL;
+-
+-      avp = (struct ath_vif *)sc->tx99_vif->drv_priv;
+       skb = alloc_skb(len, GFP_KERNEL);
+       if (!skb)
+@@ -77,14 +71,11 @@ static struct sk_buff *ath9k_build_tx99_
+       memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
+       memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
+-      hdr->seq_ctrl |= cpu_to_le16(avp->seq_no);
+-
+       tx_info = IEEE80211_SKB_CB(skb);
+       memset(tx_info, 0, sizeof(*tx_info));
+       rate = &tx_info->control.rates[0];
+       tx_info->band = sc->cur_chan->chandef.chan->band;
+       tx_info->flags = IEEE80211_TX_CTL_NO_ACK;
+-      tx_info->control.vif = sc->tx99_vif;
+       rate->count = 1;
+       if (ah->curchan && IS_CHAN_HT(ah->curchan)) {
+               rate->flags |= IEEE80211_TX_RC_MCS;
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -2973,7 +2973,7 @@ int ath9k_tx99_send(struct ath_softc *sc
+               return -EINVAL;
+       }
+-      ath_set_rates(sc->tx99_vif, NULL, bf);
++      ath_set_rates(NULL, NULL, bf);
+       ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, bf->bf_daddr);
+       ath9k_hw_tx99_start(sc->sc_ah, txctl->txq->axq_qnum);