Commit cb35582a authored by Sujith Manoharan's avatar Sujith Manoharan Committed by John W. Linville

ath9k: Cache BSS information

Using the BSS information stored in mac80211 directly
is racy in certain conditions. For example, in a MCC
setup, if the scheduler is switching channels when
a local deauth is issued, calculation of the opmode/bssid
etc. is incorrect. To avoid this, store the bss params
in the driver and use it.
Signed-off-by: default avatarSujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 093ec3c5
...@@ -585,6 +585,11 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, ...@@ -585,6 +585,11 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
struct ath_vif { struct ath_vif {
struct list_head list; struct list_head list;
/* BSS info */
u8 bssid[ETH_ALEN];
u16 aid;
bool assoc;
struct ieee80211_vif *vif; struct ieee80211_vif *vif;
struct ath_node mcast_node; struct ath_node mcast_node;
int av_bslot; int av_bslot;
......
...@@ -211,7 +211,7 @@ void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx) ...@@ -211,7 +211,7 @@ void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx)
switch (vif->type) { switch (vif->type) {
case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
if (vif->bss_conf.assoc) if (avp->assoc)
active = true; active = true;
break; break;
default: default:
...@@ -917,7 +917,7 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp, ...@@ -917,7 +917,7 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
switch (vif->type) { switch (vif->type) {
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
if (!vif->bss_conf.assoc) if (!avp->assoc)
return false; return false;
skb = ieee80211_nullfunc_get(sc->hw, vif); skb = ieee80211_nullfunc_get(sc->hw, vif);
...@@ -1339,7 +1339,7 @@ void ath9k_p2p_ps_timer(void *priv) ...@@ -1339,7 +1339,7 @@ void ath9k_p2p_ps_timer(void *priv)
rcu_read_lock(); rcu_read_lock();
vif = avp->vif; vif = avp->vif;
sta = ieee80211_find_sta(vif, vif->bss_conf.bssid); sta = ieee80211_find_sta(vif, avp->bssid);
if (!sta) if (!sta)
goto out; goto out;
......
...@@ -898,6 +898,7 @@ static bool ath9k_uses_beacons(int type) ...@@ -898,6 +898,7 @@ static bool ath9k_uses_beacons(int type)
static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data, static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data,
u8 *mac, struct ieee80211_vif *vif) u8 *mac, struct ieee80211_vif *vif)
{ {
struct ath_vif *avp = (struct ath_vif *)vif->drv_priv;
int i; int i;
if (iter_data->has_hw_macaddr) { if (iter_data->has_hw_macaddr) {
...@@ -918,7 +919,7 @@ static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data, ...@@ -918,7 +919,7 @@ static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data,
break; break;
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
iter_data->nstations++; iter_data->nstations++;
if (vif->bss_conf.assoc && !iter_data->primary_sta) if (avp->assoc && !iter_data->primary_sta)
iter_data->primary_sta = vif; iter_data->primary_sta = vif;
break; break;
case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_ADHOC:
...@@ -963,13 +964,13 @@ static void ath9k_set_assoc_state(struct ath_softc *sc, ...@@ -963,13 +964,13 @@ static void ath9k_set_assoc_state(struct ath_softc *sc,
struct ieee80211_vif *vif, bool changed) struct ieee80211_vif *vif, bool changed)
{ {
struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; struct ath_vif *avp = (struct ath_vif *)vif->drv_priv;
unsigned long flags; unsigned long flags;
set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags); set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);
ether_addr_copy(common->curbssid, bss_conf->bssid); ether_addr_copy(common->curbssid, avp->bssid);
common->curaid = bss_conf->aid; common->curaid = avp->aid;
ath9k_hw_write_associd(sc->sc_ah); ath9k_hw_write_associd(sc->sc_ah);
if (changed) { if (changed) {
...@@ -1698,6 +1699,10 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, ...@@ -1698,6 +1699,10 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
ath_dbg(common, CONFIG, "BSSID %pM Changed ASSOC %d\n", ath_dbg(common, CONFIG, "BSSID %pM Changed ASSOC %d\n",
bss_conf->bssid, bss_conf->assoc); bss_conf->bssid, bss_conf->assoc);
ether_addr_copy(avp->bssid, bss_conf->bssid);
avp->aid = bss_conf->aid;
avp->assoc = bss_conf->assoc;
ath9k_calculate_summary_state(sc, avp->chanctx); ath9k_calculate_summary_state(sc, avp->chanctx);
if (ath9k_is_chanctx_enabled()) { if (ath9k_is_chanctx_enabled()) {
......
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