diff options
author | Lennert Buytenhek <buytenh@wantstofly.org> | 2010-01-04 15:57:59 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-01-05 17:13:32 -0500 |
commit | 13935e2cf39b124c9a2ff0349b294e0b1e2e3aef (patch) | |
tree | faf724cf39bd9d3def6c2ab2ffd84b9fd33e1e7c /drivers/net/wireless/mwl8k.c | |
parent | 610677d2f0415570a7590790e8be376a946cd08b (diff) |
mwl8k: pass in HT capabilities and rates when associating
Pass the AP's MCS rate mask to SET_RATE when associating, and make
UPDATE_STADB pass in the peer's HT caps and rates when adding a new
hardware station database entry.
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwl8k.c')
-rw-r--r-- | drivers/net/wireless/mwl8k.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 2ae6c363f374..e0301b6310f9 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -2153,7 +2153,7 @@ struct mwl8k_cmd_set_rate { | |||
2153 | 2153 | ||
2154 | static int | 2154 | static int |
2155 | mwl8k_cmd_set_rate(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 2155 | mwl8k_cmd_set_rate(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
2156 | u32 legacy_rate_mask) | 2156 | u32 legacy_rate_mask, u8 *mcs_rates) |
2157 | { | 2157 | { |
2158 | struct mwl8k_cmd_set_rate *cmd; | 2158 | struct mwl8k_cmd_set_rate *cmd; |
2159 | int rc; | 2159 | int rc; |
@@ -2165,6 +2165,7 @@ mwl8k_cmd_set_rate(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
2165 | cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE); | 2165 | cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE); |
2166 | cmd->header.length = cpu_to_le16(sizeof(*cmd)); | 2166 | cmd->header.length = cpu_to_le16(sizeof(*cmd)); |
2167 | legacy_rate_mask_to_array(cmd->legacy_rates, legacy_rate_mask); | 2167 | legacy_rate_mask_to_array(cmd->legacy_rates, legacy_rate_mask); |
2168 | memcpy(cmd->mcs_set, mcs_rates, 16); | ||
2168 | 2169 | ||
2169 | rc = mwl8k_post_cmd(hw, &cmd->header); | 2170 | rc = mwl8k_post_cmd(hw, &cmd->header); |
2170 | kfree(cmd); | 2171 | kfree(cmd); |
@@ -2666,7 +2667,7 @@ struct mwl8k_cmd_update_stadb { | |||
2666 | 2667 | ||
2667 | static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw, | 2668 | static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw, |
2668 | struct ieee80211_vif *vif, | 2669 | struct ieee80211_vif *vif, |
2669 | u8 *addr, u32 legacy_rate_mask) | 2670 | struct ieee80211_sta *sta) |
2670 | { | 2671 | { |
2671 | struct mwl8k_cmd_update_stadb *cmd; | 2672 | struct mwl8k_cmd_update_stadb *cmd; |
2672 | struct peer_capability_info *p; | 2673 | struct peer_capability_info *p; |
@@ -2679,12 +2680,18 @@ static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw, | |||
2679 | cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB); | 2680 | cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB); |
2680 | cmd->header.length = cpu_to_le16(sizeof(*cmd)); | 2681 | cmd->header.length = cpu_to_le16(sizeof(*cmd)); |
2681 | cmd->action = cpu_to_le32(MWL8K_STA_DB_MODIFY_ENTRY); | 2682 | cmd->action = cpu_to_le32(MWL8K_STA_DB_MODIFY_ENTRY); |
2682 | memcpy(cmd->peer_addr, addr, ETH_ALEN); | 2683 | memcpy(cmd->peer_addr, sta->addr, ETH_ALEN); |
2683 | 2684 | ||
2684 | p = &cmd->peer_info; | 2685 | p = &cmd->peer_info; |
2685 | p->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT; | 2686 | p->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT; |
2686 | p->basic_caps = cpu_to_le16(vif->bss_conf.assoc_capability); | 2687 | p->basic_caps = cpu_to_le16(vif->bss_conf.assoc_capability); |
2687 | legacy_rate_mask_to_array(p->legacy_rates, legacy_rate_mask); | 2688 | p->ht_support = sta->ht_cap.ht_supported; |
2689 | p->ht_caps = sta->ht_cap.cap; | ||
2690 | p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) | | ||
2691 | ((sta->ht_cap.ampdu_density & 7) << 2); | ||
2692 | legacy_rate_mask_to_array(p->legacy_rates, | ||
2693 | sta->supp_rates[IEEE80211_BAND_2GHZ]); | ||
2694 | memcpy(p->ht_rates, sta->ht_cap.mcs.rx_mask, 16); | ||
2688 | p->interop = 1; | 2695 | p->interop = 1; |
2689 | p->amsdu_enabled = 0; | 2696 | p->amsdu_enabled = 0; |
2690 | 2697 | ||
@@ -2967,6 +2974,7 @@ static void mwl8k_bss_info_changed(struct ieee80211_hw *hw, | |||
2967 | { | 2974 | { |
2968 | struct mwl8k_priv *priv = hw->priv; | 2975 | struct mwl8k_priv *priv = hw->priv; |
2969 | u32 ap_legacy_rates; | 2976 | u32 ap_legacy_rates; |
2977 | u8 ap_mcs_rates[16]; | ||
2970 | int rc; | 2978 | int rc; |
2971 | 2979 | ||
2972 | if (mwl8k_fw_lock(hw)) | 2980 | if (mwl8k_fw_lock(hw)) |
@@ -2979,12 +2987,11 @@ static void mwl8k_bss_info_changed(struct ieee80211_hw *hw, | |||
2979 | priv->capture_beacon = false; | 2987 | priv->capture_beacon = false; |
2980 | 2988 | ||
2981 | /* | 2989 | /* |
2982 | * Get the AP's legacy rates. | 2990 | * Get the AP's legacy and MCS rates. |
2983 | */ | 2991 | */ |
2984 | ap_legacy_rates = 0; | 2992 | ap_legacy_rates = 0; |
2985 | if (vif->bss_conf.assoc) { | 2993 | if (vif->bss_conf.assoc) { |
2986 | struct ieee80211_sta *ap; | 2994 | struct ieee80211_sta *ap; |
2987 | |||
2988 | rcu_read_lock(); | 2995 | rcu_read_lock(); |
2989 | 2996 | ||
2990 | ap = ieee80211_find_sta(vif, vif->bss_conf.bssid); | 2997 | ap = ieee80211_find_sta(vif, vif->bss_conf.bssid); |
@@ -2994,12 +3001,13 @@ static void mwl8k_bss_info_changed(struct ieee80211_hw *hw, | |||
2994 | } | 3001 | } |
2995 | 3002 | ||
2996 | ap_legacy_rates = ap->supp_rates[IEEE80211_BAND_2GHZ]; | 3003 | ap_legacy_rates = ap->supp_rates[IEEE80211_BAND_2GHZ]; |
3004 | memcpy(ap_mcs_rates, ap->ht_cap.mcs.rx_mask, 16); | ||
2997 | 3005 | ||
2998 | rcu_read_unlock(); | 3006 | rcu_read_unlock(); |
2999 | } | 3007 | } |
3000 | 3008 | ||
3001 | if ((changed & BSS_CHANGED_ASSOC) && vif->bss_conf.assoc) { | 3009 | if ((changed & BSS_CHANGED_ASSOC) && vif->bss_conf.assoc) { |
3002 | rc = mwl8k_cmd_set_rate(hw, vif, ap_legacy_rates); | 3010 | rc = mwl8k_cmd_set_rate(hw, vif, ap_legacy_rates, ap_mcs_rates); |
3003 | if (rc) | 3011 | if (rc) |
3004 | goto out; | 3012 | goto out; |
3005 | 3013 | ||
@@ -3186,8 +3194,7 @@ struct mwl8k_sta_notify_item | |||
3186 | struct list_head list; | 3194 | struct list_head list; |
3187 | struct ieee80211_vif *vif; | 3195 | struct ieee80211_vif *vif; |
3188 | enum sta_notify_cmd cmd; | 3196 | enum sta_notify_cmd cmd; |
3189 | u8 addr[ETH_ALEN]; | 3197 | struct ieee80211_sta sta; |
3190 | u32 legacy_rate_mask; | ||
3191 | }; | 3198 | }; |
3192 | 3199 | ||
3193 | static void mwl8k_sta_notify_worker(struct work_struct *work) | 3200 | static void mwl8k_sta_notify_worker(struct work_struct *work) |
@@ -3209,19 +3216,18 @@ static void mwl8k_sta_notify_worker(struct work_struct *work) | |||
3209 | if (s->cmd == STA_NOTIFY_ADD) { | 3216 | if (s->cmd == STA_NOTIFY_ADD) { |
3210 | int rc; | 3217 | int rc; |
3211 | 3218 | ||
3212 | rc = mwl8k_cmd_update_stadb_add(hw, s->vif, | 3219 | rc = mwl8k_cmd_update_stadb_add(hw, s->vif, &s->sta); |
3213 | s->addr, s->legacy_rate_mask); | ||
3214 | if (rc >= 0) { | 3220 | if (rc >= 0) { |
3215 | struct ieee80211_sta *sta; | 3221 | struct ieee80211_sta *sta; |
3216 | 3222 | ||
3217 | rcu_read_lock(); | 3223 | rcu_read_lock(); |
3218 | sta = ieee80211_find_sta(s->vif, s->addr); | 3224 | sta = ieee80211_find_sta(s->vif, s->sta.addr); |
3219 | if (sta != NULL) | 3225 | if (sta != NULL) |
3220 | MWL8K_STA(sta)->peer_id = rc; | 3226 | MWL8K_STA(sta)->peer_id = rc; |
3221 | rcu_read_unlock(); | 3227 | rcu_read_unlock(); |
3222 | } | 3228 | } |
3223 | } else { | 3229 | } else { |
3224 | mwl8k_cmd_update_stadb_del(hw, s->vif, s->addr); | 3230 | mwl8k_cmd_update_stadb_del(hw, s->vif, s->sta.addr); |
3225 | } | 3231 | } |
3226 | 3232 | ||
3227 | kfree(s); | 3233 | kfree(s); |
@@ -3245,8 +3251,7 @@ mwl8k_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
3245 | if (s != NULL) { | 3251 | if (s != NULL) { |
3246 | s->vif = vif; | 3252 | s->vif = vif; |
3247 | s->cmd = cmd; | 3253 | s->cmd = cmd; |
3248 | memcpy(s->addr, sta->addr, ETH_ALEN); | 3254 | s->sta = *sta; |
3249 | s->legacy_rate_mask = sta->supp_rates[IEEE80211_BAND_2GHZ]; | ||
3250 | 3255 | ||
3251 | spin_lock(&priv->sta_notify_list_lock); | 3256 | spin_lock(&priv->sta_notify_list_lock); |
3252 | list_add_tail(&s->list, &priv->sta_notify_list); | 3257 | list_add_tail(&s->list, &priv->sta_notify_list); |