diff options
author | Sujith Manoharan <c_manoha@qca.qualcomm.com> | 2014-10-21 09:53:02 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-10-23 14:02:06 -0400 |
commit | 868caae3fe2e35e2353d86af95e03eeaa9439d97 (patch) | |
tree | 242ea49da511b77ff38603722cbe456a0a2308da | |
parent | 598a0df07fc6c4642f9b0497cef1233e41d4c987 (diff) |
ath9k: Enable HW queue control only for MCC
Enabling HW queue control for normal (non-mcc) mode
causes problems with queue management, resulting
in traffic stall. Since it is mainly required for
fairness in MCC mode, disable it for the general case.
Bug: https://dev.openwrt.org/ticket/18164
Cc: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ath/ath9k/init.c | 55 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 10 |
3 files changed, 41 insertions, 27 deletions
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 156a944134dc..3bd030494986 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -734,6 +734,32 @@ static const struct ieee80211_iface_combination if_comb[] = { | |||
734 | #endif | 734 | #endif |
735 | }; | 735 | }; |
736 | 736 | ||
737 | #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT | ||
738 | static void ath9k_set_mcc_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | ||
739 | { | ||
740 | struct ath_hw *ah = sc->sc_ah; | ||
741 | struct ath_common *common = ath9k_hw_common(ah); | ||
742 | |||
743 | if (!ath9k_is_chanctx_enabled()) | ||
744 | return; | ||
745 | |||
746 | hw->flags |= IEEE80211_HW_QUEUE_CONTROL; | ||
747 | hw->queues = ATH9K_NUM_TX_QUEUES; | ||
748 | hw->offchannel_tx_hw_queue = hw->queues - 1; | ||
749 | hw->wiphy->interface_modes &= ~ BIT(NL80211_IFTYPE_WDS); | ||
750 | hw->wiphy->iface_combinations = if_comb_multi; | ||
751 | hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_multi); | ||
752 | hw->wiphy->max_scan_ssids = 255; | ||
753 | hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; | ||
754 | hw->wiphy->max_remain_on_channel_duration = 10000; | ||
755 | hw->chanctx_data_size = sizeof(void *); | ||
756 | hw->extra_beacon_tailroom = | ||
757 | sizeof(struct ieee80211_p2p_noa_attr) + 9; | ||
758 | |||
759 | ath_dbg(common, CHAN_CTX, "Use channel contexts\n"); | ||
760 | } | ||
761 | #endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */ | ||
762 | |||
737 | static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | 763 | static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) |
738 | { | 764 | { |
739 | struct ath_hw *ah = sc->sc_ah; | 765 | struct ath_hw *ah = sc->sc_ah; |
@@ -746,7 +772,6 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
746 | IEEE80211_HW_SPECTRUM_MGMT | | 772 | IEEE80211_HW_SPECTRUM_MGMT | |
747 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 773 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
748 | IEEE80211_HW_SUPPORTS_RC_TABLE | | 774 | IEEE80211_HW_SUPPORTS_RC_TABLE | |
749 | IEEE80211_HW_QUEUE_CONTROL | | ||
750 | IEEE80211_HW_SUPPORTS_HT_CCK_RATES; | 775 | IEEE80211_HW_SUPPORTS_HT_CCK_RATES; |
751 | 776 | ||
752 | if (ath9k_ps_enable) | 777 | if (ath9k_ps_enable) |
@@ -781,24 +806,6 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
781 | hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); | 806 | hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); |
782 | } | 807 | } |
783 | 808 | ||
784 | #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT | ||
785 | |||
786 | if (ath9k_is_chanctx_enabled()) { | ||
787 | hw->wiphy->interface_modes &= ~ BIT(NL80211_IFTYPE_WDS); | ||
788 | hw->wiphy->iface_combinations = if_comb_multi; | ||
789 | hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_multi); | ||
790 | hw->wiphy->max_scan_ssids = 255; | ||
791 | hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; | ||
792 | hw->wiphy->max_remain_on_channel_duration = 10000; | ||
793 | hw->chanctx_data_size = sizeof(void *); | ||
794 | hw->extra_beacon_tailroom = | ||
795 | sizeof(struct ieee80211_p2p_noa_attr) + 9; | ||
796 | |||
797 | ath_dbg(common, CHAN_CTX, "Use channel contexts\n"); | ||
798 | } | ||
799 | |||
800 | #endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */ | ||
801 | |||
802 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | 809 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
803 | 810 | ||
804 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; | 811 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; |
@@ -808,12 +815,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
808 | hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; | 815 | hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; |
809 | hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; | 816 | hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; |
810 | 817 | ||
811 | /* allow 4 queues per channel context + | 818 | hw->queues = 4; |
812 | * 1 cab queue + 1 offchannel tx queue | ||
813 | */ | ||
814 | hw->queues = ATH9K_NUM_TX_QUEUES; | ||
815 | /* last queue for offchannel */ | ||
816 | hw->offchannel_tx_hw_queue = hw->queues - 1; | ||
817 | hw->max_rates = 4; | 819 | hw->max_rates = 4; |
818 | hw->max_listen_interval = 10; | 820 | hw->max_listen_interval = 10; |
819 | hw->max_rate_tries = 10; | 821 | hw->max_rate_tries = 10; |
@@ -837,6 +839,9 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
837 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | 839 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = |
838 | &common->sbands[IEEE80211_BAND_5GHZ]; | 840 | &common->sbands[IEEE80211_BAND_5GHZ]; |
839 | 841 | ||
842 | #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT | ||
843 | ath9k_set_mcc_capab(sc, hw); | ||
844 | #endif | ||
840 | ath9k_init_wow(hw); | 845 | ath9k_init_wow(hw); |
841 | ath9k_cmn_reload_chainmask(ah); | 846 | ath9k_cmn_reload_chainmask(ah); |
842 | 847 | ||
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 6f6a974f7fdb..30c66dfcd7a0 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1162,6 +1162,9 @@ static void ath9k_assign_hw_queues(struct ieee80211_hw *hw, | |||
1162 | { | 1162 | { |
1163 | int i; | 1163 | int i; |
1164 | 1164 | ||
1165 | if (!ath9k_is_chanctx_enabled()) | ||
1166 | return; | ||
1167 | |||
1165 | for (i = 0; i < IEEE80211_NUM_ACS; i++) | 1168 | for (i = 0; i < IEEE80211_NUM_ACS; i++) |
1166 | vif->hw_queue[i] = i; | 1169 | vif->hw_queue[i] = i; |
1167 | 1170 | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 493a183d0aaf..d6e54a3c88f6 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -169,7 +169,10 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, | |||
169 | 169 | ||
170 | if (txq->stopped && | 170 | if (txq->stopped && |
171 | txq->pending_frames < sc->tx.txq_max_pending[q]) { | 171 | txq->pending_frames < sc->tx.txq_max_pending[q]) { |
172 | ieee80211_wake_queue(sc->hw, info->hw_queue); | 172 | if (ath9k_is_chanctx_enabled()) |
173 | ieee80211_wake_queue(sc->hw, info->hw_queue); | ||
174 | else | ||
175 | ieee80211_wake_queue(sc->hw, q); | ||
173 | txq->stopped = false; | 176 | txq->stopped = false; |
174 | } | 177 | } |
175 | } | 178 | } |
@@ -2247,7 +2250,10 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2247 | fi->txq = q; | 2250 | fi->txq = q; |
2248 | if (++txq->pending_frames > sc->tx.txq_max_pending[q] && | 2251 | if (++txq->pending_frames > sc->tx.txq_max_pending[q] && |
2249 | !txq->stopped) { | 2252 | !txq->stopped) { |
2250 | ieee80211_stop_queue(sc->hw, info->hw_queue); | 2253 | if (ath9k_is_chanctx_enabled()) |
2254 | ieee80211_stop_queue(sc->hw, info->hw_queue); | ||
2255 | else | ||
2256 | ieee80211_stop_queue(sc->hw, q); | ||
2251 | txq->stopped = true; | 2257 | txq->stopped = true; |
2252 | } | 2258 | } |
2253 | } | 2259 | } |