Skip to content

Commit

Permalink
ath9k: Set offchannel state properly
Browse files Browse the repository at this point in the history
When switching offchannel, BSS related information
in the HW has to be reset to default values. Add a routine
to do this.

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Sujith Manoharan authored and John W. Linville committed Sep 15, 2014
1 parent 7f30eac commit 4ee26de
Showing 1 changed file with 42 additions and 15 deletions.
57 changes: 42 additions & 15 deletions drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -953,21 +953,6 @@ 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);

#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
if (ctx == &sc->offchannel.chan) {
struct ieee80211_vif *vif;

if (sc->offchannel.state < ATH_OFFCHANNEL_ROC_START)
vif = sc->offchannel.scan_vif;
else
vif = sc->offchannel.roc_vif;

if (vif)
ath9k_vif_iter(iter_data, vif->addr, vif);
iter_data->beacons = false;
}
#endif
}

static void ath9k_set_assoc_state(struct ath_softc *sc,
Expand Down Expand Up @@ -1007,6 +992,43 @@ static void ath9k_set_assoc_state(struct ath_softc *sc,
vif->addr, common->curbssid);
}

#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
static void ath9k_set_offchannel_state(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_vif *vif = NULL;

ath9k_ps_wakeup(sc);

if (sc->offchannel.state < ATH_OFFCHANNEL_ROC_START)
vif = sc->offchannel.scan_vif;
else
vif = sc->offchannel.roc_vif;

if (WARN_ON(!vif))
goto exit;

eth_zero_addr(common->curbssid);
eth_broadcast_addr(common->bssidmask);
ether_addr_copy(common->macaddr, vif->addr);
common->curaid = 0;
ah->opmode = vif->type;
ah->imask &= ~ATH9K_INT_SWBA;
ah->imask &= ~ATH9K_INT_TSFOOR;
ah->slottime = ATH9K_SLOT_TIME_9;

ath_hw_setbssidmask(common);
ath9k_hw_setopmode(ah);
ath9k_hw_write_associd(sc->sc_ah);
ath9k_hw_set_interrupts(ah);
ath9k_hw_init_global_settings(ah);

exit:
ath9k_ps_restore(sc);
}
#endif

/* Called with sc->mutex held. */
void ath9k_calculate_summary_state(struct ath_softc *sc,
struct ath_chanctx *ctx)
Expand All @@ -1021,6 +1043,11 @@ void ath9k_calculate_summary_state(struct ath_softc *sc,
if (ctx != sc->cur_chan)
return;

#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
if (ctx == &sc->offchannel.chan)
return ath9k_set_offchannel_state(sc);
#endif

ath9k_ps_wakeup(sc);
ath9k_calculate_iter_data(sc, ctx, &iter_data);

Expand Down

0 comments on commit 4ee26de

Please sign in to comment.