Commit 9fa23e17 authored by Felix Fietkau's avatar Felix Fietkau Committed by John W. Linville

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: default avatarFelix Fietkau <nbd@openwrt.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent e0e9bc82
...@@ -270,7 +270,6 @@ struct ath_node { ...@@ -270,7 +270,6 @@ struct ath_node {
struct ath_atx_ac ac[WME_NUM_AC]; struct ath_atx_ac ac[WME_NUM_AC];
u16 maxampdu; u16 maxampdu;
u8 mpdudensity; u8 mpdudensity;
int last_rssi;
}; };
#define AGGR_CLEANUP BIT(1) #define AGGR_CLEANUP BIT(1)
...@@ -662,6 +661,7 @@ struct ath_wiphy { ...@@ -662,6 +661,7 @@ struct ath_wiphy {
bool idle; bool idle;
int chan_idx; int chan_idx;
int chan_is_ht; int chan_is_ht;
int last_rssi;
}; };
void ath9k_tasklet(unsigned long data); void ath9k_tasklet(unsigned long data);
......
...@@ -703,6 +703,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, ...@@ -703,6 +703,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
const struct ath_bus_ops *bus_ops) const struct ath_bus_ops *bus_ops)
{ {
struct ieee80211_hw *hw = sc->hw; struct ieee80211_hw *hw = sc->hw;
struct ath_wiphy *aphy = hw->priv;
struct ath_common *common; struct ath_common *common;
struct ath_hw *ah; struct ath_hw *ah;
int error = 0; int error = 0;
...@@ -752,6 +753,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, ...@@ -752,6 +753,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
sc->wiphy_scheduler_int = msecs_to_jiffies(500); sc->wiphy_scheduler_int = msecs_to_jiffies(500);
aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
ath_init_leds(sc); ath_init_leds(sc);
ath_start_rfkill_poll(sc); ath_start_rfkill_poll(sc);
......
...@@ -562,7 +562,6 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) ...@@ -562,7 +562,6 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
sta->ht_cap.ampdu_factor); sta->ht_cap.ampdu_factor);
an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
an->last_rssi = ATH_RSSI_DUMMY_MARKER;
} }
} }
...@@ -831,9 +830,11 @@ static u32 ath_get_extchanmode(struct ath_softc *sc, ...@@ -831,9 +830,11 @@ static u32 ath_get_extchanmode(struct ath_softc *sc,
} }
static void ath9k_bss_assoc_info(struct ath_softc *sc, static void ath9k_bss_assoc_info(struct ath_softc *sc,
struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf) struct ieee80211_bss_conf *bss_conf)
{ {
struct ath_wiphy *aphy = hw->priv;
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
...@@ -857,6 +858,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, ...@@ -857,6 +858,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
ath_beacon_config(sc, vif); ath_beacon_config(sc, vif);
/* Reset rssi stats */ /* Reset rssi stats */
aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
sc->sc_flags |= SC_OP_ANI_RUN; sc->sc_flags |= SC_OP_ANI_RUN;
...@@ -1998,7 +2000,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, ...@@ -1998,7 +2000,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_ASSOC) { if (changed & BSS_CHANGED_ASSOC) {
ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
bss_conf->assoc); bss_conf->assoc);
ath9k_bss_assoc_info(sc, vif, bss_conf); ath9k_bss_assoc_info(sc, hw, vif, bss_conf);
} }
mutex_unlock(&sc->mutex); mutex_unlock(&sc->mutex);
......
...@@ -962,36 +962,23 @@ static void ath9k_process_rssi(struct ath_common *common, ...@@ -962,36 +962,23 @@ static void ath9k_process_rssi(struct ath_common *common,
struct ieee80211_hdr *hdr, struct ieee80211_hdr *hdr,
struct ath_rx_status *rx_stats) struct ath_rx_status *rx_stats)
{ {
struct ath_wiphy *aphy = hw->priv;
struct ath_hw *ah = common->ah; struct ath_hw *ah = common->ah;
struct ieee80211_sta *sta; int last_rssi;
struct ath_node *an;
int last_rssi = ATH_RSSI_DUMMY_MARKER;
__le16 fc; __le16 fc;
fc = hdr->frame_control; if (ah->opmode != NL80211_IFTYPE_STATION)
return;
rcu_read_lock(); fc = hdr->frame_control;
/* if (!ieee80211_is_beacon(fc) ||
* XXX: use ieee80211_find_sta! This requires quite a bit of work compare_ether_addr(hdr->addr3, common->curbssid))
* under the current ath9k virtual wiphy implementation as we have return;
* no way of tying a vif to wiphy. Typically vifs are attached to
* at least one sdata of a wiphy on mac80211 but with ath9k virtual
* wiphy you'd have to iterate over every wiphy and each sdata.
*/
if (is_multicast_ether_addr(hdr->addr1))
sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, NULL);
else
sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, hdr->addr1);
if (sta) { if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && !rx_stats->rs_moreaggr)
an = (struct ath_node *) sta->drv_priv; ATH_RSSI_LPF(aphy->last_rssi, rx_stats->rs_rssi);
if (rx_stats->rs_rssi != ATH9K_RSSI_BAD &&
!rx_stats->rs_moreaggr)
ATH_RSSI_LPF(an->last_rssi, rx_stats->rs_rssi);
last_rssi = an->last_rssi;
}
rcu_read_unlock();
last_rssi = aphy->last_rssi;
if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
rx_stats->rs_rssi = ATH_EP_RND(last_rssi, rx_stats->rs_rssi = ATH_EP_RND(last_rssi,
ATH_RSSI_EP_MULTIPLIER); ATH_RSSI_EP_MULTIPLIER);
...@@ -999,7 +986,6 @@ static void ath9k_process_rssi(struct ath_common *common, ...@@ -999,7 +986,6 @@ static void ath9k_process_rssi(struct ath_common *common,
rx_stats->rs_rssi = 0; rx_stats->rs_rssi = 0;
/* Update Beacon RSSI, this is used by ANI. */ /* Update Beacon RSSI, this is used by ANI. */
if (ieee80211_is_beacon(fc))
ah->stats.avgbrssi = rx_stats->rs_rssi; ah->stats.avgbrssi = rx_stats->rs_rssi;
} }
......
...@@ -107,6 +107,7 @@ int ath9k_wiphy_add(struct ath_softc *sc) ...@@ -107,6 +107,7 @@ int ath9k_wiphy_add(struct ath_softc *sc)
aphy->sc = sc; aphy->sc = sc;
aphy->hw = hw; aphy->hw = hw;
sc->sec_wiphy[i] = aphy; sc->sec_wiphy[i] = aphy;
aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
spin_unlock_bh(&sc->wiphy_lock); spin_unlock_bh(&sc->wiphy_lock);
memcpy(addr, common->macaddr, ETH_ALEN); memcpy(addr, common->macaddr, ETH_ALEN);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment