diff options
Diffstat (limited to 'drivers/net/wireless/ath9k/main.c')
-rw-r--r-- | drivers/net/wireless/ath9k/main.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 7e44013ba6e7..44959010c547 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -236,11 +236,11 @@ static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band) | |||
236 | * by reseting the chip. To accomplish this we must first cleanup any pending | 236 | * by reseting the chip. To accomplish this we must first cleanup any pending |
237 | * DMA, then restart stuff. | 237 | * DMA, then restart stuff. |
238 | */ | 238 | */ |
239 | static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) | 239 | int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, |
240 | struct ath9k_channel *hchan) | ||
240 | { | 241 | { |
241 | struct ath_hw *ah = sc->sc_ah; | 242 | struct ath_hw *ah = sc->sc_ah; |
242 | bool fastcc = true, stopped; | 243 | bool fastcc = true, stopped; |
243 | struct ieee80211_hw *hw = sc->hw; | ||
244 | struct ieee80211_channel *channel = hw->conf.channel; | 244 | struct ieee80211_channel *channel = hw->conf.channel; |
245 | int r; | 245 | int r; |
246 | 246 | ||
@@ -414,7 +414,7 @@ set_timer: | |||
414 | * the chainmask configuration, for bt coexistence, use | 414 | * the chainmask configuration, for bt coexistence, use |
415 | * the chainmask configuration even in legacy mode. | 415 | * the chainmask configuration even in legacy mode. |
416 | */ | 416 | */ |
417 | static void ath_update_chainmask(struct ath_softc *sc, int is_ht) | 417 | void ath_update_chainmask(struct ath_softc *sc, int is_ht) |
418 | { | 418 | { |
419 | sc->sc_flags |= SC_OP_CHAINMASK_UPDATE; | 419 | sc->sc_flags |= SC_OP_CHAINMASK_UPDATE; |
420 | if (is_ht || | 420 | if (is_ht || |
@@ -1324,6 +1324,7 @@ void ath_detach(struct ath_softc *sc) | |||
1324 | ath_deinit_rfkill(sc); | 1324 | ath_deinit_rfkill(sc); |
1325 | #endif | 1325 | #endif |
1326 | ath_deinit_leds(sc); | 1326 | ath_deinit_leds(sc); |
1327 | cancel_work_sync(&sc->chan_work); | ||
1327 | 1328 | ||
1328 | for (i = 0; i < sc->num_sec_wiphy; i++) { | 1329 | for (i = 0; i < sc->num_sec_wiphy; i++) { |
1329 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | 1330 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; |
@@ -1669,6 +1670,8 @@ int ath_attach(u16 devid, struct ath_softc *sc) | |||
1669 | ath9k_reg_apply_radar_flags(hw->wiphy); | 1670 | ath9k_reg_apply_radar_flags(hw->wiphy); |
1670 | ath9k_reg_apply_world_flags(hw->wiphy, REGDOM_SET_BY_INIT); | 1671 | ath9k_reg_apply_world_flags(hw->wiphy, REGDOM_SET_BY_INIT); |
1671 | 1672 | ||
1673 | INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); | ||
1674 | |||
1672 | error = ieee80211_register_hw(hw); | 1675 | error = ieee80211_register_hw(hw); |
1673 | 1676 | ||
1674 | if (!ath9k_is_world_regd(sc->sc_ah)) { | 1677 | if (!ath9k_is_world_regd(sc->sc_ah)) { |
@@ -1917,10 +1920,9 @@ int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc) | |||
1917 | 1920 | ||
1918 | /* XXX: Remove me once we don't depend on ath9k_channel for all | 1921 | /* XXX: Remove me once we don't depend on ath9k_channel for all |
1919 | * this redundant data */ | 1922 | * this redundant data */ |
1920 | static void ath9k_update_ichannel(struct ath_softc *sc, | 1923 | void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, |
1921 | struct ath9k_channel *ichan) | 1924 | struct ath9k_channel *ichan) |
1922 | { | 1925 | { |
1923 | struct ieee80211_hw *hw = sc->hw; | ||
1924 | struct ieee80211_channel *chan = hw->conf.channel; | 1926 | struct ieee80211_channel *chan = hw->conf.channel; |
1925 | struct ieee80211_conf *conf = &hw->conf; | 1927 | struct ieee80211_conf *conf = &hw->conf; |
1926 | 1928 | ||
@@ -1967,8 +1969,9 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1967 | 1969 | ||
1968 | pos = curchan->hw_value; | 1970 | pos = curchan->hw_value; |
1969 | 1971 | ||
1972 | sc->chan_idx = pos; | ||
1970 | init_channel = &sc->sc_ah->channels[pos]; | 1973 | init_channel = &sc->sc_ah->channels[pos]; |
1971 | ath9k_update_ichannel(sc, init_channel); | 1974 | ath9k_update_ichannel(sc, hw, init_channel); |
1972 | 1975 | ||
1973 | /* Reset SERDES registers */ | 1976 | /* Reset SERDES registers */ |
1974 | ath9k_hw_configpcipowersave(sc->sc_ah, 0); | 1977 | ath9k_hw_configpcipowersave(sc->sc_ah, 0); |
@@ -2307,15 +2310,21 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2307 | struct ieee80211_channel *curchan = hw->conf.channel; | 2310 | struct ieee80211_channel *curchan = hw->conf.channel; |
2308 | int pos = curchan->hw_value; | 2311 | int pos = curchan->hw_value; |
2309 | 2312 | ||
2313 | aphy->chan_idx = pos; | ||
2314 | aphy->chan_is_ht = conf_is_ht(conf); | ||
2315 | |||
2316 | /* TODO: do not change operation channel immediately if there | ||
2317 | * are other virtual wiphys that use another channel */ | ||
2318 | |||
2310 | DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n", | 2319 | DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n", |
2311 | curchan->center_freq); | 2320 | curchan->center_freq); |
2312 | 2321 | ||
2313 | /* XXX: remove me eventualy */ | 2322 | /* XXX: remove me eventualy */ |
2314 | ath9k_update_ichannel(sc, &sc->sc_ah->channels[pos]); | 2323 | ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]); |
2315 | 2324 | ||
2316 | ath_update_chainmask(sc, conf_is_ht(conf)); | 2325 | ath_update_chainmask(sc, conf_is_ht(conf)); |
2317 | 2326 | ||
2318 | if (ath_set_channel(sc, &sc->sc_ah->channels[pos]) < 0) { | 2327 | if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { |
2319 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n"); | 2328 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n"); |
2320 | mutex_unlock(&sc->mutex); | 2329 | mutex_unlock(&sc->mutex); |
2321 | return -EINVAL; | 2330 | return -EINVAL; |