diff options
author | Mohamed Abbas <mohamed.abbas@intel.com> | 2009-03-18 00:59:18 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-03-27 20:12:57 -0400 |
commit | 019fb97d47896c0ead4a77f55e5350c2750f675f (patch) | |
tree | fd737071fdd2b923fcdc47a6ec7d44f4ea4f9c8d /drivers/net | |
parent | 3b85875a252dbbd95c2e04d73639719a0a79634e (diff) |
iwlagn: use changed in mac_config
In function iwl_mac_config use changed flag to call only
the affected functions. This patch also allow user to cache
channel, txpower and power value when the interface is not
ready and apply the changes once the interface ready.
Signed-off-by: Mohamed Abbas <mohamed.abbas@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 161 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 4 |
2 files changed, 85 insertions, 80 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 0db3bc011ac2..4d2ed52af160 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -1567,9 +1567,8 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
1567 | if (iwl_is_associated(priv)) { | 1567 | if (iwl_is_associated(priv)) { |
1568 | struct iwl_rxon_cmd *active_rxon = | 1568 | struct iwl_rxon_cmd *active_rxon = |
1569 | (struct iwl_rxon_cmd *)&priv->active_rxon; | 1569 | (struct iwl_rxon_cmd *)&priv->active_rxon; |
1570 | 1570 | /* apply any changes in staging */ | |
1571 | memcpy(&priv->staging_rxon, &priv->active_rxon, | 1571 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
1572 | sizeof(priv->staging_rxon)); | ||
1573 | active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 1572 | active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
1574 | } else { | 1573 | } else { |
1575 | /* Initialize our rx_config data */ | 1574 | /* Initialize our rx_config data */ |
@@ -2184,110 +2183,112 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2184 | struct iwl_priv *priv = hw->priv; | 2183 | struct iwl_priv *priv = hw->priv; |
2185 | const struct iwl_channel_info *ch_info; | 2184 | const struct iwl_channel_info *ch_info; |
2186 | struct ieee80211_conf *conf = &hw->conf; | 2185 | struct ieee80211_conf *conf = &hw->conf; |
2187 | unsigned long flags; | 2186 | unsigned long flags = 0; |
2188 | int ret = 0; | 2187 | int ret = 0; |
2189 | u16 channel; | 2188 | u16 ch; |
2189 | int scan_active = 0; | ||
2190 | 2190 | ||
2191 | mutex_lock(&priv->mutex); | 2191 | mutex_lock(&priv->mutex); |
2192 | IWL_DEBUG_MAC80211(priv, "enter to channel %d\n", conf->channel->hw_value); | 2192 | IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", |
2193 | 2193 | conf->channel->hw_value, changed); | |
2194 | priv->current_ht_config.is_ht = conf_is_ht(conf); | ||
2195 | 2194 | ||
2196 | if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) { | 2195 | if (unlikely(!priv->cfg->mod_params->disable_hw_scan && |
2197 | IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - waiting for uCode\n"); | 2196 | test_bit(STATUS_SCANNING, &priv->status))) { |
2198 | goto out; | 2197 | scan_active = 1; |
2198 | IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); | ||
2199 | } | 2199 | } |
2200 | 2200 | ||
2201 | if (!conf->radio_enabled) | ||
2202 | iwl_radio_kill_sw_disable_radio(priv); | ||
2203 | 2201 | ||
2204 | if (!iwl_is_ready(priv)) { | 2202 | /* during scanning mac80211 will delay channel setting until |
2205 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); | 2203 | * scan finish with changed = 0 |
2206 | ret = -EIO; | 2204 | */ |
2207 | goto out; | 2205 | if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) { |
2208 | } | 2206 | if (scan_active) |
2207 | goto set_ch_out; | ||
2208 | |||
2209 | ch = ieee80211_frequency_to_channel(conf->channel->center_freq); | ||
2210 | ch_info = iwl_get_channel_info(priv, conf->channel->band, ch); | ||
2211 | if (!is_channel_valid(ch_info)) { | ||
2212 | IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); | ||
2213 | ret = -EINVAL; | ||
2214 | goto set_ch_out; | ||
2215 | } | ||
2209 | 2216 | ||
2210 | if (unlikely(!priv->cfg->mod_params->disable_hw_scan && | 2217 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC && |
2211 | test_bit(STATUS_SCANNING, &priv->status))) { | 2218 | !is_channel_ibss(ch_info)) { |
2212 | IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); | 2219 | IWL_ERR(priv, "channel %d in band %d not " |
2213 | mutex_unlock(&priv->mutex); | 2220 | "IBSS channel\n", |
2214 | return 0; | 2221 | conf->channel->hw_value, conf->channel->band); |
2215 | } | 2222 | ret = -EINVAL; |
2223 | goto set_ch_out; | ||
2224 | } | ||
2216 | 2225 | ||
2217 | channel = ieee80211_frequency_to_channel(conf->channel->center_freq); | 2226 | priv->current_ht_config.is_ht = conf_is_ht(conf); |
2218 | ch_info = iwl_get_channel_info(priv, conf->channel->band, channel); | ||
2219 | if (!is_channel_valid(ch_info)) { | ||
2220 | IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); | ||
2221 | ret = -EINVAL; | ||
2222 | goto out; | ||
2223 | } | ||
2224 | 2227 | ||
2225 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC && | 2228 | spin_lock_irqsave(&priv->lock, flags); |
2226 | !is_channel_ibss(ch_info)) { | ||
2227 | IWL_ERR(priv, "channel %d in band %d not IBSS channel\n", | ||
2228 | conf->channel->hw_value, conf->channel->band); | ||
2229 | ret = -EINVAL; | ||
2230 | goto out; | ||
2231 | } | ||
2232 | 2229 | ||
2233 | spin_lock_irqsave(&priv->lock, flags); | ||
2234 | 2230 | ||
2231 | /* if we are switching from ht to 2.4 clear flags | ||
2232 | * from any ht related info since 2.4 does not | ||
2233 | * support ht */ | ||
2234 | if ((le16_to_cpu(priv->staging_rxon.channel) != ch)) | ||
2235 | priv->staging_rxon.flags = 0; | ||
2235 | 2236 | ||
2236 | /* if we are switching from ht to 2.4 clear flags | 2237 | iwl_set_rxon_channel(priv, conf->channel); |
2237 | * from any ht related info since 2.4 does not | 2238 | |
2238 | * support ht */ | 2239 | iwl_set_flags_for_band(priv, conf->channel->band); |
2239 | if ((le16_to_cpu(priv->staging_rxon.channel) != channel) | 2240 | spin_unlock_irqrestore(&priv->lock, flags); |
2240 | #ifdef IEEE80211_CONF_CHANNEL_SWITCH | 2241 | set_ch_out: |
2241 | && !(conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) | 2242 | /* The list of supported rates and rate mask can be different |
2242 | #endif | 2243 | * for each band; since the band may have changed, reset |
2243 | ) | 2244 | * the rate mask to what mac80211 lists */ |
2244 | priv->staging_rxon.flags = 0; | 2245 | iwl_set_rate(priv); |
2246 | } | ||
2245 | 2247 | ||
2246 | iwl_set_rxon_channel(priv, conf->channel); | 2248 | if (changed & IEEE80211_CONF_CHANGE_PS) { |
2249 | if (conf->flags & IEEE80211_CONF_PS) | ||
2250 | ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3); | ||
2251 | else | ||
2252 | ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM); | ||
2253 | if (ret) | ||
2254 | IWL_DEBUG_MAC80211(priv, "Error setting power level\n"); | ||
2247 | 2255 | ||
2248 | iwl_set_flags_for_band(priv, conf->channel->band); | 2256 | } |
2249 | 2257 | ||
2250 | /* The list of supported rates and rate mask can be different | 2258 | if (changed & IEEE80211_CONF_CHANGE_POWER) { |
2251 | * for each band; since the band may have changed, reset | 2259 | IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n", |
2252 | * the rate mask to what mac80211 lists */ | 2260 | priv->tx_power_user_lmt, conf->power_level); |
2253 | iwl_set_rate(priv); | ||
2254 | 2261 | ||
2255 | spin_unlock_irqrestore(&priv->lock, flags); | 2262 | iwl_set_tx_power(priv, conf->power_level, false); |
2263 | } | ||
2256 | 2264 | ||
2257 | #ifdef IEEE80211_CONF_CHANNEL_SWITCH | 2265 | /* call to ensure that 4965 rx_chain is set properly in monitor mode */ |
2258 | if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) { | 2266 | iwl_set_rxon_chain(priv); |
2259 | iwl_hw_channel_switch(priv, conf->channel); | 2267 | |
2260 | goto out; | 2268 | if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) { |
2269 | if (conf->radio_enabled && | ||
2270 | iwl_radio_kill_sw_enable_radio(priv)) { | ||
2271 | IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - " | ||
2272 | "waiting for uCode\n"); | ||
2273 | goto out; | ||
2274 | } | ||
2275 | |||
2276 | if (!conf->radio_enabled) | ||
2277 | iwl_radio_kill_sw_disable_radio(priv); | ||
2261 | } | 2278 | } |
2262 | #endif | ||
2263 | 2279 | ||
2264 | if (!conf->radio_enabled) { | 2280 | if (!conf->radio_enabled) { |
2265 | IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n"); | 2281 | IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n"); |
2266 | goto out; | 2282 | goto out; |
2267 | } | 2283 | } |
2268 | 2284 | ||
2269 | if (iwl_is_rfkill(priv)) { | 2285 | if (!iwl_is_ready(priv)) { |
2270 | IWL_DEBUG_MAC80211(priv, "leave - RF kill\n"); | 2286 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); |
2271 | ret = -EIO; | ||
2272 | goto out; | 2287 | goto out; |
2273 | } | 2288 | } |
2274 | 2289 | ||
2275 | if (conf->flags & IEEE80211_CONF_PS) | 2290 | if (scan_active) |
2276 | ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3); | 2291 | goto out; |
2277 | else | ||
2278 | ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM); | ||
2279 | if (ret) | ||
2280 | IWL_DEBUG_MAC80211(priv, "Error setting power level\n"); | ||
2281 | |||
2282 | IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n", | ||
2283 | priv->tx_power_user_lmt, conf->power_level); | ||
2284 | |||
2285 | iwl_set_tx_power(priv, conf->power_level, false); | ||
2286 | |||
2287 | iwl_set_rate(priv); | ||
2288 | |||
2289 | /* call to ensure that 4965 rx_chain is set properly in monitor mode */ | ||
2290 | iwl_set_rxon_chain(priv); | ||
2291 | 2292 | ||
2292 | if (memcmp(&priv->active_rxon, | 2293 | if (memcmp(&priv->active_rxon, |
2293 | &priv->staging_rxon, sizeof(priv->staging_rxon))) | 2294 | &priv->staging_rxon, sizeof(priv->staging_rxon))) |
@@ -2295,9 +2296,9 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2295 | else | 2296 | else |
2296 | IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n"); | 2297 | IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n"); |
2297 | 2298 | ||
2298 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2299 | 2299 | ||
2300 | out: | 2300 | out: |
2301 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2301 | mutex_unlock(&priv->mutex); | 2302 | mutex_unlock(&priv->mutex); |
2302 | return ret; | 2303 | return ret; |
2303 | } | 2304 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 085e9cf1cac9..bcdecb110808 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -1437,6 +1437,10 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
1437 | 1437 | ||
1438 | priv->tx_power_user_lmt = tx_power; | 1438 | priv->tx_power_user_lmt = tx_power; |
1439 | 1439 | ||
1440 | /* if nic is not up don't send command */ | ||
1441 | if (!iwl_is_ready_rf(priv)) | ||
1442 | return ret; | ||
1443 | |||
1440 | if (force && priv->cfg->ops->lib->send_tx_power) | 1444 | if (force && priv->cfg->ops->lib->send_tx_power) |
1441 | ret = priv->cfg->ops->lib->send_tx_power(priv); | 1445 | ret = priv->cfg->ops->lib->send_tx_power(priv); |
1442 | 1446 | ||