aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath9k/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath9k/main.c')
-rw-r--r--drivers/net/wireless/ath9k/main.c27
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*/
239static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) 239int 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 */
417static void ath_update_chainmask(struct ath_softc *sc, int is_ht) 417void 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 */
1920static void ath9k_update_ichannel(struct ath_softc *sc, 1923void 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;