diff options
author | Lennert Buytenhek <buytenh@wantstofly.org> | 2010-01-12 07:49:15 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-01-12 14:21:16 -0500 |
commit | 8707d0262585423cdc053bf8db0912e53915e5e4 (patch) | |
tree | a1d98e032dd807213b7f80acc5eda2f6c2c3bcdc /drivers/net/wireless | |
parent | 854783444bab0024556c0aefdb0a860f2f1da286 (diff) |
mwl8k: handle 5 GHz legacy rate bitmaps in firmware commands
Whenever mac80211 gives us a legacy rate bitmap in the context of the
5 GHz band, we need to remember to shift the bitmap left by 5 positions
before giving it to the firmware, as the firmware follows the bitmap
bit assignment of the 2.4 GHz rate table even if we're on the 5 GHz
band, and the 2.4 GHz rate table includes five non-OFDM rates at the
start that are not valid in the 5 GHz band.
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/mwl8k.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index cc2ce61b7992..e370245b3901 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -2836,6 +2836,7 @@ static int mwl8k_cmd_set_new_stn_add(struct ieee80211_hw *hw, | |||
2836 | struct ieee80211_sta *sta) | 2836 | struct ieee80211_sta *sta) |
2837 | { | 2837 | { |
2838 | struct mwl8k_cmd_set_new_stn *cmd; | 2838 | struct mwl8k_cmd_set_new_stn *cmd; |
2839 | u32 rates; | ||
2839 | int rc; | 2840 | int rc; |
2840 | 2841 | ||
2841 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); | 2842 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); |
@@ -2848,7 +2849,11 @@ static int mwl8k_cmd_set_new_stn_add(struct ieee80211_hw *hw, | |||
2848 | memcpy(cmd->mac_addr, sta->addr, ETH_ALEN); | 2849 | memcpy(cmd->mac_addr, sta->addr, ETH_ALEN); |
2849 | cmd->stn_id = cpu_to_le16(sta->aid); | 2850 | cmd->stn_id = cpu_to_le16(sta->aid); |
2850 | cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD); | 2851 | cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD); |
2851 | cmd->legacy_rates = cpu_to_le32(sta->supp_rates[IEEE80211_BAND_2GHZ]); | 2852 | if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) |
2853 | rates = sta->supp_rates[IEEE80211_BAND_2GHZ]; | ||
2854 | else | ||
2855 | rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5; | ||
2856 | cmd->legacy_rates = cpu_to_le32(rates); | ||
2852 | if (sta->ht_cap.ht_supported) { | 2857 | if (sta->ht_cap.ht_supported) { |
2853 | cmd->ht_rates[0] = sta->ht_cap.mcs.rx_mask[0]; | 2858 | cmd->ht_rates[0] = sta->ht_cap.mcs.rx_mask[0]; |
2854 | cmd->ht_rates[1] = sta->ht_cap.mcs.rx_mask[1]; | 2859 | cmd->ht_rates[1] = sta->ht_cap.mcs.rx_mask[1]; |
@@ -2972,6 +2977,7 @@ static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw, | |||
2972 | { | 2977 | { |
2973 | struct mwl8k_cmd_update_stadb *cmd; | 2978 | struct mwl8k_cmd_update_stadb *cmd; |
2974 | struct peer_capability_info *p; | 2979 | struct peer_capability_info *p; |
2980 | u32 rates; | ||
2975 | int rc; | 2981 | int rc; |
2976 | 2982 | ||
2977 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); | 2983 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); |
@@ -2990,8 +2996,11 @@ static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw, | |||
2990 | p->ht_caps = sta->ht_cap.cap; | 2996 | p->ht_caps = sta->ht_cap.cap; |
2991 | p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) | | 2997 | p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) | |
2992 | ((sta->ht_cap.ampdu_density & 7) << 2); | 2998 | ((sta->ht_cap.ampdu_density & 7) << 2); |
2993 | legacy_rate_mask_to_array(p->legacy_rates, | 2999 | if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) |
2994 | sta->supp_rates[IEEE80211_BAND_2GHZ]); | 3000 | rates = sta->supp_rates[IEEE80211_BAND_2GHZ]; |
3001 | else | ||
3002 | rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5; | ||
3003 | legacy_rate_mask_to_array(p->legacy_rates, rates); | ||
2995 | memcpy(p->ht_rates, sta->ht_cap.mcs.rx_mask, 16); | 3004 | memcpy(p->ht_rates, sta->ht_cap.mcs.rx_mask, 16); |
2996 | p->interop = 1; | 3005 | p->interop = 1; |
2997 | p->amsdu_enabled = 0; | 3006 | p->amsdu_enabled = 0; |
@@ -3345,7 +3354,12 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
3345 | goto out; | 3354 | goto out; |
3346 | } | 3355 | } |
3347 | 3356 | ||
3348 | ap_legacy_rates = ap->supp_rates[IEEE80211_BAND_2GHZ]; | 3357 | if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) { |
3358 | ap_legacy_rates = ap->supp_rates[IEEE80211_BAND_2GHZ]; | ||
3359 | } else { | ||
3360 | ap_legacy_rates = | ||
3361 | ap->supp_rates[IEEE80211_BAND_5GHZ] << 5; | ||
3362 | } | ||
3349 | memcpy(ap_mcs_rates, ap->ht_cap.mcs.rx_mask, 16); | 3363 | memcpy(ap_mcs_rates, ap->ht_cap.mcs.rx_mask, 16); |
3350 | 3364 | ||
3351 | rcu_read_unlock(); | 3365 | rcu_read_unlock(); |
@@ -3422,7 +3436,13 @@ mwl8k_bss_info_changed_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
3422 | * beacons will always go out at 1 Mb/s). | 3436 | * beacons will always go out at 1 Mb/s). |
3423 | */ | 3437 | */ |
3424 | idx = ffs(vif->bss_conf.basic_rates); | 3438 | idx = ffs(vif->bss_conf.basic_rates); |
3425 | rate = idx ? mwl8k_rates_24[idx - 1].hw_value : 2; | 3439 | if (idx) |
3440 | idx--; | ||
3441 | |||
3442 | if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) | ||
3443 | rate = mwl8k_rates_24[idx].hw_value; | ||
3444 | else | ||
3445 | rate = mwl8k_rates_50[idx].hw_value; | ||
3426 | 3446 | ||
3427 | mwl8k_cmd_use_fixed_rate_ap(hw, rate, rate); | 3447 | mwl8k_cmd_use_fixed_rate_ap(hw, rate, rate); |
3428 | } | 3448 | } |