Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 135111
b: refs/heads/master
c: 8089cc4
h: refs/heads/master
i:
  135109: 3726a9f
  135107: cfc145d
  135103: ec842c8
v: v3
  • Loading branch information
Jouni Malinen authored and John W. Linville committed Mar 5, 2009
1 parent 40ac745 commit 5c5c744
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7ec3e514d9361596cbd8aa71ce41d6e5b0220103
refs/heads/master: 8089cc47ed45df8f5a44f92f53140e6fd0958409
2 changes: 2 additions & 0 deletions trunk/drivers/net/wireless/ath9k/ath9k.h
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,7 @@ struct ath_wiphy {
ATH_WIPHY_ACTIVE,
ATH_WIPHY_PAUSING,
ATH_WIPHY_PAUSED,
ATH_WIPHY_SCAN,
} state;
int chan_idx;
int chan_is_ht;
Expand Down Expand Up @@ -716,5 +717,6 @@ void ath9k_wiphy_chan_work(struct work_struct *work);
bool ath9k_wiphy_started(struct ath_softc *sc);
void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
struct ath_wiphy *selected);
bool ath9k_wiphy_scanning(struct ath_softc *sc);

#endif /* ATH9K_H */
35 changes: 26 additions & 9 deletions trunk/drivers/net/wireless/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2077,7 +2077,7 @@ static int ath9k_tx(struct ieee80211_hw *hw,
struct ath_tx_control txctl;
int hdrlen, padsize;

if (aphy->state != ATH_WIPHY_ACTIVE) {
if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
printk(KERN_DEBUG "ath9k: %s: TX in unexpected wiphy state "
"%d\n", wiphy_name(hw->wiphy), aphy->state);
goto exit;
Expand Down Expand Up @@ -2348,14 +2348,16 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
aphy->chan_idx = pos;
aphy->chan_is_ht = conf_is_ht(conf);

/* TODO: do not change operation channel immediately if there
* are other virtual wiphys that use another channel. For now,
* we do the change immediately to allow mac80211-operated scan
* to work. Once the scan operation is moved into ath9k, we can
* just move the current aphy in PAUSED state if the channel is
* changed into something different from the current operation
* channel. */
ath9k_wiphy_pause_all_forced(sc, aphy);
if (aphy->state == ATH_WIPHY_SCAN ||
aphy->state == ATH_WIPHY_ACTIVE)
ath9k_wiphy_pause_all_forced(sc, aphy);
else {
/*
* Do not change operational channel based on a paused
* wiphy changes.
*/
goto skip_chan_change;
}

DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
curchan->center_freq);
Expand All @@ -2372,6 +2374,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
}
}

skip_chan_change:
if (changed & IEEE80211_CONF_CHANGE_POWER)
sc->config.txpowlimit = 2 * conf->power_level;

Expand Down Expand Up @@ -2731,6 +2734,19 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;

if (ath9k_wiphy_scanning(sc)) {
printk(KERN_DEBUG "ath9k: Two wiphys trying to scan at the "
"same time\n");
/*
* Do not allow the concurrent scanning state for now. This
* could be improved with scanning control moved into ath9k.
*/
return;
}

aphy->state = ATH_WIPHY_SCAN;
ath9k_wiphy_pause_all_forced(sc, aphy);

mutex_lock(&sc->mutex);
sc->sc_flags |= SC_OP_SCANNING;
mutex_unlock(&sc->mutex);
Expand All @@ -2742,6 +2758,7 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
struct ath_softc *sc = aphy->sc;

mutex_lock(&sc->mutex);
aphy->state = ATH_WIPHY_ACTIVE;
sc->sc_flags &= ~SC_OP_SCANNING;
mutex_unlock(&sc->mutex);
}
Expand Down
41 changes: 40 additions & 1 deletion trunk/drivers/net/wireless/ath9k/virtual.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,28 @@ static bool ath9k_wiphy_pausing(struct ath_softc *sc)
return ret;
}

static bool __ath9k_wiphy_scanning(struct ath_softc *sc)
{
int i;
if (sc->pri_wiphy->state == ATH_WIPHY_SCAN)
return true;
for (i = 0; i < sc->num_sec_wiphy; i++) {
if (sc->sec_wiphy[i] &&
sc->sec_wiphy[i]->state == ATH_WIPHY_SCAN)
return true;
}
return false;
}

bool ath9k_wiphy_scanning(struct ath_softc *sc)
{
bool ret;
spin_lock_bh(&sc->wiphy_lock);
ret = __ath9k_wiphy_scanning(sc);
spin_unlock_bh(&sc->wiphy_lock);
return ret;
}

static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy);

/* caller must hold wiphy_lock */
Expand Down Expand Up @@ -463,6 +485,16 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy)
bool now;

spin_lock_bh(&sc->wiphy_lock);
if (__ath9k_wiphy_scanning(sc)) {
/*
* For now, we are using mac80211 sw scan and it expects to
* have full control over channel changes, so avoid wiphy
* scheduling during a scan. This could be optimized if the
* scanning control were moved into the driver.
*/
spin_unlock_bh(&sc->wiphy_lock);
return -EBUSY;
}
if (__ath9k_wiphy_pausing(sc)) {
if (sc->wiphy_select_failures == 0)
sc->wiphy_select_first_fail = jiffies;
Expand Down Expand Up @@ -537,7 +569,14 @@ bool ath9k_wiphy_started(struct ath_softc *sc)
static void ath9k_wiphy_pause_chan(struct ath_wiphy *aphy,
struct ath_wiphy *selected)
{
if (aphy->chan_idx == selected->chan_idx)
if (selected->state == ATH_WIPHY_SCAN) {
if (aphy == selected)
return;
/*
* Pause all other wiphys for the duration of the scan even if
* they are on the current channel now.
*/
} else if (aphy->chan_idx == selected->chan_idx)
return;
aphy->state = ATH_WIPHY_PAUSED;
ieee80211_stop_queues(aphy->hw);
Expand Down

0 comments on commit 5c5c744

Please sign in to comment.