diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-01-24 13:38:38 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-02-29 15:19:32 -0500 |
commit | 8318d78a44d49ac1edf2bdec7299de3617c4232e (patch) | |
tree | d434634418edd7399737801615d247be06616fdd /drivers/net/wireless/iwlwifi/iwl3945-base.c | |
parent | 10b6b80145cc93887dd8aab99bfffa375e9add31 (diff) |
cfg80211 API for channels/bitrates, mac80211 and driver conversion
This patch creates new cfg80211 wiphy API for channel and bitrate
registration and converts mac80211 and drivers to the new API. The
old mac80211 API is completely ripped out. All drivers (except ath5k)
are updated to the new API, in many cases I expect that optimisations
can be done.
Along with the regulatory code I've also ripped out the
IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED flag, I believe it to be
unnecessary if the hardware simply gives us whatever channels it wants
to support and we then enable/disable them as required, which is pretty
much required for travelling.
Additionally, the patch adds proper "basic" rate handling for STA
mode interface, AP mode interface will have to have new API added
to allow userspace to set the basic rate set, currently it'll be
empty... However, the basic rate handling will need to be moved to
the BSS conf stuff.
I do expect there to be bugs in this, especially wrt. transmit
power handling where I'm basically clueless about how it should work.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 445 |
1 files changed, 124 insertions, 321 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 40b71bc2c4a4..57a1d70f2abf 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -116,16 +116,10 @@ static __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr) | |||
116 | return NULL; | 116 | return NULL; |
117 | } | 117 | } |
118 | 118 | ||
119 | static const struct ieee80211_hw_mode *iwl3945_get_hw_mode( | 119 | static const struct ieee80211_supported_band *iwl3945_get_band( |
120 | struct iwl3945_priv *priv, int mode) | 120 | struct iwl3945_priv *priv, enum ieee80211_band band) |
121 | { | 121 | { |
122 | int i; | 122 | return priv->hw->wiphy->bands[band]; |
123 | |||
124 | for (i = 0; i < 3; i++) | ||
125 | if (priv->modes[i].mode == mode) | ||
126 | return &priv->modes[i]; | ||
127 | |||
128 | return NULL; | ||
129 | } | 123 | } |
130 | 124 | ||
131 | static int iwl3945_is_empty_essid(const char *essid, int essid_len) | 125 | static int iwl3945_is_empty_essid(const char *essid, int essid_len) |
@@ -547,7 +541,7 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 | |||
547 | station->sta.sta.sta_id = index; | 541 | station->sta.sta.sta_id = index; |
548 | station->sta.station_flags = 0; | 542 | station->sta.station_flags = 0; |
549 | 543 | ||
550 | if (priv->phymode == MODE_IEEE80211A) | 544 | if (priv->band == IEEE80211_BAND_5GHZ) |
551 | rate = IWL_RATE_6M_PLCP; | 545 | rate = IWL_RATE_6M_PLCP; |
552 | else | 546 | else |
553 | rate = IWL_RATE_1M_PLCP; | 547 | rate = IWL_RATE_1M_PLCP; |
@@ -894,35 +888,37 @@ int iwl3945_send_statistics_request(struct iwl3945_priv *priv) | |||
894 | 888 | ||
895 | /** | 889 | /** |
896 | * iwl3945_set_rxon_channel - Set the phymode and channel values in staging RXON | 890 | * iwl3945_set_rxon_channel - Set the phymode and channel values in staging RXON |
897 | * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz | 891 | * @band: 2.4 or 5 GHz band |
898 | * @channel: Any channel valid for the requested phymode | 892 | * @channel: Any channel valid for the requested band |
899 | 893 | ||
900 | * In addition to setting the staging RXON, priv->phymode is also set. | 894 | * In addition to setting the staging RXON, priv->band is also set. |
901 | * | 895 | * |
902 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields | 896 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields |
903 | * in the staging RXON flag structure based on the phymode | 897 | * in the staging RXON flag structure based on the band |
904 | */ | 898 | */ |
905 | static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv, u8 phymode, u16 channel) | 899 | static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv, |
900 | enum ieee80211_band band, | ||
901 | u16 channel) | ||
906 | { | 902 | { |
907 | if (!iwl3945_get_channel_info(priv, phymode, channel)) { | 903 | if (!iwl3945_get_channel_info(priv, band, channel)) { |
908 | IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", | 904 | IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", |
909 | channel, phymode); | 905 | channel, band); |
910 | return -EINVAL; | 906 | return -EINVAL; |
911 | } | 907 | } |
912 | 908 | ||
913 | if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && | 909 | if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && |
914 | (priv->phymode == phymode)) | 910 | (priv->band == band)) |
915 | return 0; | 911 | return 0; |
916 | 912 | ||
917 | priv->staging_rxon.channel = cpu_to_le16(channel); | 913 | priv->staging_rxon.channel = cpu_to_le16(channel); |
918 | if (phymode == MODE_IEEE80211A) | 914 | if (band == IEEE80211_BAND_5GHZ) |
919 | priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; | 915 | priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; |
920 | else | 916 | else |
921 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; | 917 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; |
922 | 918 | ||
923 | priv->phymode = phymode; | 919 | priv->band = band; |
924 | 920 | ||
925 | IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, phymode); | 921 | IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, band); |
926 | 922 | ||
927 | return 0; | 923 | return 0; |
928 | } | 924 | } |
@@ -1210,8 +1206,7 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv) | |||
1210 | return -EIO; | 1206 | return -EIO; |
1211 | } | 1207 | } |
1212 | 1208 | ||
1213 | /* Init the hardware's rate fallback order based on the | 1209 | /* Init the hardware's rate fallback order based on the band */ |
1214 | * phymode */ | ||
1215 | rc = iwl3945_init_hw_rate_table(priv); | 1210 | rc = iwl3945_init_hw_rate_table(priv); |
1216 | if (rc) { | 1211 | if (rc) { |
1217 | IWL_ERROR("Error setting HW rate table: %02X\n", rc); | 1212 | IWL_ERROR("Error setting HW rate table: %02X\n", rc); |
@@ -2461,9 +2456,10 @@ static int iwl3945_set_rxon_hwcrypto(struct iwl3945_priv *priv, int hw_decrypt) | |||
2461 | return 0; | 2456 | return 0; |
2462 | } | 2457 | } |
2463 | 2458 | ||
2464 | static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, u8 phymode) | 2459 | static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, |
2460 | enum ieee80211_band band) | ||
2465 | { | 2461 | { |
2466 | if (phymode == MODE_IEEE80211A) { | 2462 | if (band == IEEE80211_BAND_5GHZ) { |
2467 | priv->staging_rxon.flags &= | 2463 | priv->staging_rxon.flags &= |
2468 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | 2464 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK |
2469 | | RXON_FLG_CCK_MSK); | 2465 | | RXON_FLG_CCK_MSK); |
@@ -2526,7 +2522,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) | |||
2526 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | 2522 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; |
2527 | #endif | 2523 | #endif |
2528 | 2524 | ||
2529 | ch_info = iwl3945_get_channel_info(priv, priv->phymode, | 2525 | ch_info = iwl3945_get_channel_info(priv, priv->band, |
2530 | le16_to_cpu(priv->staging_rxon.channel)); | 2526 | le16_to_cpu(priv->staging_rxon.channel)); |
2531 | 2527 | ||
2532 | if (!ch_info) | 2528 | if (!ch_info) |
@@ -2542,11 +2538,11 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) | |||
2542 | 2538 | ||
2543 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); | 2539 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); |
2544 | if (is_channel_a_band(ch_info)) | 2540 | if (is_channel_a_band(ch_info)) |
2545 | priv->phymode = MODE_IEEE80211A; | 2541 | priv->band = IEEE80211_BAND_5GHZ; |
2546 | else | 2542 | else |
2547 | priv->phymode = MODE_IEEE80211G; | 2543 | priv->band = IEEE80211_BAND_2GHZ; |
2548 | 2544 | ||
2549 | iwl3945_set_flags_for_phymode(priv, priv->phymode); | 2545 | iwl3945_set_flags_for_phymode(priv, priv->band); |
2550 | 2546 | ||
2551 | priv->staging_rxon.ofdm_basic_rates = | 2547 | priv->staging_rxon.ofdm_basic_rates = |
2552 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | 2548 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; |
@@ -2560,7 +2556,7 @@ static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode) | |||
2560 | const struct iwl3945_channel_info *ch_info; | 2556 | const struct iwl3945_channel_info *ch_info; |
2561 | 2557 | ||
2562 | ch_info = iwl3945_get_channel_info(priv, | 2558 | ch_info = iwl3945_get_channel_info(priv, |
2563 | priv->phymode, | 2559 | priv->band, |
2564 | le16_to_cpu(priv->staging_rxon.channel)); | 2560 | le16_to_cpu(priv->staging_rxon.channel)); |
2565 | 2561 | ||
2566 | if (!ch_info || !is_channel_ibss(ch_info)) { | 2562 | if (!ch_info || !is_channel_ibss(ch_info)) { |
@@ -2792,7 +2788,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2792 | goto drop_unlock; | 2788 | goto drop_unlock; |
2793 | } | 2789 | } |
2794 | 2790 | ||
2795 | if ((ctl->tx_rate & 0xFF) == IWL_INVALID_RATE) { | 2791 | if ((ctl->tx_rate->hw_value & 0xFF) == IWL_INVALID_RATE) { |
2796 | IWL_ERROR("ERROR: No TX rate available.\n"); | 2792 | IWL_ERROR("ERROR: No TX rate available.\n"); |
2797 | goto drop_unlock; | 2793 | goto drop_unlock; |
2798 | } | 2794 | } |
@@ -2992,12 +2988,12 @@ drop: | |||
2992 | 2988 | ||
2993 | static void iwl3945_set_rate(struct iwl3945_priv *priv) | 2989 | static void iwl3945_set_rate(struct iwl3945_priv *priv) |
2994 | { | 2990 | { |
2995 | const struct ieee80211_hw_mode *hw = NULL; | 2991 | const struct ieee80211_supported_band *sband = NULL; |
2996 | struct ieee80211_rate *rate; | 2992 | struct ieee80211_rate *rate; |
2997 | int i; | 2993 | int i; |
2998 | 2994 | ||
2999 | hw = iwl3945_get_hw_mode(priv, priv->phymode); | 2995 | sband = iwl3945_get_band(priv, priv->band); |
3000 | if (!hw) { | 2996 | if (!sband) { |
3001 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); | 2997 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); |
3002 | return; | 2998 | return; |
3003 | } | 2999 | } |
@@ -3005,24 +3001,17 @@ static void iwl3945_set_rate(struct iwl3945_priv *priv) | |||
3005 | priv->active_rate = 0; | 3001 | priv->active_rate = 0; |
3006 | priv->active_rate_basic = 0; | 3002 | priv->active_rate_basic = 0; |
3007 | 3003 | ||
3008 | IWL_DEBUG_RATE("Setting rates for 802.11%c\n", | 3004 | IWL_DEBUG_RATE("Setting rates for %s GHz\n", |
3009 | hw->mode == MODE_IEEE80211A ? | 3005 | sband->band == IEEE80211_BAND_2GHZ ? "2.4" : "5"); |
3010 | 'a' : ((hw->mode == MODE_IEEE80211B) ? 'b' : 'g')); | 3006 | |
3011 | 3007 | for (i = 0; i < sband->n_bitrates; i++) { | |
3012 | for (i = 0; i < hw->num_rates; i++) { | 3008 | rate = &sband->bitrates[i]; |
3013 | rate = &(hw->rates[i]); | 3009 | if ((rate->hw_value < IWL_RATE_COUNT) && |
3014 | if ((rate->val < IWL_RATE_COUNT) && | 3010 | !(rate->flags & IEEE80211_CHAN_DISABLED)) { |
3015 | (rate->flags & IEEE80211_RATE_SUPPORTED)) { | 3011 | IWL_DEBUG_RATE("Adding rate index %d (plcp %d)\n", |
3016 | IWL_DEBUG_RATE("Adding rate index %d (plcp %d)%s\n", | 3012 | rate->hw_value, iwl3945_rates[rate->hw_value].plcp); |
3017 | rate->val, iwl3945_rates[rate->val].plcp, | 3013 | priv->active_rate |= (1 << rate->hw_value); |
3018 | (rate->flags & IEEE80211_RATE_BASIC) ? | 3014 | } |
3019 | "*" : ""); | ||
3020 | priv->active_rate |= (1 << rate->val); | ||
3021 | if (rate->flags & IEEE80211_RATE_BASIC) | ||
3022 | priv->active_rate_basic |= (1 << rate->val); | ||
3023 | } else | ||
3024 | IWL_DEBUG_RATE("Not adding rate %d (plcp %d)\n", | ||
3025 | rate->val, iwl3945_rates[rate->val].plcp); | ||
3026 | } | 3015 | } |
3027 | 3016 | ||
3028 | IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n", | 3017 | IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n", |
@@ -3436,8 +3425,6 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | |||
3436 | tx_status->flags = | 3425 | tx_status->flags = |
3437 | iwl3945_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; | 3426 | iwl3945_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; |
3438 | 3427 | ||
3439 | tx_status->control.tx_rate = iwl3945_rate_index_from_plcp(tx_resp->rate); | ||
3440 | |||
3441 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n", | 3428 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n", |
3442 | txq_id, iwl3945_get_tx_fail_reason(status), status, | 3429 | txq_id, iwl3945_get_tx_fail_reason(status), status, |
3443 | tx_resp->rate, tx_resp->failure_frame); | 3430 | tx_resp->rate, tx_resp->failure_frame); |
@@ -5026,24 +5013,24 @@ static void iwl3945_init_band_reference(const struct iwl3945_priv *priv, int ban | |||
5026 | * Based on band and channel number. | 5013 | * Based on band and channel number. |
5027 | */ | 5014 | */ |
5028 | const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv, | 5015 | const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv, |
5029 | int phymode, u16 channel) | 5016 | enum ieee80211_band band, u16 channel) |
5030 | { | 5017 | { |
5031 | int i; | 5018 | int i; |
5032 | 5019 | ||
5033 | switch (phymode) { | 5020 | switch (band) { |
5034 | case MODE_IEEE80211A: | 5021 | case IEEE80211_BAND_5GHZ: |
5035 | for (i = 14; i < priv->channel_count; i++) { | 5022 | for (i = 14; i < priv->channel_count; i++) { |
5036 | if (priv->channel_info[i].channel == channel) | 5023 | if (priv->channel_info[i].channel == channel) |
5037 | return &priv->channel_info[i]; | 5024 | return &priv->channel_info[i]; |
5038 | } | 5025 | } |
5039 | break; | 5026 | break; |
5040 | 5027 | ||
5041 | case MODE_IEEE80211B: | 5028 | case IEEE80211_BAND_2GHZ: |
5042 | case MODE_IEEE80211G: | ||
5043 | if (channel >= 1 && channel <= 14) | 5029 | if (channel >= 1 && channel <= 14) |
5044 | return &priv->channel_info[channel - 1]; | 5030 | return &priv->channel_info[channel - 1]; |
5045 | break; | 5031 | break; |
5046 | 5032 | case IEEE80211_NUM_BANDS: | |
5033 | WARN_ON(1); | ||
5047 | } | 5034 | } |
5048 | 5035 | ||
5049 | return NULL; | 5036 | return NULL; |
@@ -5106,8 +5093,8 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv) | |||
5106 | /* Loop through each band adding each of the channels */ | 5093 | /* Loop through each band adding each of the channels */ |
5107 | for (ch = 0; ch < eeprom_ch_count; ch++) { | 5094 | for (ch = 0; ch < eeprom_ch_count; ch++) { |
5108 | ch_info->channel = eeprom_ch_index[ch]; | 5095 | ch_info->channel = eeprom_ch_index[ch]; |
5109 | ch_info->phymode = (band == 1) ? MODE_IEEE80211B : | 5096 | ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ : |
5110 | MODE_IEEE80211A; | 5097 | IEEE80211_BAND_5GHZ; |
5111 | 5098 | ||
5112 | /* permanently store EEPROM's channel regulatory flags | 5099 | /* permanently store EEPROM's channel regulatory flags |
5113 | * and max power in channel info database. */ | 5100 | * and max power in channel info database. */ |
@@ -5203,18 +5190,20 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv) | |||
5203 | #define IWL_PASSIVE_DWELL_BASE (100) | 5190 | #define IWL_PASSIVE_DWELL_BASE (100) |
5204 | #define IWL_CHANNEL_TUNE_TIME 5 | 5191 | #define IWL_CHANNEL_TUNE_TIME 5 |
5205 | 5192 | ||
5206 | static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv, int phymode) | 5193 | static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv, |
5194 | enum ieee80211_band band) | ||
5207 | { | 5195 | { |
5208 | if (phymode == MODE_IEEE80211A) | 5196 | if (band == IEEE80211_BAND_5GHZ) |
5209 | return IWL_ACTIVE_DWELL_TIME_52; | 5197 | return IWL_ACTIVE_DWELL_TIME_52; |
5210 | else | 5198 | else |
5211 | return IWL_ACTIVE_DWELL_TIME_24; | 5199 | return IWL_ACTIVE_DWELL_TIME_24; |
5212 | } | 5200 | } |
5213 | 5201 | ||
5214 | static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, int phymode) | 5202 | static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, |
5203 | enum ieee80211_band band) | ||
5215 | { | 5204 | { |
5216 | u16 active = iwl3945_get_active_dwell_time(priv, phymode); | 5205 | u16 active = iwl3945_get_active_dwell_time(priv, band); |
5217 | u16 passive = (phymode != MODE_IEEE80211A) ? | 5206 | u16 passive = (band == IEEE80211_BAND_2GHZ) ? |
5218 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : | 5207 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : |
5219 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; | 5208 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; |
5220 | 5209 | ||
@@ -5234,28 +5223,29 @@ static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, int phymode | |||
5234 | return passive; | 5223 | return passive; |
5235 | } | 5224 | } |
5236 | 5225 | ||
5237 | static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | 5226 | static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, |
5227 | enum ieee80211_band band, | ||
5238 | u8 is_active, u8 direct_mask, | 5228 | u8 is_active, u8 direct_mask, |
5239 | struct iwl3945_scan_channel *scan_ch) | 5229 | struct iwl3945_scan_channel *scan_ch) |
5240 | { | 5230 | { |
5241 | const struct ieee80211_channel *channels = NULL; | 5231 | const struct ieee80211_channel *channels = NULL; |
5242 | const struct ieee80211_hw_mode *hw_mode; | 5232 | const struct ieee80211_supported_band *sband; |
5243 | const struct iwl3945_channel_info *ch_info; | 5233 | const struct iwl3945_channel_info *ch_info; |
5244 | u16 passive_dwell = 0; | 5234 | u16 passive_dwell = 0; |
5245 | u16 active_dwell = 0; | 5235 | u16 active_dwell = 0; |
5246 | int added, i; | 5236 | int added, i; |
5247 | 5237 | ||
5248 | hw_mode = iwl3945_get_hw_mode(priv, phymode); | 5238 | sband = iwl3945_get_band(priv, band); |
5249 | if (!hw_mode) | 5239 | if (!sband) |
5250 | return 0; | 5240 | return 0; |
5251 | 5241 | ||
5252 | channels = hw_mode->channels; | 5242 | channels = sband->channels; |
5253 | 5243 | ||
5254 | active_dwell = iwl3945_get_active_dwell_time(priv, phymode); | 5244 | active_dwell = iwl3945_get_active_dwell_time(priv, band); |
5255 | passive_dwell = iwl3945_get_passive_dwell_time(priv, phymode); | 5245 | passive_dwell = iwl3945_get_passive_dwell_time(priv, band); |
5256 | 5246 | ||
5257 | for (i = 0, added = 0; i < hw_mode->num_channels; i++) { | 5247 | for (i = 0, added = 0; i < sband->n_channels; i++) { |
5258 | if (channels[i].chan == | 5248 | if (channels[i].hw_value == |
5259 | le16_to_cpu(priv->active_rxon.channel)) { | 5249 | le16_to_cpu(priv->active_rxon.channel)) { |
5260 | if (iwl3945_is_associated(priv)) { | 5250 | if (iwl3945_is_associated(priv)) { |
5261 | IWL_DEBUG_SCAN | 5251 | IWL_DEBUG_SCAN |
@@ -5266,9 +5256,9 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | |||
5266 | } else if (priv->only_active_channel) | 5256 | } else if (priv->only_active_channel) |
5267 | continue; | 5257 | continue; |
5268 | 5258 | ||
5269 | scan_ch->channel = channels[i].chan; | 5259 | scan_ch->channel = channels[i].hw_value; |
5270 | 5260 | ||
5271 | ch_info = iwl3945_get_channel_info(priv, phymode, scan_ch->channel); | 5261 | ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel); |
5272 | if (!is_channel_valid(ch_info)) { | 5262 | if (!is_channel_valid(ch_info)) { |
5273 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", | 5263 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", |
5274 | scan_ch->channel); | 5264 | scan_ch->channel); |
@@ -5276,7 +5266,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | |||
5276 | } | 5266 | } |
5277 | 5267 | ||
5278 | if (!is_active || is_channel_passive(ch_info) || | 5268 | if (!is_active || is_channel_passive(ch_info) || |
5279 | !(channels[i].flag & IEEE80211_CHAN_W_ACTIVE_SCAN)) | 5269 | (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) |
5280 | scan_ch->type = 0; /* passive */ | 5270 | scan_ch->type = 0; /* passive */ |
5281 | else | 5271 | else |
5282 | scan_ch->type = 1; /* active */ | 5272 | scan_ch->type = 1; /* active */ |
@@ -5295,7 +5285,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | |||
5295 | /* scan_pwr_info->tpc.dsp_atten; */ | 5285 | /* scan_pwr_info->tpc.dsp_atten; */ |
5296 | 5286 | ||
5297 | /*scan_pwr_info->tpc.tx_gain; */ | 5287 | /*scan_pwr_info->tpc.tx_gain; */ |
5298 | if (phymode == MODE_IEEE80211A) | 5288 | if (band == IEEE80211_BAND_5GHZ) |
5299 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; | 5289 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; |
5300 | else { | 5290 | else { |
5301 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); | 5291 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); |
@@ -5319,41 +5309,23 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | |||
5319 | return added; | 5309 | return added; |
5320 | } | 5310 | } |
5321 | 5311 | ||
5322 | static void iwl3945_reset_channel_flag(struct iwl3945_priv *priv) | ||
5323 | { | ||
5324 | int i, j; | ||
5325 | for (i = 0; i < 3; i++) { | ||
5326 | struct ieee80211_hw_mode *hw_mode = (void *)&priv->modes[i]; | ||
5327 | for (j = 0; j < hw_mode->num_channels; j++) | ||
5328 | hw_mode->channels[j].flag = hw_mode->channels[j].val; | ||
5329 | } | ||
5330 | } | ||
5331 | |||
5332 | static void iwl3945_init_hw_rates(struct iwl3945_priv *priv, | 5312 | static void iwl3945_init_hw_rates(struct iwl3945_priv *priv, |
5333 | struct ieee80211_rate *rates) | 5313 | struct ieee80211_rate *rates) |
5334 | { | 5314 | { |
5335 | int i; | 5315 | int i; |
5336 | 5316 | ||
5337 | for (i = 0; i < IWL_RATE_COUNT; i++) { | 5317 | for (i = 0; i < IWL_RATE_COUNT; i++) { |
5338 | rates[i].rate = iwl3945_rates[i].ieee * 5; | 5318 | rates[i].bitrate = iwl3945_rates[i].ieee * 5; |
5339 | rates[i].val = i; /* Rate scaling will work on indexes */ | 5319 | rates[i].hw_value = i; /* Rate scaling will work on indexes */ |
5340 | rates[i].val2 = i; | 5320 | rates[i].hw_value_short = i; |
5341 | rates[i].flags = IEEE80211_RATE_SUPPORTED; | 5321 | rates[i].flags = 0; |
5342 | /* Only OFDM have the bits-per-symbol set */ | 5322 | if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) { |
5343 | if ((i <= IWL_LAST_OFDM_RATE) && (i >= IWL_FIRST_OFDM_RATE)) | ||
5344 | rates[i].flags |= IEEE80211_RATE_OFDM; | ||
5345 | else { | ||
5346 | /* | 5323 | /* |
5347 | * If CCK 1M then set rate flag to CCK else CCK_2 | 5324 | * If CCK != 1M then set short preamble rate flag. |
5348 | * which is CCK | PREAMBLE2 | ||
5349 | */ | 5325 | */ |
5350 | rates[i].flags |= (iwl3945_rates[i].plcp == 10) ? | 5326 | rates[i].flags |= (iwl3945_rates[i].plcp == 10) ? |
5351 | IEEE80211_RATE_CCK : IEEE80211_RATE_CCK_2; | 5327 | 0 : IEEE80211_RATE_SHORT_PREAMBLE; |
5352 | } | 5328 | } |
5353 | |||
5354 | /* Set up which ones are basic rates... */ | ||
5355 | if (IWL_BASIC_RATES_MASK & (1 << i)) | ||
5356 | rates[i].flags |= IEEE80211_RATE_BASIC; | ||
5357 | } | 5329 | } |
5358 | } | 5330 | } |
5359 | 5331 | ||
@@ -5363,67 +5335,41 @@ static void iwl3945_init_hw_rates(struct iwl3945_priv *priv, | |||
5363 | static int iwl3945_init_geos(struct iwl3945_priv *priv) | 5335 | static int iwl3945_init_geos(struct iwl3945_priv *priv) |
5364 | { | 5336 | { |
5365 | struct iwl3945_channel_info *ch; | 5337 | struct iwl3945_channel_info *ch; |
5366 | struct ieee80211_hw_mode *modes; | 5338 | struct ieee80211_supported_band *band; |
5367 | struct ieee80211_channel *channels; | 5339 | struct ieee80211_channel *channels; |
5368 | struct ieee80211_channel *geo_ch; | 5340 | struct ieee80211_channel *geo_ch; |
5369 | struct ieee80211_rate *rates; | 5341 | struct ieee80211_rate *rates; |
5370 | int i = 0; | 5342 | int i = 0; |
5371 | enum { | ||
5372 | A = 0, | ||
5373 | B = 1, | ||
5374 | G = 2, | ||
5375 | }; | ||
5376 | int mode_count = 3; | ||
5377 | 5343 | ||
5378 | if (priv->modes) { | 5344 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || |
5345 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | ||
5379 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); | 5346 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); |
5380 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5347 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
5381 | return 0; | 5348 | return 0; |
5382 | } | 5349 | } |
5383 | 5350 | ||
5384 | modes = kzalloc(sizeof(struct ieee80211_hw_mode) * mode_count, | ||
5385 | GFP_KERNEL); | ||
5386 | if (!modes) | ||
5387 | return -ENOMEM; | ||
5388 | |||
5389 | channels = kzalloc(sizeof(struct ieee80211_channel) * | 5351 | channels = kzalloc(sizeof(struct ieee80211_channel) * |
5390 | priv->channel_count, GFP_KERNEL); | 5352 | priv->channel_count, GFP_KERNEL); |
5391 | if (!channels) { | 5353 | if (!channels) |
5392 | kfree(modes); | ||
5393 | return -ENOMEM; | 5354 | return -ENOMEM; |
5394 | } | ||
5395 | 5355 | ||
5396 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_MAX_RATES + 1)), | 5356 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_MAX_RATES + 1)), |
5397 | GFP_KERNEL); | 5357 | GFP_KERNEL); |
5398 | if (!rates) { | 5358 | if (!rates) { |
5399 | kfree(modes); | ||
5400 | kfree(channels); | 5359 | kfree(channels); |
5401 | return -ENOMEM; | 5360 | return -ENOMEM; |
5402 | } | 5361 | } |
5403 | 5362 | ||
5404 | /* 0 = 802.11a | ||
5405 | * 1 = 802.11b | ||
5406 | * 2 = 802.11g | ||
5407 | */ | ||
5408 | |||
5409 | /* 5.2GHz channels start after the 2.4GHz channels */ | 5363 | /* 5.2GHz channels start after the 2.4GHz channels */ |
5410 | modes[A].mode = MODE_IEEE80211A; | 5364 | band = &priv->bands[IEEE80211_BAND_5GHZ]; |
5411 | modes[A].channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)]; | 5365 | band->channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)]; |
5412 | modes[A].rates = &rates[4]; | 5366 | band->bitrates = &rates[4]; |
5413 | modes[A].num_rates = 8; /* just OFDM */ | 5367 | band->n_bitrates = 8; /* just OFDM */ |
5414 | modes[A].num_channels = 0; | 5368 | |
5415 | 5369 | band = &priv->bands[IEEE80211_BAND_2GHZ]; | |
5416 | modes[B].mode = MODE_IEEE80211B; | 5370 | band->channels = channels; |
5417 | modes[B].channels = channels; | 5371 | band->bitrates = rates; |
5418 | modes[B].rates = rates; | 5372 | band->n_bitrates = 12; /* OFDM & CCK */ |
5419 | modes[B].num_rates = 4; /* just CCK */ | ||
5420 | modes[B].num_channels = 0; | ||
5421 | |||
5422 | modes[G].mode = MODE_IEEE80211G; | ||
5423 | modes[G].channels = channels; | ||
5424 | modes[G].rates = rates; | ||
5425 | modes[G].num_rates = 12; /* OFDM & CCK */ | ||
5426 | modes[G].num_channels = 0; | ||
5427 | 5373 | ||
5428 | priv->ieee_channels = channels; | 5374 | priv->ieee_channels = channels; |
5429 | priv->ieee_rates = rates; | 5375 | priv->ieee_rates = rates; |
@@ -5442,37 +5388,32 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv) | |||
5442 | } | 5388 | } |
5443 | 5389 | ||
5444 | if (is_channel_a_band(ch)) | 5390 | if (is_channel_a_band(ch)) |
5445 | geo_ch = &modes[A].channels[modes[A].num_channels++]; | 5391 | geo_ch = &priv->bands[IEEE80211_BAND_5GHZ].channels[priv->bands[IEEE80211_BAND_5GHZ].n_channels++]; |
5446 | else { | 5392 | else |
5447 | geo_ch = &modes[B].channels[modes[B].num_channels++]; | 5393 | geo_ch = &priv->bands[IEEE80211_BAND_2GHZ].channels[priv->bands[IEEE80211_BAND_2GHZ].n_channels++]; |
5448 | modes[G].num_channels++; | ||
5449 | } | ||
5450 | 5394 | ||
5451 | geo_ch->freq = ieee80211chan2mhz(ch->channel); | 5395 | geo_ch->center_freq = ieee80211chan2mhz(ch->channel); |
5452 | geo_ch->chan = ch->channel; | 5396 | geo_ch->max_power = ch->max_power_avg; |
5453 | geo_ch->power_level = ch->max_power_avg; | 5397 | geo_ch->max_antenna_gain = 0xff; |
5454 | geo_ch->antenna_max = 0xff; | ||
5455 | 5398 | ||
5456 | if (is_channel_valid(ch)) { | 5399 | if (is_channel_valid(ch)) { |
5457 | geo_ch->flag = IEEE80211_CHAN_W_SCAN; | 5400 | if (!(ch->flags & EEPROM_CHANNEL_IBSS)) |
5458 | if (ch->flags & EEPROM_CHANNEL_IBSS) | 5401 | geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; |
5459 | geo_ch->flag |= IEEE80211_CHAN_W_IBSS; | ||
5460 | 5402 | ||
5461 | if (ch->flags & EEPROM_CHANNEL_ACTIVE) | 5403 | if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) |
5462 | geo_ch->flag |= IEEE80211_CHAN_W_ACTIVE_SCAN; | 5404 | geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; |
5463 | 5405 | ||
5464 | if (ch->flags & EEPROM_CHANNEL_RADAR) | 5406 | if (ch->flags & EEPROM_CHANNEL_RADAR) |
5465 | geo_ch->flag |= IEEE80211_CHAN_W_RADAR_DETECT; | 5407 | geo_ch->flags |= IEEE80211_CHAN_RADAR; |
5466 | 5408 | ||
5467 | if (ch->max_power_avg > priv->max_channel_txpower_limit) | 5409 | if (ch->max_power_avg > priv->max_channel_txpower_limit) |
5468 | priv->max_channel_txpower_limit = | 5410 | priv->max_channel_txpower_limit = |
5469 | ch->max_power_avg; | 5411 | ch->max_power_avg; |
5470 | } | 5412 | } else |
5471 | 5413 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; | |
5472 | geo_ch->val = geo_ch->flag; | ||
5473 | } | 5414 | } |
5474 | 5415 | ||
5475 | if ((modes[A].num_channels == 0) && priv->is_abg) { | 5416 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && priv->is_abg) { |
5476 | printk(KERN_INFO DRV_NAME | 5417 | printk(KERN_INFO DRV_NAME |
5477 | ": Incorrectly detected BG card as ABG. Please send " | 5418 | ": Incorrectly detected BG card as ABG. Please send " |
5478 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", | 5419 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", |
@@ -5482,24 +5423,12 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv) | |||
5482 | 5423 | ||
5483 | printk(KERN_INFO DRV_NAME | 5424 | printk(KERN_INFO DRV_NAME |
5484 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", | 5425 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", |
5485 | modes[G].num_channels, modes[A].num_channels); | 5426 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, |
5427 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | ||
5486 | 5428 | ||
5487 | /* | 5429 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->bands[IEEE80211_BAND_2GHZ]; |
5488 | * NOTE: We register these in preference of order -- the | 5430 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->bands[IEEE80211_BAND_5GHZ]; |
5489 | * stack doesn't currently (as of 7.0.6 / Apr 24 '07) pick | ||
5490 | * a phymode based on rates or AP capabilities but seems to | ||
5491 | * configure it purely on if the channel being configured | ||
5492 | * is supported by a mode -- and the first match is taken | ||
5493 | */ | ||
5494 | |||
5495 | if (modes[G].num_channels) | ||
5496 | ieee80211_register_hwmode(priv->hw, &modes[G]); | ||
5497 | if (modes[B].num_channels) | ||
5498 | ieee80211_register_hwmode(priv->hw, &modes[B]); | ||
5499 | if (modes[A].num_channels) | ||
5500 | ieee80211_register_hwmode(priv->hw, &modes[A]); | ||
5501 | 5431 | ||
5502 | priv->modes = modes; | ||
5503 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5432 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
5504 | 5433 | ||
5505 | return 0; | 5434 | return 0; |
@@ -5510,7 +5439,6 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv) | |||
5510 | */ | 5439 | */ |
5511 | static void iwl3945_free_geos(struct iwl3945_priv *priv) | 5440 | static void iwl3945_free_geos(struct iwl3945_priv *priv) |
5512 | { | 5441 | { |
5513 | kfree(priv->modes); | ||
5514 | kfree(priv->ieee_channels); | 5442 | kfree(priv->ieee_channels); |
5515 | kfree(priv->ieee_rates); | 5443 | kfree(priv->ieee_rates); |
5516 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5444 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); |
@@ -6519,7 +6447,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6519 | struct iwl3945_scan_cmd *scan; | 6447 | struct iwl3945_scan_cmd *scan; |
6520 | struct ieee80211_conf *conf = NULL; | 6448 | struct ieee80211_conf *conf = NULL; |
6521 | u8 direct_mask; | 6449 | u8 direct_mask; |
6522 | int phymode; | 6450 | enum ieee80211_band band; |
6523 | 6451 | ||
6524 | conf = ieee80211_get_hw_conf(priv->hw); | 6452 | conf = ieee80211_get_hw_conf(priv->hw); |
6525 | 6453 | ||
@@ -6651,13 +6579,13 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6651 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; | 6579 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; |
6652 | scan->tx_cmd.rate = IWL_RATE_1M_PLCP; | 6580 | scan->tx_cmd.rate = IWL_RATE_1M_PLCP; |
6653 | scan->good_CRC_th = 0; | 6581 | scan->good_CRC_th = 0; |
6654 | phymode = MODE_IEEE80211G; | 6582 | band = IEEE80211_BAND_2GHZ; |
6655 | break; | 6583 | break; |
6656 | 6584 | ||
6657 | case 1: | 6585 | case 1: |
6658 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; | 6586 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; |
6659 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | 6587 | scan->good_CRC_th = IWL_GOOD_CRC_TH; |
6660 | phymode = MODE_IEEE80211A; | 6588 | band = IEEE80211_BAND_5GHZ; |
6661 | break; | 6589 | break; |
6662 | 6590 | ||
6663 | default: | 6591 | default: |
@@ -6680,7 +6608,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6680 | 6608 | ||
6681 | scan->channel_count = | 6609 | scan->channel_count = |
6682 | iwl3945_get_channels_for_scan( | 6610 | iwl3945_get_channels_for_scan( |
6683 | priv, phymode, 1, /* active */ | 6611 | priv, band, 1, /* active */ |
6684 | direct_mask, | 6612 | direct_mask, |
6685 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | 6613 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); |
6686 | 6614 | ||
@@ -6825,7 +6753,7 @@ static void iwl3945_bg_post_associate(struct work_struct *data) | |||
6825 | iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0); | 6753 | iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0); |
6826 | iwl3945_add_station(priv, priv->bssid, 0, 0); | 6754 | iwl3945_add_station(priv, priv->bssid, 0, 0); |
6827 | iwl3945_sync_sta(priv, IWL_STA_ID, | 6755 | iwl3945_sync_sta(priv, IWL_STA_ID, |
6828 | (priv->phymode == MODE_IEEE80211A)? | 6756 | (priv->band == IEEE80211_BAND_5GHZ) ? |
6829 | IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, | 6757 | IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, |
6830 | CMD_ASYNC); | 6758 | CMD_ASYNC); |
6831 | iwl3945_rate_scale_init(priv->hw, IWL_STA_ID); | 6759 | iwl3945_rate_scale_init(priv->hw, IWL_STA_ID); |
@@ -7020,7 +6948,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
7020 | } | 6948 | } |
7021 | 6949 | ||
7022 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | 6950 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, |
7023 | ctl->tx_rate); | 6951 | ctl->tx_rate->bitrate); |
7024 | 6952 | ||
7025 | if (iwl3945_tx_skb(priv, skb, ctl)) | 6953 | if (iwl3945_tx_skb(priv, skb, ctl)) |
7026 | dev_kfree_skb_any(skb); | 6954 | dev_kfree_skb_any(skb); |
@@ -7079,7 +7007,7 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7079 | int ret = 0; | 7007 | int ret = 0; |
7080 | 7008 | ||
7081 | mutex_lock(&priv->mutex); | 7009 | mutex_lock(&priv->mutex); |
7082 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel); | 7010 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); |
7083 | 7011 | ||
7084 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); | 7012 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); |
7085 | 7013 | ||
@@ -7099,19 +7027,20 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7099 | 7027 | ||
7100 | spin_lock_irqsave(&priv->lock, flags); | 7028 | spin_lock_irqsave(&priv->lock, flags); |
7101 | 7029 | ||
7102 | ch_info = iwl3945_get_channel_info(priv, conf->phymode, conf->channel); | 7030 | ch_info = iwl3945_get_channel_info(priv, conf->channel->band, |
7031 | conf->channel->hw_value); | ||
7103 | if (!is_channel_valid(ch_info)) { | 7032 | if (!is_channel_valid(ch_info)) { |
7104 | IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n", | 7033 | IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n", |
7105 | conf->channel, conf->phymode); | 7034 | conf->channel->hw_value, conf->channel->band); |
7106 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); | 7035 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); |
7107 | spin_unlock_irqrestore(&priv->lock, flags); | 7036 | spin_unlock_irqrestore(&priv->lock, flags); |
7108 | ret = -EINVAL; | 7037 | ret = -EINVAL; |
7109 | goto out; | 7038 | goto out; |
7110 | } | 7039 | } |
7111 | 7040 | ||
7112 | iwl3945_set_rxon_channel(priv, conf->phymode, conf->channel); | 7041 | iwl3945_set_rxon_channel(priv, conf->channel->band, conf->channel->hw_value); |
7113 | 7042 | ||
7114 | iwl3945_set_flags_for_phymode(priv, conf->phymode); | 7043 | iwl3945_set_flags_for_phymode(priv, conf->channel->band); |
7115 | 7044 | ||
7116 | /* The list of supported rates and rate mask can be different | 7045 | /* The list of supported rates and rate mask can be different |
7117 | * for each phymode; since the phymode may have changed, reset | 7046 | * for each phymode; since the phymode may have changed, reset |
@@ -7892,65 +7821,6 @@ static ssize_t store_filter_flags(struct device *d, | |||
7892 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, | 7821 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, |
7893 | store_filter_flags); | 7822 | store_filter_flags); |
7894 | 7823 | ||
7895 | static ssize_t show_tune(struct device *d, | ||
7896 | struct device_attribute *attr, char *buf) | ||
7897 | { | ||
7898 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | ||
7899 | |||
7900 | return sprintf(buf, "0x%04X\n", | ||
7901 | (priv->phymode << 8) | | ||
7902 | le16_to_cpu(priv->active_rxon.channel)); | ||
7903 | } | ||
7904 | |||
7905 | static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, u8 phymode); | ||
7906 | |||
7907 | static ssize_t store_tune(struct device *d, | ||
7908 | struct device_attribute *attr, | ||
7909 | const char *buf, size_t count) | ||
7910 | { | ||
7911 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | ||
7912 | char *p = (char *)buf; | ||
7913 | u16 tune = simple_strtoul(p, &p, 0); | ||
7914 | u8 phymode = (tune >> 8) & 0xff; | ||
7915 | u16 channel = tune & 0xff; | ||
7916 | |||
7917 | IWL_DEBUG_INFO("Tune request to:%d channel:%d\n", phymode, channel); | ||
7918 | |||
7919 | mutex_lock(&priv->mutex); | ||
7920 | if ((le16_to_cpu(priv->staging_rxon.channel) != channel) || | ||
7921 | (priv->phymode != phymode)) { | ||
7922 | const struct iwl3945_channel_info *ch_info; | ||
7923 | |||
7924 | ch_info = iwl3945_get_channel_info(priv, phymode, channel); | ||
7925 | if (!ch_info) { | ||
7926 | IWL_WARNING("Requested invalid phymode/channel " | ||
7927 | "combination: %d %d\n", phymode, channel); | ||
7928 | mutex_unlock(&priv->mutex); | ||
7929 | return -EINVAL; | ||
7930 | } | ||
7931 | |||
7932 | /* Cancel any currently running scans... */ | ||
7933 | if (iwl3945_scan_cancel_timeout(priv, 100)) | ||
7934 | IWL_WARNING("Could not cancel scan.\n"); | ||
7935 | else { | ||
7936 | IWL_DEBUG_INFO("Committing phymode and " | ||
7937 | "rxon.channel = %d %d\n", | ||
7938 | phymode, channel); | ||
7939 | |||
7940 | iwl3945_set_rxon_channel(priv, phymode, channel); | ||
7941 | iwl3945_set_flags_for_phymode(priv, phymode); | ||
7942 | |||
7943 | iwl3945_set_rate(priv); | ||
7944 | iwl3945_commit_rxon(priv); | ||
7945 | } | ||
7946 | } | ||
7947 | mutex_unlock(&priv->mutex); | ||
7948 | |||
7949 | return count; | ||
7950 | } | ||
7951 | |||
7952 | static DEVICE_ATTR(tune, S_IWUSR | S_IRUGO, show_tune, store_tune); | ||
7953 | |||
7954 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT | 7824 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT |
7955 | 7825 | ||
7956 | static ssize_t show_measurement(struct device *d, | 7826 | static ssize_t show_measurement(struct device *d, |
@@ -8165,73 +8035,8 @@ static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, | |||
8165 | static ssize_t show_channels(struct device *d, | 8035 | static ssize_t show_channels(struct device *d, |
8166 | struct device_attribute *attr, char *buf) | 8036 | struct device_attribute *attr, char *buf) |
8167 | { | 8037 | { |
8168 | struct iwl3945_priv *priv = dev_get_drvdata(d); | 8038 | /* all this shit doesn't belong into sysfs anyway */ |
8169 | int len = 0, i; | 8039 | return 0; |
8170 | struct ieee80211_channel *channels = NULL; | ||
8171 | const struct ieee80211_hw_mode *hw_mode = NULL; | ||
8172 | int count = 0; | ||
8173 | |||
8174 | if (!iwl3945_is_ready(priv)) | ||
8175 | return -EAGAIN; | ||
8176 | |||
8177 | hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211G); | ||
8178 | if (!hw_mode) | ||
8179 | hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211B); | ||
8180 | if (hw_mode) { | ||
8181 | channels = hw_mode->channels; | ||
8182 | count = hw_mode->num_channels; | ||
8183 | } | ||
8184 | |||
8185 | len += | ||
8186 | sprintf(&buf[len], | ||
8187 | "Displaying %d channels in 2.4GHz band " | ||
8188 | "(802.11bg):\n", count); | ||
8189 | |||
8190 | for (i = 0; i < count; i++) | ||
8191 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
8192 | channels[i].chan, | ||
8193 | channels[i].power_level, | ||
8194 | channels[i]. | ||
8195 | flag & IEEE80211_CHAN_W_RADAR_DETECT ? | ||
8196 | " (IEEE 802.11h required)" : "", | ||
8197 | (!(channels[i].flag & IEEE80211_CHAN_W_IBSS) | ||
8198 | || (channels[i]. | ||
8199 | flag & | ||
8200 | IEEE80211_CHAN_W_RADAR_DETECT)) ? "" : | ||
8201 | ", IBSS", | ||
8202 | channels[i]. | ||
8203 | flag & IEEE80211_CHAN_W_ACTIVE_SCAN ? | ||
8204 | "active/passive" : "passive only"); | ||
8205 | |||
8206 | hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211A); | ||
8207 | if (hw_mode) { | ||
8208 | channels = hw_mode->channels; | ||
8209 | count = hw_mode->num_channels; | ||
8210 | } else { | ||
8211 | channels = NULL; | ||
8212 | count = 0; | ||
8213 | } | ||
8214 | |||
8215 | len += sprintf(&buf[len], "Displaying %d channels in 5.2GHz band " | ||
8216 | "(802.11a):\n", count); | ||
8217 | |||
8218 | for (i = 0; i < count; i++) | ||
8219 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
8220 | channels[i].chan, | ||
8221 | channels[i].power_level, | ||
8222 | channels[i]. | ||
8223 | flag & IEEE80211_CHAN_W_RADAR_DETECT ? | ||
8224 | " (IEEE 802.11h required)" : "", | ||
8225 | (!(channels[i].flag & IEEE80211_CHAN_W_IBSS) | ||
8226 | || (channels[i]. | ||
8227 | flag & | ||
8228 | IEEE80211_CHAN_W_RADAR_DETECT)) ? "" : | ||
8229 | ", IBSS", | ||
8230 | channels[i]. | ||
8231 | flag & IEEE80211_CHAN_W_ACTIVE_SCAN ? | ||
8232 | "active/passive" : "passive only"); | ||
8233 | |||
8234 | return len; | ||
8235 | } | 8040 | } |
8236 | 8041 | ||
8237 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); | 8042 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); |
@@ -8411,7 +8216,6 @@ static struct attribute *iwl3945_sysfs_entries[] = { | |||
8411 | &dev_attr_statistics.attr, | 8216 | &dev_attr_statistics.attr, |
8412 | &dev_attr_status.attr, | 8217 | &dev_attr_status.attr, |
8413 | &dev_attr_temperature.attr, | 8218 | &dev_attr_temperature.attr, |
8414 | &dev_attr_tune.attr, | ||
8415 | &dev_attr_tx_power.attr, | 8219 | &dev_attr_tx_power.attr, |
8416 | 8220 | ||
8417 | NULL | 8221 | NULL |
@@ -8532,7 +8336,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8532 | priv->data_retry_limit = -1; | 8336 | priv->data_retry_limit = -1; |
8533 | priv->ieee_channels = NULL; | 8337 | priv->ieee_channels = NULL; |
8534 | priv->ieee_rates = NULL; | 8338 | priv->ieee_rates = NULL; |
8535 | priv->phymode = -1; | 8339 | priv->band = IEEE80211_BAND_2GHZ; |
8536 | 8340 | ||
8537 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | 8341 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); |
8538 | if (!err) | 8342 | if (!err) |
@@ -8614,7 +8418,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8614 | priv->qos_data.qos_cap.val = 0; | 8418 | priv->qos_data.qos_cap.val = 0; |
8615 | #endif /* CONFIG_IWL3945_QOS */ | 8419 | #endif /* CONFIG_IWL3945_QOS */ |
8616 | 8420 | ||
8617 | iwl3945_set_rxon_channel(priv, MODE_IEEE80211G, 6); | 8421 | iwl3945_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6); |
8618 | iwl3945_setup_deferred_work(priv); | 8422 | iwl3945_setup_deferred_work(priv); |
8619 | iwl3945_setup_rx_handlers(priv); | 8423 | iwl3945_setup_rx_handlers(priv); |
8620 | 8424 | ||
@@ -8665,7 +8469,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8665 | IWL_ERROR("initializing geos failed: %d\n", err); | 8469 | IWL_ERROR("initializing geos failed: %d\n", err); |
8666 | goto out_free_channel_map; | 8470 | goto out_free_channel_map; |
8667 | } | 8471 | } |
8668 | iwl3945_reset_channel_flag(priv); | ||
8669 | 8472 | ||
8670 | iwl3945_rate_control_register(priv->hw); | 8473 | iwl3945_rate_control_register(priv->hw); |
8671 | err = ieee80211_register_hw(priv->hw); | 8474 | err = ieee80211_register_hw(priv->hw); |