diff options
author | Ron Rindjunsky <ron.rindjunsky@intel.com> | 2008-04-23 20:15:05 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-07 15:02:20 -0400 |
commit | c7de35cd1c8b135398899f42475fa8e9d672d46e (patch) | |
tree | 14fe2e46d79e2fde48c8010cb8521fc0332d26f5 /drivers/net | |
parent | 038669e49c30867956a7fa0d06c6e0e72bb38fa8 (diff) |
iwlwifi: unify init driver flow
This patch does the following:
1 - moving init_drv from handler to regular function call
2 - move the init driver flow from iwl4965 to iwlcore, thus unify it to all
iwl family as a single flow
3 - move some general purpose functions from iwl4965 to iwlcore
Signed-off-by: Ron Rindjunsky <ron.rindjunsky@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 245 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 412 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 9 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 175 |
5 files changed, 421 insertions, 421 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 2b21edb757b9..93f4cdbae0ff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -55,44 +55,6 @@ static struct iwl_mod_params iwl4965_mod_params = { | |||
55 | 55 | ||
56 | static void iwl4965_hw_card_show_info(struct iwl_priv *priv); | 56 | static void iwl4965_hw_card_show_info(struct iwl_priv *priv); |
57 | 57 | ||
58 | #define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \ | ||
59 | [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ | ||
60 | IWL_RATE_SISO_##s##M_PLCP, \ | ||
61 | IWL_RATE_MIMO2_##s##M_PLCP,\ | ||
62 | IWL_RATE_MIMO3_##s##M_PLCP,\ | ||
63 | IWL_RATE_##r##M_IEEE, \ | ||
64 | IWL_RATE_##ip##M_INDEX, \ | ||
65 | IWL_RATE_##in##M_INDEX, \ | ||
66 | IWL_RATE_##rp##M_INDEX, \ | ||
67 | IWL_RATE_##rn##M_INDEX, \ | ||
68 | IWL_RATE_##pp##M_INDEX, \ | ||
69 | IWL_RATE_##np##M_INDEX } | ||
70 | |||
71 | /* | ||
72 | * Parameter order: | ||
73 | * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate | ||
74 | * | ||
75 | * If there isn't a valid next or previous rate then INV is used which | ||
76 | * maps to IWL_RATE_INVALID | ||
77 | * | ||
78 | */ | ||
79 | const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT] = { | ||
80 | IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */ | ||
81 | IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */ | ||
82 | IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */ | ||
83 | IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */ | ||
84 | IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */ | ||
85 | IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */ | ||
86 | IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */ | ||
87 | IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */ | ||
88 | IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */ | ||
89 | IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */ | ||
90 | IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */ | ||
91 | IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */ | ||
92 | IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */ | ||
93 | /* FIXME:RS: ^^ should be INV (legacy) */ | ||
94 | }; | ||
95 | |||
96 | #ifdef CONFIG_IWL4965_HT | 58 | #ifdef CONFIG_IWL4965_HT |
97 | 59 | ||
98 | static const u16 default_tid_to_tx_fifo[] = { | 60 | static const u16 default_tid_to_tx_fifo[] = { |
@@ -262,108 +224,12 @@ static int iwl4965_load_bsm(struct iwl_priv *priv) | |||
262 | return 0; | 224 | return 0; |
263 | } | 225 | } |
264 | 226 | ||
265 | static int iwl4965_init_drv(struct iwl_priv *priv) | ||
266 | { | ||
267 | int ret; | ||
268 | int i; | ||
269 | |||
270 | priv->retry_rate = 1; | ||
271 | priv->ibss_beacon = NULL; | ||
272 | |||
273 | spin_lock_init(&priv->lock); | ||
274 | spin_lock_init(&priv->power_data.lock); | ||
275 | spin_lock_init(&priv->sta_lock); | ||
276 | spin_lock_init(&priv->hcmd_lock); | ||
277 | spin_lock_init(&priv->lq_mngr.lock); | ||
278 | |||
279 | for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) | ||
280 | INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); | ||
281 | |||
282 | INIT_LIST_HEAD(&priv->free_frames); | ||
283 | |||
284 | mutex_init(&priv->mutex); | ||
285 | |||
286 | /* Clear the driver's (not device's) station table */ | ||
287 | iwlcore_clear_stations_table(priv); | ||
288 | |||
289 | priv->data_retry_limit = -1; | ||
290 | priv->ieee_channels = NULL; | ||
291 | priv->ieee_rates = NULL; | ||
292 | priv->band = IEEE80211_BAND_2GHZ; | ||
293 | |||
294 | priv->iw_mode = IEEE80211_IF_TYPE_STA; | ||
295 | |||
296 | priv->use_ant_b_for_management_frame = 1; /* start with ant B */ | ||
297 | priv->ps_mode = IWL_MIMO_PS_NONE; | ||
298 | |||
299 | /* Choose which receivers/antennas to use */ | ||
300 | iwl4965_set_rxon_chain(priv); | ||
301 | |||
302 | iwlcore_reset_qos(priv); | ||
303 | |||
304 | priv->qos_data.qos_active = 0; | ||
305 | priv->qos_data.qos_cap.val = 0; | ||
306 | |||
307 | iwlcore_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6); | ||
308 | |||
309 | priv->rates_mask = IWL_RATES_MASK; | ||
310 | /* If power management is turned on, default to AC mode */ | ||
311 | priv->power_mode = IWL_POWER_AC; | ||
312 | priv->user_txpower_limit = IWL_DEFAULT_TX_POWER; | ||
313 | |||
314 | ret = iwl_init_channel_map(priv); | ||
315 | if (ret) { | ||
316 | IWL_ERROR("initializing regulatory failed: %d\n", ret); | ||
317 | goto err; | ||
318 | } | ||
319 | |||
320 | ret = iwl4965_init_geos(priv); | ||
321 | if (ret) { | ||
322 | IWL_ERROR("initializing geos failed: %d\n", ret); | ||
323 | goto err_free_channel_map; | ||
324 | } | ||
325 | |||
326 | ret = ieee80211_register_hw(priv->hw); | ||
327 | if (ret) { | ||
328 | IWL_ERROR("Failed to register network device (error %d)\n", | ||
329 | ret); | ||
330 | goto err_free_geos; | ||
331 | } | ||
332 | |||
333 | priv->hw->conf.beacon_int = 100; | ||
334 | priv->mac80211_registered = 1; | ||
335 | |||
336 | return 0; | ||
337 | |||
338 | err_free_geos: | ||
339 | iwl4965_free_geos(priv); | ||
340 | err_free_channel_map: | ||
341 | iwl_free_channel_map(priv); | ||
342 | err: | ||
343 | return ret; | ||
344 | } | ||
345 | |||
346 | static int is_fat_channel(__le32 rxon_flags) | 227 | static int is_fat_channel(__le32 rxon_flags) |
347 | { | 228 | { |
348 | return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) || | 229 | return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) || |
349 | (rxon_flags & RXON_FLG_CHANNEL_MODE_MIXED_MSK); | 230 | (rxon_flags & RXON_FLG_CHANNEL_MODE_MIXED_MSK); |
350 | } | 231 | } |
351 | 232 | ||
352 | #ifdef CONFIG_IWL4965_HT | ||
353 | static u8 is_single_rx_stream(struct iwl_priv *priv) | ||
354 | { | ||
355 | return !priv->current_ht_config.is_ht || | ||
356 | ((priv->current_ht_config.supp_mcs_set[1] == 0) && | ||
357 | (priv->current_ht_config.supp_mcs_set[2] == 0)) || | ||
358 | priv->ps_mode == IWL_MIMO_PS_STATIC; | ||
359 | } | ||
360 | #else | ||
361 | static inline u8 is_single_rx_stream(struct iwl_priv *priv) | ||
362 | { | ||
363 | return 1; | ||
364 | } | ||
365 | #endif /*CONFIG_IWL4965_HT */ | ||
366 | |||
367 | int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags) | 233 | int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags) |
368 | { | 234 | { |
369 | int idx = 0; | 235 | int idx = 0; |
@@ -422,41 +288,6 @@ void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, | |||
422 | &priv->bands[IEEE80211_BAND_2GHZ].bitrates[rate_index]; | 288 | &priv->bands[IEEE80211_BAND_2GHZ].bitrates[rate_index]; |
423 | } | 289 | } |
424 | 290 | ||
425 | /* | ||
426 | * Determine how many receiver/antenna chains to use. | ||
427 | * More provides better reception via diversity. Fewer saves power. | ||
428 | * MIMO (dual stream) requires at least 2, but works better with 3. | ||
429 | * This does not determine *which* chains to use, just how many. | ||
430 | */ | ||
431 | static int iwl4965_get_rx_chain_counter(struct iwl_priv *priv, | ||
432 | u8 *idle_state, u8 *rx_state) | ||
433 | { | ||
434 | u8 is_single = is_single_rx_stream(priv); | ||
435 | u8 is_cam = test_bit(STATUS_POWER_PMI, &priv->status) ? 0 : 1; | ||
436 | |||
437 | /* # of Rx chains to use when expecting MIMO. */ | ||
438 | if (is_single || (!is_cam && (priv->ps_mode == IWL_MIMO_PS_STATIC))) | ||
439 | *rx_state = 2; | ||
440 | else | ||
441 | *rx_state = 3; | ||
442 | |||
443 | /* # Rx chains when idling and maybe trying to save power */ | ||
444 | switch (priv->ps_mode) { | ||
445 | case IWL_MIMO_PS_STATIC: | ||
446 | case IWL_MIMO_PS_DYNAMIC: | ||
447 | *idle_state = (is_cam) ? 2 : 1; | ||
448 | break; | ||
449 | case IWL_MIMO_PS_NONE: | ||
450 | *idle_state = (is_cam) ? *rx_state : 1; | ||
451 | break; | ||
452 | default: | ||
453 | *idle_state = 1; | ||
454 | break; | ||
455 | } | ||
456 | |||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | int iwl4965_hw_rxq_stop(struct iwl_priv *priv) | 291 | int iwl4965_hw_rxq_stop(struct iwl_priv *priv) |
461 | { | 292 | { |
462 | int rc; | 293 | int rc; |
@@ -2527,44 +2358,6 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv, | |||
2527 | } | 2358 | } |
2528 | 2359 | ||
2529 | /** | 2360 | /** |
2530 | * iwl4965_set_rxon_chain - Set up Rx chain usage in "staging" RXON image | ||
2531 | * | ||
2532 | * Selects how many and which Rx receivers/antennas/chains to use. | ||
2533 | * This should not be used for scan command ... it puts data in wrong place. | ||
2534 | */ | ||
2535 | void iwl4965_set_rxon_chain(struct iwl_priv *priv) | ||
2536 | { | ||
2537 | u8 is_single = is_single_rx_stream(priv); | ||
2538 | u8 idle_state, rx_state; | ||
2539 | |||
2540 | priv->staging_rxon.rx_chain = 0; | ||
2541 | rx_state = idle_state = 3; | ||
2542 | |||
2543 | /* Tell uCode which antennas are actually connected. | ||
2544 | * Before first association, we assume all antennas are connected. | ||
2545 | * Just after first association, iwl_chain_noise_calibration() | ||
2546 | * checks which antennas actually *are* connected. */ | ||
2547 | priv->staging_rxon.rx_chain |= | ||
2548 | cpu_to_le16(priv->hw_params.valid_rx_ant << | ||
2549 | RXON_RX_CHAIN_VALID_POS); | ||
2550 | |||
2551 | /* How many receivers should we use? */ | ||
2552 | iwl4965_get_rx_chain_counter(priv, &idle_state, &rx_state); | ||
2553 | priv->staging_rxon.rx_chain |= | ||
2554 | cpu_to_le16(rx_state << RXON_RX_CHAIN_MIMO_CNT_POS); | ||
2555 | priv->staging_rxon.rx_chain |= | ||
2556 | cpu_to_le16(idle_state << RXON_RX_CHAIN_CNT_POS); | ||
2557 | |||
2558 | if (!is_single && (rx_state >= 2) && | ||
2559 | !test_bit(STATUS_POWER_PMI, &priv->status)) | ||
2560 | priv->staging_rxon.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; | ||
2561 | else | ||
2562 | priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; | ||
2563 | |||
2564 | IWL_DEBUG_ASSOC("rx chain %X\n", priv->staging_rxon.rx_chain); | ||
2565 | } | ||
2566 | |||
2567 | /** | ||
2568 | * sign_extend - Sign extend a value using specified bit as sign-bit | 2361 | * sign_extend - Sign extend a value using specified bit as sign-bit |
2569 | * | 2362 | * |
2570 | * Example: sign_extend(9, 3) would return -7 as bit3 of 1001b is 1 | 2363 | * Example: sign_extend(9, 3) would return -7 as bit3 of 1001b is 1 |
@@ -3127,41 +2920,6 @@ static int iwl4965_calc_rssi(struct iwl4965_rx_phy_res *rx_resp) | |||
3127 | return (max_rssi - agc - IWL_RSSI_OFFSET); | 2920 | return (max_rssi - agc - IWL_RSSI_OFFSET); |
3128 | } | 2921 | } |
3129 | 2922 | ||
3130 | #ifdef CONFIG_IWL4965_HT | ||
3131 | |||
3132 | void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv, | ||
3133 | struct ieee80211_ht_info *ht_info, | ||
3134 | enum ieee80211_band band) | ||
3135 | { | ||
3136 | ht_info->cap = 0; | ||
3137 | memset(ht_info->supp_mcs_set, 0, 16); | ||
3138 | |||
3139 | ht_info->ht_supported = 1; | ||
3140 | |||
3141 | if (priv->hw_params.fat_channel & BIT(band)) { | ||
3142 | ht_info->cap |= (u16)IEEE80211_HT_CAP_SUP_WIDTH; | ||
3143 | ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_40; | ||
3144 | ht_info->supp_mcs_set[4] = 0x01; | ||
3145 | } | ||
3146 | ht_info->cap |= (u16)IEEE80211_HT_CAP_GRN_FLD; | ||
3147 | ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_20; | ||
3148 | ht_info->cap |= (u16)(IEEE80211_HT_CAP_MIMO_PS & | ||
3149 | (IWL_MIMO_PS_NONE << 2)); | ||
3150 | |||
3151 | if (priv->cfg->mod_params->amsdu_size_8K) | ||
3152 | ht_info->cap |= (u16)IEEE80211_HT_CAP_MAX_AMSDU; | ||
3153 | |||
3154 | ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; | ||
3155 | ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; | ||
3156 | |||
3157 | ht_info->supp_mcs_set[0] = 0xFF; | ||
3158 | if (priv->hw_params.tx_chains_num >= 2) | ||
3159 | ht_info->supp_mcs_set[1] = 0xFF; | ||
3160 | if (priv->hw_params.tx_chains_num >= 3) | ||
3161 | ht_info->supp_mcs_set[2] = 0xFF; | ||
3162 | } | ||
3163 | #endif /* CONFIG_IWL4965_HT */ | ||
3164 | |||
3165 | static void iwl4965_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) | 2923 | static void iwl4965_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) |
3166 | { | 2924 | { |
3167 | unsigned long flags; | 2925 | unsigned long flags; |
@@ -4039,7 +3797,7 @@ void iwl4965_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) | |||
4039 | 3797 | ||
4040 | rxon->flags |= cpu_to_le32(val << RXON_FLG_HT_OPERATING_MODE_POS); | 3798 | rxon->flags |= cpu_to_le32(val << RXON_FLG_HT_OPERATING_MODE_POS); |
4041 | 3799 | ||
4042 | iwl4965_set_rxon_chain(priv); | 3800 | iwl_set_rxon_chain(priv); |
4043 | 3801 | ||
4044 | IWL_DEBUG_ASSOC("supported HT rate 0x%X 0x%X 0x%X " | 3802 | IWL_DEBUG_ASSOC("supported HT rate 0x%X 0x%X 0x%X " |
4045 | "rxon flags 0x%X operation mode :0x%X " | 3803 | "rxon flags 0x%X operation mode :0x%X " |
@@ -4356,7 +4114,6 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { | |||
4356 | }; | 4114 | }; |
4357 | 4115 | ||
4358 | static struct iwl_lib_ops iwl4965_lib = { | 4116 | static struct iwl_lib_ops iwl4965_lib = { |
4359 | .init_drv = iwl4965_init_drv, | ||
4360 | .set_hw_params = iwl4965_hw_set_hw_params, | 4117 | .set_hw_params = iwl4965_hw_set_hw_params, |
4361 | .alloc_shared_mem = iwl4965_alloc_shared_mem, | 4118 | .alloc_shared_mem = iwl4965_alloc_shared_mem, |
4362 | .free_shared_mem = iwl4965_free_shared_mem, | 4119 | .free_shared_mem = iwl4965_free_shared_mem, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index e3572636e598..3b7306475531 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h | |||
@@ -748,7 +748,6 @@ extern int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv, | |||
748 | u16 byte_cnt); | 748 | u16 byte_cnt); |
749 | extern void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, | 749 | extern void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, |
750 | int is_ap); | 750 | int is_ap); |
751 | extern void iwl4965_set_rxon_chain(struct iwl_priv *priv); | ||
752 | extern int iwl4965_alive_notify(struct iwl_priv *priv); | 751 | extern int iwl4965_alive_notify(struct iwl_priv *priv); |
753 | extern void iwl4965_update_rate_scaling(struct iwl_priv *priv, u8 mode); | 752 | extern void iwl4965_update_rate_scaling(struct iwl_priv *priv, u8 mode); |
754 | extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv); | 753 | extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 68de1a4700a6..ca32fb3b9e1b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -51,6 +51,45 @@ u32 iwl_debug_level; | |||
51 | EXPORT_SYMBOL(iwl_debug_level); | 51 | EXPORT_SYMBOL(iwl_debug_level); |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | #define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \ | ||
55 | [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ | ||
56 | IWL_RATE_SISO_##s##M_PLCP, \ | ||
57 | IWL_RATE_MIMO2_##s##M_PLCP,\ | ||
58 | IWL_RATE_MIMO3_##s##M_PLCP,\ | ||
59 | IWL_RATE_##r##M_IEEE, \ | ||
60 | IWL_RATE_##ip##M_INDEX, \ | ||
61 | IWL_RATE_##in##M_INDEX, \ | ||
62 | IWL_RATE_##rp##M_INDEX, \ | ||
63 | IWL_RATE_##rn##M_INDEX, \ | ||
64 | IWL_RATE_##pp##M_INDEX, \ | ||
65 | IWL_RATE_##np##M_INDEX } | ||
66 | |||
67 | /* | ||
68 | * Parameter order: | ||
69 | * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate | ||
70 | * | ||
71 | * If there isn't a valid next or previous rate then INV is used which | ||
72 | * maps to IWL_RATE_INVALID | ||
73 | * | ||
74 | */ | ||
75 | const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT] = { | ||
76 | IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */ | ||
77 | IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */ | ||
78 | IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */ | ||
79 | IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */ | ||
80 | IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */ | ||
81 | IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */ | ||
82 | IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */ | ||
83 | IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */ | ||
84 | IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */ | ||
85 | IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */ | ||
86 | IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */ | ||
87 | IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */ | ||
88 | IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */ | ||
89 | /* FIXME:RS: ^^ should be INV (legacy) */ | ||
90 | }; | ||
91 | EXPORT_SYMBOL(iwl4965_rates); | ||
92 | |||
54 | /* This function both allocates and initializes hw and priv. */ | 93 | /* This function both allocates and initializes hw and priv. */ |
55 | struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, | 94 | struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, |
56 | struct ieee80211_ops *hw_ops) | 95 | struct ieee80211_ops *hw_ops) |
@@ -100,7 +139,7 @@ void iwlcore_clear_stations_table(struct iwl_priv *priv) | |||
100 | } | 139 | } |
101 | EXPORT_SYMBOL(iwlcore_clear_stations_table); | 140 | EXPORT_SYMBOL(iwlcore_clear_stations_table); |
102 | 141 | ||
103 | void iwlcore_reset_qos(struct iwl_priv *priv) | 142 | void iwl_reset_qos(struct iwl_priv *priv) |
104 | { | 143 | { |
105 | u16 cw_min = 15; | 144 | u16 cw_min = 15; |
106 | u16 cw_max = 1023; | 145 | u16 cw_max = 1023; |
@@ -186,7 +225,289 @@ void iwlcore_reset_qos(struct iwl_priv *priv) | |||
186 | 225 | ||
187 | spin_unlock_irqrestore(&priv->lock, flags); | 226 | spin_unlock_irqrestore(&priv->lock, flags); |
188 | } | 227 | } |
189 | EXPORT_SYMBOL(iwlcore_reset_qos); | 228 | EXPORT_SYMBOL(iwl_reset_qos); |
229 | |||
230 | #ifdef CONFIG_IWL4965_HT | ||
231 | static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, | ||
232 | struct ieee80211_ht_info *ht_info, | ||
233 | enum ieee80211_band band) | ||
234 | { | ||
235 | ht_info->cap = 0; | ||
236 | memset(ht_info->supp_mcs_set, 0, 16); | ||
237 | |||
238 | ht_info->ht_supported = 1; | ||
239 | |||
240 | if (priv->hw_params.fat_channel & BIT(band)) { | ||
241 | ht_info->cap |= (u16)IEEE80211_HT_CAP_SUP_WIDTH; | ||
242 | ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_40; | ||
243 | ht_info->supp_mcs_set[4] = 0x01; | ||
244 | } | ||
245 | ht_info->cap |= (u16)IEEE80211_HT_CAP_GRN_FLD; | ||
246 | ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_20; | ||
247 | ht_info->cap |= (u16)(IEEE80211_HT_CAP_MIMO_PS & | ||
248 | (IWL_MIMO_PS_NONE << 2)); | ||
249 | |||
250 | if (priv->cfg->mod_params->amsdu_size_8K) | ||
251 | ht_info->cap |= (u16)IEEE80211_HT_CAP_MAX_AMSDU; | ||
252 | |||
253 | ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; | ||
254 | ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; | ||
255 | |||
256 | ht_info->supp_mcs_set[0] = 0xFF; | ||
257 | if (priv->hw_params.tx_chains_num >= 2) | ||
258 | ht_info->supp_mcs_set[1] = 0xFF; | ||
259 | if (priv->hw_params.tx_chains_num >= 3) | ||
260 | ht_info->supp_mcs_set[2] = 0xFF; | ||
261 | } | ||
262 | #endif /* CONFIG_IWL4965_HT */ | ||
263 | |||
264 | static void iwlcore_init_hw_rates(struct iwl_priv *priv, | ||
265 | struct ieee80211_rate *rates) | ||
266 | { | ||
267 | int i; | ||
268 | |||
269 | for (i = 0; i < IWL_RATE_COUNT; i++) { | ||
270 | rates[i].bitrate = iwl4965_rates[i].ieee * 5; | ||
271 | rates[i].hw_value = i; /* Rate scaling will work on indexes */ | ||
272 | rates[i].hw_value_short = i; | ||
273 | rates[i].flags = 0; | ||
274 | if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) { | ||
275 | /* | ||
276 | * If CCK != 1M then set short preamble rate flag. | ||
277 | */ | ||
278 | rates[i].flags |= | ||
279 | (iwl4965_rates[i].plcp == IWL_RATE_1M_PLCP) ? | ||
280 | 0 : IEEE80211_RATE_SHORT_PREAMBLE; | ||
281 | } | ||
282 | } | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * iwlcore_init_geos - Initialize mac80211's geo/channel info based from eeprom | ||
287 | */ | ||
288 | static int iwlcore_init_geos(struct iwl_priv *priv) | ||
289 | { | ||
290 | struct iwl_channel_info *ch; | ||
291 | struct ieee80211_supported_band *sband; | ||
292 | struct ieee80211_channel *channels; | ||
293 | struct ieee80211_channel *geo_ch; | ||
294 | struct ieee80211_rate *rates; | ||
295 | int i = 0; | ||
296 | |||
297 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || | ||
298 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | ||
299 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); | ||
300 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | channels = kzalloc(sizeof(struct ieee80211_channel) * | ||
305 | priv->channel_count, GFP_KERNEL); | ||
306 | if (!channels) | ||
307 | return -ENOMEM; | ||
308 | |||
309 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)), | ||
310 | GFP_KERNEL); | ||
311 | if (!rates) { | ||
312 | kfree(channels); | ||
313 | return -ENOMEM; | ||
314 | } | ||
315 | |||
316 | /* 5.2GHz channels start after the 2.4GHz channels */ | ||
317 | sband = &priv->bands[IEEE80211_BAND_5GHZ]; | ||
318 | sband->channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)]; | ||
319 | /* just OFDM */ | ||
320 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; | ||
321 | sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE; | ||
322 | |||
323 | iwlcore_init_ht_hw_capab(priv, &sband->ht_info, IEEE80211_BAND_5GHZ); | ||
324 | |||
325 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; | ||
326 | sband->channels = channels; | ||
327 | /* OFDM & CCK */ | ||
328 | sband->bitrates = rates; | ||
329 | sband->n_bitrates = IWL_RATE_COUNT; | ||
330 | |||
331 | iwlcore_init_ht_hw_capab(priv, &sband->ht_info, IEEE80211_BAND_2GHZ); | ||
332 | |||
333 | priv->ieee_channels = channels; | ||
334 | priv->ieee_rates = rates; | ||
335 | |||
336 | iwlcore_init_hw_rates(priv, rates); | ||
337 | |||
338 | for (i = 0; i < priv->channel_count; i++) { | ||
339 | ch = &priv->channel_info[i]; | ||
340 | |||
341 | /* FIXME: might be removed if scan is OK */ | ||
342 | if (!is_channel_valid(ch)) | ||
343 | continue; | ||
344 | |||
345 | if (is_channel_a_band(ch)) | ||
346 | sband = &priv->bands[IEEE80211_BAND_5GHZ]; | ||
347 | else | ||
348 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; | ||
349 | |||
350 | geo_ch = &sband->channels[sband->n_channels++]; | ||
351 | |||
352 | geo_ch->center_freq = | ||
353 | ieee80211_channel_to_frequency(ch->channel); | ||
354 | geo_ch->max_power = ch->max_power_avg; | ||
355 | geo_ch->max_antenna_gain = 0xff; | ||
356 | geo_ch->hw_value = ch->channel; | ||
357 | |||
358 | if (is_channel_valid(ch)) { | ||
359 | if (!(ch->flags & EEPROM_CHANNEL_IBSS)) | ||
360 | geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; | ||
361 | |||
362 | if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) | ||
363 | geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; | ||
364 | |||
365 | if (ch->flags & EEPROM_CHANNEL_RADAR) | ||
366 | geo_ch->flags |= IEEE80211_CHAN_RADAR; | ||
367 | |||
368 | if (ch->max_power_avg > priv->max_channel_txpower_limit) | ||
369 | priv->max_channel_txpower_limit = | ||
370 | ch->max_power_avg; | ||
371 | } else { | ||
372 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; | ||
373 | } | ||
374 | |||
375 | /* Save flags for reg domain usage */ | ||
376 | geo_ch->orig_flags = geo_ch->flags; | ||
377 | |||
378 | IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n", | ||
379 | ch->channel, geo_ch->center_freq, | ||
380 | is_channel_a_band(ch) ? "5.2" : "2.4", | ||
381 | geo_ch->flags & IEEE80211_CHAN_DISABLED ? | ||
382 | "restricted" : "valid", | ||
383 | geo_ch->flags); | ||
384 | } | ||
385 | |||
386 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && | ||
387 | priv->cfg->sku & IWL_SKU_A) { | ||
388 | printk(KERN_INFO DRV_NAME | ||
389 | ": Incorrectly detected BG card as ABG. Please send " | ||
390 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", | ||
391 | priv->pci_dev->device, priv->pci_dev->subsystem_device); | ||
392 | priv->cfg->sku &= ~IWL_SKU_A; | ||
393 | } | ||
394 | |||
395 | printk(KERN_INFO DRV_NAME | ||
396 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", | ||
397 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, | ||
398 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | ||
399 | |||
400 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) | ||
401 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
402 | &priv->bands[IEEE80211_BAND_2GHZ]; | ||
403 | if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) | ||
404 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
405 | &priv->bands[IEEE80211_BAND_5GHZ]; | ||
406 | |||
407 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
408 | |||
409 | return 0; | ||
410 | } | ||
411 | |||
412 | /* | ||
413 | * iwlcore_free_geos - undo allocations in iwlcore_init_geos | ||
414 | */ | ||
415 | void iwlcore_free_geos(struct iwl_priv *priv) | ||
416 | { | ||
417 | kfree(priv->ieee_channels); | ||
418 | kfree(priv->ieee_rates); | ||
419 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
420 | } | ||
421 | EXPORT_SYMBOL(iwlcore_free_geos); | ||
422 | |||
423 | #ifdef CONFIG_IWL4965_HT | ||
424 | static u8 is_single_rx_stream(struct iwl_priv *priv) | ||
425 | { | ||
426 | return !priv->current_ht_config.is_ht || | ||
427 | ((priv->current_ht_config.supp_mcs_set[1] == 0) && | ||
428 | (priv->current_ht_config.supp_mcs_set[2] == 0)) || | ||
429 | priv->ps_mode == IWL_MIMO_PS_STATIC; | ||
430 | } | ||
431 | #else | ||
432 | static inline u8 is_single_rx_stream(struct iwl_priv *priv) | ||
433 | { | ||
434 | return 1; | ||
435 | } | ||
436 | #endif /*CONFIG_IWL4965_HT */ | ||
437 | |||
438 | /* | ||
439 | * Determine how many receiver/antenna chains to use. | ||
440 | * More provides better reception via diversity. Fewer saves power. | ||
441 | * MIMO (dual stream) requires at least 2, but works better with 3. | ||
442 | * This does not determine *which* chains to use, just how many. | ||
443 | */ | ||
444 | static int iwlcore_get_rx_chain_counter(struct iwl_priv *priv, | ||
445 | u8 *idle_state, u8 *rx_state) | ||
446 | { | ||
447 | u8 is_single = is_single_rx_stream(priv); | ||
448 | u8 is_cam = test_bit(STATUS_POWER_PMI, &priv->status) ? 0 : 1; | ||
449 | |||
450 | /* # of Rx chains to use when expecting MIMO. */ | ||
451 | if (is_single || (!is_cam && (priv->ps_mode == IWL_MIMO_PS_STATIC))) | ||
452 | *rx_state = 2; | ||
453 | else | ||
454 | *rx_state = 3; | ||
455 | |||
456 | /* # Rx chains when idling and maybe trying to save power */ | ||
457 | switch (priv->ps_mode) { | ||
458 | case IWL_MIMO_PS_STATIC: | ||
459 | case IWL_MIMO_PS_DYNAMIC: | ||
460 | *idle_state = (is_cam) ? 2 : 1; | ||
461 | break; | ||
462 | case IWL_MIMO_PS_NONE: | ||
463 | *idle_state = (is_cam) ? *rx_state : 1; | ||
464 | break; | ||
465 | default: | ||
466 | *idle_state = 1; | ||
467 | break; | ||
468 | } | ||
469 | |||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | /** | ||
474 | * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image | ||
475 | * | ||
476 | * Selects how many and which Rx receivers/antennas/chains to use. | ||
477 | * This should not be used for scan command ... it puts data in wrong place. | ||
478 | */ | ||
479 | void iwl_set_rxon_chain(struct iwl_priv *priv) | ||
480 | { | ||
481 | u8 is_single = is_single_rx_stream(priv); | ||
482 | u8 idle_state, rx_state; | ||
483 | |||
484 | priv->staging_rxon.rx_chain = 0; | ||
485 | rx_state = idle_state = 3; | ||
486 | |||
487 | /* Tell uCode which antennas are actually connected. | ||
488 | * Before first association, we assume all antennas are connected. | ||
489 | * Just after first association, iwl_chain_noise_calibration() | ||
490 | * checks which antennas actually *are* connected. */ | ||
491 | priv->staging_rxon.rx_chain |= | ||
492 | cpu_to_le16(priv->hw_params.valid_rx_ant << | ||
493 | RXON_RX_CHAIN_VALID_POS); | ||
494 | |||
495 | /* How many receivers should we use? */ | ||
496 | iwlcore_get_rx_chain_counter(priv, &idle_state, &rx_state); | ||
497 | priv->staging_rxon.rx_chain |= | ||
498 | cpu_to_le16(rx_state << RXON_RX_CHAIN_MIMO_CNT_POS); | ||
499 | priv->staging_rxon.rx_chain |= | ||
500 | cpu_to_le16(idle_state << RXON_RX_CHAIN_CNT_POS); | ||
501 | |||
502 | if (!is_single && (rx_state >= 2) && | ||
503 | !test_bit(STATUS_POWER_PMI, &priv->status)) | ||
504 | priv->staging_rxon.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; | ||
505 | else | ||
506 | priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; | ||
507 | |||
508 | IWL_DEBUG_ASSOC("rx chain %X\n", priv->staging_rxon.rx_chain); | ||
509 | } | ||
510 | EXPORT_SYMBOL(iwl_set_rxon_chain); | ||
190 | 511 | ||
191 | /** | 512 | /** |
192 | * iwlcore_set_rxon_channel - Set the phymode and channel values in staging RXON | 513 | * iwlcore_set_rxon_channel - Set the phymode and channel values in staging RXON |
@@ -198,7 +519,7 @@ EXPORT_SYMBOL(iwlcore_reset_qos); | |||
198 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields | 519 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields |
199 | * in the staging RXON flag structure based on the phymode | 520 | * in the staging RXON flag structure based on the phymode |
200 | */ | 521 | */ |
201 | int iwlcore_set_rxon_channel(struct iwl_priv *priv, | 522 | int iwl_set_rxon_channel(struct iwl_priv *priv, |
202 | enum ieee80211_band band, | 523 | enum ieee80211_band band, |
203 | u16 channel) | 524 | u16 channel) |
204 | { | 525 | { |
@@ -224,7 +545,7 @@ int iwlcore_set_rxon_channel(struct iwl_priv *priv, | |||
224 | 545 | ||
225 | return 0; | 546 | return 0; |
226 | } | 547 | } |
227 | EXPORT_SYMBOL(iwlcore_set_rxon_channel); | 548 | EXPORT_SYMBOL(iwl_set_rxon_channel); |
228 | 549 | ||
229 | static void iwlcore_init_hw(struct iwl_priv *priv) | 550 | static void iwlcore_init_hw(struct iwl_priv *priv) |
230 | { | 551 | { |
@@ -251,11 +572,92 @@ static void iwlcore_init_hw(struct iwl_priv *priv) | |||
251 | #endif /* CONFIG_IWL4965_HT */ | 572 | #endif /* CONFIG_IWL4965_HT */ |
252 | } | 573 | } |
253 | 574 | ||
575 | static int iwlcore_init_drv(struct iwl_priv *priv) | ||
576 | { | ||
577 | int ret; | ||
578 | int i; | ||
579 | |||
580 | priv->retry_rate = 1; | ||
581 | priv->ibss_beacon = NULL; | ||
582 | |||
583 | spin_lock_init(&priv->lock); | ||
584 | spin_lock_init(&priv->power_data.lock); | ||
585 | spin_lock_init(&priv->sta_lock); | ||
586 | spin_lock_init(&priv->hcmd_lock); | ||
587 | spin_lock_init(&priv->lq_mngr.lock); | ||
588 | |||
589 | for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) | ||
590 | INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); | ||
591 | |||
592 | INIT_LIST_HEAD(&priv->free_frames); | ||
593 | |||
594 | mutex_init(&priv->mutex); | ||
595 | |||
596 | /* Clear the driver's (not device's) station table */ | ||
597 | iwlcore_clear_stations_table(priv); | ||
598 | |||
599 | priv->data_retry_limit = -1; | ||
600 | priv->ieee_channels = NULL; | ||
601 | priv->ieee_rates = NULL; | ||
602 | priv->band = IEEE80211_BAND_2GHZ; | ||
603 | |||
604 | priv->iw_mode = IEEE80211_IF_TYPE_STA; | ||
605 | |||
606 | priv->use_ant_b_for_management_frame = 1; /* start with ant B */ | ||
607 | priv->ps_mode = IWL_MIMO_PS_NONE; | ||
608 | |||
609 | /* Choose which receivers/antennas to use */ | ||
610 | iwl_set_rxon_chain(priv); | ||
611 | |||
612 | iwl_reset_qos(priv); | ||
613 | |||
614 | priv->qos_data.qos_active = 0; | ||
615 | priv->qos_data.qos_cap.val = 0; | ||
616 | |||
617 | iwl_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6); | ||
618 | |||
619 | priv->rates_mask = IWL_RATES_MASK; | ||
620 | /* If power management is turned on, default to AC mode */ | ||
621 | priv->power_mode = IWL_POWER_AC; | ||
622 | priv->user_txpower_limit = IWL_DEFAULT_TX_POWER; | ||
623 | |||
624 | ret = iwl_init_channel_map(priv); | ||
625 | if (ret) { | ||
626 | IWL_ERROR("initializing regulatory failed: %d\n", ret); | ||
627 | goto err; | ||
628 | } | ||
629 | |||
630 | ret = iwlcore_init_geos(priv); | ||
631 | if (ret) { | ||
632 | IWL_ERROR("initializing geos failed: %d\n", ret); | ||
633 | goto err_free_channel_map; | ||
634 | } | ||
635 | |||
636 | ret = ieee80211_register_hw(priv->hw); | ||
637 | if (ret) { | ||
638 | IWL_ERROR("Failed to register network device (error %d)\n", | ||
639 | ret); | ||
640 | goto err_free_geos; | ||
641 | } | ||
642 | |||
643 | priv->hw->conf.beacon_int = 100; | ||
644 | priv->mac80211_registered = 1; | ||
645 | |||
646 | return 0; | ||
647 | |||
648 | err_free_geos: | ||
649 | iwlcore_free_geos(priv); | ||
650 | err_free_channel_map: | ||
651 | iwl_free_channel_map(priv); | ||
652 | err: | ||
653 | return ret; | ||
654 | } | ||
655 | |||
254 | int iwl_setup(struct iwl_priv *priv) | 656 | int iwl_setup(struct iwl_priv *priv) |
255 | { | 657 | { |
256 | int ret = 0; | 658 | int ret = 0; |
257 | iwlcore_init_hw(priv); | 659 | iwlcore_init_hw(priv); |
258 | ret = priv->cfg->ops->lib->init_drv(priv); | 660 | ret = iwlcore_init_drv(priv); |
259 | return ret; | 661 | return ret; |
260 | } | 662 | } |
261 | EXPORT_SYMBOL(iwl_setup); | 663 | EXPORT_SYMBOL(iwl_setup); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index e94aea3cba7c..e18940dbd13c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -97,8 +97,6 @@ struct iwl_hcmd_utils_ops { | |||
97 | }; | 97 | }; |
98 | 98 | ||
99 | struct iwl_lib_ops { | 99 | struct iwl_lib_ops { |
100 | /* iwlwifi driver (priv) init */ | ||
101 | int (*init_drv)(struct iwl_priv *priv); | ||
102 | /* set hw dependant perameters */ | 100 | /* set hw dependant perameters */ |
103 | int (*set_hw_params)(struct iwl_priv *priv); | 101 | int (*set_hw_params)(struct iwl_priv *priv); |
104 | /* ucode shared memory */ | 102 | /* ucode shared memory */ |
@@ -164,11 +162,12 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, | |||
164 | void iwl_hw_detect(struct iwl_priv *priv); | 162 | void iwl_hw_detect(struct iwl_priv *priv); |
165 | 163 | ||
166 | void iwlcore_clear_stations_table(struct iwl_priv *priv); | 164 | void iwlcore_clear_stations_table(struct iwl_priv *priv); |
167 | void iwlcore_reset_qos(struct iwl_priv *priv); | 165 | void iwl_reset_qos(struct iwl_priv *priv); |
168 | int iwlcore_set_rxon_channel(struct iwl_priv *priv, | 166 | void iwl_set_rxon_chain(struct iwl_priv *priv); |
167 | int iwl_set_rxon_channel(struct iwl_priv *priv, | ||
169 | enum ieee80211_band band, | 168 | enum ieee80211_band band, |
170 | u16 channel); | 169 | u16 channel); |
171 | 170 | void iwlcore_free_geos(struct iwl_priv *priv); | |
172 | int iwl_setup(struct iwl_priv *priv); | 171 | int iwl_setup(struct iwl_priv *priv); |
173 | 172 | ||
174 | /***************************************************** | 173 | /***************************************************** |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 89b0950f02f0..e24527313ab6 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -882,7 +882,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
882 | void iwl4965_update_chain_flags(struct iwl_priv *priv) | 882 | void iwl4965_update_chain_flags(struct iwl_priv *priv) |
883 | { | 883 | { |
884 | 884 | ||
885 | iwl4965_set_rxon_chain(priv); | 885 | iwl_set_rxon_chain(priv); |
886 | iwl4965_commit_rxon(priv); | 886 | iwl4965_commit_rxon(priv); |
887 | } | 887 | } |
888 | 888 | ||
@@ -1735,7 +1735,7 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv) | |||
1735 | memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN); | 1735 | memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN); |
1736 | priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff; | 1736 | priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff; |
1737 | priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff; | 1737 | priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff; |
1738 | iwl4965_set_rxon_chain(priv); | 1738 | iwl_set_rxon_chain(priv); |
1739 | } | 1739 | } |
1740 | 1740 | ||
1741 | static int iwl4965_set_mode(struct iwl_priv *priv, int mode) | 1741 | static int iwl4965_set_mode(struct iwl_priv *priv, int mode) |
@@ -4496,163 +4496,6 @@ static int iwl4965_get_channels_for_scan(struct iwl_priv *priv, | |||
4496 | return added; | 4496 | return added; |
4497 | } | 4497 | } |
4498 | 4498 | ||
4499 | static void iwl4965_init_hw_rates(struct iwl_priv *priv, | ||
4500 | struct ieee80211_rate *rates) | ||
4501 | { | ||
4502 | int i; | ||
4503 | |||
4504 | for (i = 0; i < IWL_RATE_COUNT; i++) { | ||
4505 | rates[i].bitrate = iwl4965_rates[i].ieee * 5; | ||
4506 | rates[i].hw_value = i; /* Rate scaling will work on indexes */ | ||
4507 | rates[i].hw_value_short = i; | ||
4508 | rates[i].flags = 0; | ||
4509 | if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) { | ||
4510 | /* | ||
4511 | * If CCK != 1M then set short preamble rate flag. | ||
4512 | */ | ||
4513 | rates[i].flags |= | ||
4514 | (iwl4965_rates[i].plcp == IWL_RATE_1M_PLCP) ? | ||
4515 | 0 : IEEE80211_RATE_SHORT_PREAMBLE; | ||
4516 | } | ||
4517 | } | ||
4518 | } | ||
4519 | |||
4520 | /** | ||
4521 | * iwl4965_init_geos - Initialize mac80211's geo/channel info based from eeprom | ||
4522 | */ | ||
4523 | int iwl4965_init_geos(struct iwl_priv *priv) | ||
4524 | { | ||
4525 | struct iwl_channel_info *ch; | ||
4526 | struct ieee80211_supported_band *sband; | ||
4527 | struct ieee80211_channel *channels; | ||
4528 | struct ieee80211_channel *geo_ch; | ||
4529 | struct ieee80211_rate *rates; | ||
4530 | int i = 0; | ||
4531 | |||
4532 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || | ||
4533 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | ||
4534 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); | ||
4535 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
4536 | return 0; | ||
4537 | } | ||
4538 | |||
4539 | channels = kzalloc(sizeof(struct ieee80211_channel) * | ||
4540 | priv->channel_count, GFP_KERNEL); | ||
4541 | if (!channels) | ||
4542 | return -ENOMEM; | ||
4543 | |||
4544 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)), | ||
4545 | GFP_KERNEL); | ||
4546 | if (!rates) { | ||
4547 | kfree(channels); | ||
4548 | return -ENOMEM; | ||
4549 | } | ||
4550 | |||
4551 | /* 5.2GHz channels start after the 2.4GHz channels */ | ||
4552 | sband = &priv->bands[IEEE80211_BAND_5GHZ]; | ||
4553 | sband->channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)]; | ||
4554 | /* just OFDM */ | ||
4555 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; | ||
4556 | sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE; | ||
4557 | |||
4558 | iwl4965_init_ht_hw_capab(priv, &sband->ht_info, IEEE80211_BAND_5GHZ); | ||
4559 | |||
4560 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; | ||
4561 | sband->channels = channels; | ||
4562 | /* OFDM & CCK */ | ||
4563 | sband->bitrates = rates; | ||
4564 | sband->n_bitrates = IWL_RATE_COUNT; | ||
4565 | |||
4566 | iwl4965_init_ht_hw_capab(priv, &sband->ht_info, IEEE80211_BAND_2GHZ); | ||
4567 | |||
4568 | priv->ieee_channels = channels; | ||
4569 | priv->ieee_rates = rates; | ||
4570 | |||
4571 | iwl4965_init_hw_rates(priv, rates); | ||
4572 | |||
4573 | for (i = 0; i < priv->channel_count; i++) { | ||
4574 | ch = &priv->channel_info[i]; | ||
4575 | |||
4576 | /* FIXME: might be removed if scan is OK */ | ||
4577 | if (!is_channel_valid(ch)) | ||
4578 | continue; | ||
4579 | |||
4580 | if (is_channel_a_band(ch)) | ||
4581 | sband = &priv->bands[IEEE80211_BAND_5GHZ]; | ||
4582 | else | ||
4583 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; | ||
4584 | |||
4585 | geo_ch = &sband->channels[sband->n_channels++]; | ||
4586 | |||
4587 | geo_ch->center_freq = ieee80211_channel_to_frequency(ch->channel); | ||
4588 | geo_ch->max_power = ch->max_power_avg; | ||
4589 | geo_ch->max_antenna_gain = 0xff; | ||
4590 | geo_ch->hw_value = ch->channel; | ||
4591 | |||
4592 | if (is_channel_valid(ch)) { | ||
4593 | if (!(ch->flags & EEPROM_CHANNEL_IBSS)) | ||
4594 | geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; | ||
4595 | |||
4596 | if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) | ||
4597 | geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; | ||
4598 | |||
4599 | if (ch->flags & EEPROM_CHANNEL_RADAR) | ||
4600 | geo_ch->flags |= IEEE80211_CHAN_RADAR; | ||
4601 | |||
4602 | if (ch->max_power_avg > priv->max_channel_txpower_limit) | ||
4603 | priv->max_channel_txpower_limit = | ||
4604 | ch->max_power_avg; | ||
4605 | } else { | ||
4606 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; | ||
4607 | } | ||
4608 | |||
4609 | /* Save flags for reg domain usage */ | ||
4610 | geo_ch->orig_flags = geo_ch->flags; | ||
4611 | |||
4612 | IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n", | ||
4613 | ch->channel, geo_ch->center_freq, | ||
4614 | is_channel_a_band(ch) ? "5.2" : "2.4", | ||
4615 | geo_ch->flags & IEEE80211_CHAN_DISABLED ? | ||
4616 | "restricted" : "valid", | ||
4617 | geo_ch->flags); | ||
4618 | } | ||
4619 | |||
4620 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && | ||
4621 | priv->cfg->sku & IWL_SKU_A) { | ||
4622 | printk(KERN_INFO DRV_NAME | ||
4623 | ": Incorrectly detected BG card as ABG. Please send " | ||
4624 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", | ||
4625 | priv->pci_dev->device, priv->pci_dev->subsystem_device); | ||
4626 | priv->cfg->sku &= ~IWL_SKU_A; | ||
4627 | } | ||
4628 | |||
4629 | printk(KERN_INFO DRV_NAME | ||
4630 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", | ||
4631 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, | ||
4632 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | ||
4633 | |||
4634 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) | ||
4635 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
4636 | &priv->bands[IEEE80211_BAND_2GHZ]; | ||
4637 | if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) | ||
4638 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
4639 | &priv->bands[IEEE80211_BAND_5GHZ]; | ||
4640 | |||
4641 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
4642 | |||
4643 | return 0; | ||
4644 | } | ||
4645 | |||
4646 | /* | ||
4647 | * iwl4965_free_geos - undo allocations in iwl4965_init_geos | ||
4648 | */ | ||
4649 | void iwl4965_free_geos(struct iwl_priv *priv) | ||
4650 | { | ||
4651 | kfree(priv->ieee_channels); | ||
4652 | kfree(priv->ieee_rates); | ||
4653 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
4654 | } | ||
4655 | |||
4656 | /****************************************************************************** | 4499 | /****************************************************************************** |
4657 | * | 4500 | * |
4658 | * uCode download functions | 4501 | * uCode download functions |
@@ -5807,7 +5650,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv) | |||
5807 | if (priv->current_ht_config.is_ht) | 5650 | if (priv->current_ht_config.is_ht) |
5808 | iwl4965_set_rxon_ht(priv, &priv->current_ht_config); | 5651 | iwl4965_set_rxon_ht(priv, &priv->current_ht_config); |
5809 | #endif /* CONFIG_IWL4965_HT*/ | 5652 | #endif /* CONFIG_IWL4965_HT*/ |
5810 | iwl4965_set_rxon_chain(priv); | 5653 | iwl_set_rxon_chain(priv); |
5811 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); | 5654 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); |
5812 | 5655 | ||
5813 | IWL_DEBUG_ASSOC("assoc id %d beacon interval %d\n", | 5656 | IWL_DEBUG_ASSOC("assoc id %d beacon interval %d\n", |
@@ -6153,7 +5996,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
6153 | priv->staging_rxon.flags = 0; | 5996 | priv->staging_rxon.flags = 0; |
6154 | #endif /* CONFIG_IWL4965_HT */ | 5997 | #endif /* CONFIG_IWL4965_HT */ |
6155 | 5998 | ||
6156 | iwlcore_set_rxon_channel(priv, conf->channel->band, | 5999 | iwl_set_rxon_channel(priv, conf->channel->band, |
6157 | ieee80211_frequency_to_channel(conf->channel->center_freq)); | 6000 | ieee80211_frequency_to_channel(conf->channel->center_freq)); |
6158 | 6001 | ||
6159 | iwl4965_set_flags_for_phymode(priv, conf->channel->band); | 6002 | iwl4965_set_flags_for_phymode(priv, conf->channel->band); |
@@ -6225,7 +6068,7 @@ static void iwl4965_config_ap(struct iwl_priv *priv) | |||
6225 | IWL_WARNING("REPLY_RXON_TIMING failed - " | 6068 | IWL_WARNING("REPLY_RXON_TIMING failed - " |
6226 | "Attempting to continue.\n"); | 6069 | "Attempting to continue.\n"); |
6227 | 6070 | ||
6228 | iwl4965_set_rxon_chain(priv); | 6071 | iwl_set_rxon_chain(priv); |
6229 | 6072 | ||
6230 | /* FIXME: what should be the assoc_id for AP? */ | 6073 | /* FIXME: what should be the assoc_id for AP? */ |
6231 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); | 6074 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); |
@@ -6437,7 +6280,7 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, | |||
6437 | if (changes & BSS_CHANGED_HT) { | 6280 | if (changes & BSS_CHANGED_HT) { |
6438 | IWL_DEBUG_MAC80211("HT %d\n", bss_conf->assoc_ht); | 6281 | IWL_DEBUG_MAC80211("HT %d\n", bss_conf->assoc_ht); |
6439 | iwl4965_ht_conf(priv, bss_conf); | 6282 | iwl4965_ht_conf(priv, bss_conf); |
6440 | iwl4965_set_rxon_chain(priv); | 6283 | iwl_set_rxon_chain(priv); |
6441 | } | 6284 | } |
6442 | 6285 | ||
6443 | if (changes & BSS_CHANGED_ASSOC) { | 6286 | if (changes & BSS_CHANGED_ASSOC) { |
@@ -6761,7 +6604,7 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) | |||
6761 | spin_unlock_irqrestore(&priv->lock, flags); | 6604 | spin_unlock_irqrestore(&priv->lock, flags); |
6762 | #endif /* CONFIG_IWL4965_HT */ | 6605 | #endif /* CONFIG_IWL4965_HT */ |
6763 | 6606 | ||
6764 | iwlcore_reset_qos(priv); | 6607 | iwl_reset_qos(priv); |
6765 | 6608 | ||
6766 | cancel_delayed_work(&priv->post_associate); | 6609 | cancel_delayed_work(&priv->post_associate); |
6767 | 6610 | ||
@@ -6848,7 +6691,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
6848 | IWL_DEBUG_MAC80211("leave\n"); | 6691 | IWL_DEBUG_MAC80211("leave\n"); |
6849 | spin_unlock_irqrestore(&priv->lock, flags); | 6692 | spin_unlock_irqrestore(&priv->lock, flags); |
6850 | 6693 | ||
6851 | iwlcore_reset_qos(priv); | 6694 | iwl_reset_qos(priv); |
6852 | 6695 | ||
6853 | queue_work(priv->workqueue, &priv->post_associate.work); | 6696 | queue_work(priv->workqueue, &priv->post_associate.work); |
6854 | 6697 | ||
@@ -7636,7 +7479,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) | |||
7636 | pci_set_drvdata(pdev, NULL); | 7479 | pci_set_drvdata(pdev, NULL); |
7637 | 7480 | ||
7638 | iwl_free_channel_map(priv); | 7481 | iwl_free_channel_map(priv); |
7639 | iwl4965_free_geos(priv); | 7482 | iwlcore_free_geos(priv); |
7640 | 7483 | ||
7641 | if (priv->ibss_beacon) | 7484 | if (priv->ibss_beacon) |
7642 | dev_kfree_skb(priv->ibss_beacon); | 7485 | dev_kfree_skb(priv->ibss_beacon); |