diff options
author | Eliad Peller <eliad@wizery.com> | 2011-09-19 06:51:42 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2011-09-23 08:59:45 -0400 |
commit | af7fbb28efff0c0d8fc0852ad6622e5437a7611e (patch) | |
tree | 53afcd5afb6666c61c52a901b706689a1aab43d9 | |
parent | 68eaaf6ee5ac35d8e592834219cee9c9e88fdb24 (diff) |
wl12xx: implement set_bitrate_mask callback
Save the configured bitrate, and use the min allowed rate
as the basic rate (e.g. when scanning).
Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
-rw-r--r-- | drivers/net/wireless/wl12xx/cmd.c | 19 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/init.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 79 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/scan.c | 23 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.c | 23 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl12xx.h | 1 |
7 files changed, 102 insertions, 65 deletions
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 51be8f7fbb88..287fe95ecb40 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c | |||
@@ -1112,6 +1112,7 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl, | |||
1112 | { | 1112 | { |
1113 | struct sk_buff *skb; | 1113 | struct sk_buff *skb; |
1114 | int ret; | 1114 | int ret; |
1115 | u32 rate; | ||
1115 | 1116 | ||
1116 | skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len, | 1117 | skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len, |
1117 | ie, ie_len); | 1118 | ie, ie_len); |
@@ -1122,14 +1123,13 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl, | |||
1122 | 1123 | ||
1123 | wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len); | 1124 | wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len); |
1124 | 1125 | ||
1126 | rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]); | ||
1125 | if (band == IEEE80211_BAND_2GHZ) | 1127 | if (band == IEEE80211_BAND_2GHZ) |
1126 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, | 1128 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, |
1127 | skb->data, skb->len, 0, | 1129 | skb->data, skb->len, 0, rate); |
1128 | wl->conf.tx.basic_rate); | ||
1129 | else | 1130 | else |
1130 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, | 1131 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, |
1131 | skb->data, skb->len, 0, | 1132 | skb->data, skb->len, 0, rate); |
1132 | wl->conf.tx.basic_rate_5); | ||
1133 | 1133 | ||
1134 | out: | 1134 | out: |
1135 | dev_kfree_skb(skb); | 1135 | dev_kfree_skb(skb); |
@@ -1140,6 +1140,7 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, | |||
1140 | struct sk_buff *skb) | 1140 | struct sk_buff *skb) |
1141 | { | 1141 | { |
1142 | int ret; | 1142 | int ret; |
1143 | u32 rate; | ||
1143 | 1144 | ||
1144 | if (!skb) | 1145 | if (!skb) |
1145 | skb = ieee80211_ap_probereq_get(wl->hw, wl->vif); | 1146 | skb = ieee80211_ap_probereq_get(wl->hw, wl->vif); |
@@ -1148,14 +1149,13 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, | |||
1148 | 1149 | ||
1149 | wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len); | 1150 | wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len); |
1150 | 1151 | ||
1152 | rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[wl->band]); | ||
1151 | if (wl->band == IEEE80211_BAND_2GHZ) | 1153 | if (wl->band == IEEE80211_BAND_2GHZ) |
1152 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, | 1154 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, |
1153 | skb->data, skb->len, 0, | 1155 | skb->data, skb->len, 0, rate); |
1154 | wl->conf.tx.basic_rate); | ||
1155 | else | 1156 | else |
1156 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, | 1157 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, |
1157 | skb->data, skb->len, 0, | 1158 | skb->data, skb->len, 0, rate); |
1158 | wl->conf.tx.basic_rate_5); | ||
1159 | 1159 | ||
1160 | if (ret < 0) | 1160 | if (ret < 0) |
1161 | wl1271_error("Unable to set ap probe request template."); | 1161 | wl1271_error("Unable to set ap probe request template."); |
@@ -1448,7 +1448,8 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid) | |||
1448 | sta_rates |= sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET; | 1448 | sta_rates |= sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET; |
1449 | 1449 | ||
1450 | cmd->supported_rates = | 1450 | cmd->supported_rates = |
1451 | cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates)); | 1451 | cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates, |
1452 | wl->band)); | ||
1452 | 1453 | ||
1453 | wl1271_debug(DEBUG_CMD, "new peer rates=0x%x queues=0x%x", | 1454 | wl1271_debug(DEBUG_CMD, "new peer rates=0x%x queues=0x%x", |
1454 | cmd->supported_rates, sta->uapsd_queues); | 1455 | cmd->supported_rates, sta->uapsd_queues); |
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index 09515f5e5e1d..04db64c94e9a 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c | |||
@@ -103,6 +103,7 @@ static int wl1271_ap_init_deauth_template(struct wl1271 *wl) | |||
103 | { | 103 | { |
104 | struct wl12xx_disconn_template *tmpl; | 104 | struct wl12xx_disconn_template *tmpl; |
105 | int ret; | 105 | int ret; |
106 | u32 rate; | ||
106 | 107 | ||
107 | tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL); | 108 | tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL); |
108 | if (!tmpl) { | 109 | if (!tmpl) { |
@@ -113,9 +114,9 @@ static int wl1271_ap_init_deauth_template(struct wl1271 *wl) | |||
113 | tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 114 | tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
114 | IEEE80211_STYPE_DEAUTH); | 115 | IEEE80211_STYPE_DEAUTH); |
115 | 116 | ||
117 | rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); | ||
116 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, | 118 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, |
117 | tmpl, sizeof(*tmpl), 0, | 119 | tmpl, sizeof(*tmpl), 0, rate); |
118 | wl1271_tx_min_rate_get(wl)); | ||
119 | 120 | ||
120 | out: | 121 | out: |
121 | kfree(tmpl); | 122 | kfree(tmpl); |
@@ -126,6 +127,7 @@ static int wl1271_ap_init_null_template(struct wl1271 *wl) | |||
126 | { | 127 | { |
127 | struct ieee80211_hdr_3addr *nullfunc; | 128 | struct ieee80211_hdr_3addr *nullfunc; |
128 | int ret; | 129 | int ret; |
130 | u32 rate; | ||
129 | 131 | ||
130 | nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL); | 132 | nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL); |
131 | if (!nullfunc) { | 133 | if (!nullfunc) { |
@@ -142,9 +144,9 @@ static int wl1271_ap_init_null_template(struct wl1271 *wl) | |||
142 | memcpy(nullfunc->addr2, wl->mac_addr, ETH_ALEN); | 144 | memcpy(nullfunc->addr2, wl->mac_addr, ETH_ALEN); |
143 | memcpy(nullfunc->addr3, wl->mac_addr, ETH_ALEN); | 145 | memcpy(nullfunc->addr3, wl->mac_addr, ETH_ALEN); |
144 | 146 | ||
147 | rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); | ||
145 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc, | 148 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc, |
146 | sizeof(*nullfunc), 0, | 149 | sizeof(*nullfunc), 0, rate); |
147 | wl1271_tx_min_rate_get(wl)); | ||
148 | 150 | ||
149 | out: | 151 | out: |
150 | kfree(nullfunc); | 152 | kfree(nullfunc); |
@@ -155,6 +157,7 @@ static int wl1271_ap_init_qos_null_template(struct wl1271 *wl) | |||
155 | { | 157 | { |
156 | struct ieee80211_qos_hdr *qosnull; | 158 | struct ieee80211_qos_hdr *qosnull; |
157 | int ret; | 159 | int ret; |
160 | u32 rate; | ||
158 | 161 | ||
159 | qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL); | 162 | qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL); |
160 | if (!qosnull) { | 163 | if (!qosnull) { |
@@ -171,9 +174,9 @@ static int wl1271_ap_init_qos_null_template(struct wl1271 *wl) | |||
171 | memcpy(qosnull->addr2, wl->mac_addr, ETH_ALEN); | 174 | memcpy(qosnull->addr2, wl->mac_addr, ETH_ALEN); |
172 | memcpy(qosnull->addr3, wl->mac_addr, ETH_ALEN); | 175 | memcpy(qosnull->addr3, wl->mac_addr, ETH_ALEN); |
173 | 176 | ||
177 | rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); | ||
174 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull, | 178 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull, |
175 | sizeof(*qosnull), 0, | 179 | sizeof(*qosnull), 0, rate); |
176 | wl1271_tx_min_rate_get(wl)); | ||
177 | 180 | ||
178 | out: | 181 | out: |
179 | kfree(qosnull); | 182 | kfree(qosnull); |
@@ -498,7 +501,7 @@ int wl1271_init_ap_rates(struct wl1271 *wl) | |||
498 | return ret; | 501 | return ret; |
499 | 502 | ||
500 | /* use the min basic rate for AP broadcast/multicast */ | 503 | /* use the min basic rate for AP broadcast/multicast */ |
501 | rc.enabled_rates = wl1271_tx_min_rate_get(wl); | 504 | rc.enabled_rates = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); |
502 | rc.short_retry_limit = 10; | 505 | rc.short_retry_limit = 10; |
503 | rc.long_retry_limit = 10; | 506 | rc.long_retry_limit = 10; |
504 | rc.aflags = 0; | 507 | rc.aflags = 0; |
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 02b5c007d1bf..384ba1944396 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -2099,6 +2099,8 @@ deinit: | |||
2099 | wl->time_offset = 0; | 2099 | wl->time_offset = 0; |
2100 | wl->session_counter = 0; | 2100 | wl->session_counter = 0; |
2101 | wl->rate_set = CONF_TX_RATE_MASK_BASIC; | 2101 | wl->rate_set = CONF_TX_RATE_MASK_BASIC; |
2102 | wl->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate; | ||
2103 | wl->bitrate_masks[IEEE80211_BAND_5GHZ] = wl->conf.tx.basic_rate_5; | ||
2102 | wl->vif = NULL; | 2104 | wl->vif = NULL; |
2103 | wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT; | 2105 | wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT; |
2104 | wl1271_free_ap_keys(wl); | 2106 | wl1271_free_ap_keys(wl); |
@@ -2237,14 +2239,8 @@ out: | |||
2237 | 2239 | ||
2238 | static void wl1271_set_band_rate(struct wl1271 *wl) | 2240 | static void wl1271_set_band_rate(struct wl1271 *wl) |
2239 | { | 2241 | { |
2240 | if (wl->band == IEEE80211_BAND_2GHZ) { | 2242 | wl->basic_rate_set = wl->bitrate_masks[wl->band]; |
2241 | wl->basic_rate_set = wl->conf.tx.basic_rate; | 2243 | wl->rate_set = wl->basic_rate_set; |
2242 | wl->rate_set = wl->conf.tx.basic_rate; | ||
2243 | } else { | ||
2244 | wl->basic_rate_set = wl->conf.tx.basic_rate_5; | ||
2245 | wl->rate_set = wl->conf.tx.basic_rate_5; | ||
2246 | } | ||
2247 | |||
2248 | } | 2244 | } |
2249 | 2245 | ||
2250 | static bool wl12xx_is_roc(struct wl1271 *wl) | 2246 | static bool wl12xx_is_roc(struct wl1271 *wl) |
@@ -2273,7 +2269,7 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle) | |||
2273 | if (ret < 0) | 2269 | if (ret < 0) |
2274 | goto out; | 2270 | goto out; |
2275 | } | 2271 | } |
2276 | wl->rate_set = wl1271_tx_min_rate_get(wl); | 2272 | wl->rate_set = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); |
2277 | ret = wl1271_acx_sta_rate_policies(wl); | 2273 | ret = wl1271_acx_sta_rate_policies(wl); |
2278 | if (ret < 0) | 2274 | if (ret < 0) |
2279 | goto out; | 2275 | goto out; |
@@ -2370,7 +2366,8 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
2370 | if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) | 2366 | if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) |
2371 | wl1271_set_band_rate(wl); | 2367 | wl1271_set_band_rate(wl); |
2372 | 2368 | ||
2373 | wl->basic_rate = wl1271_tx_min_rate_get(wl); | 2369 | wl->basic_rate = |
2370 | wl1271_tx_min_rate_get(wl, wl->basic_rate_set); | ||
2374 | ret = wl1271_acx_sta_rate_policies(wl); | 2371 | ret = wl1271_acx_sta_rate_policies(wl); |
2375 | if (ret < 0) | 2372 | if (ret < 0) |
2376 | wl1271_warning("rate policy for channel " | 2373 | wl1271_warning("rate policy for channel " |
@@ -3214,6 +3211,7 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, | |||
3214 | 3211 | ||
3215 | if ((changed & BSS_CHANGED_BEACON)) { | 3212 | if ((changed & BSS_CHANGED_BEACON)) { |
3216 | struct ieee80211_hdr *hdr; | 3213 | struct ieee80211_hdr *hdr; |
3214 | u32 min_rate; | ||
3217 | int ieoffset = offsetof(struct ieee80211_mgmt, | 3215 | int ieoffset = offsetof(struct ieee80211_mgmt, |
3218 | u.beacon.variable); | 3216 | u.beacon.variable); |
3219 | struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif); | 3217 | struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif); |
@@ -3229,12 +3227,13 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, | |||
3229 | dev_kfree_skb(beacon); | 3227 | dev_kfree_skb(beacon); |
3230 | goto out; | 3228 | goto out; |
3231 | } | 3229 | } |
3230 | min_rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); | ||
3232 | tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON : | 3231 | tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON : |
3233 | CMD_TEMPL_BEACON; | 3232 | CMD_TEMPL_BEACON; |
3234 | ret = wl1271_cmd_template_set(wl, tmpl_id, | 3233 | ret = wl1271_cmd_template_set(wl, tmpl_id, |
3235 | beacon->data, | 3234 | beacon->data, |
3236 | beacon->len, 0, | 3235 | beacon->len, 0, |
3237 | wl1271_tx_min_rate_get(wl)); | 3236 | min_rate); |
3238 | if (ret < 0) { | 3237 | if (ret < 0) { |
3239 | dev_kfree_skb(beacon); | 3238 | dev_kfree_skb(beacon); |
3240 | goto out; | 3239 | goto out; |
@@ -3261,13 +3260,13 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, | |||
3261 | ret = wl1271_ap_set_probe_resp_tmpl(wl, | 3260 | ret = wl1271_ap_set_probe_resp_tmpl(wl, |
3262 | beacon->data, | 3261 | beacon->data, |
3263 | beacon->len, | 3262 | beacon->len, |
3264 | wl1271_tx_min_rate_get(wl)); | 3263 | min_rate); |
3265 | else | 3264 | else |
3266 | ret = wl1271_cmd_template_set(wl, | 3265 | ret = wl1271_cmd_template_set(wl, |
3267 | CMD_TEMPL_PROBE_RESPONSE, | 3266 | CMD_TEMPL_PROBE_RESPONSE, |
3268 | beacon->data, | 3267 | beacon->data, |
3269 | beacon->len, 0, | 3268 | beacon->len, 0, |
3270 | wl1271_tx_min_rate_get(wl)); | 3269 | min_rate); |
3271 | dev_kfree_skb(beacon); | 3270 | dev_kfree_skb(beacon); |
3272 | if (ret < 0) | 3271 | if (ret < 0) |
3273 | goto out; | 3272 | goto out; |
@@ -3288,8 +3287,10 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl, | |||
3288 | if ((changed & BSS_CHANGED_BASIC_RATES)) { | 3287 | if ((changed & BSS_CHANGED_BASIC_RATES)) { |
3289 | u32 rates = bss_conf->basic_rates; | 3288 | u32 rates = bss_conf->basic_rates; |
3290 | 3289 | ||
3291 | wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates); | 3290 | wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates, |
3292 | wl->basic_rate = wl1271_tx_min_rate_get(wl); | 3291 | wl->band); |
3292 | wl->basic_rate = wl1271_tx_min_rate_get(wl, | ||
3293 | wl->basic_rate_set); | ||
3293 | 3294 | ||
3294 | ret = wl1271_init_ap_rates(wl); | 3295 | ret = wl1271_init_ap_rates(wl); |
3295 | if (ret < 0) { | 3296 | if (ret < 0) { |
@@ -3471,12 +3472,15 @@ sta_not_found: | |||
3471 | * to use with control frames. | 3472 | * to use with control frames. |
3472 | */ | 3473 | */ |
3473 | rates = bss_conf->basic_rates; | 3474 | rates = bss_conf->basic_rates; |
3474 | wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, | 3475 | wl->basic_rate_set = |
3475 | rates); | 3476 | wl1271_tx_enabled_rates_get(wl, rates, |
3476 | wl->basic_rate = wl1271_tx_min_rate_get(wl); | 3477 | wl->band); |
3478 | wl->basic_rate = | ||
3479 | wl1271_tx_min_rate_get(wl, wl->basic_rate_set); | ||
3477 | if (sta_rate_set) | 3480 | if (sta_rate_set) |
3478 | wl->rate_set = wl1271_tx_enabled_rates_get(wl, | 3481 | wl->rate_set = wl1271_tx_enabled_rates_get(wl, |
3479 | sta_rate_set); | 3482 | sta_rate_set, |
3483 | wl->band); | ||
3480 | ret = wl1271_acx_sta_rate_policies(wl); | 3484 | ret = wl1271_acx_sta_rate_policies(wl); |
3481 | if (ret < 0) | 3485 | if (ret < 0) |
3482 | goto out; | 3486 | goto out; |
@@ -3523,7 +3527,8 @@ sta_not_found: | |||
3523 | 3527 | ||
3524 | /* revert back to minimum rates for the current band */ | 3528 | /* revert back to minimum rates for the current band */ |
3525 | wl1271_set_band_rate(wl); | 3529 | wl1271_set_band_rate(wl); |
3526 | wl->basic_rate = wl1271_tx_min_rate_get(wl); | 3530 | wl->basic_rate = |
3531 | wl1271_tx_min_rate_get(wl, wl->basic_rate_set); | ||
3527 | ret = wl1271_acx_sta_rate_policies(wl); | 3532 | ret = wl1271_acx_sta_rate_policies(wl); |
3528 | if (ret < 0) | 3533 | if (ret < 0) |
3529 | goto out; | 3534 | goto out; |
@@ -3574,9 +3579,11 @@ sta_not_found: | |||
3574 | 3579 | ||
3575 | if (bss_conf->ibss_joined) { | 3580 | if (bss_conf->ibss_joined) { |
3576 | u32 rates = bss_conf->basic_rates; | 3581 | u32 rates = bss_conf->basic_rates; |
3577 | wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, | 3582 | wl->basic_rate_set = |
3578 | rates); | 3583 | wl1271_tx_enabled_rates_get(wl, rates, |
3579 | wl->basic_rate = wl1271_tx_min_rate_get(wl); | 3584 | wl->band); |
3585 | wl->basic_rate = | ||
3586 | wl1271_tx_min_rate_get(wl, wl->basic_rate_set); | ||
3580 | 3587 | ||
3581 | /* by default, use 11b + OFDM rates */ | 3588 | /* by default, use 11b + OFDM rates */ |
3582 | wl->rate_set = CONF_TX_IBSS_DEFAULT_RATES; | 3589 | wl->rate_set = CONF_TX_IBSS_DEFAULT_RATES; |
@@ -4098,6 +4105,29 @@ out: | |||
4098 | return ret; | 4105 | return ret; |
4099 | } | 4106 | } |
4100 | 4107 | ||
4108 | static int wl12xx_set_bitrate_mask(struct ieee80211_hw *hw, | ||
4109 | struct ieee80211_vif *vif, | ||
4110 | const struct cfg80211_bitrate_mask *mask) | ||
4111 | { | ||
4112 | struct wl1271 *wl = hw->priv; | ||
4113 | int i; | ||
4114 | |||
4115 | wl1271_debug(DEBUG_MAC80211, "mac80211 set_bitrate_mask 0x%x 0x%x", | ||
4116 | mask->control[NL80211_BAND_2GHZ].legacy, | ||
4117 | mask->control[NL80211_BAND_5GHZ].legacy); | ||
4118 | |||
4119 | mutex_lock(&wl->mutex); | ||
4120 | |||
4121 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) | ||
4122 | wl->bitrate_masks[i] = | ||
4123 | wl1271_tx_enabled_rates_get(wl, | ||
4124 | mask->control[i].legacy, | ||
4125 | i); | ||
4126 | mutex_unlock(&wl->mutex); | ||
4127 | |||
4128 | return 0; | ||
4129 | } | ||
4130 | |||
4101 | static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) | 4131 | static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) |
4102 | { | 4132 | { |
4103 | struct wl1271 *wl = hw->priv; | 4133 | struct wl1271 *wl = hw->priv; |
@@ -4373,6 +4403,7 @@ static const struct ieee80211_ops wl1271_ops = { | |||
4373 | .sta_remove = wl1271_op_sta_remove, | 4403 | .sta_remove = wl1271_op_sta_remove, |
4374 | .ampdu_action = wl1271_op_ampdu_action, | 4404 | .ampdu_action = wl1271_op_ampdu_action, |
4375 | .tx_frames_pending = wl1271_tx_frames_pending, | 4405 | .tx_frames_pending = wl1271_tx_frames_pending, |
4406 | .set_bitrate_mask = wl12xx_set_bitrate_mask, | ||
4376 | CFG80211_TESTMODE_CMD(wl1271_tm_cmd) | 4407 | CFG80211_TESTMODE_CMD(wl1271_tm_cmd) |
4377 | }; | 4408 | }; |
4378 | 4409 | ||
@@ -4793,6 +4824,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void) | |||
4793 | 4824 | ||
4794 | /* Apply default driver configuration. */ | 4825 | /* Apply default driver configuration. */ |
4795 | wl1271_conf_init(wl); | 4826 | wl1271_conf_init(wl); |
4827 | wl->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate; | ||
4828 | wl->bitrate_masks[IEEE80211_BAND_5GHZ] = wl->conf.tx.basic_rate_5; | ||
4796 | 4829 | ||
4797 | order = get_order(WL1271_AGGR_BUFFER_SIZE); | 4830 | order = get_order(WL1271_AGGR_BUFFER_SIZE); |
4798 | wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); | 4831 | wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); |
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 08f7e826d27b..128ccb79318c 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "scan.h" | 28 | #include "scan.h" |
29 | #include "acx.h" | 29 | #include "acx.h" |
30 | #include "ps.h" | 30 | #include "ps.h" |
31 | #include "tx.h" | ||
31 | 32 | ||
32 | void wl1271_scan_complete_work(struct work_struct *work) | 33 | void wl1271_scan_complete_work(struct work_struct *work) |
33 | { | 34 | { |
@@ -243,14 +244,17 @@ out: | |||
243 | void wl1271_scan_stm(struct wl1271 *wl) | 244 | void wl1271_scan_stm(struct wl1271 *wl) |
244 | { | 245 | { |
245 | int ret = 0; | 246 | int ret = 0; |
247 | enum ieee80211_band band; | ||
248 | u32 rate; | ||
246 | 249 | ||
247 | switch (wl->scan.state) { | 250 | switch (wl->scan.state) { |
248 | case WL1271_SCAN_STATE_IDLE: | 251 | case WL1271_SCAN_STATE_IDLE: |
249 | break; | 252 | break; |
250 | 253 | ||
251 | case WL1271_SCAN_STATE_2GHZ_ACTIVE: | 254 | case WL1271_SCAN_STATE_2GHZ_ACTIVE: |
252 | ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, false, | 255 | band = IEEE80211_BAND_2GHZ; |
253 | wl->conf.tx.basic_rate); | 256 | rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]); |
257 | ret = wl1271_scan_send(wl, band, false, rate); | ||
254 | if (ret == WL1271_NOTHING_TO_SCAN) { | 258 | if (ret == WL1271_NOTHING_TO_SCAN) { |
255 | wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE; | 259 | wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE; |
256 | wl1271_scan_stm(wl); | 260 | wl1271_scan_stm(wl); |
@@ -259,8 +263,9 @@ void wl1271_scan_stm(struct wl1271 *wl) | |||
259 | break; | 263 | break; |
260 | 264 | ||
261 | case WL1271_SCAN_STATE_2GHZ_PASSIVE: | 265 | case WL1271_SCAN_STATE_2GHZ_PASSIVE: |
262 | ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true, | 266 | band = IEEE80211_BAND_2GHZ; |
263 | wl->conf.tx.basic_rate); | 267 | rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]); |
268 | ret = wl1271_scan_send(wl, band, true, rate); | ||
264 | if (ret == WL1271_NOTHING_TO_SCAN) { | 269 | if (ret == WL1271_NOTHING_TO_SCAN) { |
265 | if (wl->enable_11a) | 270 | if (wl->enable_11a) |
266 | wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE; | 271 | wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE; |
@@ -272,8 +277,9 @@ void wl1271_scan_stm(struct wl1271 *wl) | |||
272 | break; | 277 | break; |
273 | 278 | ||
274 | case WL1271_SCAN_STATE_5GHZ_ACTIVE: | 279 | case WL1271_SCAN_STATE_5GHZ_ACTIVE: |
275 | ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, false, | 280 | band = IEEE80211_BAND_5GHZ; |
276 | wl->conf.tx.basic_rate_5); | 281 | rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]); |
282 | ret = wl1271_scan_send(wl, band, false, rate); | ||
277 | if (ret == WL1271_NOTHING_TO_SCAN) { | 283 | if (ret == WL1271_NOTHING_TO_SCAN) { |
278 | wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE; | 284 | wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE; |
279 | wl1271_scan_stm(wl); | 285 | wl1271_scan_stm(wl); |
@@ -282,8 +288,9 @@ void wl1271_scan_stm(struct wl1271 *wl) | |||
282 | break; | 288 | break; |
283 | 289 | ||
284 | case WL1271_SCAN_STATE_5GHZ_PASSIVE: | 290 | case WL1271_SCAN_STATE_5GHZ_PASSIVE: |
285 | ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, true, | 291 | band = IEEE80211_BAND_5GHZ; |
286 | wl->conf.tx.basic_rate_5); | 292 | rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]); |
293 | ret = wl1271_scan_send(wl, band, true, rate); | ||
287 | if (ret == WL1271_NOTHING_TO_SCAN) { | 294 | if (ret == WL1271_NOTHING_TO_SCAN) { |
288 | wl->scan.state = WL1271_SCAN_STATE_DONE; | 295 | wl->scan.state = WL1271_SCAN_STATE_DONE; |
289 | wl1271_scan_stm(wl); | 296 | wl1271_scan_stm(wl); |
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index f6e95e439308..bad9e29d49b0 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c | |||
@@ -450,13 +450,14 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, | |||
450 | return total_len; | 450 | return total_len; |
451 | } | 451 | } |
452 | 452 | ||
453 | u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) | 453 | u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set, |
454 | enum ieee80211_band rate_band) | ||
454 | { | 455 | { |
455 | struct ieee80211_supported_band *band; | 456 | struct ieee80211_supported_band *band; |
456 | u32 enabled_rates = 0; | 457 | u32 enabled_rates = 0; |
457 | int bit; | 458 | int bit; |
458 | 459 | ||
459 | band = wl->hw->wiphy->bands[wl->band]; | 460 | band = wl->hw->wiphy->bands[rate_band]; |
460 | for (bit = 0; bit < band->n_bitrates; bit++) { | 461 | for (bit = 0; bit < band->n_bitrates; bit++) { |
461 | if (rate_set & 0x1) | 462 | if (rate_set & 0x1) |
462 | enabled_rates |= band->bitrates[bit].hw_value; | 463 | enabled_rates |= band->bitrates[bit].hw_value; |
@@ -989,20 +990,10 @@ void wl1271_tx_flush(struct wl1271 *wl) | |||
989 | wl1271_warning("Unable to flush all TX buffers, timed out."); | 990 | wl1271_warning("Unable to flush all TX buffers, timed out."); |
990 | } | 991 | } |
991 | 992 | ||
992 | u32 wl1271_tx_min_rate_get(struct wl1271 *wl) | 993 | u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set) |
993 | { | 994 | { |
994 | int i; | 995 | if (WARN_ON(!rate_set)) |
995 | u32 rate = 0; | 996 | return 0; |
996 | |||
997 | if (!wl->basic_rate_set) { | ||
998 | WARN_ON(1); | ||
999 | wl->basic_rate_set = wl->conf.tx.basic_rate; | ||
1000 | } | ||
1001 | |||
1002 | for (i = 0; !rate; i++) { | ||
1003 | if ((wl->basic_rate_set >> i) & 0x1) | ||
1004 | rate = 1 << i; | ||
1005 | } | ||
1006 | 997 | ||
1007 | return rate; | 998 | return BIT(__ffs(rate_set)); |
1008 | } | 999 | } |
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index d6fdbf904a09..dc4f09adf088 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h | |||
@@ -209,8 +209,9 @@ void wl1271_tx_complete(struct wl1271 *wl); | |||
209 | void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues); | 209 | void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues); |
210 | void wl1271_tx_flush(struct wl1271 *wl); | 210 | void wl1271_tx_flush(struct wl1271 *wl); |
211 | u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); | 211 | u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); |
212 | u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set); | 212 | u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set, |
213 | u32 wl1271_tx_min_rate_get(struct wl1271 *wl); | 213 | enum ieee80211_band rate_band); |
214 | u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set); | ||
214 | u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct sk_buff *skb); | 215 | u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct sk_buff *skb); |
215 | void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid); | 216 | void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid); |
216 | void wl1271_handle_tx_low_watermark(struct wl1271 *wl); | 217 | void wl1271_handle_tx_low_watermark(struct wl1271 *wl); |
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 3ceb20c170bc..45f03f578e18 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h | |||
@@ -526,6 +526,7 @@ struct wl1271 { | |||
526 | u32 basic_rate_set; | 526 | u32 basic_rate_set; |
527 | u32 basic_rate; | 527 | u32 basic_rate; |
528 | u32 rate_set; | 528 | u32 rate_set; |
529 | u32 bitrate_masks[IEEE80211_NUM_BANDS]; | ||
529 | 530 | ||
530 | /* The current band */ | 531 | /* The current band */ |
531 | enum ieee80211_band band; | 532 | enum ieee80211_band band; |