aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2011-09-19 06:51:42 -0400
committerLuciano Coelho <coelho@ti.com>2011-09-23 08:59:45 -0400
commitaf7fbb28efff0c0d8fc0852ad6622e5437a7611e (patch)
tree53afcd5afb6666c61c52a901b706689a1aab43d9
parent68eaaf6ee5ac35d8e592834219cee9c9e88fdb24 (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.c19
-rw-r--r--drivers/net/wireless/wl12xx/init.c17
-rw-r--r--drivers/net/wireless/wl12xx/main.c79
-rw-r--r--drivers/net/wireless/wl12xx/scan.c23
-rw-r--r--drivers/net/wireless/wl12xx/tx.c23
-rw-r--r--drivers/net/wireless/wl12xx/tx.h5
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h1
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
1134out: 1134out:
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
120out: 121out:
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
149out: 151out:
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
178out: 181out:
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
2238static void wl1271_set_band_rate(struct wl1271 *wl) 2240static 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
2250static bool wl12xx_is_roc(struct wl1271 *wl) 2246static 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
4108static 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
4101static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) 4131static 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
32void wl1271_scan_complete_work(struct work_struct *work) 33void wl1271_scan_complete_work(struct work_struct *work)
33{ 34{
@@ -243,14 +244,17 @@ out:
243void wl1271_scan_stm(struct wl1271 *wl) 244void 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
453u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) 453u32 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
992u32 wl1271_tx_min_rate_get(struct wl1271 *wl) 993u32 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);
209void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues); 209void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues);
210void wl1271_tx_flush(struct wl1271 *wl); 210void wl1271_tx_flush(struct wl1271 *wl);
211u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); 211u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
212u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set); 212u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set,
213u32 wl1271_tx_min_rate_get(struct wl1271 *wl); 213 enum ieee80211_band rate_band);
214u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set);
214u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct sk_buff *skb); 215u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct sk_buff *skb);
215void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid); 216void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid);
216void wl1271_handle_tx_low_watermark(struct wl1271 *wl); 217void 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;