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/iwl4965-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/iwl4965-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 438 |
1 files changed, 113 insertions, 325 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 5f38fc585eda..6de969de4c84 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -115,16 +115,10 @@ __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr) | |||
115 | return NULL; | 115 | return NULL; |
116 | } | 116 | } |
117 | 117 | ||
118 | static const struct ieee80211_hw_mode *iwl4965_get_hw_mode( | 118 | static const struct ieee80211_supported_band *iwl4965_get_hw_mode( |
119 | struct iwl4965_priv *priv, int mode) | 119 | struct iwl4965_priv *priv, enum ieee80211_band band) |
120 | { | 120 | { |
121 | int i; | 121 | return priv->hw->wiphy->bands[band]; |
122 | |||
123 | for (i = 0; i < 3; i++) | ||
124 | if (priv->modes[i].mode == mode) | ||
125 | return &priv->modes[i]; | ||
126 | |||
127 | return NULL; | ||
128 | } | 122 | } |
129 | 123 | ||
130 | static int iwl4965_is_empty_essid(const char *essid, int essid_len) | 124 | static int iwl4965_is_empty_essid(const char *essid, int essid_len) |
@@ -937,28 +931,29 @@ static int iwl4965_rxon_add_station(struct iwl4965_priv *priv, | |||
937 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields | 931 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields |
938 | * in the staging RXON flag structure based on the phymode | 932 | * in the staging RXON flag structure based on the phymode |
939 | */ | 933 | */ |
940 | static int iwl4965_set_rxon_channel(struct iwl4965_priv *priv, u8 phymode, | 934 | static int iwl4965_set_rxon_channel(struct iwl4965_priv *priv, |
935 | enum ieee80211_band band, | ||
941 | u16 channel) | 936 | u16 channel) |
942 | { | 937 | { |
943 | if (!iwl4965_get_channel_info(priv, phymode, channel)) { | 938 | if (!iwl4965_get_channel_info(priv, band, channel)) { |
944 | IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", | 939 | IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", |
945 | channel, phymode); | 940 | channel, band); |
946 | return -EINVAL; | 941 | return -EINVAL; |
947 | } | 942 | } |
948 | 943 | ||
949 | if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && | 944 | if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && |
950 | (priv->phymode == phymode)) | 945 | (priv->band == band)) |
951 | return 0; | 946 | return 0; |
952 | 947 | ||
953 | priv->staging_rxon.channel = cpu_to_le16(channel); | 948 | priv->staging_rxon.channel = cpu_to_le16(channel); |
954 | if (phymode == MODE_IEEE80211A) | 949 | if (band == IEEE80211_BAND_5GHZ) |
955 | priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; | 950 | priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; |
956 | else | 951 | else |
957 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; | 952 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; |
958 | 953 | ||
959 | priv->phymode = phymode; | 954 | priv->band = band; |
960 | 955 | ||
961 | IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, phymode); | 956 | IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, band); |
962 | 957 | ||
963 | return 0; | 958 | return 0; |
964 | } | 959 | } |
@@ -2571,9 +2566,10 @@ static int iwl4965_set_rxon_hwcrypto(struct iwl4965_priv *priv, int hw_decrypt) | |||
2571 | return 0; | 2566 | return 0; |
2572 | } | 2567 | } |
2573 | 2568 | ||
2574 | static void iwl4965_set_flags_for_phymode(struct iwl4965_priv *priv, u8 phymode) | 2569 | static void iwl4965_set_flags_for_phymode(struct iwl4965_priv *priv, |
2570 | enum ieee80211_band band) | ||
2575 | { | 2571 | { |
2576 | if (phymode == MODE_IEEE80211A) { | 2572 | if (band == IEEE80211_BAND_5GHZ) { |
2577 | priv->staging_rxon.flags &= | 2573 | priv->staging_rxon.flags &= |
2578 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | 2574 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK |
2579 | | RXON_FLG_CCK_MSK); | 2575 | | RXON_FLG_CCK_MSK); |
@@ -2636,7 +2632,7 @@ static void iwl4965_connection_init_rx_config(struct iwl4965_priv *priv) | |||
2636 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | 2632 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; |
2637 | #endif | 2633 | #endif |
2638 | 2634 | ||
2639 | ch_info = iwl4965_get_channel_info(priv, priv->phymode, | 2635 | ch_info = iwl4965_get_channel_info(priv, priv->band, |
2640 | le16_to_cpu(priv->staging_rxon.channel)); | 2636 | le16_to_cpu(priv->staging_rxon.channel)); |
2641 | 2637 | ||
2642 | if (!ch_info) | 2638 | if (!ch_info) |
@@ -2651,12 +2647,9 @@ static void iwl4965_connection_init_rx_config(struct iwl4965_priv *priv) | |||
2651 | ch_info = &priv->channel_info[0]; | 2647 | ch_info = &priv->channel_info[0]; |
2652 | 2648 | ||
2653 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); | 2649 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); |
2654 | if (is_channel_a_band(ch_info)) | 2650 | priv->band = ch_info->band; |
2655 | priv->phymode = MODE_IEEE80211A; | ||
2656 | else | ||
2657 | priv->phymode = MODE_IEEE80211G; | ||
2658 | 2651 | ||
2659 | iwl4965_set_flags_for_phymode(priv, priv->phymode); | 2652 | iwl4965_set_flags_for_phymode(priv, priv->band); |
2660 | 2653 | ||
2661 | priv->staging_rxon.ofdm_basic_rates = | 2654 | priv->staging_rxon.ofdm_basic_rates = |
2662 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | 2655 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; |
@@ -2678,7 +2671,7 @@ static int iwl4965_set_mode(struct iwl4965_priv *priv, int mode) | |||
2678 | const struct iwl4965_channel_info *ch_info; | 2671 | const struct iwl4965_channel_info *ch_info; |
2679 | 2672 | ||
2680 | ch_info = iwl4965_get_channel_info(priv, | 2673 | ch_info = iwl4965_get_channel_info(priv, |
2681 | priv->phymode, | 2674 | priv->band, |
2682 | le16_to_cpu(priv->staging_rxon.channel)); | 2675 | le16_to_cpu(priv->staging_rxon.channel)); |
2683 | 2676 | ||
2684 | if (!ch_info || !is_channel_ibss(ch_info)) { | 2677 | if (!ch_info || !is_channel_ibss(ch_info)) { |
@@ -2918,7 +2911,7 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, | |||
2918 | goto drop_unlock; | 2911 | goto drop_unlock; |
2919 | } | 2912 | } |
2920 | 2913 | ||
2921 | if ((ctl->tx_rate & 0xFF) == IWL_INVALID_RATE) { | 2914 | if ((ctl->tx_rate->hw_value & 0xFF) == IWL_INVALID_RATE) { |
2922 | IWL_ERROR("ERROR: No TX rate available.\n"); | 2915 | IWL_ERROR("ERROR: No TX rate available.\n"); |
2923 | goto drop_unlock; | 2916 | goto drop_unlock; |
2924 | } | 2917 | } |
@@ -3125,11 +3118,11 @@ drop: | |||
3125 | 3118 | ||
3126 | static void iwl4965_set_rate(struct iwl4965_priv *priv) | 3119 | static void iwl4965_set_rate(struct iwl4965_priv *priv) |
3127 | { | 3120 | { |
3128 | const struct ieee80211_hw_mode *hw = NULL; | 3121 | const struct ieee80211_supported_band *hw = NULL; |
3129 | struct ieee80211_rate *rate; | 3122 | struct ieee80211_rate *rate; |
3130 | int i; | 3123 | int i; |
3131 | 3124 | ||
3132 | hw = iwl4965_get_hw_mode(priv, priv->phymode); | 3125 | hw = iwl4965_get_hw_mode(priv, priv->band); |
3133 | if (!hw) { | 3126 | if (!hw) { |
3134 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); | 3127 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); |
3135 | return; | 3128 | return; |
@@ -3138,24 +3131,10 @@ static void iwl4965_set_rate(struct iwl4965_priv *priv) | |||
3138 | priv->active_rate = 0; | 3131 | priv->active_rate = 0; |
3139 | priv->active_rate_basic = 0; | 3132 | priv->active_rate_basic = 0; |
3140 | 3133 | ||
3141 | IWL_DEBUG_RATE("Setting rates for 802.11%c\n", | 3134 | for (i = 0; i < hw->n_bitrates; i++) { |
3142 | hw->mode == MODE_IEEE80211A ? | 3135 | rate = &(hw->bitrates[i]); |
3143 | 'a' : ((hw->mode == MODE_IEEE80211B) ? 'b' : 'g')); | 3136 | if (rate->hw_value < IWL_RATE_COUNT) |
3144 | 3137 | priv->active_rate |= (1 << rate->hw_value); | |
3145 | for (i = 0; i < hw->num_rates; i++) { | ||
3146 | rate = &(hw->rates[i]); | ||
3147 | if ((rate->val < IWL_RATE_COUNT) && | ||
3148 | (rate->flags & IEEE80211_RATE_SUPPORTED)) { | ||
3149 | IWL_DEBUG_RATE("Adding rate index %d (plcp %d)%s\n", | ||
3150 | rate->val, iwl4965_rates[rate->val].plcp, | ||
3151 | (rate->flags & IEEE80211_RATE_BASIC) ? | ||
3152 | "*" : ""); | ||
3153 | priv->active_rate |= (1 << rate->val); | ||
3154 | if (rate->flags & IEEE80211_RATE_BASIC) | ||
3155 | priv->active_rate_basic |= (1 << rate->val); | ||
3156 | } else | ||
3157 | IWL_DEBUG_RATE("Not adding rate %d (plcp %d)\n", | ||
3158 | rate->val, iwl4965_rates[rate->val].plcp); | ||
3159 | } | 3138 | } |
3160 | 3139 | ||
3161 | IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n", | 3140 | IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n", |
@@ -3775,9 +3754,6 @@ static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv, | |||
3775 | tx_status->flags = | 3754 | tx_status->flags = |
3776 | iwl4965_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; | 3755 | iwl4965_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; |
3777 | 3756 | ||
3778 | tx_status->control.tx_rate = | ||
3779 | iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags); | ||
3780 | |||
3781 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x " | 3757 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x " |
3782 | "retries %d\n", txq_id, iwl4965_get_tx_fail_reason(status), | 3758 | "retries %d\n", txq_id, iwl4965_get_tx_fail_reason(status), |
3783 | status, le32_to_cpu(tx_resp->rate_n_flags), | 3759 | status, le32_to_cpu(tx_resp->rate_n_flags), |
@@ -5419,24 +5395,23 @@ static void iwl4965_init_band_reference(const struct iwl4965_priv *priv, | |||
5419 | * Based on band and channel number. | 5395 | * Based on band and channel number. |
5420 | */ | 5396 | */ |
5421 | const struct iwl4965_channel_info *iwl4965_get_channel_info(const struct iwl4965_priv *priv, | 5397 | const struct iwl4965_channel_info *iwl4965_get_channel_info(const struct iwl4965_priv *priv, |
5422 | int phymode, u16 channel) | 5398 | enum ieee80211_band band, u16 channel) |
5423 | { | 5399 | { |
5424 | int i; | 5400 | int i; |
5425 | 5401 | ||
5426 | switch (phymode) { | 5402 | switch (band) { |
5427 | case MODE_IEEE80211A: | 5403 | case IEEE80211_BAND_5GHZ: |
5428 | for (i = 14; i < priv->channel_count; i++) { | 5404 | for (i = 14; i < priv->channel_count; i++) { |
5429 | if (priv->channel_info[i].channel == channel) | 5405 | if (priv->channel_info[i].channel == channel) |
5430 | return &priv->channel_info[i]; | 5406 | return &priv->channel_info[i]; |
5431 | } | 5407 | } |
5432 | break; | 5408 | break; |
5433 | 5409 | case IEEE80211_BAND_2GHZ: | |
5434 | case MODE_IEEE80211B: | ||
5435 | case MODE_IEEE80211G: | ||
5436 | if (channel >= 1 && channel <= 14) | 5410 | if (channel >= 1 && channel <= 14) |
5437 | return &priv->channel_info[channel - 1]; | 5411 | return &priv->channel_info[channel - 1]; |
5438 | break; | 5412 | break; |
5439 | 5413 | default: | |
5414 | BUG(); | ||
5440 | } | 5415 | } |
5441 | 5416 | ||
5442 | return NULL; | 5417 | return NULL; |
@@ -5499,8 +5474,8 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv) | |||
5499 | /* Loop through each band adding each of the channels */ | 5474 | /* Loop through each band adding each of the channels */ |
5500 | for (ch = 0; ch < eeprom_ch_count; ch++) { | 5475 | for (ch = 0; ch < eeprom_ch_count; ch++) { |
5501 | ch_info->channel = eeprom_ch_index[ch]; | 5476 | ch_info->channel = eeprom_ch_index[ch]; |
5502 | ch_info->phymode = (band == 1) ? MODE_IEEE80211B : | 5477 | ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ : |
5503 | MODE_IEEE80211A; | 5478 | IEEE80211_BAND_5GHZ; |
5504 | 5479 | ||
5505 | /* permanently store EEPROM's channel regulatory flags | 5480 | /* permanently store EEPROM's channel regulatory flags |
5506 | * and max power in channel info database. */ | 5481 | * and max power in channel info database. */ |
@@ -5559,14 +5534,14 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv) | |||
5559 | 5534 | ||
5560 | /* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */ | 5535 | /* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */ |
5561 | for (band = 6; band <= 7; band++) { | 5536 | for (band = 6; band <= 7; band++) { |
5562 | int phymode; | 5537 | enum ieee80211_band ieeeband; |
5563 | u8 fat_extension_chan; | 5538 | u8 fat_extension_chan; |
5564 | 5539 | ||
5565 | iwl4965_init_band_reference(priv, band, &eeprom_ch_count, | 5540 | iwl4965_init_band_reference(priv, band, &eeprom_ch_count, |
5566 | &eeprom_ch_info, &eeprom_ch_index); | 5541 | &eeprom_ch_info, &eeprom_ch_index); |
5567 | 5542 | ||
5568 | /* EEPROM band 6 is 2.4, band 7 is 5 GHz */ | 5543 | /* EEPROM band 6 is 2.4, band 7 is 5 GHz */ |
5569 | phymode = (band == 6) ? MODE_IEEE80211B : MODE_IEEE80211A; | 5544 | ieeeband = (band == 6) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; |
5570 | 5545 | ||
5571 | /* Loop through each band adding each of the channels */ | 5546 | /* Loop through each band adding each of the channels */ |
5572 | for (ch = 0; ch < eeprom_ch_count; ch++) { | 5547 | for (ch = 0; ch < eeprom_ch_count; ch++) { |
@@ -5580,13 +5555,13 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv) | |||
5580 | fat_extension_chan = HT_IE_EXT_CHANNEL_ABOVE; | 5555 | fat_extension_chan = HT_IE_EXT_CHANNEL_ABOVE; |
5581 | 5556 | ||
5582 | /* Set up driver's info for lower half */ | 5557 | /* Set up driver's info for lower half */ |
5583 | iwl4965_set_fat_chan_info(priv, phymode, | 5558 | iwl4965_set_fat_chan_info(priv, ieeeband, |
5584 | eeprom_ch_index[ch], | 5559 | eeprom_ch_index[ch], |
5585 | &(eeprom_ch_info[ch]), | 5560 | &(eeprom_ch_info[ch]), |
5586 | fat_extension_chan); | 5561 | fat_extension_chan); |
5587 | 5562 | ||
5588 | /* Set up driver's info for upper half */ | 5563 | /* Set up driver's info for upper half */ |
5589 | iwl4965_set_fat_chan_info(priv, phymode, | 5564 | iwl4965_set_fat_chan_info(priv, ieeeband, |
5590 | (eeprom_ch_index[ch] + 4), | 5565 | (eeprom_ch_index[ch] + 4), |
5591 | &(eeprom_ch_info[ch]), | 5566 | &(eeprom_ch_info[ch]), |
5592 | HT_IE_EXT_CHANNEL_BELOW); | 5567 | HT_IE_EXT_CHANNEL_BELOW); |
@@ -5628,18 +5603,20 @@ static void iwl4965_free_channel_map(struct iwl4965_priv *priv) | |||
5628 | #define IWL_PASSIVE_DWELL_BASE (100) | 5603 | #define IWL_PASSIVE_DWELL_BASE (100) |
5629 | #define IWL_CHANNEL_TUNE_TIME 5 | 5604 | #define IWL_CHANNEL_TUNE_TIME 5 |
5630 | 5605 | ||
5631 | static inline u16 iwl4965_get_active_dwell_time(struct iwl4965_priv *priv, int phymode) | 5606 | static inline u16 iwl4965_get_active_dwell_time(struct iwl4965_priv *priv, |
5607 | enum ieee80211_band band) | ||
5632 | { | 5608 | { |
5633 | if (phymode == MODE_IEEE80211A) | 5609 | if (band == IEEE80211_BAND_5GHZ) |
5634 | return IWL_ACTIVE_DWELL_TIME_52; | 5610 | return IWL_ACTIVE_DWELL_TIME_52; |
5635 | else | 5611 | else |
5636 | return IWL_ACTIVE_DWELL_TIME_24; | 5612 | return IWL_ACTIVE_DWELL_TIME_24; |
5637 | } | 5613 | } |
5638 | 5614 | ||
5639 | static u16 iwl4965_get_passive_dwell_time(struct iwl4965_priv *priv, int phymode) | 5615 | static u16 iwl4965_get_passive_dwell_time(struct iwl4965_priv *priv, |
5616 | enum ieee80211_band band) | ||
5640 | { | 5617 | { |
5641 | u16 active = iwl4965_get_active_dwell_time(priv, phymode); | 5618 | u16 active = iwl4965_get_active_dwell_time(priv, band); |
5642 | u16 passive = (phymode != MODE_IEEE80211A) ? | 5619 | u16 passive = (band != IEEE80211_BAND_5GHZ) ? |
5643 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : | 5620 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : |
5644 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; | 5621 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; |
5645 | 5622 | ||
@@ -5659,28 +5636,29 @@ static u16 iwl4965_get_passive_dwell_time(struct iwl4965_priv *priv, int phymode | |||
5659 | return passive; | 5636 | return passive; |
5660 | } | 5637 | } |
5661 | 5638 | ||
5662 | static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode, | 5639 | static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, |
5640 | enum ieee80211_band band, | ||
5663 | u8 is_active, u8 direct_mask, | 5641 | u8 is_active, u8 direct_mask, |
5664 | struct iwl4965_scan_channel *scan_ch) | 5642 | struct iwl4965_scan_channel *scan_ch) |
5665 | { | 5643 | { |
5666 | const struct ieee80211_channel *channels = NULL; | 5644 | const struct ieee80211_channel *channels = NULL; |
5667 | const struct ieee80211_hw_mode *hw_mode; | 5645 | const struct ieee80211_supported_band *sband; |
5668 | const struct iwl4965_channel_info *ch_info; | 5646 | const struct iwl4965_channel_info *ch_info; |
5669 | u16 passive_dwell = 0; | 5647 | u16 passive_dwell = 0; |
5670 | u16 active_dwell = 0; | 5648 | u16 active_dwell = 0; |
5671 | int added, i; | 5649 | int added, i; |
5672 | 5650 | ||
5673 | hw_mode = iwl4965_get_hw_mode(priv, phymode); | 5651 | sband = iwl4965_get_hw_mode(priv, band); |
5674 | if (!hw_mode) | 5652 | if (!sband) |
5675 | return 0; | 5653 | return 0; |
5676 | 5654 | ||
5677 | channels = hw_mode->channels; | 5655 | channels = sband->channels; |
5678 | 5656 | ||
5679 | active_dwell = iwl4965_get_active_dwell_time(priv, phymode); | 5657 | active_dwell = iwl4965_get_active_dwell_time(priv, band); |
5680 | passive_dwell = iwl4965_get_passive_dwell_time(priv, phymode); | 5658 | passive_dwell = iwl4965_get_passive_dwell_time(priv, band); |
5681 | 5659 | ||
5682 | for (i = 0, added = 0; i < hw_mode->num_channels; i++) { | 5660 | for (i = 0, added = 0; i < sband->n_channels; i++) { |
5683 | if (channels[i].chan == | 5661 | if (ieee80211_frequency_to_channel(channels[i].center_freq) == |
5684 | le16_to_cpu(priv->active_rxon.channel)) { | 5662 | le16_to_cpu(priv->active_rxon.channel)) { |
5685 | if (iwl4965_is_associated(priv)) { | 5663 | if (iwl4965_is_associated(priv)) { |
5686 | IWL_DEBUG_SCAN | 5664 | IWL_DEBUG_SCAN |
@@ -5691,9 +5669,9 @@ static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode, | |||
5691 | } else if (priv->only_active_channel) | 5669 | } else if (priv->only_active_channel) |
5692 | continue; | 5670 | continue; |
5693 | 5671 | ||
5694 | scan_ch->channel = channels[i].chan; | 5672 | scan_ch->channel = ieee80211_frequency_to_channel(channels[i].center_freq); |
5695 | 5673 | ||
5696 | ch_info = iwl4965_get_channel_info(priv, phymode, | 5674 | ch_info = iwl4965_get_channel_info(priv, band, |
5697 | scan_ch->channel); | 5675 | scan_ch->channel); |
5698 | if (!is_channel_valid(ch_info)) { | 5676 | if (!is_channel_valid(ch_info)) { |
5699 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", | 5677 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", |
@@ -5702,7 +5680,7 @@ static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode, | |||
5702 | } | 5680 | } |
5703 | 5681 | ||
5704 | if (!is_active || is_channel_passive(ch_info) || | 5682 | if (!is_active || is_channel_passive(ch_info) || |
5705 | !(channels[i].flag & IEEE80211_CHAN_W_ACTIVE_SCAN)) | 5683 | (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) |
5706 | scan_ch->type = 0; /* passive */ | 5684 | scan_ch->type = 0; /* passive */ |
5707 | else | 5685 | else |
5708 | scan_ch->type = 1; /* active */ | 5686 | scan_ch->type = 1; /* active */ |
@@ -5721,7 +5699,7 @@ static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode, | |||
5721 | /* scan_pwr_info->tpc.dsp_atten; */ | 5699 | /* scan_pwr_info->tpc.dsp_atten; */ |
5722 | 5700 | ||
5723 | /*scan_pwr_info->tpc.tx_gain; */ | 5701 | /*scan_pwr_info->tpc.tx_gain; */ |
5724 | if (phymode == MODE_IEEE80211A) | 5702 | if (band == IEEE80211_BAND_5GHZ) |
5725 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; | 5703 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; |
5726 | else { | 5704 | else { |
5727 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); | 5705 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); |
@@ -5745,41 +5723,23 @@ static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode, | |||
5745 | return added; | 5723 | return added; |
5746 | } | 5724 | } |
5747 | 5725 | ||
5748 | static void iwl4965_reset_channel_flag(struct iwl4965_priv *priv) | ||
5749 | { | ||
5750 | int i, j; | ||
5751 | for (i = 0; i < 3; i++) { | ||
5752 | struct ieee80211_hw_mode *hw_mode = (void *)&priv->modes[i]; | ||
5753 | for (j = 0; j < hw_mode->num_channels; j++) | ||
5754 | hw_mode->channels[j].flag = hw_mode->channels[j].val; | ||
5755 | } | ||
5756 | } | ||
5757 | |||
5758 | static void iwl4965_init_hw_rates(struct iwl4965_priv *priv, | 5726 | static void iwl4965_init_hw_rates(struct iwl4965_priv *priv, |
5759 | struct ieee80211_rate *rates) | 5727 | struct ieee80211_rate *rates) |
5760 | { | 5728 | { |
5761 | int i; | 5729 | int i; |
5762 | 5730 | ||
5763 | for (i = 0; i < IWL_RATE_COUNT; i++) { | 5731 | for (i = 0; i < IWL_RATE_COUNT; i++) { |
5764 | rates[i].rate = iwl4965_rates[i].ieee * 5; | 5732 | rates[i].bitrate = iwl4965_rates[i].ieee * 5; |
5765 | rates[i].val = i; /* Rate scaling will work on indexes */ | 5733 | rates[i].hw_value = i; /* Rate scaling will work on indexes */ |
5766 | rates[i].val2 = i; | 5734 | rates[i].hw_value_short = i; |
5767 | rates[i].flags = IEEE80211_RATE_SUPPORTED; | 5735 | rates[i].flags = 0; |
5768 | /* Only OFDM have the bits-per-symbol set */ | 5736 | if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) { |
5769 | if ((i <= IWL_LAST_OFDM_RATE) && (i >= IWL_FIRST_OFDM_RATE)) | ||
5770 | rates[i].flags |= IEEE80211_RATE_OFDM; | ||
5771 | else { | ||
5772 | /* | 5737 | /* |
5773 | * If CCK 1M then set rate flag to CCK else CCK_2 | 5738 | * If CCK != 1M then set short preamble rate flag. |
5774 | * which is CCK | PREAMBLE2 | ||
5775 | */ | 5739 | */ |
5776 | rates[i].flags |= (iwl4965_rates[i].plcp == 10) ? | 5740 | rates[i].flags |= (iwl4965_rates[i].plcp == 10) ? |
5777 | IEEE80211_RATE_CCK : IEEE80211_RATE_CCK_2; | 5741 | 0 : IEEE80211_RATE_SHORT_PREAMBLE; |
5778 | } | 5742 | } |
5779 | |||
5780 | /* Set up which ones are basic rates... */ | ||
5781 | if (IWL_BASIC_RATES_MASK & (1 << i)) | ||
5782 | rates[i].flags |= IEEE80211_RATE_BASIC; | ||
5783 | } | 5743 | } |
5784 | } | 5744 | } |
5785 | 5745 | ||
@@ -5789,74 +5749,47 @@ static void iwl4965_init_hw_rates(struct iwl4965_priv *priv, | |||
5789 | static int iwl4965_init_geos(struct iwl4965_priv *priv) | 5749 | static int iwl4965_init_geos(struct iwl4965_priv *priv) |
5790 | { | 5750 | { |
5791 | struct iwl4965_channel_info *ch; | 5751 | struct iwl4965_channel_info *ch; |
5792 | struct ieee80211_hw_mode *modes; | 5752 | struct ieee80211_supported_band *band; |
5793 | struct ieee80211_channel *channels; | 5753 | struct ieee80211_channel *channels; |
5794 | struct ieee80211_channel *geo_ch; | 5754 | struct ieee80211_channel *geo_ch; |
5795 | struct ieee80211_rate *rates; | 5755 | struct ieee80211_rate *rates; |
5796 | int i = 0; | 5756 | int i = 0; |
5797 | enum { | ||
5798 | A = 0, | ||
5799 | B = 1, | ||
5800 | G = 2, | ||
5801 | }; | ||
5802 | int mode_count = 3; | ||
5803 | 5757 | ||
5804 | if (priv->modes) { | 5758 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || |
5759 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | ||
5805 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); | 5760 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); |
5806 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5761 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
5807 | return 0; | 5762 | return 0; |
5808 | } | 5763 | } |
5809 | 5764 | ||
5810 | modes = kzalloc(sizeof(struct ieee80211_hw_mode) * mode_count, | ||
5811 | GFP_KERNEL); | ||
5812 | if (!modes) | ||
5813 | return -ENOMEM; | ||
5814 | |||
5815 | channels = kzalloc(sizeof(struct ieee80211_channel) * | 5765 | channels = kzalloc(sizeof(struct ieee80211_channel) * |
5816 | priv->channel_count, GFP_KERNEL); | 5766 | priv->channel_count, GFP_KERNEL); |
5817 | if (!channels) { | 5767 | if (!channels) |
5818 | kfree(modes); | ||
5819 | return -ENOMEM; | 5768 | return -ENOMEM; |
5820 | } | ||
5821 | 5769 | ||
5822 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_MAX_RATES + 1)), | 5770 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_MAX_RATES + 1)), |
5823 | GFP_KERNEL); | 5771 | GFP_KERNEL); |
5824 | if (!rates) { | 5772 | if (!rates) { |
5825 | kfree(modes); | ||
5826 | kfree(channels); | 5773 | kfree(channels); |
5827 | return -ENOMEM; | 5774 | return -ENOMEM; |
5828 | } | 5775 | } |
5829 | 5776 | ||
5830 | /* 0 = 802.11a | ||
5831 | * 1 = 802.11b | ||
5832 | * 2 = 802.11g | ||
5833 | */ | ||
5834 | |||
5835 | /* 5.2GHz channels start after the 2.4GHz channels */ | 5777 | /* 5.2GHz channels start after the 2.4GHz channels */ |
5836 | modes[A].mode = MODE_IEEE80211A; | ||
5837 | modes[A].channels = &channels[ARRAY_SIZE(iwl4965_eeprom_band_1)]; | ||
5838 | modes[A].rates = rates; | ||
5839 | modes[A].num_rates = 8; /* just OFDM */ | ||
5840 | modes[A].rates = &rates[4]; | ||
5841 | modes[A].num_channels = 0; | ||
5842 | #ifdef CONFIG_IWL4965_HT | 5778 | #ifdef CONFIG_IWL4965_HT |
5843 | iwl4965_init_ht_hw_capab(&modes[A].ht_info, MODE_IEEE80211A); | 5779 | iwl4965_init_ht_hw_capab(&modes[A].ht_info, MODE_IEEE80211A); |
5844 | #endif | 5780 | #endif |
5845 | |||
5846 | modes[B].mode = MODE_IEEE80211B; | ||
5847 | modes[B].channels = channels; | ||
5848 | modes[B].rates = rates; | ||
5849 | modes[B].num_rates = 4; /* just CCK */ | ||
5850 | modes[B].num_channels = 0; | ||
5851 | |||
5852 | modes[G].mode = MODE_IEEE80211G; | ||
5853 | modes[G].channels = channels; | ||
5854 | modes[G].rates = rates; | ||
5855 | modes[G].num_rates = 12; /* OFDM & CCK */ | ||
5856 | modes[G].num_channels = 0; | ||
5857 | #ifdef CONFIG_IWL4965_HT | 5781 | #ifdef CONFIG_IWL4965_HT |
5858 | iwl4965_init_ht_hw_capab(&modes[G].ht_info, MODE_IEEE80211G); | 5782 | iwl4965_init_ht_hw_capab(&modes[G].ht_info, MODE_IEEE80211G); |
5859 | #endif | 5783 | #endif |
5784 | band = &priv->bands[IEEE80211_BAND_5GHZ]; | ||
5785 | band->channels = &channels[ARRAY_SIZE(iwl4965_eeprom_band_1)]; | ||
5786 | band->bitrates = &rates[4]; | ||
5787 | band->n_bitrates = 8; /* just OFDM */ | ||
5788 | |||
5789 | band = &priv->bands[IEEE80211_BAND_2GHZ]; | ||
5790 | band->channels = channels; | ||
5791 | band->bitrates = rates; | ||
5792 | band->n_bitrates = 12; /* OFDM & CCK */ | ||
5860 | 5793 | ||
5861 | priv->ieee_channels = channels; | 5794 | priv->ieee_channels = channels; |
5862 | priv->ieee_rates = rates; | 5795 | priv->ieee_rates = rates; |
@@ -5875,37 +5808,32 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv) | |||
5875 | } | 5808 | } |
5876 | 5809 | ||
5877 | if (is_channel_a_band(ch)) { | 5810 | if (is_channel_a_band(ch)) { |
5878 | geo_ch = &modes[A].channels[modes[A].num_channels++]; | 5811 | geo_ch = &priv->bands[IEEE80211_BAND_5GHZ].channels[priv->bands[IEEE80211_BAND_5GHZ].n_channels++]; |
5879 | } else { | 5812 | } else |
5880 | geo_ch = &modes[B].channels[modes[B].num_channels++]; | 5813 | geo_ch = &priv->bands[IEEE80211_BAND_2GHZ].channels[priv->bands[IEEE80211_BAND_2GHZ].n_channels++]; |
5881 | modes[G].num_channels++; | ||
5882 | } | ||
5883 | 5814 | ||
5884 | geo_ch->freq = ieee80211chan2mhz(ch->channel); | 5815 | geo_ch->center_freq = ieee80211chan2mhz(ch->channel); |
5885 | geo_ch->chan = ch->channel; | 5816 | geo_ch->max_power = ch->max_power_avg; |
5886 | geo_ch->power_level = ch->max_power_avg; | 5817 | geo_ch->max_antenna_gain = 0xff; |
5887 | geo_ch->antenna_max = 0xff; | ||
5888 | 5818 | ||
5889 | if (is_channel_valid(ch)) { | 5819 | if (is_channel_valid(ch)) { |
5890 | geo_ch->flag = IEEE80211_CHAN_W_SCAN; | 5820 | if (!(ch->flags & EEPROM_CHANNEL_IBSS)) |
5891 | if (ch->flags & EEPROM_CHANNEL_IBSS) | 5821 | geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; |
5892 | geo_ch->flag |= IEEE80211_CHAN_W_IBSS; | ||
5893 | 5822 | ||
5894 | if (ch->flags & EEPROM_CHANNEL_ACTIVE) | 5823 | if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) |
5895 | geo_ch->flag |= IEEE80211_CHAN_W_ACTIVE_SCAN; | 5824 | geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; |
5896 | 5825 | ||
5897 | if (ch->flags & EEPROM_CHANNEL_RADAR) | 5826 | if (ch->flags & EEPROM_CHANNEL_RADAR) |
5898 | geo_ch->flag |= IEEE80211_CHAN_W_RADAR_DETECT; | 5827 | geo_ch->flags |= IEEE80211_CHAN_RADAR; |
5899 | 5828 | ||
5900 | if (ch->max_power_avg > priv->max_channel_txpower_limit) | 5829 | if (ch->max_power_avg > priv->max_channel_txpower_limit) |
5901 | priv->max_channel_txpower_limit = | 5830 | priv->max_channel_txpower_limit = |
5902 | ch->max_power_avg; | 5831 | ch->max_power_avg; |
5903 | } | 5832 | } else |
5904 | 5833 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; | |
5905 | geo_ch->val = geo_ch->flag; | ||
5906 | } | 5834 | } |
5907 | 5835 | ||
5908 | if ((modes[A].num_channels == 0) && priv->is_abg) { | 5836 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && priv->is_abg) { |
5909 | printk(KERN_INFO DRV_NAME | 5837 | printk(KERN_INFO DRV_NAME |
5910 | ": Incorrectly detected BG card as ABG. Please send " | 5838 | ": Incorrectly detected BG card as ABG. Please send " |
5911 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", | 5839 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", |
@@ -5915,24 +5843,12 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv) | |||
5915 | 5843 | ||
5916 | printk(KERN_INFO DRV_NAME | 5844 | printk(KERN_INFO DRV_NAME |
5917 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", | 5845 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", |
5918 | modes[G].num_channels, modes[A].num_channels); | 5846 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, |
5919 | 5847 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | |
5920 | /* | ||
5921 | * NOTE: We register these in preference of order -- the | ||
5922 | * stack doesn't currently (as of 7.0.6 / Apr 24 '07) pick | ||
5923 | * a phymode based on rates or AP capabilities but seems to | ||
5924 | * configure it purely on if the channel being configured | ||
5925 | * is supported by a mode -- and the first match is taken | ||
5926 | */ | ||
5927 | 5848 | ||
5928 | if (modes[G].num_channels) | 5849 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->bands[IEEE80211_BAND_2GHZ]; |
5929 | ieee80211_register_hwmode(priv->hw, &modes[G]); | 5850 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->bands[IEEE80211_BAND_5GHZ]; |
5930 | if (modes[B].num_channels) | ||
5931 | ieee80211_register_hwmode(priv->hw, &modes[B]); | ||
5932 | if (modes[A].num_channels) | ||
5933 | ieee80211_register_hwmode(priv->hw, &modes[A]); | ||
5934 | 5851 | ||
5935 | priv->modes = modes; | ||
5936 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5852 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
5937 | 5853 | ||
5938 | return 0; | 5854 | return 0; |
@@ -5943,7 +5859,6 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv) | |||
5943 | */ | 5859 | */ |
5944 | static void iwl4965_free_geos(struct iwl4965_priv *priv) | 5860 | static void iwl4965_free_geos(struct iwl4965_priv *priv) |
5945 | { | 5861 | { |
5946 | kfree(priv->modes); | ||
5947 | kfree(priv->ieee_channels); | 5862 | kfree(priv->ieee_channels); |
5948 | kfree(priv->ieee_rates); | 5863 | kfree(priv->ieee_rates); |
5949 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5864 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); |
@@ -6945,7 +6860,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
6945 | struct iwl4965_scan_cmd *scan; | 6860 | struct iwl4965_scan_cmd *scan; |
6946 | struct ieee80211_conf *conf = NULL; | 6861 | struct ieee80211_conf *conf = NULL; |
6947 | u8 direct_mask; | 6862 | u8 direct_mask; |
6948 | int phymode; | 6863 | enum ieee80211_band band; |
6949 | 6864 | ||
6950 | conf = ieee80211_get_hw_conf(priv->hw); | 6865 | conf = ieee80211_get_hw_conf(priv->hw); |
6951 | 6866 | ||
@@ -7075,7 +6990,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
7075 | RATE_MCS_ANT_B_MSK|RATE_MCS_CCK_MSK); | 6990 | RATE_MCS_ANT_B_MSK|RATE_MCS_CCK_MSK); |
7076 | 6991 | ||
7077 | scan->good_CRC_th = 0; | 6992 | scan->good_CRC_th = 0; |
7078 | phymode = MODE_IEEE80211G; | 6993 | band = IEEE80211_BAND_2GHZ; |
7079 | break; | 6994 | break; |
7080 | 6995 | ||
7081 | case 1: | 6996 | case 1: |
@@ -7083,7 +6998,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
7083 | iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, | 6998 | iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, |
7084 | RATE_MCS_ANT_B_MSK); | 6999 | RATE_MCS_ANT_B_MSK); |
7085 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | 7000 | scan->good_CRC_th = IWL_GOOD_CRC_TH; |
7086 | phymode = MODE_IEEE80211A; | 7001 | band = IEEE80211_BAND_5GHZ; |
7087 | break; | 7002 | break; |
7088 | 7003 | ||
7089 | default: | 7004 | default: |
@@ -7113,7 +7028,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
7113 | 7028 | ||
7114 | scan->channel_count = | 7029 | scan->channel_count = |
7115 | iwl4965_get_channels_for_scan( | 7030 | iwl4965_get_channels_for_scan( |
7116 | priv, phymode, 1, /* active */ | 7031 | priv, band, 1, /* active */ |
7117 | direct_mask, | 7032 | direct_mask, |
7118 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | 7033 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); |
7119 | 7034 | ||
@@ -7463,7 +7378,7 @@ static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
7463 | } | 7378 | } |
7464 | 7379 | ||
7465 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | 7380 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, |
7466 | ctl->tx_rate); | 7381 | ctl->tx_rate->bitrate); |
7467 | 7382 | ||
7468 | if (iwl4965_tx_skb(priv, skb, ctl)) | 7383 | if (iwl4965_tx_skb(priv, skb, ctl)) |
7469 | dev_kfree_skb_any(skb); | 7384 | dev_kfree_skb_any(skb); |
@@ -7522,7 +7437,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7522 | int ret = 0; | 7437 | int ret = 0; |
7523 | 7438 | ||
7524 | mutex_lock(&priv->mutex); | 7439 | mutex_lock(&priv->mutex); |
7525 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel); | 7440 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); |
7526 | 7441 | ||
7527 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); | 7442 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); |
7528 | 7443 | ||
@@ -7542,10 +7457,9 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7542 | 7457 | ||
7543 | spin_lock_irqsave(&priv->lock, flags); | 7458 | spin_lock_irqsave(&priv->lock, flags); |
7544 | 7459 | ||
7545 | ch_info = iwl4965_get_channel_info(priv, conf->phymode, conf->channel); | 7460 | ch_info = iwl4965_get_channel_info(priv, conf->channel->band, |
7461 | ieee80211_frequency_to_channel(conf->channel->center_freq)); | ||
7546 | if (!is_channel_valid(ch_info)) { | 7462 | if (!is_channel_valid(ch_info)) { |
7547 | IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n", | ||
7548 | conf->channel, conf->phymode); | ||
7549 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); | 7463 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); |
7550 | spin_unlock_irqrestore(&priv->lock, flags); | 7464 | spin_unlock_irqrestore(&priv->lock, flags); |
7551 | ret = -EINVAL; | 7465 | ret = -EINVAL; |
@@ -7564,12 +7478,13 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7564 | priv->staging_rxon.flags = 0; | 7478 | priv->staging_rxon.flags = 0; |
7565 | #endif /* CONFIG_IWL4965_HT */ | 7479 | #endif /* CONFIG_IWL4965_HT */ |
7566 | 7480 | ||
7567 | iwl4965_set_rxon_channel(priv, conf->phymode, conf->channel); | 7481 | iwl4965_set_rxon_channel(priv, conf->channel->band, |
7482 | ieee80211_frequency_to_channel(conf->channel->center_freq)); | ||
7568 | 7483 | ||
7569 | iwl4965_set_flags_for_phymode(priv, conf->phymode); | 7484 | iwl4965_set_flags_for_phymode(priv, conf->channel->band); |
7570 | 7485 | ||
7571 | /* The list of supported rates and rate mask can be different | 7486 | /* The list of supported rates and rate mask can be different |
7572 | * for each phymode; since the phymode may have changed, reset | 7487 | * for each band; since the band may have changed, reset |
7573 | * the rate mask to what mac80211 lists */ | 7488 | * the rate mask to what mac80211 lists */ |
7574 | iwl4965_set_rate(priv); | 7489 | iwl4965_set_rate(priv); |
7575 | 7490 | ||
@@ -7839,7 +7754,7 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, | |||
7839 | } | 7754 | } |
7840 | 7755 | ||
7841 | if (changes & BSS_CHANGED_ERP_CTS_PROT) { | 7756 | if (changes & BSS_CHANGED_ERP_CTS_PROT) { |
7842 | if (bss_conf->use_cts_prot && (priv->phymode != MODE_IEEE80211A)) | 7757 | if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) |
7843 | priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; | 7758 | priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; |
7844 | else | 7759 | else |
7845 | priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; | 7760 | priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; |
@@ -8277,7 +8192,6 @@ static void iwl4965_set_ht_capab(struct ieee80211_hw *hw, | |||
8277 | u8 use_current_config) | 8192 | u8 use_current_config) |
8278 | { | 8193 | { |
8279 | struct ieee80211_conf *conf = &hw->conf; | 8194 | struct ieee80211_conf *conf = &hw->conf; |
8280 | struct ieee80211_hw_mode *mode = conf->mode; | ||
8281 | 8195 | ||
8282 | if (use_current_config) { | 8196 | if (use_current_config) { |
8283 | ht_cap->cap_info = cpu_to_le16(conf->ht_conf.cap); | 8197 | ht_cap->cap_info = cpu_to_le16(conf->ht_conf.cap); |
@@ -8488,65 +8402,6 @@ static ssize_t store_filter_flags(struct device *d, | |||
8488 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, | 8402 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, |
8489 | store_filter_flags); | 8403 | store_filter_flags); |
8490 | 8404 | ||
8491 | static ssize_t show_tune(struct device *d, | ||
8492 | struct device_attribute *attr, char *buf) | ||
8493 | { | ||
8494 | struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; | ||
8495 | |||
8496 | return sprintf(buf, "0x%04X\n", | ||
8497 | (priv->phymode << 8) | | ||
8498 | le16_to_cpu(priv->active_rxon.channel)); | ||
8499 | } | ||
8500 | |||
8501 | static void iwl4965_set_flags_for_phymode(struct iwl4965_priv *priv, u8 phymode); | ||
8502 | |||
8503 | static ssize_t store_tune(struct device *d, | ||
8504 | struct device_attribute *attr, | ||
8505 | const char *buf, size_t count) | ||
8506 | { | ||
8507 | struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; | ||
8508 | char *p = (char *)buf; | ||
8509 | u16 tune = simple_strtoul(p, &p, 0); | ||
8510 | u8 phymode = (tune >> 8) & 0xff; | ||
8511 | u16 channel = tune & 0xff; | ||
8512 | |||
8513 | IWL_DEBUG_INFO("Tune request to:%d channel:%d\n", phymode, channel); | ||
8514 | |||
8515 | mutex_lock(&priv->mutex); | ||
8516 | if ((le16_to_cpu(priv->staging_rxon.channel) != channel) || | ||
8517 | (priv->phymode != phymode)) { | ||
8518 | const struct iwl4965_channel_info *ch_info; | ||
8519 | |||
8520 | ch_info = iwl4965_get_channel_info(priv, phymode, channel); | ||
8521 | if (!ch_info) { | ||
8522 | IWL_WARNING("Requested invalid phymode/channel " | ||
8523 | "combination: %d %d\n", phymode, channel); | ||
8524 | mutex_unlock(&priv->mutex); | ||
8525 | return -EINVAL; | ||
8526 | } | ||
8527 | |||
8528 | /* Cancel any currently running scans... */ | ||
8529 | if (iwl4965_scan_cancel_timeout(priv, 100)) | ||
8530 | IWL_WARNING("Could not cancel scan.\n"); | ||
8531 | else { | ||
8532 | IWL_DEBUG_INFO("Committing phymode and " | ||
8533 | "rxon.channel = %d %d\n", | ||
8534 | phymode, channel); | ||
8535 | |||
8536 | iwl4965_set_rxon_channel(priv, phymode, channel); | ||
8537 | iwl4965_set_flags_for_phymode(priv, phymode); | ||
8538 | |||
8539 | iwl4965_set_rate(priv); | ||
8540 | iwl4965_commit_rxon(priv); | ||
8541 | } | ||
8542 | } | ||
8543 | mutex_unlock(&priv->mutex); | ||
8544 | |||
8545 | return count; | ||
8546 | } | ||
8547 | |||
8548 | static DEVICE_ATTR(tune, S_IWUSR | S_IRUGO, show_tune, store_tune); | ||
8549 | |||
8550 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT | 8405 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT |
8551 | 8406 | ||
8552 | static ssize_t show_measurement(struct device *d, | 8407 | static ssize_t show_measurement(struct device *d, |
@@ -8736,73 +8591,8 @@ static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, | |||
8736 | static ssize_t show_channels(struct device *d, | 8591 | static ssize_t show_channels(struct device *d, |
8737 | struct device_attribute *attr, char *buf) | 8592 | struct device_attribute *attr, char *buf) |
8738 | { | 8593 | { |
8739 | struct iwl4965_priv *priv = dev_get_drvdata(d); | 8594 | /* all this shit doesn't belong into sysfs anyway */ |
8740 | int len = 0, i; | 8595 | return 0; |
8741 | struct ieee80211_channel *channels = NULL; | ||
8742 | const struct ieee80211_hw_mode *hw_mode = NULL; | ||
8743 | int count = 0; | ||
8744 | |||
8745 | if (!iwl4965_is_ready(priv)) | ||
8746 | return -EAGAIN; | ||
8747 | |||
8748 | hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211G); | ||
8749 | if (!hw_mode) | ||
8750 | hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211B); | ||
8751 | if (hw_mode) { | ||
8752 | channels = hw_mode->channels; | ||
8753 | count = hw_mode->num_channels; | ||
8754 | } | ||
8755 | |||
8756 | len += | ||
8757 | sprintf(&buf[len], | ||
8758 | "Displaying %d channels in 2.4GHz band " | ||
8759 | "(802.11bg):\n", count); | ||
8760 | |||
8761 | for (i = 0; i < count; i++) | ||
8762 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
8763 | channels[i].chan, | ||
8764 | channels[i].power_level, | ||
8765 | channels[i]. | ||
8766 | flag & IEEE80211_CHAN_W_RADAR_DETECT ? | ||
8767 | " (IEEE 802.11h required)" : "", | ||
8768 | (!(channels[i].flag & IEEE80211_CHAN_W_IBSS) | ||
8769 | || (channels[i]. | ||
8770 | flag & | ||
8771 | IEEE80211_CHAN_W_RADAR_DETECT)) ? "" : | ||
8772 | ", IBSS", | ||
8773 | channels[i]. | ||
8774 | flag & IEEE80211_CHAN_W_ACTIVE_SCAN ? | ||
8775 | "active/passive" : "passive only"); | ||
8776 | |||
8777 | hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211A); | ||
8778 | if (hw_mode) { | ||
8779 | channels = hw_mode->channels; | ||
8780 | count = hw_mode->num_channels; | ||
8781 | } else { | ||
8782 | channels = NULL; | ||
8783 | count = 0; | ||
8784 | } | ||
8785 | |||
8786 | len += sprintf(&buf[len], "Displaying %d channels in 5.2GHz band " | ||
8787 | "(802.11a):\n", count); | ||
8788 | |||
8789 | for (i = 0; i < count; i++) | ||
8790 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
8791 | channels[i].chan, | ||
8792 | channels[i].power_level, | ||
8793 | channels[i]. | ||
8794 | flag & IEEE80211_CHAN_W_RADAR_DETECT ? | ||
8795 | " (IEEE 802.11h required)" : "", | ||
8796 | (!(channels[i].flag & IEEE80211_CHAN_W_IBSS) | ||
8797 | || (channels[i]. | ||
8798 | flag & | ||
8799 | IEEE80211_CHAN_W_RADAR_DETECT)) ? "" : | ||
8800 | ", IBSS", | ||
8801 | channels[i]. | ||
8802 | flag & IEEE80211_CHAN_W_ACTIVE_SCAN ? | ||
8803 | "active/passive" : "passive only"); | ||
8804 | |||
8805 | return len; | ||
8806 | } | 8596 | } |
8807 | 8597 | ||
8808 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); | 8598 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); |
@@ -8981,7 +8771,6 @@ static struct attribute *iwl4965_sysfs_entries[] = { | |||
8981 | &dev_attr_statistics.attr, | 8771 | &dev_attr_statistics.attr, |
8982 | &dev_attr_status.attr, | 8772 | &dev_attr_status.attr, |
8983 | &dev_attr_temperature.attr, | 8773 | &dev_attr_temperature.attr, |
8984 | &dev_attr_tune.attr, | ||
8985 | &dev_attr_tx_power.attr, | 8774 | &dev_attr_tx_power.attr, |
8986 | 8775 | ||
8987 | NULL | 8776 | NULL |
@@ -9109,7 +8898,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9109 | priv->data_retry_limit = -1; | 8898 | priv->data_retry_limit = -1; |
9110 | priv->ieee_channels = NULL; | 8899 | priv->ieee_channels = NULL; |
9111 | priv->ieee_rates = NULL; | 8900 | priv->ieee_rates = NULL; |
9112 | priv->phymode = -1; | 8901 | priv->band = IEEE80211_BAND_2GHZ; |
9113 | 8902 | ||
9114 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | 8903 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); |
9115 | if (!err) | 8904 | if (!err) |
@@ -9175,7 +8964,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9175 | priv->qos_data.qos_cap.val = 0; | 8964 | priv->qos_data.qos_cap.val = 0; |
9176 | #endif /* CONFIG_IWL4965_QOS */ | 8965 | #endif /* CONFIG_IWL4965_QOS */ |
9177 | 8966 | ||
9178 | iwl4965_set_rxon_channel(priv, MODE_IEEE80211G, 6); | 8967 | iwl4965_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6); |
9179 | iwl4965_setup_deferred_work(priv); | 8968 | iwl4965_setup_deferred_work(priv); |
9180 | iwl4965_setup_rx_handlers(priv); | 8969 | iwl4965_setup_rx_handlers(priv); |
9181 | 8970 | ||
@@ -9226,7 +9015,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9226 | IWL_ERROR("initializing geos failed: %d\n", err); | 9015 | IWL_ERROR("initializing geos failed: %d\n", err); |
9227 | goto out_free_channel_map; | 9016 | goto out_free_channel_map; |
9228 | } | 9017 | } |
9229 | iwl4965_reset_channel_flag(priv); | ||
9230 | 9018 | ||
9231 | iwl4965_rate_control_register(priv->hw); | 9019 | iwl4965_rate_control_register(priv->hw); |
9232 | err = ieee80211_register_hw(priv->hw); | 9020 | err = ieee80211_register_hw(priv->hw); |