2012-03-20 14:40:08

by Michal Kazior

[permalink] [raw]
Subject: [RFC 05/12] mac80211: split channel state

We split channel state to a separate structure. This makes it easier to
wrap functions around channel operations alone without worrying whether
it's comming from ieee80211_local or ieee80211_sub_if_data.

Later a function: ieee80211_get_channel_state(local, sdata) would be
introduced to proxy access to appropriate ieee80211_channel_state
structure.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/adm8211.c | 2 +-
drivers/net/wireless/at76c50x-usb.c | 4 +-
drivers/net/wireless/ath/ath5k/base.c | 2 +-
drivers/net/wireless/ath/ath5k/mac80211-ops.c | 4 +-
drivers/net/wireless/ath/ath9k/ani.c | 4 +-
drivers/net/wireless/ath/ath9k/beacon.c | 2 +-
drivers/net/wireless/ath/ath9k/calib.c | 2 +-
drivers/net/wireless/ath/ath9k/common.c | 4 +-
drivers/net/wireless/ath/ath9k/htc_drv_main.c | 14 +++---
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 8 ++--
drivers/net/wireless/ath/ath9k/hw.c | 4 +-
drivers/net/wireless/ath/ath9k/main.c | 10 ++--
drivers/net/wireless/ath/ath9k/rc.c | 6 +-
drivers/net/wireless/ath/ath9k/recv.c | 6 +-
drivers/net/wireless/ath/carl9170/debug.c | 4 +-
drivers/net/wireless/ath/carl9170/mac.c | 8 ++--
drivers/net/wireless/ath/carl9170/main.c | 6 +-
drivers/net/wireless/ath/carl9170/phy.c | 4 +-
drivers/net/wireless/b43/b43.h | 2 +-
drivers/net/wireless/b43/main.c | 8 ++--
drivers/net/wireless/b43/phy_ht.c | 4 +-
drivers/net/wireless/b43/phy_lcn.c | 4 +-
drivers/net/wireless/b43/phy_n.c | 4 +-
drivers/net/wireless/b43legacy/main.c | 8 ++--
.../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 6 +-
drivers/net/wireless/iwlegacy/3945-rs.c | 2 +-
drivers/net/wireless/iwlegacy/4965-rs.c | 2 +-
drivers/net/wireless/iwlegacy/common.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 2 +-
drivers/net/wireless/libertas_tf/main.c | 8 ++--
drivers/net/wireless/mac80211_hwsim.c | 8 ++--
drivers/net/wireless/mwl8k.c | 30 +++++-----
drivers/net/wireless/p54/fwio.c | 4 +-
drivers/net/wireless/p54/main.c | 4 +-
drivers/net/wireless/p54/txrx.c | 4 +-
drivers/net/wireless/rt2x00/rt2800lib.c | 6 +-
drivers/net/wireless/rt2x00/rt2x00config.c | 10 ++--
drivers/net/wireless/rt2x00/rt61pci.c | 2 +-
drivers/net/wireless/rt2x00/rt73usb.c | 2 +-
drivers/net/wireless/rtl818x/rtl8180/dev.c | 4 +-
drivers/net/wireless/rtl818x/rtl8180/grf5101.c | 2 +-
drivers/net/wireless/rtl818x/rtl8180/max2820.c | 2 +-
drivers/net/wireless/rtl818x/rtl8180/rtl8225.c | 2 +-
drivers/net/wireless/rtl818x/rtl8180/sa2400.c | 2 +-
drivers/net/wireless/rtl818x/rtl8187/dev.c | 4 +-
drivers/net/wireless/rtl818x/rtl8187/rtl8225.c | 2 +-
drivers/net/wireless/rtlwifi/base.c | 4 +-
drivers/net/wireless/rtlwifi/core.c | 6 +-
drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 4 +-
drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 8 ++--
drivers/net/wireless/rtlwifi/rtl8192de/trx.c | 4 +-
drivers/net/wireless/rtlwifi/rtl8192se/trx.c | 4 +-
drivers/net/wireless/wl1251/main.c | 4 +-
drivers/net/wireless/wl12xx/main.c | 14 +++---
drivers/net/wireless/zd1211rw/zd_mac.c | 4 +-
include/net/mac80211.h | 27 ++++++---
net/mac80211/cfg.c | 54 +++++++++++--------
net/mac80211/chan.c | 8 ++-
net/mac80211/debugfs.c | 5 +-
net/mac80211/driver-trace.h | 4 +-
net/mac80211/ibss.c | 22 +++++---
net/mac80211/ieee80211_i.h | 23 ++++++--
net/mac80211/iface.c | 10 ++--
net/mac80211/main.c | 40 ++++++++------
net/mac80211/mesh.c | 18 ++++---
net/mac80211/mesh_hwmp.c | 3 +-
net/mac80211/mesh_plink.c | 8 ++-
net/mac80211/mlme.c | 55 ++++++++++++--------
net/mac80211/rate.h | 3 +-
net/mac80211/rc80211_minstrel_ht.c | 7 ++-
net/mac80211/rx.c | 5 +-
net/mac80211/scan.c | 6 ++-
net/mac80211/tx.c | 15 ++++--
net/mac80211/util.c | 32 ++++++++----
net/mac80211/work.c | 21 ++++----
76 files changed, 371 insertions(+), 283 deletions(-)

diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index f5ce562..51ed961 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -1293,7 +1293,7 @@ static int adm8211_config(struct ieee80211_hw *dev, u32 changed)
{
struct adm8211_priv *priv = dev->priv;
struct ieee80211_conf *conf = &dev->conf;
- int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
+ int channel = ieee80211_frequency_to_channel(conf->chan_conf->channel->center_freq);

if (channel != priv->channel) {
priv->channel = channel;
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 4045e5a..f0aee73 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1973,12 +1973,12 @@ static int at76_config(struct ieee80211_hw *hw, u32 changed)
struct at76_priv *priv = hw->priv;

at76_dbg(DBG_MAC80211, "%s(): channel %d",
- __func__, hw->conf.channel->hw_value);
+ __func__, hw->conf.chan_conf->channel->hw_value);
at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:");

mutex_lock(&priv->mtx);

- priv->channel = hw->conf.channel->hw_value;
+ priv->channel = hw->conf.chan_conf->channel->hw_value;

if (is_valid_ether_addr(priv->bssid))
at76_join(priv);
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 0e643b0..6dcac46 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2623,7 +2623,7 @@ int ath5k_start(struct ieee80211_hw *hw)
* be followed by initialization of the appropriate bits
* and then setup of the interrupt mask.
*/
- ah->curchan = ah->hw->conf.channel;
+ ah->curchan = ah->hw->conf.chan_conf->channel;
ah->imask = AR5K_INT_RXOK
| AR5K_INT_RXERR
| AR5K_INT_RXEOL
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index 5c53299..63fcafc 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -199,7 +199,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
mutex_lock(&ah->lock);

if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
- ret = ath5k_chan_set(ah, conf->channel);
+ ret = ath5k_chan_set(ah, conf->chan_conf->channel);
if (ret < 0)
goto unlock;
}
@@ -672,7 +672,7 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey)

memcpy(survey, &ah->survey, sizeof(*survey));

- survey->channel = conf->channel;
+ survey->channel = conf->chan_conf->channel;
survey->noise = ah->ah_noise_floor;
survey->filled = SURVEY_INFO_NOISE_DBM |
SURVEY_INFO_CHANNEL_TIME |
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index bc56f57..9f7f38f 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -209,7 +209,7 @@ static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah)
aniState->firstepLevel + 1);
return;
} else {
- if ((conf->channel->band == IEEE80211_BAND_2GHZ) &&
+ if ((conf->chan_conf->channel->band == IEEE80211_BAND_2GHZ) &&
!conf_is_ht(conf)) {
if (!aniState->ofdmWeakSigDetectOff)
ath9k_hw_ani_control(ah,
@@ -249,7 +249,7 @@ static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah)
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
aniState->firstepLevel + 1);
} else {
- if ((conf->channel->band == IEEE80211_BAND_2GHZ) &&
+ if ((conf->chan_conf->channel->band == IEEE80211_BAND_2GHZ) &&
!conf_is_ht(conf)) {
if (aniState->firstepLevel > 0)
ath9k_hw_ani_control(ah,
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 6264182..532b667 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -80,7 +80,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif,

ath9k_reset_beacon_status(sc);

- sband = &sc->sbands[common->hw->conf.channel->band];
+ sband = &sc->sbands[common->hw->conf.chan_conf->channel->band];
rate = sband->bitrates[rateidx].hw_value;
if (vif->bss_conf.use_short_preamble)
rate |= sband->bitrates[rateidx].hw_value_short;
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 2f4b48e..75f0ec5 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -208,7 +208,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
return true;

ath_dbg(common, CALIBRATE, "Resetting Cal %d state for channel %u\n",
- currCal->calData->calType, conf->channel->center_freq);
+ currCal->calData->calType, conf->chan_conf->channel->center_freq);

ah->caldata->CalValid &= ~currCal->calData->calType;
currCal->calState = CAL_WAITING;
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index 905f1b3..d822d05 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -133,13 +133,13 @@ EXPORT_SYMBOL(ath9k_cmn_update_ichannel);
struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
struct ath_hw *ah)
{
- struct ieee80211_channel *curchan = hw->conf.channel;
+ struct ieee80211_channel *curchan = hw->conf.chan_conf->channel;
struct ath9k_channel *channel;
u8 chan_idx;

chan_idx = curchan->hw_value;
channel = &ah->channels[chan_idx];
- ath9k_cmn_update_ichannel(channel, curchan, hw->conf.channel_type);
+ ath9k_cmn_update_ichannel(channel, curchan, hw->conf.chan_conf->channel_type);

return channel;
}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 2b8f61c..d66ae61 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -183,7 +183,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv)
{
struct ath_hw *ah = priv->ah;
struct ath_common *common = ath9k_hw_common(ah);
- struct ieee80211_channel *channel = priv->hw->conf.channel;
+ struct ieee80211_channel *channel = priv->hw->conf.chan_conf->channel;
struct ath9k_hw_cal_data *caldata = NULL;
enum htc_phymode mode;
__be16 htc_mode;
@@ -243,7 +243,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_conf *conf = &common->hw->conf;
bool fastcc;
- struct ieee80211_channel *channel = hw->conf.channel;
+ struct ieee80211_channel *channel = hw->conf.chan_conf->channel;
struct ath9k_hw_cal_data *caldata = NULL;
enum htc_phymode mode;
__be16 htc_mode;
@@ -599,7 +599,7 @@ static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv,
u32 caps = 0;
int i, j;

- sband = priv->hw->wiphy->bands[priv->hw->conf.channel->band];
+ sband = priv->hw->wiphy->bands[priv->hw->conf.chan_conf->channel->band];

for (i = 0, j = 0; i < sband->n_bitrates; i++) {
if (sta->supp_rates[sband->band] & BIT(i)) {
@@ -899,7 +899,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
struct ath9k_htc_priv *priv = hw->priv;
struct ath_hw *ah = priv->ah;
struct ath_common *common = ath9k_hw_common(ah);
- struct ieee80211_channel *curchan = hw->conf.channel;
+ struct ieee80211_channel *curchan = hw->conf.chan_conf->channel;
struct ath9k_channel *init_channel;
int ret = 0;
enum htc_phymode mode;
@@ -1211,15 +1211,15 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
}

if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
- struct ieee80211_channel *curchan = hw->conf.channel;
+ struct ieee80211_channel *curchan = hw->conf.chan_conf->channel;
int pos = curchan->hw_value;

ath_dbg(common, CONFIG, "Set channel: %d MHz\n",
curchan->center_freq);

ath9k_cmn_update_ichannel(&priv->ah->channels[pos],
- hw->conf.channel,
- hw->conf.channel_type);
+ hw->conf.chan_conf->channel,
+ hw->conf.chan_conf->channel_type);

if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
ath_err(common, "Unable to set channel\n");
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 3e40a64..b1e106f 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -490,7 +490,7 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,
if (txs->ts_flags & ATH9K_HTC_TXSTAT_SGI)
rate->flags |= IEEE80211_TX_RC_SHORT_GI;
} else {
- if (cur_conf->channel->band == IEEE80211_BAND_5GHZ)
+ if (cur_conf->chan_conf->channel->band == IEEE80211_BAND_5GHZ)
rate->idx += 4; /* No CCK rates */
}

@@ -939,7 +939,7 @@ static void ath9k_process_rate(struct ieee80211_hw *hw,
return;
}

- band = hw->conf.channel->band;
+ band = hw->conf.chan_conf->channel->band;
sband = hw->wiphy->bands[band];

for (i = 0; i < sband->n_bitrates; i++) {
@@ -1078,8 +1078,8 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;

rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp);
- rx_status->band = hw->conf.channel->band;
- rx_status->freq = hw->conf.channel->center_freq;
+ rx_status->band = hw->conf.chan_conf->channel->band;
+ rx_status->freq = hw->conf.chan_conf->channel->center_freq;
rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
rx_status->antenna = rxbuf->rxstatus.rs_antenna;
rx_status->flag |= RX_FLAG_MACTIME_MPDU;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 3022c4e..b42e61b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -94,7 +94,7 @@ static void ath9k_hw_set_clockrate(struct ath_hw *ah)
clockrate = 117;
else if (!ah->curchan) /* should really check for CCK instead */
clockrate = ATH9K_CLOCK_RATE_CCK;
- else if (conf->channel->band == IEEE80211_BAND_2GHZ)
+ else if (conf->chan_conf->channel->band == IEEE80211_BAND_2GHZ)
clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)
clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
@@ -1041,7 +1041,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
* BA frames in some implementations, but it has been found to fix ACK
* timeout issues in other cases as well.
*/
- if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ) {
+ if (conf->chan_conf->channel && conf->chan_conf->channel->band == IEEE80211_BAND_2GHZ) {
acktimeout += 64 - sifstime - ah->slottime;
ctstimeout += 48 - sifstime - ah->slottime;
}
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 3879485..4a324b7 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -409,7 +409,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int
txctl.txq = sc->tx.txq_map[WME_AC_BE];

memset(tx_info, 0, sizeof(*tx_info));
- tx_info->band = hw->conf.channel->band;
+ tx_info->band = hw->conf.chan_conf->channel->band;
tx_info->flags |= IEEE80211_TX_CTL_NO_ACK;
tx_info->control.rates[0].idx = 0;
tx_info->control.rates[0].count = 1;
@@ -983,7 +983,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
struct ath_softc *sc = hw->priv;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
- struct ieee80211_channel *curchan = hw->conf.channel;
+ struct ieee80211_channel *curchan = hw->conf.chan_conf->channel;
struct ath9k_channel *init_channel;
int r;

@@ -1587,7 +1587,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
}

if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
- struct ieee80211_channel *curchan = hw->conf.channel;
+ struct ieee80211_channel *curchan = hw->conf.chan_conf->channel;
int pos = curchan->hw_value;
int old_pos = -1;
unsigned long flags;
@@ -1601,7 +1601,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
sc->sc_flags &= ~SC_OP_OFFCHANNEL;

ath_dbg(common, CONFIG, "Set channel: %d MHz type: %d\n",
- curchan->center_freq, conf->channel_type);
+ curchan->center_freq, conf->chan_conf->channel_type);

/* update survey stats for the old channel before switching */
spin_lock_irqsave(&common->cc_lock, flags);
@@ -1616,7 +1616,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
ath9k_hw_getnf(ah, ah->curchan);

ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
- curchan, conf->channel_type);
+ curchan, conf->chan_conf->channel_type);

/*
* If the operating channel changes, change the survey in-use flags
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 4f84849..b1c58f0 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -740,7 +740,7 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,

/* All protection frames are transmited at 2Mb/s for 802.11g,
* otherwise we transmit them at 1Mb/s */
- if (sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ &&
+ if (sc->hw->conf.chan_conf->channel->band == IEEE80211_BAND_2GHZ &&
!conf_is_ht(&sc->hw->conf))
enable_g_protection = 1;

@@ -868,7 +868,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
* So, set fourth rate in series to be same as third one for
* above conditions.
*/
- if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) &&
+ if ((sc->hw->conf.chan_conf->channel->band == IEEE80211_BAND_2GHZ) &&
(conf_is_ht(&sc->hw->conf))) {
u8 dot11rate = rate_table->info[rix].dot11rate;
u8 phy = rate_table->info[rix].phy;
@@ -1473,7 +1473,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,

ath_dbg(ath9k_hw_common(sc->sc_ah), CONFIG,
"Operating HT Bandwidth changed to: %d\n",
- sc->hw->conf.channel_type);
+ sc->hw->conf.chan_conf->channel_type);
}
}
}
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index f4ae3ba..0420df4 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -903,7 +903,7 @@ static int ath9k_process_rate(struct ath_common *common,
enum ieee80211_band band;
unsigned int i = 0;

- band = hw->conf.channel->band;
+ band = hw->conf.chan_conf->channel->band;
sband = hw->wiphy->bands[band];

if (rx_stats->rs_rate & 0x80) {
@@ -998,8 +998,8 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
if (ath9k_process_rate(common, hw, rx_stats, rx_status))
return -EINVAL;

- rx_status->band = hw->conf.channel->band;
- rx_status->freq = hw->conf.channel->center_freq;
+ rx_status->band = hw->conf.chan_conf->channel->band;
+ rx_status->freq = hw->conf.chan_conf->channel->center_freq;
rx_status->signal = ah->noise + rx_stats->rs_rssi;
rx_status->antenna = rx_stats->rs_antenna;
rx_status->flag |= RX_FLAG_MACTIME_MPDU;
diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c
index 3c16422..43dd22c 100644
--- a/drivers/net/wireless/ath/carl9170/debug.c
+++ b/drivers/net/wireless/ath/carl9170/debug.c
@@ -659,8 +659,8 @@ static ssize_t carl9170_debugfs_bug_write(struct ar9170 *ar, const char *buf,
goto out;

case 'P':
- err = carl9170_set_channel(ar, ar->hw->conf.channel,
- ar->hw->conf.channel_type, CARL9170_RFI_COLD);
+ err = carl9170_set_channel(ar, ar->hw->conf.chan_conf->channel,
+ ar->hw->conf.chan_conf->channel_type, CARL9170_RFI_COLD);
if (err < 0)
count = err;

diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c
index 53415bf..91f6bfa 100644
--- a/drivers/net/wireless/ath/carl9170/mac.c
+++ b/drivers/net/wireless/ath/carl9170/mac.c
@@ -48,7 +48,7 @@ int carl9170_set_dyn_sifs_ack(struct ar9170 *ar)
if (conf_is_ht40(&ar->hw->conf))
val = 0x010a;
else {
- if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+ if (ar->hw->conf.chan_conf->channel->band == IEEE80211_BAND_2GHZ)
val = 0x105;
else
val = 0x104;
@@ -66,7 +66,7 @@ int carl9170_set_rts_cts_rate(struct ar9170 *ar)
rts_rate = 0x1da;
cts_rate = 0x10a;
} else {
- if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
+ if (ar->hw->conf.chan_conf->channel->band == IEEE80211_BAND_2GHZ) {
/* 11 mbit CCK */
rts_rate = 033;
cts_rate = 003;
@@ -93,7 +93,7 @@ int carl9170_set_slot_time(struct ar9170 *ar)
return 0;
}

- if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) ||
+ if ((ar->hw->conf.chan_conf->channel->band == IEEE80211_BAND_5GHZ) ||
vif->bss_conf.use_short_slot)
slottime = 9;

@@ -120,7 +120,7 @@ int carl9170_set_mac_rates(struct ar9170 *ar)
basic |= (vif->bss_conf.basic_rates & 0xff0) << 4;
rcu_read_unlock();

- if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
+ if (ar->hw->conf.chan_conf->channel->band == IEEE80211_BAND_5GHZ)
mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */
else
mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 8d2523b..25133a9 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -868,8 +868,8 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
if (err)
goto out;

- err = carl9170_set_channel(ar, hw->conf.channel,
- hw->conf.channel_type, CARL9170_RFI_NONE);
+ err = carl9170_set_channel(ar, hw->conf.chan_conf->channel,
+ hw->conf.chan_conf->channel_type, CARL9170_RFI_NONE);
if (err)
goto out;

@@ -887,7 +887,7 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
}

if (changed & IEEE80211_CONF_CHANGE_POWER) {
- err = carl9170_set_mac_tpc(ar, ar->hw->conf.channel);
+ err = carl9170_set_mac_tpc(ar, ar->hw->conf.chan_conf->channel);
if (err)
goto out;
}
diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
index b72c09c..976ec51 100644
--- a/drivers/net/wireless/ath/carl9170/phy.c
+++ b/drivers/net/wireless/ath/carl9170/phy.c
@@ -1331,7 +1331,7 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw)
* CTL_ETSI for 2GHz and CTL_FCC for 5GHz.
*/
ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory,
- ar->hw->conf.channel->band);
+ ar->hw->conf.chan_conf->channel->band);

/* ctl group not found - either invalid band (NO_CTL) or ww roaming */
if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL)
@@ -1341,7 +1341,7 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw)
/* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */
return;

- if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
+ if (ar->hw->conf.chan_conf->channel->band == IEEE80211_BAND_2GHZ) {
modes = mode_list_2ghz;
nr_modes = ARRAY_SIZE(mode_list_2ghz);
} else {
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 67c13af..cdc54e2 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -966,7 +966,7 @@ static inline int b43_is_mode(struct b43_wl *wl, int type)
*/
static inline enum ieee80211_band b43_current_band(struct b43_wl *wl)
{
- return wl->hw->conf.channel->band;
+ return wl->hw->conf.chan_conf->channel->band;
}

static inline int b43_bus_may_powerdown(struct b43_wldev *wldev)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index c79e663..afc2c02 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3815,7 +3815,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
dev = wl->current_dev;

/* Switch the band (if necessary). This might change the active core. */
- err = b43_switch_band(wl, conf->channel);
+ err = b43_switch_band(wl, conf->chan_conf->channel);
if (err)
goto out_unlock_mutex;

@@ -3845,8 +3845,8 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)

/* Switch to the requested channel.
* The firmware takes care of races with the TX handler. */
- if (conf->channel->hw_value != phy->channel)
- b43_switch_channel(dev, conf->channel->hw_value);
+ if (conf->chan_conf->channel->hw_value != phy->channel)
+ b43_switch_channel(dev, conf->chan_conf->channel->hw_value);

dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);

@@ -4917,7 +4917,7 @@ static int b43_op_get_survey(struct ieee80211_hw *hw, int idx,
if (idx != 0)
return -ENOENT;

- survey->channel = conf->channel;
+ survey->channel = conf->chan_conf->channel;
survey->filled = SURVEY_INFO_NOISE_DBM;
survey->noise = dev->stats.link_noise;

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 7416c5e..3f48cc7 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -525,8 +525,8 @@ static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on)
static int b43_phy_ht_op_switch_channel(struct b43_wldev *dev,
unsigned int new_channel)
{
- struct ieee80211_channel *channel = dev->wl->hw->conf.channel;
- enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type;
+ struct ieee80211_channel *channel = dev->wl->hw->conf.chan_conf->channel;
+ enum nl80211_channel_type channel_type = dev->wl->hw->conf.chan_conf->channel_type;

if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
if ((new_channel < 1) || (new_channel > 14))
diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c
index a13e28e..6d8df04 100644
--- a/drivers/net/wireless/b43/phy_lcn.c
+++ b/drivers/net/wireless/b43/phy_lcn.c
@@ -808,8 +808,8 @@ static void b43_phy_lcn_op_switch_analog(struct b43_wldev *dev, bool on)
static int b43_phy_lcn_op_switch_channel(struct b43_wldev *dev,
unsigned int new_channel)
{
- struct ieee80211_channel *channel = dev->wl->hw->conf.channel;
- enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type;
+ struct ieee80211_channel *channel = dev->wl->hw->conf.chan_conf->channel;
+ enum nl80211_channel_type channel_type = dev->wl->hw->conf.chan_conf->channel_type;

if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
if ((new_channel < 1) || (new_channel > 14))
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 1081188..d753578 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -4939,8 +4939,8 @@ static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
unsigned int new_channel)
{
- struct ieee80211_channel *channel = dev->wl->hw->conf.channel;
- enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type;
+ struct ieee80211_channel *channel = dev->wl->hw->conf.chan_conf->channel;
+ enum nl80211_channel_type channel_type = dev->wl->hw->conf.chan_conf->channel_type;

if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
if ((new_channel < 1) || (new_channel > 14))
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index df7e16d..be95ae5 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2694,7 +2694,7 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
goto out_unlock_mutex;

/* Switch the PHY mode (if necessary). */
- switch (conf->channel->band) {
+ switch (conf->chan_conf->channel->band) {
case IEEE80211_BAND_2GHZ:
if (phy->type == B43legacy_PHYTYPE_B)
new_phymode = B43legacy_PHYMODE_B;
@@ -2722,8 +2722,8 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,

/* Switch to the requested channel.
* The firmware takes care of races with the TX handler. */
- if (conf->channel->hw_value != phy->channel)
- b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0);
+ if (conf->chan_conf->channel->hw_value != phy->channel)
+ b43legacy_radio_selectchannel(dev, conf->chan_conf->channel->hw_value, 0);

dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);

@@ -3532,7 +3532,7 @@ static int b43legacy_op_get_survey(struct ieee80211_hw *hw, int idx,
if (idx != 0)
return -ENOENT;

- survey->channel = conf->channel;
+ survey->channel = conf->chan_conf->channel;
survey->filled = SURVEY_INFO_NOISE_DBM;
survey->noise = dev->stats.link_noise;

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 569ab8a..7bb81fe 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -394,10 +394,10 @@ static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
new_int);
}
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
- if (conf->channel_type == NL80211_CHAN_HT20 ||
- conf->channel_type == NL80211_CHAN_NO_HT)
+ if (conf->chan_conf->channel_type == NL80211_CHAN_HT20 ||
+ conf->chan_conf->channel_type == NL80211_CHAN_NO_HT)
err = brcms_c_set_channel(wl->wlc,
- conf->channel->hw_value);
+ conf->chan_conf->channel->hw_value);
else
err = -ENOTSUPP;
}
diff --git a/drivers/net/wireless/iwlegacy/3945-rs.c b/drivers/net/wireless/iwlegacy/3945-rs.c
index 70bee1a..768e7b4 100644
--- a/drivers/net/wireless/iwlegacy/3945-rs.c
+++ b/drivers/net/wireless/iwlegacy/3945-rs.c
@@ -347,7 +347,7 @@ il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id)

psta = (struct il3945_sta_priv *)sta->drv_priv;
rs_sta = &psta->rs_sta;
- sband = hw->wiphy->bands[conf->channel->band];
+ sband = hw->wiphy->bands[conf->chan_conf->channel->band];

rs_sta->il = il;

diff --git a/drivers/net/wireless/iwlegacy/4965-rs.c b/drivers/net/wireless/iwlegacy/4965-rs.c
index d7e2856..f8921fa 100644
--- a/drivers/net/wireless/iwlegacy/4965-rs.c
+++ b/drivers/net/wireless/iwlegacy/4965-rs.c
@@ -2300,7 +2300,7 @@ il4965_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id)

sta_priv = (struct il_station_priv *)sta->drv_priv;
lq_sta = &sta_priv->lq_sta;
- sband = hw->wiphy->bands[conf->channel->band];
+ sband = hw->wiphy->bands[conf->chan_conf->channel->band];

lq_sta->lq.sta_id = sta_id;

diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index e5ac047..c2d73c9 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -4943,7 +4943,7 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed)
struct il_priv *il = hw->priv;
const struct il_channel_info *ch_info;
struct ieee80211_conf *conf = &hw->conf;
- struct ieee80211_channel *channel = conf->channel;
+ struct ieee80211_channel *channel = conf->chan_conf->channel;
struct il_ht_config *ht_conf = &il->current_ht_config;
unsigned long flags = 0;
int ret = 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 53f8c51..2b3d16d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -2829,7 +2829,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i

sta_priv = (struct iwl_station_priv *) sta->drv_priv;
lq_sta = &sta_priv->lq_sta;
- sband = hw->wiphy->bands[conf->channel->band];
+ sband = hw->wiphy->bands[conf->chan_conf->channel->band];


lq_sta->lq.sta_id = sta_id;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index 2e1a317..ce575d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -543,7 +543,7 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_rxon_context *ctx;
struct ieee80211_conf *conf = &hw->conf;
- struct ieee80211_channel *channel = conf->channel;
+ struct ieee80211_channel *channel = conf->chan_conf->channel;
const struct iwl_channel_info *ch_info;
int ret = 0;

diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
index a034572..3e629e1 100644
--- a/drivers/net/wireless/libertas_tf/main.c
+++ b/drivers/net/wireless/libertas_tf/main.c
@@ -410,9 +410,9 @@ static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed)
struct ieee80211_conf *conf = &hw->conf;
lbtf_deb_enter(LBTF_DEB_MACOPS);

- if (conf->channel->center_freq != priv->cur_freq) {
- priv->cur_freq = conf->channel->center_freq;
- lbtf_set_channel(priv, conf->channel->hw_value);
+ if (conf->chan_conf->channel->center_freq != priv->cur_freq) {
+ priv->cur_freq = conf->chan_conf->channel->center_freq;
+ lbtf_set_channel(priv, conf->chan_conf->channel->hw_value);
}
lbtf_deb_leave(LBTF_DEB_MACOPS);
return 0;
@@ -535,7 +535,7 @@ static int lbtf_op_get_survey(struct ieee80211_hw *hw, int idx,
if (idx != 0)
return -ENOENT;

- survey->channel = conf->channel;
+ survey->channel = conf->chan_conf->channel;
survey->filled = SURVEY_INFO_NOISE_DBM;
survey->noise = priv->noise;

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index b7ce6a6..6741028 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -870,15 +870,15 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
wiphy_debug(hw->wiphy,
"%s (freq=%d/%s idle=%d ps=%d smps=%s)\n",
__func__,
- conf->channel->center_freq,
- hwsim_chantypes[conf->channel_type],
+ conf->chan_conf->channel->center_freq,
+ hwsim_chantypes[conf->chan_conf->channel_type],
!!(conf->flags & IEEE80211_CONF_IDLE),
!!(conf->flags & IEEE80211_CONF_PS),
smps_modes[conf->smps_mode]);

data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);

- data->channel = conf->channel;
+ data->channel = conf->chan_conf->channel;
data->power_level = conf->power_level;
if (!data->started || !data->beacon_int)
del_timer(&data->beacon_timer);
@@ -1038,7 +1038,7 @@ static int mac80211_hwsim_get_survey(
return -ENOENT;

/* Current channel */
- survey->channel = conf->channel;
+ survey->channel = conf->chan_conf->channel;

/*
* Magically conjured noise level --- this is only ok for simulated hardware.
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index ac7c983..216c6e0 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2760,7 +2760,7 @@ static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw,
struct ieee80211_conf *conf,
unsigned short pwr)
{
- struct ieee80211_channel *channel = conf->channel;
+ struct ieee80211_channel *channel = conf->chan_conf->channel;
struct mwl8k_cmd_tx_power *cmd;
int rc;
int i;
@@ -2780,14 +2780,14 @@ static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw,

cmd->channel = cpu_to_le16(channel->hw_value);

- if (conf->channel_type == NL80211_CHAN_NO_HT ||
- conf->channel_type == NL80211_CHAN_HT20) {
+ if (conf->chan_conf->channel_type == NL80211_CHAN_NO_HT ||
+ conf->chan_conf->channel_type == NL80211_CHAN_HT20) {
cmd->bw = cpu_to_le16(0x2);
} else {
cmd->bw = cpu_to_le16(0x4);
- if (conf->channel_type == NL80211_CHAN_HT40MINUS)
+ if (conf->chan_conf->channel_type == NL80211_CHAN_HT40MINUS)
cmd->sub_ch = cpu_to_le16(0x3);
- else if (conf->channel_type == NL80211_CHAN_HT40PLUS)
+ else if (conf->chan_conf->channel_type == NL80211_CHAN_HT40PLUS)
cmd->sub_ch = cpu_to_le16(0x1);
}

@@ -2931,7 +2931,7 @@ struct mwl8k_cmd_set_rf_channel {
static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
struct ieee80211_conf *conf)
{
- struct ieee80211_channel *channel = conf->channel;
+ struct ieee80211_channel *channel = conf->chan_conf->channel;
struct mwl8k_cmd_set_rf_channel *cmd;
int rc;

@@ -2949,12 +2949,12 @@ static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
else if (channel->band == IEEE80211_BAND_5GHZ)
cmd->channel_flags |= cpu_to_le32(0x00000004);

- if (conf->channel_type == NL80211_CHAN_NO_HT ||
- conf->channel_type == NL80211_CHAN_HT20)
+ if (conf->chan_conf->channel_type == NL80211_CHAN_NO_HT ||
+ conf->chan_conf->channel_type == NL80211_CHAN_HT20)
cmd->channel_flags |= cpu_to_le32(0x00000080);
- else if (conf->channel_type == NL80211_CHAN_HT40MINUS)
+ else if (conf->chan_conf->channel_type == NL80211_CHAN_HT40MINUS)
cmd->channel_flags |= cpu_to_le32(0x000001900);
- else if (conf->channel_type == NL80211_CHAN_HT40PLUS)
+ else if (conf->chan_conf->channel_type == NL80211_CHAN_HT40PLUS)
cmd->channel_flags |= cpu_to_le32(0x000000900);

rc = mwl8k_post_cmd(hw, &cmd->header);
@@ -3818,7 +3818,7 @@ static int mwl8k_cmd_set_new_stn_add(struct ieee80211_hw *hw,
memcpy(cmd->mac_addr, sta->addr, ETH_ALEN);
cmd->stn_id = cpu_to_le16(sta->aid);
cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD);
- if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+ if (hw->conf.chan_conf->channel->band == IEEE80211_BAND_2GHZ)
rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
else
rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5;
@@ -4229,7 +4229,7 @@ static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw,
p->ht_caps = cpu_to_le16(sta->ht_cap.cap);
p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) |
((sta->ht_cap.ampdu_density & 7) << 2);
- if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+ if (hw->conf.chan_conf->channel->band == IEEE80211_BAND_2GHZ)
rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
else
rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5;
@@ -4700,7 +4700,7 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
goto out;
}

- if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
+ if (hw->conf.chan_conf->channel->band == IEEE80211_BAND_2GHZ) {
ap_legacy_rates = ap->supp_rates[IEEE80211_BAND_2GHZ];
} else {
ap_legacy_rates =
@@ -4785,7 +4785,7 @@ mwl8k_bss_info_changed_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
if (idx)
idx--;

- if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+ if (hw->conf.chan_conf->channel->band == IEEE80211_BAND_2GHZ)
rate = mwl8k_rates_24[idx].hw_value;
else
rate = mwl8k_rates_50[idx].hw_value;
@@ -5060,7 +5060,7 @@ static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx,
if (idx != 0)
return -ENOENT;

- survey->channel = conf->channel;
+ survey->channel = conf->chan_conf->channel;
survey->filled = SURVEY_INFO_NOISE_DBM;
survey->noise = priv->noise;

diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c
index 18e82b3..533ad8b 100644
--- a/drivers/net/wireless/p54/fwio.c
+++ b/drivers/net/wireless/p54/fwio.c
@@ -402,7 +402,7 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
struct p54_rssi_db_entry *rssi_data;
unsigned int i;
void *entry;
- __le16 freq = cpu_to_le16(priv->hw->conf.channel->center_freq);
+ __le16 freq = cpu_to_le16(priv->hw->conf.chan_conf->channel->center_freq);

skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) +
2 + sizeof(*iq_autocal) + sizeof(*body) +
@@ -532,7 +532,7 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
err:
wiphy_err(priv->hw->wiphy, "frequency change to channel %d failed.\n",
ieee80211_frequency_to_channel(
- priv->hw->conf.channel->center_freq));
+ priv->hw->conf.chan_conf->channel->center_freq));

dev_kfree_skb_any(skb);
return -EINVAL;
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index ee8af1f..ecb617f 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -339,7 +339,7 @@ static int p54_config(struct ieee80211_hw *dev, u32 changed)
* TODO: Use the LM_SCAN_TRAP to determine the current
* operating channel.
*/
- priv->curchan = priv->hw->conf.channel;
+ priv->curchan = priv->hw->conf.chan_conf->channel;
p54_reset_stats(priv);
WARN_ON(p54_fetch_statistics(priv));
}
@@ -479,7 +479,7 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev,
p54_set_edcf(priv);
}
if (changed & BSS_CHANGED_BASIC_RATES) {
- if (dev->conf.channel->band == IEEE80211_BAND_5GHZ)
+ if (dev->conf.chan_conf->channel->band == IEEE80211_BAND_5GHZ)
priv->basic_rate_mask = (info->basic_rates << 4);
else
priv->basic_rate_mask = info->basic_rates;
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index a08a6f0..4a29b0d 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -354,13 +354,13 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb)
rx_status->signal = p54_rssi_to_dbm(priv, hdr->rssi);
if (hdr->rate & 0x10)
rx_status->flag |= RX_FLAG_SHORTPRE;
- if (priv->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
+ if (priv->hw->conf.chan_conf->channel->band == IEEE80211_BAND_5GHZ)
rx_status->rate_idx = (rate < 4) ? 0 : rate - 4;
else
rx_status->rate_idx = rate;

rx_status->freq = freq;
- rx_status->band = priv->hw->conf.channel->band;
+ rx_status->band = priv->hw->conf.chan_conf->channel->band;
rx_status->antenna = hdr->antenna;

tsf32 = le32_to_cpu(hdr->tsf32);
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 6c0a12e..e5bcf18 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2628,11 +2628,11 @@ void rt2800_config(struct rt2x00_dev *rt2x00dev,
if (flags & IEEE80211_CONF_CHANGE_CHANNEL) {
rt2800_config_channel(rt2x00dev, libconf->conf,
&libconf->rf, &libconf->channel);
- rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band,
+ rt2800_config_txpower(rt2x00dev, libconf->conf->chan_conf->channel->band,
libconf->conf->power_level);
}
if (flags & IEEE80211_CONF_CHANGE_POWER)
- rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band,
+ rt2800_config_txpower(rt2x00dev, libconf->conf->chan_conf->channel->band,
libconf->conf->power_level);
if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
rt2800_config_retry_limit(rt2x00dev, libconf);
@@ -4845,7 +4845,7 @@ int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
if (idx != 0)
return -ENOENT;

- survey->channel = conf->channel;
+ survey->channel = conf->chan_conf->channel;

rt2800_register_read(rt2x00dev, CH_IDLE_STA, &idle);
rt2800_register_read(rt2x00dev, CH_BUSY_STA, &busy);
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 293676b..1d0c232 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -184,7 +184,7 @@ static u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
/*
* Initialize center channel to current channel.
*/
- center_channel = spec->channels[conf->channel->hw_value].channel;
+ center_channel = spec->channels[conf->chan_conf->channel->hw_value].channel;

/*
* Adjust center channel to HT40+ and HT40- operation.
@@ -199,7 +199,7 @@ static u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
return i;

WARN_ON(1);
- return conf->channel->hw_value;
+ return conf->chan_conf->channel->hw_value;
}

void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
@@ -222,7 +222,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
hw_value = rt2x00ht_center_channel(rt2x00dev, conf);
} else {
clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
- hw_value = conf->channel->hw_value;
+ hw_value = conf->chan_conf->channel->hw_value;
}

memcpy(&libconf.rf,
@@ -274,8 +274,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
else
clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);

- rt2x00dev->curr_band = conf->channel->band;
- rt2x00dev->curr_freq = conf->channel->center_freq;
+ rt2x00dev->curr_band = conf->chan_conf->channel->band;
+ rt2x00dev->curr_freq = conf->chan_conf->channel->center_freq;
rt2x00dev->tx_power = conf->power_level;
rt2x00dev->short_retry = conf->short_frame_max_tx_count;
rt2x00dev->long_retry = conf->long_frame_max_tx_count;
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index e0c6d11..f5121de 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -847,7 +847,7 @@ static void rt61pci_config_lna_gain(struct rt2x00_dev *rt2x00dev,
u16 eeprom;
short lna_gain = 0;

- if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) {
+ if (libconf->conf->chan_conf->channel->band == IEEE80211_BAND_2GHZ) {
if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags))
lna_gain += 14;

diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index e477a96..b4f3291 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -739,7 +739,7 @@ static void rt73usb_config_lna_gain(struct rt2x00_dev *rt2x00dev,
u16 eeprom;
short lna_gain = 0;

- if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) {
+ if (libconf->conf->chan_conf->channel->band == IEEE80211_BAND_2GHZ) {
if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags))
lna_gain += 14;

diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c
index 2f14a5f..0502510 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c
@@ -145,8 +145,8 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
signal = priv->rf->calc_rssi(agc, sq);
}
rx_status.signal = signal;
- rx_status.freq = dev->conf.channel->center_freq;
- rx_status.band = dev->conf.channel->band;
+ rx_status.freq = dev->conf.chan_conf->channel->center_freq;
+ rx_status.band = dev->conf.chan_conf->channel->band;
rx_status.mactime = le64_to_cpu(entry->tsft);
rx_status.flag |= RX_FLAG_MACTIME_MPDU;
if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
diff --git a/drivers/net/wireless/rtl818x/rtl8180/grf5101.c b/drivers/net/wireless/rtl818x/rtl8180/grf5101.c
index 5ee7589..54e1d5f 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/grf5101.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/grf5101.c
@@ -82,7 +82,7 @@ static void grf5101_rf_set_channel(struct ieee80211_hw *dev,
struct ieee80211_conf *conf)
{
struct rtl8180_priv *priv = dev->priv;
- int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
+ int channel = ieee80211_frequency_to_channel(conf->chan_conf->channel->center_freq);
u32 txpw = priv->channels[channel - 1].hw_value & 0xFF;
u32 chan = channel - 1;

diff --git a/drivers/net/wireless/rtl818x/rtl8180/max2820.c b/drivers/net/wireless/rtl818x/rtl8180/max2820.c
index 667b336..4a773ab 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/max2820.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/max2820.c
@@ -95,7 +95,7 @@ static void max2820_rf_set_channel(struct ieee80211_hw *dev,
{
struct rtl8180_priv *priv = dev->priv;
int channel = conf ?
- ieee80211_frequency_to_channel(conf->channel->center_freq) : 1;
+ ieee80211_frequency_to_channel(conf->chan_conf->channel->center_freq) : 1;
unsigned int chan_idx = channel - 1;
u32 txpw = priv->channels[chan_idx].hw_value & 0xFF;
u32 chan = max2820_chan[chan_idx];
diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c
index 7c4574b..b24176b 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c
@@ -719,7 +719,7 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
struct ieee80211_conf *conf)
{
struct rtl8180_priv *priv = dev->priv;
- int chan = ieee80211_frequency_to_channel(conf->channel->center_freq);
+ int chan = ieee80211_frequency_to_channel(conf->chan_conf->channel->center_freq);

if (priv->rf->init == rtl8225_rf_init)
rtl8225_rf_set_tx_power(dev, chan);
diff --git a/drivers/net/wireless/rtl818x/rtl8180/sa2400.c b/drivers/net/wireless/rtl818x/rtl8180/sa2400.c
index 44771a6..24ac295 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/sa2400.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/sa2400.c
@@ -105,7 +105,7 @@ static void sa2400_rf_set_channel(struct ieee80211_hw *dev,
struct ieee80211_conf *conf)
{
struct rtl8180_priv *priv = dev->priv;
- int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
+ int channel = ieee80211_frequency_to_channel(conf->chan_conf->channel->center_freq);
u32 txpw = priv->channels[channel - 1].hw_value & 0xFF;
u32 chan = sa2400_chan[channel - 1];

diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
index cf53ac9..c6e43e7 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
@@ -376,8 +376,8 @@ static void rtl8187_rx_cb(struct urb *urb)
rate = (flags >> 20) & 0xF;
skb_trim(skb, flags & 0x0FFF);
rx_status.rate_idx = rate;
- rx_status.freq = dev->conf.channel->center_freq;
- rx_status.band = dev->conf.channel->band;
+ rx_status.freq = dev->conf.chan_conf->channel->center_freq;
+ rx_status.band = dev->conf.chan_conf->channel->band;
rx_status.flag |= RX_FLAG_MACTIME_MPDU;
if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c
index 908903f..2828841 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c
+++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c
@@ -905,7 +905,7 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
struct ieee80211_conf *conf)
{
struct rtl8187_priv *priv = dev->priv;
- int chan = ieee80211_frequency_to_channel(conf->channel->center_freq);
+ int chan = ieee80211_frequency_to_channel(conf->chan_conf->channel->center_freq);

if (priv->rf->init == rtl8225_rf_init)
rtl8225_rf_set_tx_power(dev, chan);
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index 5100235..7092cf2 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -692,7 +692,7 @@ int rtlwifi_rate_mapping(struct ieee80211_hw *hw,
int rate_idx;

if (false == isht) {
- if (IEEE80211_BAND_2GHZ == hw->conf.channel->band) {
+ if (IEEE80211_BAND_2GHZ == hw->conf.chan_conf->channel->band) {
switch (desc_rate) {
case DESC92_RATE1M:
rate_idx = 0;
@@ -1339,7 +1339,7 @@ int rtl_send_smps_action(struct ieee80211_hw *hw,

info->control.rates[0].idx = 0;
info->control.sta = sta;
- info->band = hw->conf.channel->band;
+ info->band = hw->conf.chan_conf->channel->band;
rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc);
}
err_free:
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index 278e9f9..48b5594 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -318,7 +318,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
}

if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
- struct ieee80211_channel *channel = hw->conf.channel;
+ struct ieee80211_channel *channel = hw->conf.chan_conf->channel;
u8 wide_chan = (u8) channel->hw_value;

/*
@@ -330,7 +330,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
*info for cisco1253 bw20, so we modify
*it here based on UPPER & LOWER
*/
- switch (hw->conf.channel_type) {
+ switch (hw->conf.chan_conf->channel_type) {
case NL80211_CHAN_HT20:
case NL80211_CHAN_NO_HT:
/* SC */
@@ -388,7 +388,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
rtlpriv->cfg->ops->switch_channel(hw);
rtlpriv->cfg->ops->set_channel_access(hw);
rtlpriv->cfg->ops->set_bw_mode(hw,
- hw->conf.channel_type);
+ hw->conf.chan_conf->channel_type);
}

mutex_unlock(&rtlpriv->locks.conf_mutex);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
index 37b1363..f1ef817 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -552,8 +552,8 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);

- rx_status->freq = hw->conf.channel->center_freq;
- rx_status->band = hw->conf.channel->band;
+ rx_status->freq = hw->conf.chan_conf->channel->center_freq;
+ rx_status->band = hw->conf.chan_conf->channel->band;

if (GET_RX_DESC_CRC32(pdesc))
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
index 21bc827..c2ed11f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
@@ -324,8 +324,8 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
&& (GET_RX_DESC_FAGGR(pdesc) == 1));
stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
- rx_status->freq = hw->conf.channel->center_freq;
- rx_status->band = hw->conf.channel->band;
+ rx_status->freq = hw->conf.chan_conf->channel->center_freq;
+ rx_status->band = hw->conf.chan_conf->channel->band;
if (GET_RX_DESC_CRC32(pdesc))
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
if (!GET_RX_DESC_SWDEC(pdesc))
@@ -395,8 +395,8 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
stats.rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(rxdesc);
/* TODO: is center_freq changed when doing scan? */
/* TODO: Shall we add protection or just skip those two step? */
- rx_status->freq = hw->conf.channel->center_freq;
- rx_status->band = hw->conf.channel->band;
+ rx_status->freq = hw->conf.chan_conf->channel->center_freq;
+ rx_status->band = hw->conf.chan_conf->channel->band;
if (GET_RX_DESC_CRC32(rxdesc))
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
if (!GET_RX_DESC_SWDEC(rxdesc))
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
index a7f6126..76660c3 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
@@ -503,8 +503,8 @@ bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
&& (GET_RX_DESC_FAGGR(pdesc) == 1));
stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
- rx_status->freq = hw->conf.channel->center_freq;
- rx_status->band = hw->conf.channel->band;
+ rx_status->freq = hw->conf.chan_conf->channel->center_freq;
+ rx_status->band = hw->conf.chan_conf->channel->band;
if (GET_RX_DESC_CRC32(pdesc))
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
if (!GET_RX_DESC_SWDEC(pdesc))
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
index 2fd3d13..3ce9cea 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
@@ -538,8 +538,8 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
if (stats->hwerror)
return false;

- rx_status->freq = hw->conf.channel->center_freq;
- rx_status->band = hw->conf.channel->band;
+ rx_status->freq = hw->conf.chan_conf->channel->center_freq;
+ rx_status->band = hw->conf.chan_conf->channel->band;

hdr = (struct ieee80211_hdr *)(skb->data + stats->rx_drvinfo_size
+ stats->rx_bufshift);
diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c
index 41302c7..004add1 100644
--- a/drivers/net/wireless/wl1251/main.c
+++ b/drivers/net/wireless/wl1251/main.c
@@ -591,7 +591,7 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
struct ieee80211_conf *conf = &hw->conf;
int channel, ret = 0;

- channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
+ channel = ieee80211_frequency_to_channel(conf->chan_conf->channel->center_freq);

wl1251_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d",
channel,
@@ -1214,7 +1214,7 @@ static int wl1251_op_get_survey(struct ieee80211_hw *hw, int idx,
if (idx != 0)
return -ENOENT;

- survey->channel = conf->channel;
+ survey->channel = conf->chan_conf->channel;
survey->filled = SURVEY_INFO_NOISE_DBM;
survey->noise = wl->noise;

diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 3900236..a37e53e 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -2585,15 +2585,15 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
int channel, ret;

- channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
+ channel = ieee80211_frequency_to_channel(conf->chan_conf->channel->center_freq);

/* if the channel changes while joined, join again */
if (changed & IEEE80211_CONF_CHANGE_CHANNEL &&
- ((wlvif->band != conf->channel->band) ||
+ ((wlvif->band != conf->chan_conf->channel->band) ||
(wlvif->channel != channel))) {
/* send all pending packets */
wl1271_tx_work_locked(wl);
- wlvif->band = conf->channel->band;
+ wlvif->band = conf->chan_conf->channel->band;
wlvif->channel = channel;

if (!is_ap) {
@@ -2689,7 +2689,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
struct ieee80211_conf *conf = &hw->conf;
int channel, ret = 0;

- channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
+ channel = ieee80211_frequency_to_channel(conf->chan_conf->channel->center_freq);

wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d %s"
" changed 0x%x",
@@ -2712,7 +2712,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)

/* we support configuring the channel and band even while off */
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
- wl->band = conf->channel->band;
+ wl->band = conf->chan_conf->channel->band;
wl->channel = channel;
}

@@ -3813,7 +3813,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
goto sta_not_found;

/* save the supp_rates of the ap */
- sta_rate_set = sta->supp_rates[wl->hw->conf.channel->band];
+ sta_rate_set = sta->supp_rates[wl->hw->conf.chan_conf->channel->band];
if (sta->ht_cap.ht_supported)
sta_rate_set |=
(sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
@@ -4195,7 +4195,7 @@ static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx,
if (idx != 0)
return -ENOENT;

- survey->channel = conf->channel;
+ survey->channel = conf->chan_conf->channel;
survey->filled = SURVEY_INFO_NOISE_DBM;
survey->noise = wl->noise;

diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 9fcde36..3b6232a 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -1154,10 +1154,10 @@ static int zd_op_config(struct ieee80211_hw *hw, u32 changed)
struct ieee80211_conf *conf = &hw->conf;

spin_lock_irq(&mac->lock);
- mac->channel = conf->channel->hw_value;
+ mac->channel = conf->chan_conf->channel->hw_value;
spin_unlock_irq(&mac->lock);

- return zd_chip_set_channel(&mac->chip, conf->channel->hw_value);
+ return zd_chip_set_channel(&mac->chip, conf->chan_conf->channel->hw_value);
}

static void zd_beacon_done(struct zd_mac *mac)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 9a012be..fa71c97 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -140,6 +140,17 @@ struct ieee80211_low_level_stats {
};

/**
+ * struct ieee80211_channel_conf - configuration of the channel
+ *
+ * @channel: the channel to tune to
+ * @channel_type: the channel (HT) type
+ */
+struct ieee80211_channel_conf {
+ struct ieee80211_channel *channel;
+ enum nl80211_channel_type channel_type;
+};
+
+/**
* enum ieee80211_bss_change - BSS change notification flags
*
* These flags are used with the bss_info_changed() callback
@@ -804,9 +815,6 @@ enum ieee80211_smps_mode {
*
* @power_level: requested transmit power (in dBm)
*
- * @channel: the channel to tune to
- * @channel_type: the channel (HT) type
- *
* @long_frame_max_tx_count: Maximum number of transmissions for a "long" frame
* (a frame not RTS protected), called "dot11LongRetryLimit" in 802.11,
* but actually means the number of transmissions not the number of retries
@@ -814,6 +822,8 @@ enum ieee80211_smps_mode {
* frame, called "dot11ShortRetryLimit" in 802.11, but actually means the
* number of transmissions not the number of retries
*
+ * @chan_conf: Channel configuration (eg. what channel we're tuned to)
+ *
* @smps_mode: spatial multiplexing powersave mode; note that
* %IEEE80211_SMPS_STATIC is used when the device is not
* configured for an HT channel
@@ -828,8 +838,7 @@ struct ieee80211_conf {

u8 long_frame_max_tx_count, short_frame_max_tx_count;

- struct ieee80211_channel *channel;
- enum nl80211_channel_type channel_type;
+ struct ieee80211_channel_conf *chan_conf;
enum ieee80211_smps_mode smps_mode;
};

@@ -3649,19 +3658,19 @@ void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
static inline bool
conf_is_ht20(struct ieee80211_conf *conf)
{
- return conf->channel_type == NL80211_CHAN_HT20;
+ return conf->chan_conf->channel_type == NL80211_CHAN_HT20;
}

static inline bool
conf_is_ht40_minus(struct ieee80211_conf *conf)
{
- return conf->channel_type == NL80211_CHAN_HT40MINUS;
+ return conf->chan_conf->channel_type == NL80211_CHAN_HT40MINUS;
}

static inline bool
conf_is_ht40_plus(struct ieee80211_conf *conf)
{
- return conf->channel_type == NL80211_CHAN_HT40PLUS;
+ return conf->chan_conf->channel_type == NL80211_CHAN_HT40PLUS;
}

static inline bool
@@ -3673,7 +3682,7 @@ conf_is_ht40(struct ieee80211_conf *conf)
static inline bool
conf_is_ht(struct ieee80211_conf *conf)
{
- return conf->channel_type != NL80211_CHAN_NO_HT;
+ return conf->chan_conf->channel_type != NL80211_CHAN_NO_HT;
}

static inline enum nl80211_iftype
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 677d659..88cc128 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -327,10 +327,11 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,

static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, int idx)
{
+ struct ieee80211_channel_state *chan_state = &sta->local->chan_state;
if (!(rate->flags & RATE_INFO_FLAGS_MCS)) {
struct ieee80211_supported_band *sband;
sband = sta->local->hw.wiphy->bands[
- sta->local->hw.conf.channel->band];
+ chan_state->conf.channel->band];
rate->legacy = sband->bitrates[idx].bitrate;
} else
rate->mcs = idx;
@@ -736,9 +737,10 @@ static int sta_apply_parameters(struct ieee80211_local *local,
int i, j;
struct ieee80211_supported_band *sband;
struct ieee80211_sub_if_data *sdata = sta->sdata;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
u32 mask, set;

- sband = local->hw.wiphy->bands[local->oper_channel->band];
+ sband = local->hw.wiphy->bands[chan_state->oper_channel->band];

mask = params->sta_flags_mask;
set = params->sta_flags_set;
@@ -853,7 +855,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
rates |= BIT(j);
}
}
- sta->sta.supp_rates[local->oper_channel->band] = rates;
+ sta->sta.supp_rates[chan_state->oper_channel->band] = rates;
}

if (params->ht_capa)
@@ -1363,10 +1365,12 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
struct net_device *dev,
struct bss_parameters *params)
{
+ struct ieee80211_channel_state *chan_state;
struct ieee80211_sub_if_data *sdata;
u32 changed = 0;

sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ chan_state = &sdata->local->chan_state;

if (params->use_cts_prot >= 0) {
sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot;
@@ -1379,7 +1383,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
}

if (!sdata->vif.bss_conf.use_short_slot &&
- sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) {
+ chan_state->conf.channel->band == IEEE80211_BAND_5GHZ) {
sdata->vif.bss_conf.use_short_slot = true;
changed |= BSS_CHANGED_ERP_SLOT;
}
@@ -1393,9 +1397,8 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
if (params->basic_rates) {
int i, j;
u32 rates = 0;
- struct ieee80211_local *local = wiphy_priv(wiphy);
struct ieee80211_supported_band *sband =
- wiphy->bands[local->oper_channel->band];
+ wiphy->bands[chan_state->oper_channel->band];

for (i = 0; i < params->basic_rates_len; i++) {
int rate = (params->basic_rates[i] & 0x7f) * 5;
@@ -1469,6 +1472,7 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
enum nl80211_channel_type channel_type)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_sub_if_data *sdata = NULL;
struct ieee80211_channel *old_oper;
enum nl80211_channel_type old_oper_type;
@@ -1481,9 +1485,9 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
case CHAN_MODE_HOPPING:
return -EBUSY;
case CHAN_MODE_FIXED:
- if (local->oper_channel != chan)
+ if (chan_state->oper_channel != chan)
return -EBUSY;
- if (!sdata && local->_oper_channel_type == channel_type)
+ if (!sdata && chan_state->_oper_channel_type == channel_type)
return 0;
break;
case CHAN_MODE_UNDEFINED:
@@ -1492,17 +1496,17 @@ static int ieee80211_set_channel(struct wiphy *wiphy,

if (sdata)
old_vif_oper_type = sdata->vif.bss_conf.channel_type;
- old_oper_type = local->_oper_channel_type;
+ old_oper_type = chan_state->_oper_channel_type;

if (!ieee80211_set_channel_type(local, sdata, channel_type))
return -EBUSY;

- old_oper = local->oper_channel;
- local->oper_channel = chan;
+ old_oper = chan_state->oper_channel;
+ chan_state->oper_channel = chan;

/* Update driver if changes were actually made. */
- if ((old_oper != local->oper_channel) ||
- (old_oper_type != local->_oper_channel_type))
+ if ((old_oper != chan_state->oper_channel) ||
+ (old_oper_type != chan_state->_oper_channel_type))
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);

if (sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR &&
@@ -1594,12 +1598,13 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
{
struct ieee80211_local *local = wiphy_priv(wiphy);
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_channel_state *chan_state = &local->chan_state;

switch (ieee80211_get_channel_mode(local, sdata)) {
case CHAN_MODE_HOPPING:
return -EBUSY;
case CHAN_MODE_FIXED:
- if (local->oper_channel == req->bss->channel)
+ if (chan_state->oper_channel == req->bss->channel)
break;
return -EBUSY;
case CHAN_MODE_UNDEFINED:
@@ -1626,6 +1631,7 @@ static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
{
struct ieee80211_local *local = wiphy_priv(wiphy);
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_channel_state *chan_state = &local->chan_state;

switch (ieee80211_get_channel_mode(local, sdata)) {
case CHAN_MODE_HOPPING:
@@ -1633,7 +1639,7 @@ static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
case CHAN_MODE_FIXED:
if (!params->channel_fixed)
return -EBUSY;
- if (local->oper_channel == params->channel)
+ if (chan_state->oper_channel == params->channel)
break;
return -EBUSY;
case CHAN_MODE_UNDEFINED:
@@ -1691,7 +1697,8 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
enum nl80211_tx_power_setting type, int mbm)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
- struct ieee80211_channel *chan = local->hw.conf.channel;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
+ struct ieee80211_channel *chan = chan_state->conf.channel;
u32 changes = 0;

switch (type) {
@@ -2025,6 +2032,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct sk_buff *skb;
struct sta_info *sta;
struct ieee80211_work *wk;
@@ -2039,12 +2047,12 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
IEEE80211_TX_CTL_REQ_TX_STATUS;

/* Check that we are on the requested channel for transmission */
- if (chan != local->tmp_channel &&
- chan != local->oper_channel)
+ if (chan != chan_state->tmp_channel &&
+ chan != chan_state->oper_channel)
is_offchan = true;
if (channel_type_valid &&
- (channel_type != local->tmp_channel_type &&
- channel_type != local->_oper_channel_type))
+ (channel_type != chan_state->tmp_channel_type &&
+ channel_type != chan_state->_oper_channel_type))
is_offchan = true;

if (chan == local->hw_roc_channel) {
@@ -2296,10 +2304,11 @@ static void ieee80211_tdls_add_ext_capab(struct sk_buff *skb)
static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
u16 capab;

capab = 0;
- if (local->oper_channel->band != IEEE80211_BAND_2GHZ)
+ if (chan_state->oper_channel->band != IEEE80211_BAND_2GHZ)
return capab;

if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
@@ -2669,8 +2678,9 @@ static struct ieee80211_channel *
ieee80211_wiphy_get_channel(struct wiphy *wiphy)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
+ struct ieee80211_channel_state *chan_state = &local->chan_state;

- return local->oper_channel;
+ return chan_state->oper_channel;
}

struct cfg80211_ops mac80211_config_ops = {
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 421c64e..b4b5303 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -68,6 +68,7 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
enum nl80211_channel_type chantype)
{
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_sub_if_data *tmp;
enum nl80211_channel_type superchan = NL80211_CHAN_NO_HT;
bool result;
@@ -124,7 +125,7 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local,
goto out;
}

- local->_oper_channel_type = superchan;
+ chan_state->_oper_channel_type = superchan;

if (sdata)
sdata->vif.bss_conf.channel_type = chantype;
@@ -146,15 +147,16 @@ enum nl80211_channel_type ieee80211_get_tx_channel_type(
enum nl80211_channel_type channel_type)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;

switch (channel_type) {
case NL80211_CHAN_HT40PLUS:
- if (local->hw.conf.channel->flags &
+ if (chan_state->conf.channel->flags &
IEEE80211_CHAN_NO_HT40PLUS)
return NL80211_CHAN_HT20;
break;
case NL80211_CHAN_HT40MINUS:
- if (local->hw.conf.channel->flags &
+ if (chan_state->conf.channel->flags &
IEEE80211_CHAN_NO_HT40MINUS)
return NL80211_CHAN_HT20;
break;
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index cc5b7a6..8ff846a 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -70,7 +70,7 @@ DEBUGFS_READONLY_FILE(user_power, "%d",
DEBUGFS_READONLY_FILE(power, "%d",
local->hw.conf.power_level);
DEBUGFS_READONLY_FILE(frequency, "%d",
- local->hw.conf.channel->center_freq);
+ local->chan_state.conf.channel->center_freq);
DEBUGFS_READONLY_FILE(total_ps_buffered, "%d",
local->total_ps_buffered);
DEBUGFS_READONLY_FILE(wep_iv, "%#08x",
@@ -101,9 +101,10 @@ static ssize_t channel_type_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ieee80211_local *local = file->private_data;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
const char *buf;

- switch (local->hw.conf.channel_type) {
+ switch (chan_state->conf.channel_type) {
case NL80211_CHAN_NO_HT:
buf = "no ht\n";
break;
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 21d6f52..0b61a8e 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -247,8 +247,8 @@ TRACE_EVENT(drv_config,
__entry->listen_interval = local->hw.conf.listen_interval;
__entry->long_frame_max_tx_count = local->hw.conf.long_frame_max_tx_count;
__entry->short_frame_max_tx_count = local->hw.conf.short_frame_max_tx_count;
- __entry->center_freq = local->hw.conf.channel->center_freq;
- __entry->channel_type = local->hw.conf.channel_type;
+ __entry->center_freq = local->chan_state.conf.channel->center_freq;
+ __entry->channel_type = local->chan_state.conf.channel_type;
__entry->smps = local->hw.conf.smps_mode;
),

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 8bea83b..d2bffcd 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -43,6 +43,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
int rates, i;
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
@@ -80,7 +81,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,

sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;

- local->oper_channel = chan;
+ chan_state->oper_channel = chan;
channel_type = ifibss->channel_type;
if (channel_type > NL80211_CHAN_HT20 &&
!cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type))
@@ -203,7 +204,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
mod_timer(&ifibss->timer,
round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));

- bss = cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel,
+ bss = cfg80211_inform_bss_frame(local->hw.wiphy, chan_state->conf.channel,
mgmt, skb->len, 0, GFP_KERNEL);
cfg80211_put_bss(bss);
netif_carrier_on(sdata->dev);
@@ -297,8 +298,9 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct sta_info *sta;
- int band = local->hw.conf.channel->band;
+ int band = chan_state->conf.channel->band;

/*
* XXX: Consider removing the least recently used entry and
@@ -380,6 +382,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
bool beacon)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
int freq;
struct cfg80211_bss *cbss;
struct ieee80211_bss *bss;
@@ -498,7 +501,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
goto put_bss;

/* different channel */
- if (cbss->channel != local->oper_channel)
+ if (cbss->channel != chan_state->oper_channel)
goto put_bss;

/* different SSID */
@@ -576,8 +579,9 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct sta_info *sta;
- int band = local->hw.conf.channel->band;
+ int band = chan_state->conf.channel->band;

/*
* XXX: Consider removing the least recently used entry and
@@ -713,6 +717,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct cfg80211_bss *cbss;
struct ieee80211_channel *chan = NULL;
const u8 *bssid = NULL;
@@ -780,13 +785,13 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)

if (time_after(jiffies, ifibss->ibss_join_req +
IEEE80211_IBSS_JOIN_TIMEOUT)) {
- if (!(local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS)) {
+ if (!(chan_state->oper_channel->flags & IEEE80211_CHAN_NO_IBSS)) {
ieee80211_sta_create_ibss(sdata);
return;
}
printk(KERN_DEBUG "%s: IBSS not allowed on"
" %d MHz\n", sdata->name,
- local->hw.conf.channel->center_freq);
+ chan_state->conf.channel->center_freq);

/* No IBSS found - decrease scan interval and continue
* scanning. */
@@ -1051,6 +1056,7 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
struct cfg80211_ibss_params *params)
{
+ struct ieee80211_channel_state *chan_state = &sdata->local->chan_state;
struct sk_buff *skb;
u32 changed = 0;

@@ -1090,7 +1096,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,

/* fix ourselves to that channel now already */
if (params->channel_fixed) {
- sdata->local->oper_channel = params->channel;
+ chan_state->oper_channel = params->channel;
if (!ieee80211_set_channel_type(sdata->local, sdata,
params->channel_type)) {
mutex_unlock(&sdata->u.ibss.mtx);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 69a38be..b459451 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -610,6 +610,22 @@ struct ieee80211_if_mesh {
do { } while (0)
#endif

+struct ieee80211_channel_state {
+ /* Hardware state */
+ struct ieee80211_channel_conf conf;
+
+ /* Current operating channel */
+ enum nl80211_channel_type _oper_channel_type;
+ struct ieee80211_channel *oper_channel;
+
+ /* CSA channel; scheduled when, e.g. AP switches channels */
+ struct ieee80211_channel *csa_channel;
+
+ /* Temporary remain-on-channel for off-channel operations */
+ struct ieee80211_channel *tmp_channel;
+ enum nl80211_channel_type tmp_channel_type;
+};
+
/**
* enum ieee80211_sub_if_data_flags - virtual interface flags
*
@@ -972,12 +988,9 @@ struct ieee80211_local {
enum mac80211_scan_state next_scan_state;
struct delayed_work scan_work;
struct ieee80211_sub_if_data *scan_sdata;
- enum nl80211_channel_type _oper_channel_type;
- struct ieee80211_channel *oper_channel, *csa_channel;

- /* Temporary remain-on-channel for off-channel operations */
- struct ieee80211_channel *tmp_channel;
- enum nl80211_channel_type tmp_channel_type;
+ /* Channel state */
+ struct ieee80211_channel_state chan_state;

/* SNMP counters */
/* dot11CountersTable */
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index c7c60ce..4ee77a2 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -390,6 +390,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
bool going_down)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
unsigned long flags;
struct sk_buff *skb, *tmp;
u32 hw_reconf_flags = 0;
@@ -561,11 +562,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
/* Re-calculate channel-type, in case there are multiple vifs
* on different channel types.
*/
- orig_ct = local->_oper_channel_type;
+ orig_ct = chan_state->_oper_channel_type;
ieee80211_set_channel_type(local, NULL, NL80211_CHAN_NO_HT);

/* do after stop to avoid reconfiguring when we stop anyway */
- if (hw_reconf_flags || (orig_ct != local->_oper_channel_type))
+ if (hw_reconf_flags || (orig_ct != chan_state->_oper_channel_type))
ieee80211_hw_config(local, hw_reconf_flags);

spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
@@ -982,6 +983,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
enum nl80211_iftype type)
{
int ret;
+ struct ieee80211_channel_state *chan_state = &sdata->local->chan_state;

ASSERT_RTNL();

@@ -989,7 +991,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
return 0;

/* Setting ad-hoc mode on non-IBSS channel is not supported. */
- if (sdata->local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS &&
+ if (chan_state->oper_channel->flags & IEEE80211_CHAN_NO_IBSS &&
type == NL80211_IFTYPE_ADHOC)
return -EOPNOTSUPP;

@@ -1006,7 +1008,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
/* reset some values that shouldn't be kept across type changes */
sdata->vif.bss_conf.basic_rates =
ieee80211_mandatory_rates(sdata,
- sdata->local->hw.conf.channel->band);
+ chan_state->conf.channel->band);
sdata->drop_unencrypted = 0;
if (type == NL80211_IFTYPE_STATION)
sdata->u.mgd.use_4addr = false;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index b581a24..f5ca305 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -94,6 +94,7 @@ static void ieee80211_reconfig_filter(struct work_struct *work)

int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
{
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_channel *chan;
int ret = 0;
int power;
@@ -111,30 +112,30 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
/* If scanning on oper channel, use whatever channel-type
* is currently in use.
*/
- if (chan == local->oper_channel)
- channel_type = local->_oper_channel_type;
+ if (chan == chan_state->oper_channel)
+ channel_type = chan_state->_oper_channel_type;
else
channel_type = NL80211_CHAN_NO_HT;
- } else if (local->tmp_channel) {
- chan = local->tmp_channel;
- channel_type = local->tmp_channel_type;
+ } else if (chan_state->tmp_channel) {
+ chan = chan_state->tmp_channel;
+ channel_type = chan_state->tmp_channel_type;
} else {
- chan = local->oper_channel;
- channel_type = local->_oper_channel_type;
+ chan = chan_state->oper_channel;
+ channel_type = chan_state->_oper_channel_type;
}

- if (chan != local->oper_channel ||
- channel_type != local->_oper_channel_type)
+ if (chan != chan_state->oper_channel ||
+ channel_type != chan_state->_oper_channel_type)
local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
else
local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL;

offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;

- if (offchannel_flag || chan != local->hw.conf.channel ||
- channel_type != local->hw.conf.channel_type) {
- local->hw.conf.channel = chan;
- local->hw.conf.channel_type = channel_type;
+ if (offchannel_flag || chan != chan_state->conf.channel ||
+ channel_type != chan_state->conf.channel_type) {
+ chan_state->conf.channel = chan;
+ chan_state->conf.channel_type = channel_type;
changed |= IEEE80211_CONF_CHANGE_CHANNEL;
}

@@ -586,6 +587,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
BUG_ON(!ops->configure_filter);
local->ops = ops;

+ local->hw.conf.chan_conf = &local->chan_state.conf;
+
/* set up some defaults */
local->hw.queues = 1;
local->hw.max_rates = 1;
@@ -673,6 +676,7 @@ EXPORT_SYMBOL(ieee80211_alloc_hw);
int ieee80211_register_hw(struct ieee80211_hw *hw)
{
struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
int result, i;
enum ieee80211_band band;
int channels, max_bitrates;
@@ -704,7 +708,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
/*
* generic code guarantees at least one band,
* set this very early because much code assumes
- * that hw.conf.channel is assigned
+ * that hw.conf.chan_conf->channel is assigned
*/
channels = 0;
max_bitrates = 0;
@@ -715,11 +719,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
sband = local->hw.wiphy->bands[band];
if (!sband)
continue;
- if (!local->oper_channel) {
+ if (!chan_state->oper_channel) {
/* init channel we're on */
- local->hw.conf.channel =
- local->oper_channel = &sband->channels[0];
- local->hw.conf.channel_type = NL80211_CHAN_NO_HT;
+ local->hw.conf.chan_conf->channel =
+ chan_state->oper_channel = &sband->channels[0];
+ local->hw.conf.chan_conf->channel_type = NL80211_CHAN_NO_HT;
}
channels += sband->n_channels;

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 0e6106e..b512c38 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -77,6 +77,7 @@ bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_dat
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;

/*
* As support for each feature is added, check for matching
@@ -99,7 +100,7 @@ bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_dat

/* disallow peering with mismatched channel types for now */
if (ie->ht_info_elem &&
- (local->_oper_channel_type !=
+ (chan_state->_oper_channel_type !=
ieee80211_ht_info_to_channel_type(ie->ht_info_elem)))
goto mismatch;

@@ -333,18 +334,19 @@ int mesh_add_ds_params_ie(struct sk_buff *skb,
struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_supported_band *sband;
u8 *pos;

if (skb_tailroom(skb) < 3)
return -ENOMEM;

- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+ sband = local->hw.wiphy->bands[chan_state->conf.channel->band];
if (sband->band == IEEE80211_BAND_2GHZ) {
pos = skb_put(skb, 2 + 1);
*pos++ = WLAN_EID_DS_PARAMS;
*pos++ = 1;
- *pos++ = ieee80211_frequency_to_channel(local->hw.conf.channel->center_freq);
+ *pos++ = ieee80211_frequency_to_channel(chan_state->conf.channel->center_freq);
}

return 0;
@@ -354,12 +356,13 @@ int mesh_add_ht_cap_ie(struct sk_buff *skb,
struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_supported_band *sband;
u8 *pos;

- sband = local->hw.wiphy->bands[local->oper_channel->band];
+ sband = local->hw.wiphy->bands[chan_state->oper_channel->band];
if (!sband->ht_cap.ht_supported ||
- local->_oper_channel_type == NL80211_CHAN_NO_HT)
+ chan_state->_oper_channel_type == NL80211_CHAN_NO_HT)
return 0;

if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap))
@@ -375,8 +378,9 @@ int mesh_add_ht_info_ie(struct sk_buff *skb,
struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
- struct ieee80211_channel *channel = local->oper_channel;
- enum nl80211_channel_type channel_type = local->_oper_channel_type;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
+ struct ieee80211_channel *channel = chan_state->oper_channel;
+ enum nl80211_channel_type channel_type = chan_state->_oper_channel_type;
struct ieee80211_supported_band *sband =
local->hw.wiphy->bands[channel->band];
struct ieee80211_sta_ht_cap *ht_cap = &sband->ht_cap;
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 1c6f3d0..9215cca 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -323,6 +323,7 @@ void ieee80211s_update_metric(struct ieee80211_local *local,
static u32 airtime_link_metric_get(struct ieee80211_local *local,
struct sta_info *sta)
{
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_supported_band *sband;
struct rate_info rinfo;
/* This should be adjusted for each device */
@@ -333,7 +334,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
u32 tx_time, estimated_retx;
u64 result;

- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+ sband = local->hw.wiphy->bands[chan_state->conf.channel->band];

if (sta->fail_avg >= 100)
return MAX_METRIC;
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index aee6014..c0722b0 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -90,10 +90,11 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
struct ieee802_11_elems *elems)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_supported_band *sband;
struct sta_info *sta;

- sband = local->hw.wiphy->bands[local->oper_channel->band];
+ sband = local->hw.wiphy->bands[chan_state->oper_channel->band];

if (local->num_sta >= MESH_MAX_PLINKS)
return NULL;
@@ -108,7 +109,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,

set_sta_flag(sta, WLAN_STA_WME);

- sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
+ sta->sta.supp_rates[chan_state->conf.channel->band] = rates;
if (elems->ht_cap_elem)
ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
elems->ht_cap_elem,
@@ -279,6 +280,7 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates,
struct ieee802_11_elems *elems)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct sta_info *sta;

rcu_read_lock();
@@ -303,7 +305,7 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates,
}

sta->last_rx = jiffies;
- sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
+ sta->sta.supp_rates[chan_state->conf.channel->band] = rates;
if (mesh_peer_accepts_plinks(elems) &&
sta->plink_state == NL80211_PLINK_LISTEN &&
sdata->u.mesh.accepting_plinks &&
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 9d0e865..2616bbd 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -182,6 +182,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
bool beacon_htcap_ie)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_supported_band *sband;
struct sta_info *sta;
u32 changed = 0;
@@ -192,14 +193,14 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
enum nl80211_channel_type rx_channel_type = NL80211_CHAN_NO_HT;
enum nl80211_channel_type tx_channel_type;

- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+ sband = local->hw.wiphy->bands[chan_state->conf.channel->band];
prev_chantype = sdata->vif.bss_conf.channel_type;


hti_cfreq = ieee80211_channel_to_frequency(hti->control_chan,
sband->band);
/* check that channel matches the right operating channel */
- if (local->hw.conf.channel->center_freq != hti_cfreq) {
+ if (chan_state->conf.channel->center_freq != hti_cfreq) {
/* Some APs mess this up, evidently.
* Netgear WNDR3700 sometimes reports 4 higher than
* the actual channel, for instance.
@@ -210,7 +211,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
" hti-cfreq: %d hti->control_chan: %d"
" band: %d. Disabling HT.\n",
sdata->name,
- local->hw.conf.channel->center_freq,
+ local->hw.conf.chan_conf->channel->center_freq,
hti_cfreq, hti->control_chan,
sband->band);
enable_ht = false;
@@ -236,8 +237,8 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,

tx_channel_type = ieee80211_get_tx_channel_type(sdata, rx_channel_type);

- if (local->tmp_channel)
- local->tmp_channel_type = rx_channel_type;
+ if (chan_state->tmp_channel)
+ chan_state->tmp_channel_type = rx_channel_type;

if (!ieee80211_set_channel_type(local, sdata, rx_channel_type)) {
/* can only fail due to HT40+/- mismatch */
@@ -386,6 +387,7 @@ static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
struct sk_buff *skb;
@@ -399,7 +401,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)

lockdep_assert_held(&ifmgd->mtx);

- sband = local->hw.wiphy->bands[local->oper_channel->band];
+ sband = local->hw.wiphy->bands[chan_state->oper_channel->band];

if (assoc_data->supp_rates_len) {
/*
@@ -520,7 +522,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
*pos++ = WLAN_EID_PWR_CAPABILITY;
*pos++ = 2;
*pos++ = 0; /* min tx power */
- *pos++ = local->oper_channel->max_power; /* max tx power */
+ *pos++ = chan_state->oper_channel->max_power; /* max tx power */

/* 2. supported channels */
/* TODO: get this in reg domain format */
@@ -558,7 +560,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)

if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_information_ie,
- sband, local->oper_channel, ifmgd->ap_smps);
+ sband, chan_state->oper_channel, ifmgd->ap_smps);

/* if present, add any custom non-vendor IEs that go after HT */
if (assoc_data->ie_len && assoc_data->ie) {
@@ -717,6 +719,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work);
+ struct ieee80211_channel_state *chan_state = &sdata->local->chan_state;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;

if (!ieee80211_sdata_running(sdata))
@@ -726,18 +729,18 @@ static void ieee80211_chswitch_work(struct work_struct *work)
if (!ifmgd->associated)
goto out;

- sdata->local->oper_channel = sdata->local->csa_channel;
+ chan_state->oper_channel = chan_state->csa_channel;
if (!sdata->local->ops->channel_switch) {
/* call "hw_config" only if doing sw channel switch */
ieee80211_hw_config(sdata->local,
IEEE80211_CONF_CHANGE_CHANNEL);
} else {
/* update the device channel directly */
- sdata->local->hw.conf.channel = sdata->local->oper_channel;
+ chan_state->conf.channel = chan_state->oper_channel;
}

/* XXX: shouldn't really modify cfg80211-owned data! */
- ifmgd->associated->channel = sdata->local->oper_channel;
+ ifmgd->associated->channel = chan_state->oper_channel;

ieee80211_wake_queues_by_reason(&sdata->local->hw,
IEEE80211_QUEUE_STOP_REASON_CSA);
@@ -749,9 +752,11 @@ static void ieee80211_chswitch_work(struct work_struct *work)
void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
{
struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_channel_state *chan_state;
struct ieee80211_if_managed *ifmgd;

sdata = vif_to_sdata(vif);
+ chan_state = &sdata->local->chan_state;
ifmgd = &sdata->u.mgd;

trace_api_chswitch_done(sdata, success);
@@ -762,7 +767,7 @@ void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
* good handling of this situation, possibly we
* should just drop the association.
*/
- sdata->local->csa_channel = sdata->local->oper_channel;
+ chan_state->csa_channel = chan_state->oper_channel;
}

ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
@@ -791,6 +796,7 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
struct cfg80211_bss *cbss =
container_of((void *)bss, struct cfg80211_bss, priv);
struct ieee80211_channel *new_ch;
+ struct ieee80211_channel_state *chan_state = &sdata->local->chan_state;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
cbss->channel->band);
@@ -813,7 +819,7 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
if (!new_ch || new_ch->flags & IEEE80211_CHAN_DISABLED)
return;

- sdata->local->csa_channel = new_ch;
+ chan_state->csa_channel = new_ch;

if (sdata->local->ops->channel_switch) {
/* use driver's channel switch callback */
@@ -851,7 +857,7 @@ static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
u16 capab_info, u8 *pwr_constr_elem,
u8 pwr_constr_elem_len)
{
- struct ieee80211_conf *conf = &sdata->local->hw.conf;
+ struct ieee80211_channel_state *chan_state = &sdata->local->chan_state;

if (!(capab_info & WLAN_CAPABILITY_SPECTRUM_MGMT))
return;
@@ -860,7 +866,7 @@ static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
if (pwr_constr_elem_len != 1)
return;

- if ((*pwr_constr_elem <= conf->channel->max_reg_power) &&
+ if ((*pwr_constr_elem <= chan_state->conf.channel->max_reg_power) &&
(*pwr_constr_elem != sdata->local->power_constr_level)) {
sdata->local->power_constr_level = *pwr_constr_elem;
ieee80211_hw_config(sdata->local, 0);
@@ -1272,6 +1278,7 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
u16 capab, bool erp_valid, u8 erp)
{
struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
+ struct ieee80211_channel_state *chan_state = &sdata->local->chan_state;
u32 changed = 0;
bool use_protection;
bool use_short_preamble;
@@ -1286,7 +1293,7 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
}

use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
- if (sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ)
+ if (chan_state->conf.channel->band == IEEE80211_BAND_5GHZ)
use_short_slot = true;

if (use_protection != bss_conf->use_cts_prot) {
@@ -1580,6 +1587,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
bool beacon)
{
+ struct ieee80211_channel_state *chan_state = &sdata->local->chan_state;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
bool already = false;

@@ -1589,7 +1597,7 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
if (sdata->local->scanning)
return;

- if (sdata->local->tmp_channel)
+ if (chan_state->tmp_channel)
return;

mutex_lock(&ifmgd->mtx);
@@ -1992,6 +2000,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_supported_band *sband;
struct sta_info *sta;
u8 *pos;
@@ -2045,7 +2054,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
return false;
}

- sband = local->hw.wiphy->bands[local->oper_channel->band];
+ sband = local->hw.wiphy->bands[chan_state->oper_channel->band];

if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
@@ -2331,6 +2340,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
size_t baselen;
struct ieee802_11_elems elems;
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
u32 changed = 0;
bool erp_valid, directed_tim = false;
u8 erp_value = 0;
@@ -2344,7 +2354,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
if (baselen > len)
return;

- if (rx_status->freq != local->hw.conf.channel->center_freq)
+ if (rx_status->freq != chan_state->conf.channel->center_freq)
return;

if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon &&
@@ -2518,7 +2528,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
return;
}

- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+ sband = local->hw.wiphy->bands[chan_state->conf.channel->band];

ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
elems.ht_cap_elem, &sta->sta.ht_cap);
@@ -3055,6 +3065,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
struct cfg80211_bss *cbss, bool assoc)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct ieee80211_bss *bss = (void *)cbss->priv;
struct sta_info *sta;
@@ -3081,7 +3092,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
mutex_unlock(&local->mtx);

/* switch to the right channel */
- local->oper_channel = cbss->channel;
+ chan_state->oper_channel = cbss->channel;
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);

if (!have_sta) {
@@ -3117,7 +3128,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
sdata->vif.bss_conf.basic_rates = basic_rates;

/* cf. IEEE 802.11 9.2.12 */
- if (local->oper_channel->band == IEEE80211_BAND_2GHZ &&
+ if (chan_state->oper_channel->band == IEEE80211_BAND_2GHZ &&
have_higher_than_11mbit)
sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
else
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index fbb1efd..626fb79 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -47,6 +47,7 @@ static inline void rate_control_tx_status(struct ieee80211_local *local,
static inline void rate_control_rate_init(struct sta_info *sta)
{
struct ieee80211_local *local = sta->sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct rate_control_ref *ref = sta->rate_ctrl;
struct ieee80211_sta *ista = &sta->sta;
void *priv_sta = sta->rate_ctrl_priv;
@@ -55,7 +56,7 @@ static inline void rate_control_rate_init(struct sta_info *sta)
if (!ref)
return;

- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+ sband = local->hw.wiphy->bands[chan_state->conf.channel->band];

ref->ops->rate_init(ref->priv, sband, ista, priv_sta);
set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 00355ef..aa828f4 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -790,9 +790,12 @@ static void
minstrel_ht_rate_init(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta)
{
- struct minstrel_priv *mp = priv;
+ struct sta_info *stai = container_of(sta, struct sta_info, sta);
+ struct ieee80211_sub_if_data *sdata = stai->sdata;
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;

- minstrel_ht_update_caps(priv, sband, sta, priv_sta, mp->hw->conf.channel_type);
+ minstrel_ht_update_caps(priv, sband, sta, priv_sta, chan_state->conf.channel_type);
}

static void
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 5749c74..98bb52d 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2204,6 +2204,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
{
struct ieee80211_local *local = rx->local;
struct ieee80211_sub_if_data *sdata = rx->sdata;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
int len = rx->skb->len;
@@ -2273,7 +2274,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
local, sband, rx->sta,
IEEE80211_RC_SMPS_CHANGED,
ieee80211_get_tx_channel_type(
- sdata, local->_oper_channel_type));
+ sdata, chan_state->_oper_channel_type));
goto handled;
}
default:
@@ -2315,7 +2316,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)

goto queue;
case WLAN_CATEGORY_SPECTRUM_MGMT:
- if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ)
+ if (chan_state->conf.channel->band != IEEE80211_BAND_5GHZ)
break;

if (sdata->vif.type != NL80211_IFTYPE_STATION)
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 33cd169..5e7a1f8 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -182,6 +182,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
ieee80211_rx_result
ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
{
+ struct ieee80211_channel_state *chan_state = &sdata->local->chan_state;
struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_mgmt *mgmt;
struct ieee80211_bss *bss;
@@ -245,7 +246,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
if (bss)
ieee80211_rx_bss_put(sdata->local, bss);

- if (channel == sdata->local->oper_channel)
+ if (channel == chan_state->oper_channel)
return RX_CONTINUE;

dev_kfree_skb(skb);
@@ -603,7 +604,8 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
{
int i;
struct ieee80211_sub_if_data *sdata = local->scan_sdata;
- enum ieee80211_band band = local->hw.conf.channel->band;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
+ enum ieee80211_band band = chan_state->conf.channel->band;

for (i = 0; i < local->scan_req->n_ssids; i++)
ieee80211_send_probe_req(
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index d241d83..ede173e 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1133,6 +1133,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_hdr *hdr;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
int tid;
@@ -1142,7 +1143,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
tx->skb = skb;
tx->local = local;
tx->sdata = sdata;
- tx->channel = local->hw.conf.channel;
+ tx->channel = chan_state->conf.channel;
__skb_queue_head_init(&tx->skbs);

/*
@@ -1373,6 +1374,7 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb, bool txpending)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_tx_data tx;
ieee80211_tx_result res_prepare;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -1397,7 +1399,7 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,
goto out;
}

- tx.channel = local->hw.conf.channel;
+ tx.channel = chan_state->conf.channel;
info->band = tx.channel->band;

if (!invoke_tx_handlers(&tx))
@@ -1567,7 +1569,8 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
- struct ieee80211_channel *chan = local->hw.conf.channel;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
+ struct ieee80211_channel *chan = chan_state->conf.channel;
struct ieee80211_radiotap_header *prthdr =
(struct ieee80211_radiotap_header *)skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -2287,13 +2290,14 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
u16 *tim_offset, u16 *tim_length)
{
struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct sk_buff *skb = NULL;
struct ieee80211_tx_info *info;
struct ieee80211_sub_if_data *sdata = NULL;
struct ieee80211_if_ap *ap = NULL;
struct beacon_data *beacon;
struct ieee80211_supported_band *sband;
- enum ieee80211_band band = local->hw.conf.channel->band;
+ enum ieee80211_band band = chan_state->conf.channel->band;
struct ieee80211_tx_rate_control txrc;

sband = local->hw.wiphy->bands[band];
@@ -2652,6 +2656,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct sk_buff *skb = NULL;
struct ieee80211_tx_data tx;
struct ieee80211_sub_if_data *sdata;
@@ -2695,7 +2700,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
info = IEEE80211_SKB_CB(skb);

tx.flags |= IEEE80211_TX_PS_BUFFERED;
- tx.channel = local->hw.conf.channel;
+ tx.channel = chan_state->conf.channel;
info->band = tx.channel->band;

if (invoke_tx_handlers(&tx))
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index e8b6b31..fd398a7 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -110,6 +110,7 @@ int ieee80211_frame_duration(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata, size_t len,
int rate, int erp, int short_preamble)
{
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
int dur;

/* calculate duration (in microseconds, rounded up to next higher
@@ -121,7 +122,7 @@ int ieee80211_frame_duration(struct ieee80211_local *local,
* DIV_ROUND_UP() operations.
*/

- if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ || erp) {
+ if (chan_state->conf.channel->band == IEEE80211_BAND_5GHZ || erp) {
/*
* OFDM:
*
@@ -194,6 +195,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
const struct ieee80211_tx_info *frame_txctl)
{
struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_rate *rate;
struct ieee80211_sub_if_data *sdata = NULL;
bool short_preamble;
@@ -203,7 +205,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,

WARN_ON_ONCE(!vif);

- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+ sband = local->hw.wiphy->bands[chan_state->conf.channel->band];

short_preamble = false;

@@ -237,6 +239,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
const struct ieee80211_tx_info *frame_txctl)
{
struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_rate *rate;
struct ieee80211_sub_if_data *sdata = NULL;
bool short_preamble;
@@ -246,7 +249,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,

WARN_ON_ONCE(!vif);

- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+ sband = local->hw.wiphy->bands[chan_state->conf.channel->band];

short_preamble = false;

@@ -781,6 +784,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
bool bss_notify)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_tx_queue_params qparam;
int queue;
bool use_11b;
@@ -791,7 +795,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,

memset(&qparam, 0, sizeof(qparam));

- use_11b = (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) &&
+ use_11b = (chan_state->conf.channel->band == IEEE80211_BAND_2GHZ) &&
!(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE);

for (queue = 0; queue < local->hw.queues; queue++) {
@@ -859,6 +863,7 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
const u8 *supp_rates)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
int i, have_higher_than_11mbit = 0;

/* cf. IEEE 802.11 9.2.12 */
@@ -866,7 +871,7 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
if ((supp_rates[i] & 0x7f) * 5 > 110)
have_higher_than_11mbit = 1;

- if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
+ if (chan_state->conf.channel->band == IEEE80211_BAND_2GHZ &&
have_higher_than_11mbit)
sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
else
@@ -879,6 +884,7 @@ u32 ieee80211_mandatory_rates(struct ieee80211_sub_if_data *sdata,
enum ieee80211_band band)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_supported_band *sband;
struct ieee80211_rate *bitrates;
u32 mandatory_rates;
@@ -888,7 +894,7 @@ u32 ieee80211_mandatory_rates(struct ieee80211_sub_if_data *sdata,
sband = local->hw.wiphy->bands[band];
if (!sband) {
WARN_ON(1);
- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+ sband = local->hw.wiphy->bands[chan_state->conf.channel->band];
}

if (band == IEEE80211_BAND_2GHZ)
@@ -1049,6 +1055,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
bool directed)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
size_t buf_len;
@@ -1069,10 +1076,10 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
chan = 0;
else
chan = ieee80211_frequency_to_channel(
- local->hw.conf.channel->center_freq);
+ chan_state->conf.channel->center_freq);

buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len,
- local->hw.conf.channel->band,
+ chan_state->conf.channel->band,
ratemask, chan);

skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
@@ -1117,6 +1124,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
enum ieee80211_band band)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_supported_band *sband;
struct ieee80211_rate *bitrates;
size_t num_rates;
@@ -1126,7 +1134,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,

if (!sband) {
WARN_ON(1);
- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+ sband = local->hw.wiphy->bands[chan_state->conf.channel->band];
}

bitrates = sband->bitrates;
@@ -1691,11 +1699,12 @@ int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
{
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_supported_band *sband;
int rate;
u8 i, rates, *pos;

- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+ sband = local->hw.wiphy->bands[chan_state->conf.channel->band];
rates = sband->n_bitrates;
if (rates > 8)
rates = 8;
@@ -1718,11 +1727,12 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
{
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_supported_band *sband;
int rate;
u8 i, exrates, *pos;

- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+ sband = local->hw.wiphy->bands[chan_state->conf.channel->band];
exrates = sband->n_bitrates;
if (exrates > 8)
exrates -= 8;
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index c6e230e..91114db 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -117,6 +117,7 @@ static void ieee80211_work_work(struct work_struct *work)
{
struct ieee80211_local *local =
container_of(work, struct ieee80211_local, work_work);
+ struct ieee80211_channel_state *chan_state = &local->chan_state;
struct ieee80211_work *wk, *tmp;
LIST_HEAD(free_work);
enum work_action rma;
@@ -140,18 +141,18 @@ static void ieee80211_work_work(struct work_struct *work)
bool started = wk->started;

/* mark work as started if it's on the current off-channel */
- if (!started && local->tmp_channel &&
- wk->chan == local->tmp_channel &&
- wk->chan_type == local->tmp_channel_type) {
+ if (!started && chan_state->tmp_channel &&
+ wk->chan == chan_state->tmp_channel &&
+ wk->chan_type == chan_state->tmp_channel_type) {
started = true;
wk->timeout = jiffies;
}

- if (!started && !local->tmp_channel) {
+ if (!started && !chan_state->tmp_channel) {
ieee80211_offchannel_stop_vifs(local, true);

- local->tmp_channel = wk->chan;
- local->tmp_channel_type = wk->chan_type;
+ chan_state->tmp_channel = wk->chan;
+ chan_state->tmp_channel_type = wk->chan_type;

ieee80211_hw_config(local, 0);

@@ -210,14 +211,14 @@ static void ieee80211_work_work(struct work_struct *work)
list_for_each_entry(wk, &local->work_list, list) {
if (!wk->started)
continue;
- if (wk->chan != local->tmp_channel ||
- wk->chan_type != local->tmp_channel_type)
+ if (wk->chan != chan_state->tmp_channel ||
+ wk->chan_type != chan_state->tmp_channel_type)
continue;
remain_off_channel = true;
}

- if (!remain_off_channel && local->tmp_channel) {
- local->tmp_channel = NULL;
+ if (!remain_off_channel && chan_state->tmp_channel) {
+ chan_state->tmp_channel = NULL;
ieee80211_hw_config(local, 0);

ieee80211_offchannel_return(local, true);
--
1.7.0.4