From: Felix Fietkau Date: Mon, 29 Aug 2011 08:00:00 +0000 (+0000) Subject: ath9k: minor fixes for the antenna control patch X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=8643ea587a96f4db9aa43babf0bd678018fa4b38;p=openwrt%2Fstaging%2Fstintel.git ath9k: minor fixes for the antenna control patch SVN-Revision: 28109 --- diff --git a/package/mac80211/patches/582-ath9k_antdiv_comb_cb.patch b/package/mac80211/patches/582-ath9k_antdiv_comb_cb.patch deleted file mode 100644 index 92c8ea4b8b..0000000000 --- a/package/mac80211/patches/582-ath9k_antdiv_comb_cb.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/hw-ops.h -+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h -@@ -121,13 +121,15 @@ static inline void ath9k_hw_set_clrdmask - static inline void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah, - struct ath_hw_antcomb_conf *antconf) - { -- ath9k_hw_ops(ah)->antdiv_comb_conf_get(ah, antconf); -+ if (ath9k_hw_ops(ah)->antdiv_comb_conf_get) -+ ath9k_hw_ops(ah)->antdiv_comb_conf_get(ah, antconf); - } - - static inline void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah, - struct ath_hw_antcomb_conf *antconf) - { -- ath9k_hw_ops(ah)->antdiv_comb_conf_set(ah, antconf); -+ if (ath9k_hw_ops(ah)->antdiv_comb_conf_set) -+ ath9k_hw_ops(ah)->antdiv_comb_conf_set(ah, antconf); - } - - /* Private hardware call ops */ ---- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c -+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c -@@ -570,8 +570,10 @@ void ar9002_hw_attach_phy_ops(struct ath - priv_ops->compute_pll_control = ar9002_hw_compute_pll_control; - priv_ops->do_getnf = ar9002_hw_do_getnf; - -- ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get; -- ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set; -+ if (AR_SREV_9285(ah)) { -+ ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get; -+ ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set; -+ } - - ar9002_hw_set_nf_limits(ah); - } ---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c -@@ -1283,8 +1283,10 @@ void ar9003_hw_attach_phy_ops(struct ath - priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs; - priv_ops->set_radar_params = ar9003_hw_set_radar_params; - -- ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get; -- ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set; -+ if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) { -+ ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get; -+ ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set; -+ } - - ar9003_hw_set_nf_limits(ah); - ar9003_hw_set_radar_conf(ah); diff --git a/package/mac80211/patches/582-ath9k_antenna_control.patch b/package/mac80211/patches/582-ath9k_antenna_control.patch new file mode 100644 index 0000000000..ecd86808d7 --- /dev/null +++ b/package/mac80211/patches/582-ath9k_antenna_control.patch @@ -0,0 +1,178 @@ +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -652,9 +652,22 @@ static void ath9k_init_txpower_limits(st + ah->curchan = curchan; + } + ++void ath9k_reload_chainmask_settings(struct ath_softc *sc) ++{ ++ if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)) ++ return; ++ ++ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) ++ setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); ++ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) ++ setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); ++} ++ ++ + void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) + { +- struct ath_common *common = ath9k_hw_common(sc->sc_ah); ++ struct ath_hw *ah = sc->sc_ah; ++ struct ath_common *common = ath9k_hw_common(ah); + + hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | +@@ -692,6 +705,16 @@ void ath9k_set_hw_capab(struct ath_softc + hw->sta_data_size = sizeof(struct ath_node); + hw->vif_data_size = sizeof(struct ath_vif); + ++ hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1; ++ hw->wiphy->available_antennas_tx = BIT(ah->caps.max_txchains) - 1; ++ ++ /* single chain devices with rx diversity */ ++ if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) ++ hw->wiphy->available_antennas_rx = BIT(0) | BIT(1); ++ ++ sc->ant_rx = hw->wiphy->available_antennas_rx; ++ sc->ant_tx = hw->wiphy->available_antennas_tx; ++ + #ifdef CONFIG_ATH9K_RATE_CONTROL + hw->rate_control_algorithm = "ath9k_rate_control"; + #endif +@@ -703,12 +726,7 @@ void ath9k_set_hw_capab(struct ath_softc + hw->wiphy->bands[IEEE80211_BAND_5GHZ] = + &sc->sbands[IEEE80211_BAND_5GHZ]; + +- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { +- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) +- setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); +- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) +- setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); +- } ++ ath9k_reload_chainmask_settings(sc); + + SET_IEEE80211_PERM_ADDR(hw, common->macaddr); + } +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -652,6 +652,7 @@ struct ath_softc { + struct ath_descdma txsdma; + + struct ath_ant_comb ant_comb; ++ u8 ant_tx, ant_rx; + }; + + void ath9k_tasklet(unsigned long data); +@@ -673,6 +674,7 @@ int ath9k_init_device(u16 devid, struct + const struct ath_bus_ops *bus_ops); + void ath9k_deinit_device(struct ath_softc *sc); + void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); ++void ath9k_reload_chainmask_settings(struct ath_softc *sc); + + void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); + bool ath9k_uses_beacons(int type); +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -262,6 +262,22 @@ static bool ath_complete_reset(struct at + ath_start_ani(common); + } + ++ if (ath9k_hw_ops(ah)->antdiv_comb_conf_get && sc->ant_rx != 3) { ++ struct ath_hw_antcomb_conf div_ant_conf; ++ u8 lna_conf; ++ ++ ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf); ++ ++ if (sc->ant_rx == 1) ++ lna_conf = ATH_ANT_DIV_COMB_LNA1; ++ else ++ lna_conf = ATH_ANT_DIV_COMB_LNA2; ++ div_ant_conf.main_lna_conf = lna_conf; ++ div_ant_conf.alt_lna_conf = lna_conf; ++ ++ ath9k_hw_antdiv_comb_conf_set(ah, &div_ant_conf); ++ } ++ + ieee80211_wake_queues(sc->hw); + + return true; +@@ -2360,6 +2376,59 @@ static int ath9k_get_stats(struct ieee80 + return 0; + } + ++static u32 fill_chainmask(u32 cap, u32 new) ++{ ++ u32 filled = 0; ++ int i; ++ ++ for (i = 0; cap && new; i++, cap >>= 1) { ++ if (!(cap & BIT(0))) ++ continue; ++ ++ if (new & BIT(0)) ++ filled |= BIT(i); ++ ++ new >>= 1; ++ } ++ ++ return filled; ++} ++ ++static int ath9k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) ++{ ++ struct ath_softc *sc = hw->priv; ++ struct ath_hw *ah = sc->sc_ah; ++ ++ if (!rx_ant || !tx_ant) ++ return -EINVAL; ++ ++ sc->ant_rx = rx_ant; ++ sc->ant_tx = tx_ant; ++ ++ if (ah->caps.rx_chainmask == 1) ++ return 0; ++ ++ /* AR9100 runs into calibration issues if not all rx chains are enabled */ ++ if (AR_SREV_9100(ah)) ++ ah->rxchainmask = 0x7; ++ else ++ ah->rxchainmask = fill_chainmask(ah->caps.rx_chainmask, rx_ant); ++ ++ ah->txchainmask = fill_chainmask(ah->caps.tx_chainmask, tx_ant); ++ ath9k_reload_chainmask_settings(sc); ++ ++ return 0; ++} ++ ++static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) ++{ ++ struct ath_softc *sc = hw->priv; ++ ++ *tx_ant = sc->ant_tx; ++ *rx_ant = sc->ant_rx; ++ return 0; ++} ++ + struct ieee80211_ops ath9k_ops = { + .tx = ath9k_tx, + .start = ath9k_start, +@@ -2386,4 +2455,6 @@ struct ieee80211_ops ath9k_ops = { + .tx_frames_pending = ath9k_tx_frames_pending, + .tx_last_beacon = ath9k_tx_last_beacon, + .get_stats = ath9k_get_stats, ++ .set_antenna = ath9k_set_antenna, ++ .get_antenna = ath9k_get_antenna, + }; +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -1956,7 +1956,7 @@ int ath_rx_tasklet(struct ath_softc *sc, + ath_rx_ps(sc, skb); + spin_unlock_irqrestore(&sc->sc_pm_lock, flags); + +- if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) ++ if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx == 3) + ath_ant_comb_scan(sc, &rs); + + ieee80211_rx(hw, skb); diff --git a/package/mac80211/patches/583-ath9k_antenna_control.patch b/package/mac80211/patches/583-ath9k_antenna_control.patch deleted file mode 100644 index a1caa8aaa9..0000000000 --- a/package/mac80211/patches/583-ath9k_antenna_control.patch +++ /dev/null @@ -1,179 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/init.c -+++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -652,9 +652,22 @@ static void ath9k_init_txpower_limits(st - ah->curchan = curchan; - } - -+void ath9k_reload_chainmask_settings(struct ath_softc *sc) -+{ -+ if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)) -+ return; -+ -+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) -+ setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); -+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) -+ setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); -+} -+ -+ - void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) - { -- struct ath_common *common = ath9k_hw_common(sc->sc_ah); -+ struct ath_hw *ah = sc->sc_ah; -+ struct ath_common *common = ath9k_hw_common(ah); - - hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | -@@ -692,6 +705,17 @@ void ath9k_set_hw_capab(struct ath_softc - hw->sta_data_size = sizeof(struct ath_node); - hw->vif_data_size = sizeof(struct ath_vif); - -+ hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1; -+ hw->wiphy->available_antennas_tx = BIT(ah->caps.max_txchains) - 1; -+ -+ /* single chain devices with rx diversity */ -+ if (ah->caps.max_rxchains == 1 && -+ ath9k_hw_ops(ah)->antdiv_comb_conf_get) -+ hw->wiphy->available_antennas_rx = 3; -+ -+ sc->ant_rx = hw->wiphy->available_antennas_rx; -+ sc->ant_tx = hw->wiphy->available_antennas_tx; -+ - #ifdef CONFIG_ATH9K_RATE_CONTROL - hw->rate_control_algorithm = "ath9k_rate_control"; - #endif -@@ -703,12 +727,7 @@ void ath9k_set_hw_capab(struct ath_softc - hw->wiphy->bands[IEEE80211_BAND_5GHZ] = - &sc->sbands[IEEE80211_BAND_5GHZ]; - -- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { -- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) -- setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); -- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) -- setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); -- } -+ ath9k_reload_chainmask_settings(sc); - - SET_IEEE80211_PERM_ADDR(hw, common->macaddr); - } ---- a/drivers/net/wireless/ath/ath9k/ath9k.h -+++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -652,6 +652,7 @@ struct ath_softc { - struct ath_descdma txsdma; - - struct ath_ant_comb ant_comb; -+ u32 ant_tx, ant_rx; - }; - - void ath9k_tasklet(unsigned long data); -@@ -673,6 +674,7 @@ int ath9k_init_device(u16 devid, struct - const struct ath_bus_ops *bus_ops); - void ath9k_deinit_device(struct ath_softc *sc); - void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); -+void ath9k_reload_chainmask_settings(struct ath_softc *sc); - - void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); - bool ath9k_uses_beacons(int type); ---- a/drivers/net/wireless/ath/ath9k/main.c -+++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -262,6 +262,22 @@ static bool ath_complete_reset(struct at - ath_start_ani(common); - } - -+ if (ath9k_hw_ops(ah)->antdiv_comb_conf_get && sc->ant_rx != 3) { -+ struct ath_hw_antcomb_conf div_ant_conf; -+ u8 lna_conf; -+ -+ ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf); -+ -+ if (sc->ant_rx == 1) -+ lna_conf = ATH_ANT_DIV_COMB_LNA1; -+ else -+ lna_conf = ATH_ANT_DIV_COMB_LNA2; -+ div_ant_conf.main_lna_conf = lna_conf; -+ div_ant_conf.alt_lna_conf = lna_conf; -+ -+ ath9k_hw_antdiv_comb_conf_set(ah, &div_ant_conf); -+ } -+ - ieee80211_wake_queues(sc->hw); - - return true; -@@ -2360,6 +2376,59 @@ static int ath9k_get_stats(struct ieee80 - return 0; - } - -+static u32 fill_chainmask(u32 cap, u32 new) -+{ -+ u32 filled = 0; -+ int i; -+ -+ for (i = 0; cap && new; i++, cap >>= 1) { -+ if (!(cap & BIT(0))) -+ continue; -+ -+ if (new & BIT(0)) -+ filled |= BIT(i); -+ -+ new >>= 1; -+ } -+ -+ return filled; -+} -+ -+static int ath9k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) -+{ -+ struct ath_softc *sc = hw->priv; -+ struct ath_hw *ah = sc->sc_ah; -+ -+ if (!rx_ant || !tx_ant) -+ return -EINVAL; -+ -+ sc->ant_rx = rx_ant; -+ sc->ant_tx = tx_ant; -+ -+ if (ah->caps.rx_chainmask == 1) -+ return 0; -+ -+ /* AR9100 runs into calibration issues if not all rx chains are enabled */ -+ if (AR_SREV_9100(ah)) -+ ah->rxchainmask = 0x7; -+ else -+ ah->rxchainmask = fill_chainmask(ah->caps.rx_chainmask, rx_ant); -+ -+ ah->txchainmask = fill_chainmask(ah->caps.tx_chainmask, tx_ant); -+ ath9k_reload_chainmask_settings(sc); -+ -+ return 0; -+} -+ -+static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) -+{ -+ struct ath_softc *sc = hw->priv; -+ -+ *tx_ant = sc->ant_tx; -+ *rx_ant = sc->ant_rx; -+ return 0; -+} -+ - struct ieee80211_ops ath9k_ops = { - .tx = ath9k_tx, - .start = ath9k_start, -@@ -2386,4 +2455,6 @@ struct ieee80211_ops ath9k_ops = { - .tx_frames_pending = ath9k_tx_frames_pending, - .tx_last_beacon = ath9k_tx_last_beacon, - .get_stats = ath9k_get_stats, -+ .set_antenna = ath9k_set_antenna, -+ .get_antenna = ath9k_get_antenna, - }; ---- a/drivers/net/wireless/ath/ath9k/recv.c -+++ b/drivers/net/wireless/ath/ath9k/recv.c -@@ -1956,7 +1956,7 @@ int ath_rx_tasklet(struct ath_softc *sc, - ath_rx_ps(sc, skb); - spin_unlock_irqrestore(&sc->sc_pm_lock, flags); - -- if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) -+ if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx == 3) - ath_ant_comb_scan(sc, &rs); - - ieee80211_rx(hw, skb);