diff options
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 | ||