From 60590a642deca89da8068e48214cc3d1ec107e36 Mon Sep 17 00:00:00 2001 From: nbd Date: Mon, 29 Jul 2013 19:44:05 +0000 Subject: ath9k: fix several issues in the tx queueing rework Signed-off-by: Felix Fietkau git-svn-id: svn://svn.openwrt.org/openwrt/trunk@37616 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../patches/572-ath9k_multicast_node.patch | 108 +++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 package/kernel/mac80211/patches/572-ath9k_multicast_node.patch (limited to 'package/kernel/mac80211/patches/572-ath9k_multicast_node.patch') diff --git a/package/kernel/mac80211/patches/572-ath9k_multicast_node.patch b/package/kernel/mac80211/patches/572-ath9k_multicast_node.patch new file mode 100644 index 0000000000..cbe3816b12 --- /dev/null +++ b/package/kernel/mac80211/patches/572-ath9k_multicast_node.patch @@ -0,0 +1,108 @@ +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -265,6 +265,7 @@ struct ath_node { + u8 mpdudensity; + + bool sleeping; ++ bool no_ps_filter; + + #if defined(CPTCFG_MAC80211_DEBUGFS) && defined(CPTCFG_ATH9K_DEBUGFS) + struct dentry *node_stat; +@@ -364,6 +365,7 @@ void ath9k_release_buffered_frames(struc + /********/ + + struct ath_vif { ++ struct ath_node mcast_node; + int av_bslot; + bool primary_sta_vif; + __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -971,6 +971,8 @@ static int ath9k_add_interface(struct ie + struct ath_softc *sc = hw->priv; + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); ++ struct ath_vif *avp = (void *)vif->drv_priv; ++ struct ath_node *an = &avp->mcast_node; + + mutex_lock(&sc->mutex); + +@@ -984,6 +986,12 @@ static int ath9k_add_interface(struct ie + if (ath9k_uses_beacons(vif->type)) + ath9k_beacon_assign_slot(sc, vif); + ++ an->sc = sc; ++ an->sta = NULL; ++ an->vif = vif; ++ an->no_ps_filter = true; ++ ath_tx_node_init(sc, an); ++ + mutex_unlock(&sc->mutex); + return 0; + } +@@ -1021,6 +1029,7 @@ static void ath9k_remove_interface(struc + { + struct ath_softc *sc = hw->priv; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); ++ struct ath_vif *avp = (void *)vif->drv_priv; + + ath_dbg(common, CONFIG, "Detach Interface\n"); + +@@ -1035,6 +1044,8 @@ static void ath9k_remove_interface(struc + ath9k_calculate_summary_state(hw, NULL); + ath9k_ps_restore(sc); + ++ ath_tx_node_cleanup(sc, &avp->mcast_node); ++ + mutex_unlock(&sc->mutex); + } + +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -135,6 +135,9 @@ static struct ath_frame_info *get_frame_ + + static void ath_send_bar(struct ath_atx_tid *tid, u16 seqno) + { ++ if (!tid->an->sta) ++ return; ++ + ieee80211_send_bar(tid->an->vif, tid->an->sta->addr, tid->tidno, + seqno << IEEE80211_SEQ_SEQ_SHIFT); + } +@@ -1352,7 +1355,7 @@ static bool ath_tx_sched_aggr(struct ath + if (list_empty(&bf_q)) + return false; + +- if (tid->ac->clear_ps_filter) { ++ if (tid->ac->clear_ps_filter || tid->an->no_ps_filter) { + tid->ac->clear_ps_filter = false; + tx_info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; + } +@@ -1542,7 +1545,7 @@ void ath9k_release_buffered_frames(struc + sent++; + TX_STAT_INC(txq->axq_qnum, a_queued_hw); + +- if (ath_tid_has_buffered(tid)) ++ if (an->sta && ath_tid_has_buffered(tid)) + ieee80211_sta_set_buffered(an->sta, i, false); + } + ath_txq_unlock_complete(sc, tid->ac->txq); +@@ -2075,6 +2078,7 @@ static int ath_tx_prepare(struct ieee802 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_sta *sta = txctl->sta; + struct ieee80211_vif *vif = info->control.vif; ++ struct ath_vif *avp; + struct ath_softc *sc = hw->priv; + int frmlen = skb->len + FCS_LEN; + int padpos, padsize; +@@ -2082,6 +2086,10 @@ static int ath_tx_prepare(struct ieee802 + /* NOTE: sta can be NULL according to net/mac80211.h */ + if (sta) + txctl->an = (struct ath_node *)sta->drv_priv; ++ else if (vif && ieee80211_is_data(hdr->frame_control)) { ++ avp = (void *)vif->drv_priv; ++ txctl->an = &avp->mcast_node; ++ } + + if (info->control.hw_key) + frmlen += info->control.hw_key->icv_len; -- cgit v1.2.3