aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2013-08-06 08:18:13 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-08-09 15:58:24 -0400
commitf89d1bc4271153ac7864051778c0f2443e5cf2cd (patch)
tree6ffbdac8b042eb4cd6ceba24cbb891cfa1fd1ca6 /drivers/net/wireless/ath/ath9k
parent020f20f693c254a6daa727473d6e855a63c3e502 (diff)
ath9k: use software queueing for multicast traffic
Create a per-vif dummy node entry for keeping the multicast software queues. This helps in setups with a lot of mulitcast traffic that could otherwise potentially drown out unicast traffic to stations. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c12
3 files changed, 23 insertions, 2 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 41ea3fd5b9bb..505c615ada1b 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -265,6 +265,7 @@ struct ath_node {
265 u8 mpdudensity; 265 u8 mpdudensity;
266 266
267 bool sleeping; 267 bool sleeping;
268 bool no_ps_filter;
268 269
269#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) 270#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS)
270 struct dentry *node_stat; 271 struct dentry *node_stat;
@@ -364,6 +365,7 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
364/********/ 365/********/
365 366
366struct ath_vif { 367struct ath_vif {
368 struct ath_node mcast_node;
367 int av_bslot; 369 int av_bslot;
368 bool primary_sta_vif; 370 bool primary_sta_vif;
369 __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ 371 __le64 tsf_adjust; /* TSF adjustment for staggered beacons */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 252497ae5089..911744f5c43c 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -963,6 +963,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
963 struct ath_softc *sc = hw->priv; 963 struct ath_softc *sc = hw->priv;
964 struct ath_hw *ah = sc->sc_ah; 964 struct ath_hw *ah = sc->sc_ah;
965 struct ath_common *common = ath9k_hw_common(ah); 965 struct ath_common *common = ath9k_hw_common(ah);
966 struct ath_vif *avp = (void *)vif->drv_priv;
967 struct ath_node *an = &avp->mcast_node;
966 968
967 mutex_lock(&sc->mutex); 969 mutex_lock(&sc->mutex);
968 970
@@ -976,6 +978,12 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
976 if (ath9k_uses_beacons(vif->type)) 978 if (ath9k_uses_beacons(vif->type))
977 ath9k_beacon_assign_slot(sc, vif); 979 ath9k_beacon_assign_slot(sc, vif);
978 980
981 an->sc = sc;
982 an->sta = NULL;
983 an->vif = vif;
984 an->no_ps_filter = true;
985 ath_tx_node_init(sc, an);
986
979 mutex_unlock(&sc->mutex); 987 mutex_unlock(&sc->mutex);
980 return 0; 988 return 0;
981} 989}
@@ -1013,6 +1021,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
1013{ 1021{
1014 struct ath_softc *sc = hw->priv; 1022 struct ath_softc *sc = hw->priv;
1015 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1023 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1024 struct ath_vif *avp = (void *)vif->drv_priv;
1016 1025
1017 ath_dbg(common, CONFIG, "Detach Interface\n"); 1026 ath_dbg(common, CONFIG, "Detach Interface\n");
1018 1027
@@ -1027,6 +1036,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
1027 ath9k_calculate_summary_state(hw, NULL); 1036 ath9k_calculate_summary_state(hw, NULL);
1028 ath9k_ps_restore(sc); 1037 ath9k_ps_restore(sc);
1029 1038
1039 ath_tx_node_cleanup(sc, &avp->mcast_node);
1040
1030 mutex_unlock(&sc->mutex); 1041 mutex_unlock(&sc->mutex);
1031} 1042}
1032 1043
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index f9e6eb2a4e0b..d8dfb3ec818a 100644
--- 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_info(struct sk_buff *skb)
135 135
136static void ath_send_bar(struct ath_atx_tid *tid, u16 seqno) 136static void ath_send_bar(struct ath_atx_tid *tid, u16 seqno)
137{ 137{
138 if (!tid->an->sta)
139 return;
140
138 ieee80211_send_bar(tid->an->vif, tid->an->sta->addr, tid->tidno, 141 ieee80211_send_bar(tid->an->vif, tid->an->sta->addr, tid->tidno,
139 seqno << IEEE80211_SEQ_SEQ_SHIFT); 142 seqno << IEEE80211_SEQ_SEQ_SHIFT);
140} 143}
@@ -1382,7 +1385,7 @@ static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
1382 if (list_empty(&bf_q)) 1385 if (list_empty(&bf_q))
1383 return false; 1386 return false;
1384 1387
1385 if (tid->ac->clear_ps_filter) { 1388 if (tid->ac->clear_ps_filter || tid->an->no_ps_filter) {
1386 tid->ac->clear_ps_filter = false; 1389 tid->ac->clear_ps_filter = false;
1387 tx_info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; 1390 tx_info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
1388 } 1391 }
@@ -1572,7 +1575,7 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
1572 sent++; 1575 sent++;
1573 TX_STAT_INC(txq->axq_qnum, a_queued_hw); 1576 TX_STAT_INC(txq->axq_qnum, a_queued_hw);
1574 1577
1575 if (!ath_tid_has_buffered(tid)) 1578 if (an->sta && !ath_tid_has_buffered(tid))
1576 ieee80211_sta_set_buffered(an->sta, i, false); 1579 ieee80211_sta_set_buffered(an->sta, i, false);
1577 } 1580 }
1578 ath_txq_unlock_complete(sc, tid->ac->txq); 1581 ath_txq_unlock_complete(sc, tid->ac->txq);
@@ -2104,6 +2107,7 @@ static int ath_tx_prepare(struct ieee80211_hw *hw, struct sk_buff *skb,
2104 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2107 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2105 struct ieee80211_sta *sta = txctl->sta; 2108 struct ieee80211_sta *sta = txctl->sta;
2106 struct ieee80211_vif *vif = info->control.vif; 2109 struct ieee80211_vif *vif = info->control.vif;
2110 struct ath_vif *avp;
2107 struct ath_softc *sc = hw->priv; 2111 struct ath_softc *sc = hw->priv;
2108 int frmlen = skb->len + FCS_LEN; 2112 int frmlen = skb->len + FCS_LEN;
2109 int padpos, padsize; 2113 int padpos, padsize;
@@ -2111,6 +2115,10 @@ static int ath_tx_prepare(struct ieee80211_hw *hw, struct sk_buff *skb,
2111 /* NOTE: sta can be NULL according to net/mac80211.h */ 2115 /* NOTE: sta can be NULL according to net/mac80211.h */
2112 if (sta) 2116 if (sta)
2113 txctl->an = (struct ath_node *)sta->drv_priv; 2117 txctl->an = (struct ath_node *)sta->drv_priv;
2118 else if (vif && ieee80211_is_data(hdr->frame_control)) {
2119 avp = (void *)vif->drv_priv;
2120 txctl->an = &avp->mcast_node;
2121 }
2114 2122
2115 if (info->control.hw_key) 2123 if (info->control.hw_key)
2116 frmlen += info->control.hw_key->icv_len; 2124 frmlen += info->control.hw_key->icv_len;