diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-core.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 484 |
1 files changed, 2 insertions, 482 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 46490d3b95b..88ea31d9eb7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -28,7 +28,6 @@ | |||
28 | 28 | ||
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/etherdevice.h> | ||
32 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
33 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
34 | #include <net/mac80211.h> | 33 | #include <net/mac80211.h> |
@@ -44,189 +43,6 @@ | |||
44 | 43 | ||
45 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 44 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
46 | 45 | ||
47 | #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ | ||
48 | #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ | ||
49 | static void iwl_init_ht_hw_capab(const struct iwl_priv *priv, | ||
50 | struct ieee80211_sta_ht_cap *ht_info, | ||
51 | enum ieee80211_band band) | ||
52 | { | ||
53 | u16 max_bit_rate = 0; | ||
54 | u8 rx_chains_num = hw_params(priv).rx_chains_num; | ||
55 | u8 tx_chains_num = hw_params(priv).tx_chains_num; | ||
56 | |||
57 | ht_info->cap = 0; | ||
58 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | ||
59 | |||
60 | ht_info->ht_supported = true; | ||
61 | |||
62 | if (cfg(priv)->ht_params && | ||
63 | cfg(priv)->ht_params->ht_greenfield_support) | ||
64 | ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; | ||
65 | ht_info->cap |= IEEE80211_HT_CAP_SGI_20; | ||
66 | max_bit_rate = MAX_BIT_RATE_20_MHZ; | ||
67 | if (hw_params(priv).ht40_channel & BIT(band)) { | ||
68 | ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
69 | ht_info->cap |= IEEE80211_HT_CAP_SGI_40; | ||
70 | ht_info->mcs.rx_mask[4] = 0x01; | ||
71 | max_bit_rate = MAX_BIT_RATE_40_MHZ; | ||
72 | } | ||
73 | |||
74 | if (iwlagn_mod_params.amsdu_size_8K) | ||
75 | ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; | ||
76 | |||
77 | ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; | ||
78 | ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; | ||
79 | |||
80 | ht_info->mcs.rx_mask[0] = 0xFF; | ||
81 | if (rx_chains_num >= 2) | ||
82 | ht_info->mcs.rx_mask[1] = 0xFF; | ||
83 | if (rx_chains_num >= 3) | ||
84 | ht_info->mcs.rx_mask[2] = 0xFF; | ||
85 | |||
86 | /* Highest supported Rx data rate */ | ||
87 | max_bit_rate *= rx_chains_num; | ||
88 | WARN_ON(max_bit_rate & ~IEEE80211_HT_MCS_RX_HIGHEST_MASK); | ||
89 | ht_info->mcs.rx_highest = cpu_to_le16(max_bit_rate); | ||
90 | |||
91 | /* Tx MCS capabilities */ | ||
92 | ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; | ||
93 | if (tx_chains_num != rx_chains_num) { | ||
94 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; | ||
95 | ht_info->mcs.tx_params |= ((tx_chains_num - 1) << | ||
96 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * iwl_init_geos - Initialize mac80211's geo/channel info based from eeprom | ||
102 | */ | ||
103 | int iwl_init_geos(struct iwl_priv *priv) | ||
104 | { | ||
105 | struct iwl_channel_info *ch; | ||
106 | struct ieee80211_supported_band *sband; | ||
107 | struct ieee80211_channel *channels; | ||
108 | struct ieee80211_channel *geo_ch; | ||
109 | struct ieee80211_rate *rates; | ||
110 | int i = 0; | ||
111 | s8 max_tx_power = IWLAGN_TX_POWER_TARGET_POWER_MIN; | ||
112 | |||
113 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || | ||
114 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | ||
115 | IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n"); | ||
116 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | channels = kcalloc(priv->channel_count, | ||
121 | sizeof(struct ieee80211_channel), GFP_KERNEL); | ||
122 | if (!channels) | ||
123 | return -ENOMEM; | ||
124 | |||
125 | rates = kcalloc(IWL_RATE_COUNT_LEGACY, sizeof(struct ieee80211_rate), | ||
126 | GFP_KERNEL); | ||
127 | if (!rates) { | ||
128 | kfree(channels); | ||
129 | return -ENOMEM; | ||
130 | } | ||
131 | |||
132 | /* 5.2GHz channels start after the 2.4GHz channels */ | ||
133 | sband = &priv->bands[IEEE80211_BAND_5GHZ]; | ||
134 | sband->channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)]; | ||
135 | /* just OFDM */ | ||
136 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; | ||
137 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; | ||
138 | |||
139 | if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) | ||
140 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, | ||
141 | IEEE80211_BAND_5GHZ); | ||
142 | |||
143 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; | ||
144 | sband->channels = channels; | ||
145 | /* OFDM & CCK */ | ||
146 | sband->bitrates = rates; | ||
147 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY; | ||
148 | |||
149 | if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) | ||
150 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, | ||
151 | IEEE80211_BAND_2GHZ); | ||
152 | |||
153 | priv->ieee_channels = channels; | ||
154 | priv->ieee_rates = rates; | ||
155 | |||
156 | for (i = 0; i < priv->channel_count; i++) { | ||
157 | ch = &priv->channel_info[i]; | ||
158 | |||
159 | /* FIXME: might be removed if scan is OK */ | ||
160 | if (!is_channel_valid(ch)) | ||
161 | continue; | ||
162 | |||
163 | sband = &priv->bands[ch->band]; | ||
164 | |||
165 | geo_ch = &sband->channels[sband->n_channels++]; | ||
166 | |||
167 | geo_ch->center_freq = | ||
168 | ieee80211_channel_to_frequency(ch->channel, ch->band); | ||
169 | geo_ch->max_power = ch->max_power_avg; | ||
170 | geo_ch->max_antenna_gain = 0xff; | ||
171 | geo_ch->hw_value = ch->channel; | ||
172 | |||
173 | if (is_channel_valid(ch)) { | ||
174 | if (!(ch->flags & EEPROM_CHANNEL_IBSS)) | ||
175 | geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; | ||
176 | |||
177 | if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) | ||
178 | geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; | ||
179 | |||
180 | if (ch->flags & EEPROM_CHANNEL_RADAR) | ||
181 | geo_ch->flags |= IEEE80211_CHAN_RADAR; | ||
182 | |||
183 | geo_ch->flags |= ch->ht40_extension_channel; | ||
184 | |||
185 | if (ch->max_power_avg > max_tx_power) | ||
186 | max_tx_power = ch->max_power_avg; | ||
187 | } else { | ||
188 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; | ||
189 | } | ||
190 | |||
191 | IWL_DEBUG_INFO(priv, "Channel %d Freq=%d[%sGHz] %s flag=0x%X\n", | ||
192 | ch->channel, geo_ch->center_freq, | ||
193 | is_channel_a_band(ch) ? "5.2" : "2.4", | ||
194 | geo_ch->flags & IEEE80211_CHAN_DISABLED ? | ||
195 | "restricted" : "valid", | ||
196 | geo_ch->flags); | ||
197 | } | ||
198 | |||
199 | priv->tx_power_device_lmt = max_tx_power; | ||
200 | priv->tx_power_user_lmt = max_tx_power; | ||
201 | priv->tx_power_next = max_tx_power; | ||
202 | |||
203 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && | ||
204 | hw_params(priv).sku & EEPROM_SKU_CAP_BAND_52GHZ) { | ||
205 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " | ||
206 | "Please send your %s to maintainer.\n", | ||
207 | trans(priv)->hw_id_str); | ||
208 | hw_params(priv).sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; | ||
209 | } | ||
210 | |||
211 | IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", | ||
212 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, | ||
213 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | ||
214 | |||
215 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
216 | |||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | /* | ||
221 | * iwl_free_geos - undo allocations in iwl_init_geos | ||
222 | */ | ||
223 | void iwl_free_geos(struct iwl_priv *priv) | ||
224 | { | ||
225 | kfree(priv->ieee_channels); | ||
226 | kfree(priv->ieee_rates); | ||
227 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
228 | } | ||
229 | |||
230 | static bool iwl_is_channel_extension(struct iwl_priv *priv, | 46 | static bool iwl_is_channel_extension(struct iwl_priv *priv, |
231 | enum ieee80211_band band, | 47 | enum ieee80211_band band, |
232 | u16 channel, u8 extension_chan_offset) | 48 | u16 channel, u8 extension_chan_offset) |
@@ -271,255 +87,6 @@ bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, | |||
271 | ctx->ht.extension_chan_offset); | 87 | ctx->ht.extension_chan_offset); |
272 | } | 88 | } |
273 | 89 | ||
274 | static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val) | ||
275 | { | ||
276 | u16 new_val; | ||
277 | u16 beacon_factor; | ||
278 | |||
279 | /* | ||
280 | * If mac80211 hasn't given us a beacon interval, program | ||
281 | * the default into the device (not checking this here | ||
282 | * would cause the adjustment below to return the maximum | ||
283 | * value, which may break PAN.) | ||
284 | */ | ||
285 | if (!beacon_val) | ||
286 | return DEFAULT_BEACON_INTERVAL; | ||
287 | |||
288 | /* | ||
289 | * If the beacon interval we obtained from the peer | ||
290 | * is too large, we'll have to wake up more often | ||
291 | * (and in IBSS case, we'll beacon too much) | ||
292 | * | ||
293 | * For example, if max_beacon_val is 4096, and the | ||
294 | * requested beacon interval is 7000, we'll have to | ||
295 | * use 3500 to be able to wake up on the beacons. | ||
296 | * | ||
297 | * This could badly influence beacon detection stats. | ||
298 | */ | ||
299 | |||
300 | beacon_factor = (beacon_val + max_beacon_val) / max_beacon_val; | ||
301 | new_val = beacon_val / beacon_factor; | ||
302 | |||
303 | if (!new_val) | ||
304 | new_val = max_beacon_val; | ||
305 | |||
306 | return new_val; | ||
307 | } | ||
308 | |||
309 | int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | ||
310 | { | ||
311 | u64 tsf; | ||
312 | s32 interval_tm, rem; | ||
313 | struct ieee80211_conf *conf = NULL; | ||
314 | u16 beacon_int; | ||
315 | struct ieee80211_vif *vif = ctx->vif; | ||
316 | |||
317 | conf = &priv->hw->conf; | ||
318 | |||
319 | lockdep_assert_held(&priv->mutex); | ||
320 | |||
321 | memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd)); | ||
322 | |||
323 | ctx->timing.timestamp = cpu_to_le64(priv->timestamp); | ||
324 | ctx->timing.listen_interval = cpu_to_le16(conf->listen_interval); | ||
325 | |||
326 | beacon_int = vif ? vif->bss_conf.beacon_int : 0; | ||
327 | |||
328 | /* | ||
329 | * TODO: For IBSS we need to get atim_window from mac80211, | ||
330 | * for now just always use 0 | ||
331 | */ | ||
332 | ctx->timing.atim_window = 0; | ||
333 | |||
334 | if (ctx->ctxid == IWL_RXON_CTX_PAN && | ||
335 | (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION) && | ||
336 | iwl_is_associated(priv, IWL_RXON_CTX_BSS) && | ||
337 | priv->contexts[IWL_RXON_CTX_BSS].vif && | ||
338 | priv->contexts[IWL_RXON_CTX_BSS].vif->bss_conf.beacon_int) { | ||
339 | ctx->timing.beacon_interval = | ||
340 | priv->contexts[IWL_RXON_CTX_BSS].timing.beacon_interval; | ||
341 | beacon_int = le16_to_cpu(ctx->timing.beacon_interval); | ||
342 | } else if (ctx->ctxid == IWL_RXON_CTX_BSS && | ||
343 | iwl_is_associated(priv, IWL_RXON_CTX_PAN) && | ||
344 | priv->contexts[IWL_RXON_CTX_PAN].vif && | ||
345 | priv->contexts[IWL_RXON_CTX_PAN].vif->bss_conf.beacon_int && | ||
346 | (!iwl_is_associated_ctx(ctx) || !ctx->vif || | ||
347 | !ctx->vif->bss_conf.beacon_int)) { | ||
348 | ctx->timing.beacon_interval = | ||
349 | priv->contexts[IWL_RXON_CTX_PAN].timing.beacon_interval; | ||
350 | beacon_int = le16_to_cpu(ctx->timing.beacon_interval); | ||
351 | } else { | ||
352 | beacon_int = iwl_adjust_beacon_interval(beacon_int, | ||
353 | IWL_MAX_UCODE_BEACON_INTERVAL * TIME_UNIT); | ||
354 | ctx->timing.beacon_interval = cpu_to_le16(beacon_int); | ||
355 | } | ||
356 | |||
357 | ctx->beacon_int = beacon_int; | ||
358 | |||
359 | tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */ | ||
360 | interval_tm = beacon_int * TIME_UNIT; | ||
361 | rem = do_div(tsf, interval_tm); | ||
362 | ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem); | ||
363 | |||
364 | ctx->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ?: 1) : 1; | ||
365 | |||
366 | IWL_DEBUG_ASSOC(priv, | ||
367 | "beacon interval %d beacon timer %d beacon tim %d\n", | ||
368 | le16_to_cpu(ctx->timing.beacon_interval), | ||
369 | le32_to_cpu(ctx->timing.beacon_init_val), | ||
370 | le16_to_cpu(ctx->timing.atim_window)); | ||
371 | |||
372 | return iwl_dvm_send_cmd_pdu(priv, ctx->rxon_timing_cmd, | ||
373 | CMD_SYNC, sizeof(ctx->timing), &ctx->timing); | ||
374 | } | ||
375 | |||
376 | void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | ||
377 | int hw_decrypt) | ||
378 | { | ||
379 | struct iwl_rxon_cmd *rxon = &ctx->staging; | ||
380 | |||
381 | if (hw_decrypt) | ||
382 | rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK; | ||
383 | else | ||
384 | rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK; | ||
385 | |||
386 | } | ||
387 | |||
388 | /* validate RXON structure is valid */ | ||
389 | int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | ||
390 | { | ||
391 | struct iwl_rxon_cmd *rxon = &ctx->staging; | ||
392 | u32 errors = 0; | ||
393 | |||
394 | if (rxon->flags & RXON_FLG_BAND_24G_MSK) { | ||
395 | if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) { | ||
396 | IWL_WARN(priv, "check 2.4G: wrong narrow\n"); | ||
397 | errors |= BIT(0); | ||
398 | } | ||
399 | if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) { | ||
400 | IWL_WARN(priv, "check 2.4G: wrong radar\n"); | ||
401 | errors |= BIT(1); | ||
402 | } | ||
403 | } else { | ||
404 | if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) { | ||
405 | IWL_WARN(priv, "check 5.2G: not short slot!\n"); | ||
406 | errors |= BIT(2); | ||
407 | } | ||
408 | if (rxon->flags & RXON_FLG_CCK_MSK) { | ||
409 | IWL_WARN(priv, "check 5.2G: CCK!\n"); | ||
410 | errors |= BIT(3); | ||
411 | } | ||
412 | } | ||
413 | if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) { | ||
414 | IWL_WARN(priv, "mac/bssid mcast!\n"); | ||
415 | errors |= BIT(4); | ||
416 | } | ||
417 | |||
418 | /* make sure basic rates 6Mbps and 1Mbps are supported */ | ||
419 | if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 && | ||
420 | (rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) { | ||
421 | IWL_WARN(priv, "neither 1 nor 6 are basic\n"); | ||
422 | errors |= BIT(5); | ||
423 | } | ||
424 | |||
425 | if (le16_to_cpu(rxon->assoc_id) > 2007) { | ||
426 | IWL_WARN(priv, "aid > 2007\n"); | ||
427 | errors |= BIT(6); | ||
428 | } | ||
429 | |||
430 | if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) | ||
431 | == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) { | ||
432 | IWL_WARN(priv, "CCK and short slot\n"); | ||
433 | errors |= BIT(7); | ||
434 | } | ||
435 | |||
436 | if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) | ||
437 | == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) { | ||
438 | IWL_WARN(priv, "CCK and auto detect"); | ||
439 | errors |= BIT(8); | ||
440 | } | ||
441 | |||
442 | if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK | | ||
443 | RXON_FLG_TGG_PROTECT_MSK)) == | ||
444 | RXON_FLG_TGG_PROTECT_MSK) { | ||
445 | IWL_WARN(priv, "TGg but no auto-detect\n"); | ||
446 | errors |= BIT(9); | ||
447 | } | ||
448 | |||
449 | if (rxon->channel == 0) { | ||
450 | IWL_WARN(priv, "zero channel is invalid\n"); | ||
451 | errors |= BIT(10); | ||
452 | } | ||
453 | |||
454 | WARN(errors, "Invalid RXON (%#x), channel %d", | ||
455 | errors, le16_to_cpu(rxon->channel)); | ||
456 | |||
457 | return errors ? -EINVAL : 0; | ||
458 | } | ||
459 | |||
460 | /** | ||
461 | * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed | ||
462 | * @priv: staging_rxon is compared to active_rxon | ||
463 | * | ||
464 | * If the RXON structure is changing enough to require a new tune, | ||
465 | * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that | ||
466 | * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. | ||
467 | */ | ||
468 | int iwl_full_rxon_required(struct iwl_priv *priv, | ||
469 | struct iwl_rxon_context *ctx) | ||
470 | { | ||
471 | const struct iwl_rxon_cmd *staging = &ctx->staging; | ||
472 | const struct iwl_rxon_cmd *active = &ctx->active; | ||
473 | |||
474 | #define CHK(cond) \ | ||
475 | if ((cond)) { \ | ||
476 | IWL_DEBUG_INFO(priv, "need full RXON - " #cond "\n"); \ | ||
477 | return 1; \ | ||
478 | } | ||
479 | |||
480 | #define CHK_NEQ(c1, c2) \ | ||
481 | if ((c1) != (c2)) { \ | ||
482 | IWL_DEBUG_INFO(priv, "need full RXON - " \ | ||
483 | #c1 " != " #c2 " - %d != %d\n", \ | ||
484 | (c1), (c2)); \ | ||
485 | return 1; \ | ||
486 | } | ||
487 | |||
488 | /* These items are only settable from the full RXON command */ | ||
489 | CHK(!iwl_is_associated_ctx(ctx)); | ||
490 | CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr)); | ||
491 | CHK(compare_ether_addr(staging->node_addr, active->node_addr)); | ||
492 | CHK(compare_ether_addr(staging->wlap_bssid_addr, | ||
493 | active->wlap_bssid_addr)); | ||
494 | CHK_NEQ(staging->dev_type, active->dev_type); | ||
495 | CHK_NEQ(staging->channel, active->channel); | ||
496 | CHK_NEQ(staging->air_propagation, active->air_propagation); | ||
497 | CHK_NEQ(staging->ofdm_ht_single_stream_basic_rates, | ||
498 | active->ofdm_ht_single_stream_basic_rates); | ||
499 | CHK_NEQ(staging->ofdm_ht_dual_stream_basic_rates, | ||
500 | active->ofdm_ht_dual_stream_basic_rates); | ||
501 | CHK_NEQ(staging->ofdm_ht_triple_stream_basic_rates, | ||
502 | active->ofdm_ht_triple_stream_basic_rates); | ||
503 | CHK_NEQ(staging->assoc_id, active->assoc_id); | ||
504 | |||
505 | /* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can | ||
506 | * be updated with the RXON_ASSOC command -- however only some | ||
507 | * flag transitions are allowed using RXON_ASSOC */ | ||
508 | |||
509 | /* Check if we are not switching bands */ | ||
510 | CHK_NEQ(staging->flags & RXON_FLG_BAND_24G_MSK, | ||
511 | active->flags & RXON_FLG_BAND_24G_MSK); | ||
512 | |||
513 | /* Check if we are switching association toggle */ | ||
514 | CHK_NEQ(staging->filter_flags & RXON_FILTER_ASSOC_MSK, | ||
515 | active->filter_flags & RXON_FILTER_ASSOC_MSK); | ||
516 | |||
517 | #undef CHK | ||
518 | #undef CHK_NEQ | ||
519 | |||
520 | return 0; | ||
521 | } | ||
522 | |||
523 | static void _iwl_set_rxon_ht(struct iwl_priv *priv, | 90 | static void _iwl_set_rxon_ht(struct iwl_priv *priv, |
524 | struct iwl_ht_config *ht_conf, | 91 | struct iwl_ht_config *ht_conf, |
525 | struct iwl_rxon_context *ctx) | 92 | struct iwl_rxon_context *ctx) |
@@ -595,46 +162,6 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) | |||
595 | _iwl_set_rxon_ht(priv, ht_conf, ctx); | 162 | _iwl_set_rxon_ht(priv, ht_conf, ctx); |
596 | } | 163 | } |
597 | 164 | ||
598 | /* Return valid, unused, channel for a passive scan to reset the RF */ | ||
599 | u8 iwl_get_single_channel_number(struct iwl_priv *priv, | ||
600 | enum ieee80211_band band) | ||
601 | { | ||
602 | const struct iwl_channel_info *ch_info; | ||
603 | int i; | ||
604 | u8 channel = 0; | ||
605 | u8 min, max; | ||
606 | struct iwl_rxon_context *ctx; | ||
607 | |||
608 | if (band == IEEE80211_BAND_5GHZ) { | ||
609 | min = 14; | ||
610 | max = priv->channel_count; | ||
611 | } else { | ||
612 | min = 0; | ||
613 | max = 14; | ||
614 | } | ||
615 | |||
616 | for (i = min; i < max; i++) { | ||
617 | bool busy = false; | ||
618 | |||
619 | for_each_context(priv, ctx) { | ||
620 | busy = priv->channel_info[i].channel == | ||
621 | le16_to_cpu(ctx->staging.channel); | ||
622 | if (busy) | ||
623 | break; | ||
624 | } | ||
625 | |||
626 | if (busy) | ||
627 | continue; | ||
628 | |||
629 | channel = priv->channel_info[i].channel; | ||
630 | ch_info = iwl_get_channel_info(priv, band, channel); | ||
631 | if (is_channel_valid(ch_info)) | ||
632 | break; | ||
633 | } | ||
634 | |||
635 | return channel; | ||
636 | } | ||
637 | |||
638 | /** | 165 | /** |
639 | * iwl_set_rxon_channel - Set the band and channel values in staging RXON | 166 | * iwl_set_rxon_channel - Set the band and channel values in staging RXON |
640 | * @ch: requested channel as a pointer to struct ieee80211_channel | 167 | * @ch: requested channel as a pointer to struct ieee80211_channel |
@@ -828,7 +355,7 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv, | |||
828 | } | 355 | } |
829 | #endif | 356 | #endif |
830 | 357 | ||
831 | static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | 358 | void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) |
832 | { | 359 | { |
833 | unsigned int reload_msec; | 360 | unsigned int reload_msec; |
834 | unsigned long reload_jiffies; | 361 | unsigned long reload_jiffies; |
@@ -842,7 +369,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
842 | priv->ucode_loaded = false; | 369 | priv->ucode_loaded = false; |
843 | 370 | ||
844 | /* Set the FW error flag -- cleared on iwl_down */ | 371 | /* Set the FW error flag -- cleared on iwl_down */ |
845 | set_bit(STATUS_FW_ERROR, &priv->shrd->status); | 372 | set_bit(STATUS_FW_ERROR, &priv->status); |
846 | 373 | ||
847 | /* Cancel currently queued command. */ | 374 | /* Cancel currently queued command. */ |
848 | clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status); | 375 | clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status); |
@@ -1451,13 +978,6 @@ __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, | |||
1451 | return cpu_to_le32(res); | 978 | return cpu_to_le32(res); |
1452 | } | 979 | } |
1453 | 980 | ||
1454 | void iwl_nic_error(struct iwl_op_mode *op_mode) | ||
1455 | { | ||
1456 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
1457 | |||
1458 | iwlagn_fw_error(priv, false); | ||
1459 | } | ||
1460 | |||
1461 | void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) | 981 | void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) |
1462 | { | 982 | { |
1463 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 983 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |