diff options
author | Sujith Manoharan <c_manoha@qca.qualcomm.com> | 2014-09-19 13:00:42 +0530 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-09-26 17:06:51 -0400 |
commit | 2ce73c02743f0abf7dbf0cc05cf0f92cf7ed951d (patch) | |
tree | f42fa6dd7a6e471a106ee573bd7ff8715d3eff32 | |
parent | fbf019909173c683d85f7f63b0a33746bf5e4a02 (diff) | |
download | linux-2ce73c02743f0abf7dbf0cc05cf0f92cf7ed951d.tar.gz linux-2ce73c02743f0abf7dbf0cc05cf0f92cf7ed951d.tar.bz2 linux-2ce73c02743f0abf7dbf0cc05cf0f92cf7ed951d.zip |
ath9k: Fix p2p address management
When multiple channel contexts are enabled, a p2p interface
that is assigned to a context will have an address that
is different from the device mac address, which is used
by wpa_s as the p2p device ID.
Certain frames like provision requests use the device address
and these get dropped since ath9k_calculate_summary_state()
iterates over only the active interfaces in a context and the
device address is not used.
Fix this by adding the device mac address to the bssid mask.
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/ath9k.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 36 |
2 files changed, 37 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index d2a1ee1b072d..37a5ccf64dff 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -354,6 +354,7 @@ struct ath_chanctx { bool switch_after_beacon; short nvifs; + short nvifs_assigned; unsigned int rxfilter; }; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 78fc5398c99e..32f9db9bd53c 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -940,6 +940,34 @@ static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data, } } +static void ath9k_update_bssid_mask(struct ath_softc *sc, + struct ath_chanctx *ctx, + struct ath9k_vif_iter_data *iter_data) +{ + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_vif *avp; + int i; + + if (!ath9k_is_chanctx_enabled()) + return; + + list_for_each_entry(avp, &ctx->vifs, list) { + if (ctx->nvifs_assigned != 1) + continue; + + if (!avp->vif->p2p || !iter_data->has_hw_macaddr) + continue; + + ether_addr_copy(common->curbssid, avp->bssid); + + /* perm_addr will be used as the p2p device address. */ + for (i = 0; i < ETH_ALEN; i++) + iter_data->mask[i] &= + ~(iter_data->hw_macaddr[i] ^ + sc->hw->wiphy->perm_addr[i]); + } +} + /* Called with sc->mutex held. */ void ath9k_calculate_iter_data(struct ath_softc *sc, struct ath_chanctx *ctx, @@ -958,6 +986,8 @@ void ath9k_calculate_iter_data(struct ath_softc *sc, list_for_each_entry(avp, &ctx->vifs, list) ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif); + + ath9k_update_bssid_mask(sc, ctx, iter_data); } static void ath9k_set_assoc_state(struct ath_softc *sc, @@ -1122,6 +1152,10 @@ void ath9k_calculate_summary_state(struct ath_softc *sc, else clear_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags); + ath_dbg(common, CONFIG, + "macaddr: %pM, bssid: %pM, bssidmask: %pM\n", + common->macaddr, common->curbssid, common->bssidmask); + ath9k_ps_restore(sc); } @@ -2356,6 +2390,7 @@ static int ath9k_assign_vif_chanctx(struct ieee80211_hw *hw, conf->def.chan->center_freq); avp->chanctx = ctx; + ctx->nvifs_assigned++; list_add_tail(&avp->list, &ctx->vifs); ath9k_calculate_summary_state(sc, ctx); for (i = 0; i < IEEE80211_NUM_ACS; i++) @@ -2384,6 +2419,7 @@ static void ath9k_unassign_vif_chanctx(struct ieee80211_hw *hw, conf->def.chan->center_freq); avp->chanctx = NULL; + ctx->nvifs_assigned--; list_del(&avp->list); ath9k_calculate_summary_state(sc, ctx); for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) |