aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath9k/main.c
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2009-03-03 12:23:32 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-03-05 14:39:46 -0500
commit0e2dedf971f3feefd4d3d3d8cb5c57b1757f1101 (patch)
tree8ae3400d17331c000ac204ab85a970434f5e5233 /drivers/net/wireless/ath9k/main.c
parentf0ed85c6c7960b26666db013e02e748b56eef98a (diff)
ath9k: Add routines for switching between active virtual wiphys
ath9k_wiphy_select() can be used to select a virtual wiphy to be activated. Other virtual wiphys will be paused and once that is done, the operational channel is changed and the wiphys that are on the selected channel will be unpaused. Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
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;