aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx
diff options
context:
space:
mode:
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>2010-04-01 04:38:20 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-06 16:55:12 -0400
commitebba60c66b3aa321a84c9a90a343c91fde972066 (patch)
tree49bf6e52a558b530a864c453a695bf0d4800dbed /drivers/net/wireless/wl12xx
parent40b359c61dc496508b77d1242726e40238e62128 (diff)
wl1271: Use minimum rate for each band for control messages
Currently the mac80211 is not telling a hardware rate controlled driver a rate to use for association frames etc. So to be safe, use the lowest rate of each band for communication. Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com> Reviewed-by: Teemu Paasikivi <ext-teemu.3.paasikivi@nokia.com> Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.c27
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_conf.h13
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c98
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.h1
7 files changed, 108 insertions, 36 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index c5559efcf5a7..a29969efc861 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -447,6 +447,7 @@ struct wl1271 {
447 /* currently configured rate set */ 447 /* currently configured rate set */
448 u32 sta_rate_set; 448 u32 sta_rate_set;
449 u32 basic_rate_set; 449 u32 basic_rate_set;
450 u32 basic_rate;
450 u32 rate_set; 451 u32 rate_set;
451 452
452 /* The current band */ 453 /* The current band */
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index 8f0bd5bee6f9..621c94691e7e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -802,7 +802,7 @@ int wl1271_acx_rate_policies(struct wl1271 *wl)
802 802
803 /* configure one basic rate class */ 803 /* configure one basic rate class */
804 idx = ACX_TX_BASIC_RATE; 804 idx = ACX_TX_BASIC_RATE;
805 acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate_set); 805 acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate);
806 acx->rate_class[idx].short_retry_limit = c->short_retry_limit; 806 acx->rate_class[idx].short_retry_limit = c->short_retry_limit;
807 acx->rate_class[idx].long_retry_limit = c->long_retry_limit; 807 acx->rate_class[idx].long_retry_limit = c->long_retry_limit;
808 acx->rate_class[idx].aflags = c->aflags; 808 acx->rate_class[idx].aflags = c->aflags;
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index f11f9f47ffd5..5cee59fb8c5e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -317,18 +317,10 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
317 join->rx_config_options = cpu_to_le32(wl->rx_config); 317 join->rx_config_options = cpu_to_le32(wl->rx_config);
318 join->rx_filter_options = cpu_to_le32(wl->rx_filter); 318 join->rx_filter_options = cpu_to_le32(wl->rx_filter);
319 join->bss_type = bss_type; 319 join->bss_type = bss_type;
320 join->basic_rate_set = wl->basic_rate_set;
320 321
321 if (wl->band == IEEE80211_BAND_2GHZ) 322 if (wl->band == IEEE80211_BAND_5GHZ)
322 join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_1MBPS |
323 CONF_HW_BIT_RATE_2MBPS |
324 CONF_HW_BIT_RATE_5_5MBPS |
325 CONF_HW_BIT_RATE_11MBPS);
326 else {
327 join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ; 323 join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ;
328 join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_6MBPS |
329 CONF_HW_BIT_RATE_12MBPS |
330 CONF_HW_BIT_RATE_24MBPS);
331 }
332 324
333 join->beacon_interval = cpu_to_le16(wl->beacon_int); 325 join->beacon_interval = cpu_to_le16(wl->beacon_int);
334 join->dtim_interval = WL1271_DEFAULT_DTIM_PERIOD; 326 join->dtim_interval = WL1271_DEFAULT_DTIM_PERIOD;
@@ -581,17 +573,21 @@ int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
581 struct wl1271_cmd_trigger_scan_to *trigger = NULL; 573 struct wl1271_cmd_trigger_scan_to *trigger = NULL;
582 struct wl1271_cmd_scan *params = NULL; 574 struct wl1271_cmd_scan *params = NULL;
583 struct ieee80211_channel *channels; 575 struct ieee80211_channel *channels;
576 u32 rate;
584 int i, j, n_ch, ret; 577 int i, j, n_ch, ret;
585 u16 scan_options = 0; 578 u16 scan_options = 0;
586 u8 ieee_band; 579 u8 ieee_band;
587 580
588 if (band == WL1271_SCAN_BAND_2_4_GHZ) 581 if (band == WL1271_SCAN_BAND_2_4_GHZ) {
589 ieee_band = IEEE80211_BAND_2GHZ; 582 ieee_band = IEEE80211_BAND_2GHZ;
590 else if (band == WL1271_SCAN_BAND_DUAL && wl1271_11a_enabled()) 583 rate = wl->conf.tx.basic_rate;
584 } else if (band == WL1271_SCAN_BAND_DUAL && wl1271_11a_enabled()) {
591 ieee_band = IEEE80211_BAND_2GHZ; 585 ieee_band = IEEE80211_BAND_2GHZ;
592 else if (band == WL1271_SCAN_BAND_5_GHZ && wl1271_11a_enabled()) 586 rate = wl->conf.tx.basic_rate;
587 } else if (band == WL1271_SCAN_BAND_5_GHZ && wl1271_11a_enabled()) {
593 ieee_band = IEEE80211_BAND_5GHZ; 588 ieee_band = IEEE80211_BAND_5GHZ;
594 else 589 rate = wl->conf.tx.basic_rate_5;
590 } else
595 return -EINVAL; 591 return -EINVAL;
596 592
597 if (wl->hw->wiphy->bands[ieee_band]->channels == NULL) 593 if (wl->hw->wiphy->bands[ieee_band]->channels == NULL)
@@ -618,8 +614,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
618 params->params.scan_options = cpu_to_le16(scan_options); 614 params->params.scan_options = cpu_to_le16(scan_options);
619 615
620 params->params.num_probe_requests = probe_requests; 616 params->params.num_probe_requests = probe_requests;
621 /* Let the fw autodetect suitable tx_rate for probes */ 617 params->params.tx_rate = rate;
622 params->params.tx_rate = 0;
623 params->params.tid_trigger = 0; 618 params->params.tid_trigger = 0;
624 params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; 619 params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
625 620
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h
index 82b5dabb6e8d..0b34b6261176 100644
--- a/drivers/net/wireless/wl12xx/wl1271_conf.h
+++ b/drivers/net/wireless/wl12xx/wl1271_conf.h
@@ -674,6 +674,19 @@ struct conf_tx_settings {
674 */ 674 */
675 u16 tx_compl_threshold; 675 u16 tx_compl_threshold;
676 676
677 /*
678 * The rate used for control messages and scanning on the 2.4GHz band
679 *
680 * Range: CONF_HW_BIT_RATE_* bit mask
681 */
682 u32 basic_rate;
683
684 /*
685 * The rate used for control messages and scanning on the 5GHz band
686 *
687 * Range: CONF_HW_BIT_RATE_* bit mask
688 */
689 u32 basic_rate_5;
677}; 690};
678 691
679enum { 692enum {
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 2494c967bb34..ca5cd325fac7 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -116,8 +116,7 @@ static struct conf_drv_settings default_conf = {
116 .tx = { 116 .tx = {
117 .tx_energy_detection = 0, 117 .tx_energy_detection = 0,
118 .rc_conf = { 118 .rc_conf = {
119 .enabled_rates = CONF_HW_BIT_RATE_1MBPS | 119 .enabled_rates = 0,
120 CONF_HW_BIT_RATE_2MBPS,
121 .short_retry_limit = 10, 120 .short_retry_limit = 10,
122 .long_retry_limit = 10, 121 .long_retry_limit = 10,
123 .aflags = 0 122 .aflags = 0
@@ -214,7 +213,9 @@ static struct conf_drv_settings default_conf = {
214 }, 213 },
215 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD, 214 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
216 .tx_compl_timeout = 700, 215 .tx_compl_timeout = 700,
217 .tx_compl_threshold = 4 216 .tx_compl_threshold = 4,
217 .basic_rate = CONF_HW_BIT_RATE_1MBPS,
218 .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS,
218 }, 219 },
219 .conn = { 220 .conn = {
220 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, 221 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
@@ -1171,6 +1172,32 @@ out:
1171 return ret; 1172 return ret;
1172} 1173}
1173 1174
1175static void wl1271_set_band_rate(struct wl1271 *wl)
1176{
1177 if (wl->band == IEEE80211_BAND_2GHZ)
1178 wl->basic_rate_set = wl->conf.tx.basic_rate;
1179 else
1180 wl->basic_rate_set = wl->conf.tx.basic_rate_5;
1181}
1182
1183static u32 wl1271_min_rate_get(struct wl1271 *wl)
1184{
1185 int i;
1186 u32 rate = 0;
1187
1188 if (!wl->basic_rate_set) {
1189 WARN_ON(1);
1190 wl->basic_rate_set = wl->conf.tx.basic_rate;
1191 }
1192
1193 for (i = 0; !rate; i++) {
1194 if ((wl->basic_rate_set >> i) & 0x1)
1195 rate = 1 << i;
1196 }
1197
1198 return rate;
1199}
1200
1174static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) 1201static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1175{ 1202{
1176 struct wl1271 *wl = hw->priv; 1203 struct wl1271 *wl = hw->priv;
@@ -1187,12 +1214,38 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1187 1214
1188 mutex_lock(&wl->mutex); 1215 mutex_lock(&wl->mutex);
1189 1216
1190 wl->band = conf->channel->band;
1191
1192 ret = wl1271_ps_elp_wakeup(wl, false); 1217 ret = wl1271_ps_elp_wakeup(wl, false);
1193 if (ret < 0) 1218 if (ret < 0)
1194 goto out; 1219 goto out;
1195 1220
1221 /* if the channel changes while joined, join again */
1222 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1223 wl->band = conf->channel->band;
1224 wl->channel = channel;
1225
1226 /*
1227 * FIXME: the mac80211 should really provide a fixed rate
1228 * to use here. for now, just use the smallest possible rate
1229 * for the band as a fixed rate for association frames and
1230 * other control messages.
1231 */
1232 if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
1233 wl1271_set_band_rate(wl);
1234
1235 wl->basic_rate = wl1271_min_rate_get(wl);
1236 ret = wl1271_acx_rate_policies(wl);
1237 if (ret < 0)
1238 wl1271_warning("rate policy for update channel "
1239 "failed %d", ret);
1240
1241 if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) {
1242 ret = wl1271_cmd_join(wl, wl->set_bss_type);
1243 if (ret < 0)
1244 wl1271_warning("cmd join to update channel "
1245 "failed %d", ret);
1246 }
1247 }
1248
1196 if (changed & IEEE80211_CONF_CHANGE_IDLE) { 1249 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1197 if (conf->flags & IEEE80211_CONF_IDLE && 1250 if (conf->flags & IEEE80211_CONF_IDLE &&
1198 test_bit(WL1271_FLAG_JOINED, &wl->flags)) 1251 test_bit(WL1271_FLAG_JOINED, &wl->flags))
@@ -1201,7 +1254,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1201 wl1271_join_channel(wl, channel); 1254 wl1271_join_channel(wl, channel);
1202 1255
1203 if (conf->flags & IEEE80211_CONF_IDLE) { 1256 if (conf->flags & IEEE80211_CONF_IDLE) {
1204 wl->rate_set = CONF_TX_RATE_MASK_BASIC; 1257 wl->rate_set = wl1271_min_rate_get(wl);
1205 wl->sta_rate_set = 0; 1258 wl->sta_rate_set = 0;
1206 wl1271_acx_rate_policies(wl); 1259 wl1271_acx_rate_policies(wl);
1207 wl1271_acx_keep_alive_config( 1260 wl1271_acx_keep_alive_config(
@@ -1210,18 +1263,6 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1210 } 1263 }
1211 } 1264 }
1212 1265
1213 /* if the channel changes while joined, join again */
1214 if (channel != wl->channel &&
1215 test_bit(WL1271_FLAG_JOINED, &wl->flags)) {
1216 wl->channel = channel;
1217 /* FIXME: maybe use CMD_CHANNEL_SWITCH for this? */
1218 ret = wl1271_cmd_join(wl, wl->set_bss_type);
1219 if (ret < 0)
1220 wl1271_warning("cmd join to update channel failed %d",
1221 ret);
1222 } else
1223 wl->channel = channel;
1224
1225 if (conf->flags & IEEE80211_CONF_PS && 1266 if (conf->flags & IEEE80211_CONF_PS &&
1226 !test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { 1267 !test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) {
1227 set_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags); 1268 set_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags);
@@ -1659,10 +1700,23 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1659 1700
1660 if (changed & BSS_CHANGED_ASSOC) { 1701 if (changed & BSS_CHANGED_ASSOC) {
1661 if (bss_conf->assoc) { 1702 if (bss_conf->assoc) {
1703 u32 rates;
1662 wl->aid = bss_conf->aid; 1704 wl->aid = bss_conf->aid;
1663 set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); 1705 set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
1664 1706
1665 /* 1707 /*
1708 * use basic rates from AP, and determine lowest rate
1709 * to use with control frames.
1710 */
1711 rates = bss_conf->basic_rates;
1712 wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl,
1713 rates);
1714 wl->basic_rate = wl1271_min_rate_get(wl);
1715 ret = wl1271_acx_rate_policies(wl);
1716 if (ret < 0)
1717 goto out_sleep;
1718
1719 /*
1666 * with wl1271, we don't need to update the 1720 * with wl1271, we don't need to update the
1667 * beacon_int and dtim_period, because the firmware 1721 * beacon_int and dtim_period, because the firmware
1668 * updates it by itself when the first beacon is 1722 * updates it by itself when the first beacon is
@@ -1712,6 +1766,13 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1712 clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); 1766 clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
1713 wl->aid = 0; 1767 wl->aid = 0;
1714 1768
1769 /* revert back to minimum rates for the current band */
1770 wl1271_set_band_rate(wl);
1771 wl->basic_rate = wl1271_min_rate_get(wl);
1772 ret = wl1271_acx_rate_policies(wl);
1773 if (ret < 0)
1774 goto out_sleep;
1775
1715 /* disable connection monitor features */ 1776 /* disable connection monitor features */
1716 ret = wl1271_acx_conn_monit_params(wl, false); 1777 ret = wl1271_acx_conn_monit_params(wl, false);
1717 1778
@@ -2261,6 +2322,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
2261 wl->psm_entry_retry = 0; 2322 wl->psm_entry_retry = 0;
2262 wl->power_level = WL1271_DEFAULT_POWER_LEVEL; 2323 wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
2263 wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC; 2324 wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC;
2325 wl->basic_rate = CONF_TX_RATE_MASK_BASIC;
2264 wl->rate_set = CONF_TX_RATE_MASK_BASIC; 2326 wl->rate_set = CONF_TX_RATE_MASK_BASIC;
2265 wl->sta_rate_set = 0; 2327 wl->sta_rate_set = 0;
2266 wl->band = IEEE80211_BAND_2GHZ; 2328 wl->band = IEEE80211_BAND_2GHZ;
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c
index 66b48b70444e..0b8cdb4e22b6 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.c
@@ -220,7 +220,7 @@ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb)
220 return ret; 220 return ret;
221} 221}
222 222
223static u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) 223u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
224{ 224{
225 struct ieee80211_supported_band *band; 225 struct ieee80211_supported_band *band;
226 u32 enabled_rates = 0; 226 u32 enabled_rates = 0;
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h
index b03c95d9673f..3b8b7ac253fd 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.h
@@ -160,5 +160,6 @@ void wl1271_tx_work(struct work_struct *work);
160void wl1271_tx_complete(struct wl1271 *wl); 160void wl1271_tx_complete(struct wl1271 *wl);
161void wl1271_tx_flush(struct wl1271 *wl); 161void wl1271_tx_flush(struct wl1271 *wl);
162u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate); 162u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate);
163u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set);
163 164
164#endif 165#endif