aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-10-15 14:03:31 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-11-09 16:13:24 -0500
commit9fa23e1741404207c414fad69212a8763c138bf0 (patch)
tree884ce215ce933b8f6266f92b3e51162a9dc30631
parente0e9bc82fb0813fd353b0abbba0f1d6a680cc77c (diff)
ath9k: optimize/fix ANI RSSI processing
ANI needs the RSSI average only in station mode, and only for tracking the signal strength of beacons of the AP that it is connected to. Adjust the code to track on the beacon RSSI, and store the average of that in the ath_wiphy struct. With these changes, we can get rid of this extra station lookup in the rx path, which saves precious CPU cycles. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c38
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c1
5 files changed, 20 insertions, 29 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 9b8e7e3fcebd..81fed83add7a 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -270,7 +270,6 @@ struct ath_node {
270 struct ath_atx_ac ac[WME_NUM_AC]; 270 struct ath_atx_ac ac[WME_NUM_AC];
271 u16 maxampdu; 271 u16 maxampdu;
272 u8 mpdudensity; 272 u8 mpdudensity;
273 int last_rssi;
274}; 273};
275 274
276#define AGGR_CLEANUP BIT(1) 275#define AGGR_CLEANUP BIT(1)
@@ -662,6 +661,7 @@ struct ath_wiphy {
662 bool idle; 661 bool idle;
663 int chan_idx; 662 int chan_idx;
664 int chan_is_ht; 663 int chan_is_ht;
664 int last_rssi;
665}; 665};
666 666
667void ath9k_tasklet(unsigned long data); 667void ath9k_tasklet(unsigned long data);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 95b41db0d86b..12f4fd79c907 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -703,6 +703,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
703 const struct ath_bus_ops *bus_ops) 703 const struct ath_bus_ops *bus_ops)
704{ 704{
705 struct ieee80211_hw *hw = sc->hw; 705 struct ieee80211_hw *hw = sc->hw;
706 struct ath_wiphy *aphy = hw->priv;
706 struct ath_common *common; 707 struct ath_common *common;
707 struct ath_hw *ah; 708 struct ath_hw *ah;
708 int error = 0; 709 int error = 0;
@@ -752,6 +753,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
752 INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); 753 INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
753 INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); 754 INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
754 sc->wiphy_scheduler_int = msecs_to_jiffies(500); 755 sc->wiphy_scheduler_int = msecs_to_jiffies(500);
756 aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
755 757
756 ath_init_leds(sc); 758 ath_init_leds(sc);
757 ath_start_rfkill_poll(sc); 759 ath_start_rfkill_poll(sc);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index ade9d7c16032..7185ef3a3bff 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -562,7 +562,6 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
562 an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + 562 an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
563 sta->ht_cap.ampdu_factor); 563 sta->ht_cap.ampdu_factor);
564 an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); 564 an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
565 an->last_rssi = ATH_RSSI_DUMMY_MARKER;
566 } 565 }
567} 566}
568 567
@@ -831,9 +830,11 @@ static u32 ath_get_extchanmode(struct ath_softc *sc,
831} 830}
832 831
833static void ath9k_bss_assoc_info(struct ath_softc *sc, 832static void ath9k_bss_assoc_info(struct ath_softc *sc,
833 struct ieee80211_hw *hw,
834 struct ieee80211_vif *vif, 834 struct ieee80211_vif *vif,
835 struct ieee80211_bss_conf *bss_conf) 835 struct ieee80211_bss_conf *bss_conf)
836{ 836{
837 struct ath_wiphy *aphy = hw->priv;
837 struct ath_hw *ah = sc->sc_ah; 838 struct ath_hw *ah = sc->sc_ah;
838 struct ath_common *common = ath9k_hw_common(ah); 839 struct ath_common *common = ath9k_hw_common(ah);
839 840
@@ -857,6 +858,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
857 ath_beacon_config(sc, vif); 858 ath_beacon_config(sc, vif);
858 859
859 /* Reset rssi stats */ 860 /* Reset rssi stats */
861 aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
860 sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; 862 sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
861 863
862 sc->sc_flags |= SC_OP_ANI_RUN; 864 sc->sc_flags |= SC_OP_ANI_RUN;
@@ -1998,7 +2000,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1998 if (changed & BSS_CHANGED_ASSOC) { 2000 if (changed & BSS_CHANGED_ASSOC) {
1999 ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", 2001 ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
2000 bss_conf->assoc); 2002 bss_conf->assoc);
2001 ath9k_bss_assoc_info(sc, vif, bss_conf); 2003 ath9k_bss_assoc_info(sc, hw, vif, bss_conf);
2002 } 2004 }
2003 2005
2004 mutex_unlock(&sc->mutex); 2006 mutex_unlock(&sc->mutex);
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index fddb0129bb57..c04a940550bd 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -962,36 +962,23 @@ static void ath9k_process_rssi(struct ath_common *common,
962 struct ieee80211_hdr *hdr, 962 struct ieee80211_hdr *hdr,
963 struct ath_rx_status *rx_stats) 963 struct ath_rx_status *rx_stats)
964{ 964{
965 struct ath_wiphy *aphy = hw->priv;
965 struct ath_hw *ah = common->ah; 966 struct ath_hw *ah = common->ah;
966 struct ieee80211_sta *sta; 967 int last_rssi;
967 struct ath_node *an;
968 int last_rssi = ATH_RSSI_DUMMY_MARKER;
969 __le16 fc; 968 __le16 fc;
970 969
970 if (ah->opmode != NL80211_IFTYPE_STATION)
971 return;
972
971 fc = hdr->frame_control; 973 fc = hdr->frame_control;
974 if (!ieee80211_is_beacon(fc) ||
975 compare_ether_addr(hdr->addr3, common->curbssid))
976 return;
972 977
973 rcu_read_lock(); 978 if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && !rx_stats->rs_moreaggr)
974 /* 979 ATH_RSSI_LPF(aphy->last_rssi, rx_stats->rs_rssi);
975 * XXX: use ieee80211_find_sta! This requires quite a bit of work
976 * under the current ath9k virtual wiphy implementation as we have
977 * no way of tying a vif to wiphy. Typically vifs are attached to
978 * at least one sdata of a wiphy on mac80211 but with ath9k virtual
979 * wiphy you'd have to iterate over every wiphy and each sdata.
980 */
981 if (is_multicast_ether_addr(hdr->addr1))
982 sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, NULL);
983 else
984 sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, hdr->addr1);
985
986 if (sta) {
987 an = (struct ath_node *) sta->drv_priv;
988 if (rx_stats->rs_rssi != ATH9K_RSSI_BAD &&
989 !rx_stats->rs_moreaggr)
990 ATH_RSSI_LPF(an->last_rssi, rx_stats->rs_rssi);
991 last_rssi = an->last_rssi;
992 }
993 rcu_read_unlock();
994 980
981 last_rssi = aphy->last_rssi;
995 if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) 982 if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
996 rx_stats->rs_rssi = ATH_EP_RND(last_rssi, 983 rx_stats->rs_rssi = ATH_EP_RND(last_rssi,
997 ATH_RSSI_EP_MULTIPLIER); 984 ATH_RSSI_EP_MULTIPLIER);
@@ -999,8 +986,7 @@ static void ath9k_process_rssi(struct ath_common *common,
999 rx_stats->rs_rssi = 0; 986 rx_stats->rs_rssi = 0;
1000 987
1001 /* Update Beacon RSSI, this is used by ANI. */ 988 /* Update Beacon RSSI, this is used by ANI. */
1002 if (ieee80211_is_beacon(fc)) 989 ah->stats.avgbrssi = rx_stats->rs_rssi;
1003 ah->stats.avgbrssi = rx_stats->rs_rssi;
1004} 990}
1005 991
1006/* 992/*
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index ec7cf5ee56bc..cb6c48be1245 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -107,6 +107,7 @@ int ath9k_wiphy_add(struct ath_softc *sc)
107 aphy->sc = sc; 107 aphy->sc = sc;
108 aphy->hw = hw; 108 aphy->hw = hw;
109 sc->sec_wiphy[i] = aphy; 109 sc->sec_wiphy[i] = aphy;
110 aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
110 spin_unlock_bh(&sc->wiphy_lock); 111 spin_unlock_bh(&sc->wiphy_lock);
111 112
112 memcpy(addr, common->macaddr, ETH_ALEN); 113 memcpy(addr, common->macaddr, ETH_ALEN);