diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-09-27 14:20:23 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-09-27 14:20:23 -0400 |
commit | 85a8eefdc9ee5ec222fb146a4df5d67c306488c4 (patch) | |
tree | aa6929ffc9ec2a909e63b9f0125f78101e11164c | |
parent | bb8f2cb284f1afa430a252d306d2bb29f6b9ce64 (diff) | |
parent | 6b661895a195f244097a60d4d4c9f09983d7efc7 (diff) |
Merge branch 'for-linville' of git://github.com/lucacoelho/wl12xx
-rw-r--r-- | drivers/net/wireless/wl12xx/Makefile | 6 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/cmd.c | 43 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/conf.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/event.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/init.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 201 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/scan.c | 42 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/sdio_test.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.c | 38 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl12xx.h | 5 |
11 files changed, 274 insertions, 106 deletions
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile index 521c0414e52e..621b3483ca2c 100644 --- a/drivers/net/wireless/wl12xx/Makefile +++ b/drivers/net/wireless/wl12xx/Makefile | |||
@@ -1,16 +1,16 @@ | |||
1 | wl12xx-objs = main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o \ | 1 | wl12xx-objs = main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o \ |
2 | boot.o init.o debugfs.o scan.o | 2 | boot.o init.o debugfs.o scan.o |
3 | 3 | ||
4 | wl12xx_spi-objs = spi.o | 4 | wl12xx_spi-objs = spi.o |
5 | wl12xx_sdio-objs = sdio.o | 5 | wl12xx_sdio-objs = sdio.o |
6 | wl12xx_sdio_test-objs = sdio_test.o | 6 | wl12xx_sdio_test-objs = sdio_test.o |
7 | 7 | ||
8 | wl12xx-$(CONFIG_NL80211_TESTMODE) += testmode.o | 8 | wl12xx-$(CONFIG_NL80211_TESTMODE) += testmode.o |
9 | obj-$(CONFIG_WL12XX) += wl12xx.o | 9 | obj-$(CONFIG_WL12XX) += wl12xx.o |
10 | obj-$(CONFIG_WL12XX_SPI) += wl12xx_spi.o | 10 | obj-$(CONFIG_WL12XX_SPI) += wl12xx_spi.o |
11 | obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o | 11 | obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o |
12 | 12 | ||
13 | obj-$(CONFIG_WL12XX_SDIO_TEST) += wl12xx_sdio_test.o | 13 | obj-$(CONFIG_WL12XX_SDIO_TEST) += wl12xx_sdio_test.o |
14 | 14 | ||
15 | # small builtin driver bit | 15 | # small builtin driver bit |
16 | obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o | 16 | obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o |
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 084262f169b2..287fe95ecb40 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c | |||
@@ -661,12 +661,9 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl) | |||
661 | 661 | ||
662 | wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wl->role_id); | 662 | wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wl->role_id); |
663 | 663 | ||
664 | /* | 664 | /* trying to use hidden SSID with an old hostapd version */ |
665 | * We currently do not support hidden SSID. The real SSID | 665 | if (wl->ssid_len == 0 && !bss_conf->hidden_ssid) { |
666 | * should be fetched from mac80211 first. | 666 | wl1271_error("got a null SSID from beacon/bss"); |
667 | */ | ||
668 | if (wl->ssid_len == 0) { | ||
669 | wl1271_warning("Hidden SSID currently not supported for AP"); | ||
670 | ret = -EINVAL; | 667 | ret = -EINVAL; |
671 | goto out; | 668 | goto out; |
672 | } | 669 | } |
@@ -695,9 +692,18 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl) | |||
695 | cmd->ap.dtim_interval = bss_conf->dtim_period; | 692 | cmd->ap.dtim_interval = bss_conf->dtim_period; |
696 | cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP; | 693 | cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP; |
697 | cmd->channel = wl->channel; | 694 | cmd->channel = wl->channel; |
698 | cmd->ap.ssid_len = wl->ssid_len; | 695 | |
699 | cmd->ap.ssid_type = WL12XX_SSID_TYPE_PUBLIC; | 696 | if (!bss_conf->hidden_ssid) { |
700 | memcpy(cmd->ap.ssid, wl->ssid, wl->ssid_len); | 697 | /* take the SSID from the beacon for backward compatibility */ |
698 | cmd->ap.ssid_type = WL12XX_SSID_TYPE_PUBLIC; | ||
699 | cmd->ap.ssid_len = wl->ssid_len; | ||
700 | memcpy(cmd->ap.ssid, wl->ssid, wl->ssid_len); | ||
701 | } else { | ||
702 | cmd->ap.ssid_type = WL12XX_SSID_TYPE_HIDDEN; | ||
703 | cmd->ap.ssid_len = bss_conf->ssid_len; | ||
704 | memcpy(cmd->ap.ssid, bss_conf->ssid, bss_conf->ssid_len); | ||
705 | } | ||
706 | |||
701 | cmd->ap.local_rates = cpu_to_le32(0xffffffff); | 707 | cmd->ap.local_rates = cpu_to_le32(0xffffffff); |
702 | 708 | ||
703 | switch (wl->band) { | 709 | switch (wl->band) { |
@@ -1106,6 +1112,7 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl, | |||
1106 | { | 1112 | { |
1107 | struct sk_buff *skb; | 1113 | struct sk_buff *skb; |
1108 | int ret; | 1114 | int ret; |
1115 | u32 rate; | ||
1109 | 1116 | ||
1110 | skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len, | 1117 | skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len, |
1111 | ie, ie_len); | 1118 | ie, ie_len); |
@@ -1116,14 +1123,13 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl, | |||
1116 | 1123 | ||
1117 | wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len); | 1124 | wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len); |
1118 | 1125 | ||
1126 | rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]); | ||
1119 | if (band == IEEE80211_BAND_2GHZ) | 1127 | if (band == IEEE80211_BAND_2GHZ) |
1120 | 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, |
1121 | skb->data, skb->len, 0, | 1129 | skb->data, skb->len, 0, rate); |
1122 | wl->conf.tx.basic_rate); | ||
1123 | else | 1130 | else |
1124 | 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, |
1125 | skb->data, skb->len, 0, | 1132 | skb->data, skb->len, 0, rate); |
1126 | wl->conf.tx.basic_rate_5); | ||
1127 | 1133 | ||
1128 | out: | 1134 | out: |
1129 | dev_kfree_skb(skb); | 1135 | dev_kfree_skb(skb); |
@@ -1134,6 +1140,7 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, | |||
1134 | struct sk_buff *skb) | 1140 | struct sk_buff *skb) |
1135 | { | 1141 | { |
1136 | int ret; | 1142 | int ret; |
1143 | u32 rate; | ||
1137 | 1144 | ||
1138 | if (!skb) | 1145 | if (!skb) |
1139 | skb = ieee80211_ap_probereq_get(wl->hw, wl->vif); | 1146 | skb = ieee80211_ap_probereq_get(wl->hw, wl->vif); |
@@ -1142,14 +1149,13 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, | |||
1142 | 1149 | ||
1143 | wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len); | 1150 | wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len); |
1144 | 1151 | ||
1152 | rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[wl->band]); | ||
1145 | if (wl->band == IEEE80211_BAND_2GHZ) | 1153 | if (wl->band == IEEE80211_BAND_2GHZ) |
1146 | 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, |
1147 | skb->data, skb->len, 0, | 1155 | skb->data, skb->len, 0, rate); |
1148 | wl->conf.tx.basic_rate); | ||
1149 | else | 1156 | else |
1150 | 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, |
1151 | skb->data, skb->len, 0, | 1158 | skb->data, skb->len, 0, rate); |
1152 | wl->conf.tx.basic_rate_5); | ||
1153 | 1159 | ||
1154 | if (ret < 0) | 1160 | if (ret < 0) |
1155 | wl1271_error("Unable to set ap probe request template."); | 1161 | wl1271_error("Unable to set ap probe request template."); |
@@ -1442,7 +1448,8 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid) | |||
1442 | 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; |
1443 | 1449 | ||
1444 | cmd->supported_rates = | 1450 | cmd->supported_rates = |
1445 | 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)); | ||
1446 | 1453 | ||
1447 | 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", |
1448 | cmd->supported_rates, sta->uapsd_queues); | 1455 | cmd->supported_rates, sta->uapsd_queues); |
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index 45428a21f9e2..6a6805c3cc74 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h | |||
@@ -454,12 +454,10 @@ struct conf_rx_settings { | |||
454 | #define CONF_TX_AP_DEFAULT_MGMT_RATES (CONF_HW_BIT_RATE_1MBPS | \ | 454 | #define CONF_TX_AP_DEFAULT_MGMT_RATES (CONF_HW_BIT_RATE_1MBPS | \ |
455 | CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS) | 455 | CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS) |
456 | 456 | ||
457 | /* | 457 | /* default rates for working as IBSS (11b and OFDM) */ |
458 | * Default rates for working as IBSS. use 11b rates | ||
459 | */ | ||
460 | #define CONF_TX_IBSS_DEFAULT_RATES (CONF_HW_BIT_RATE_1MBPS | \ | 458 | #define CONF_TX_IBSS_DEFAULT_RATES (CONF_HW_BIT_RATE_1MBPS | \ |
461 | CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \ | 459 | CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \ |
462 | CONF_HW_BIT_RATE_11MBPS); | 460 | CONF_HW_BIT_RATE_11MBPS | CONF_TX_OFDM_RATES); |
463 | 461 | ||
464 | struct conf_tx_rate_class { | 462 | struct conf_tx_rate_class { |
465 | 463 | ||
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index c73fe4c6b616..e66db69f8d17 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c | |||
@@ -181,7 +181,7 @@ static void wl1271_stop_ba_event(struct wl1271 *wl) | |||
181 | } else { | 181 | } else { |
182 | int i; | 182 | int i; |
183 | struct wl1271_link *lnk; | 183 | struct wl1271_link *lnk; |
184 | for (i = WL1271_AP_STA_HLID_START; i < WL12XX_MAX_LINKS; i++) { | 184 | for (i = WL1271_AP_STA_HLID_START; i < AP_MAX_LINKS; i++) { |
185 | lnk = &wl->links[i]; | 185 | lnk = &wl->links[i]; |
186 | if (!wl1271_is_active_sta(wl, i) || !lnk->ba_bitmap) | 186 | if (!wl1271_is_active_sta(wl, i) || !lnk->ba_bitmap) |
187 | continue; | 187 | continue; |
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 680f5582618e..a51dd0ed6d2d 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; |
@@ -2355,6 +2351,8 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
2355 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL && | 2351 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL && |
2356 | ((wl->band != conf->channel->band) || | 2352 | ((wl->band != conf->channel->band) || |
2357 | (wl->channel != channel))) { | 2353 | (wl->channel != channel))) { |
2354 | /* send all pending packets */ | ||
2355 | wl1271_tx_work_locked(wl); | ||
2358 | wl->band = conf->channel->band; | 2356 | wl->band = conf->channel->band; |
2359 | wl->channel = channel; | 2357 | wl->channel = channel; |
2360 | 2358 | ||
@@ -2368,7 +2366,8 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
2368 | if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) | 2366 | if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) |
2369 | wl1271_set_band_rate(wl); | 2367 | wl1271_set_band_rate(wl); |
2370 | 2368 | ||
2371 | wl->basic_rate = wl1271_tx_min_rate_get(wl); | 2369 | wl->basic_rate = |
2370 | wl1271_tx_min_rate_get(wl, wl->basic_rate_set); | ||
2372 | ret = wl1271_acx_sta_rate_policies(wl); | 2371 | ret = wl1271_acx_sta_rate_policies(wl); |
2373 | if (ret < 0) | 2372 | if (ret < 0) |
2374 | wl1271_warning("rate policy for channel " | 2373 | wl1271_warning("rate policy for channel " |
@@ -3069,6 +3068,93 @@ static int wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *skb, | |||
3069 | return 0; | 3068 | return 0; |
3070 | } | 3069 | } |
3071 | 3070 | ||
3071 | static void wl12xx_remove_ie(struct sk_buff *skb, u8 eid, int ieoffset) | ||
3072 | { | ||
3073 | int len; | ||
3074 | const u8 *next, *end = skb->data + skb->len; | ||
3075 | u8 *ie = (u8 *)cfg80211_find_ie(eid, skb->data + ieoffset, | ||
3076 | skb->len - ieoffset); | ||
3077 | if (!ie) | ||
3078 | return; | ||
3079 | len = ie[1] + 2; | ||
3080 | next = ie + len; | ||
3081 | memmove(ie, next, end - next); | ||
3082 | skb_trim(skb, skb->len - len); | ||
3083 | } | ||
3084 | |||
3085 | static void wl12xx_remove_vendor_ie(struct sk_buff *skb, | ||
3086 | unsigned int oui, u8 oui_type, | ||
3087 | int ieoffset) | ||
3088 | { | ||
3089 | int len; | ||
3090 | const u8 *next, *end = skb->data + skb->len; | ||
3091 | u8 *ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type, | ||
3092 | skb->data + ieoffset, | ||
3093 | skb->len - ieoffset); | ||
3094 | if (!ie) | ||
3095 | return; | ||
3096 | len = ie[1] + 2; | ||
3097 | next = ie + len; | ||
3098 | memmove(ie, next, end - next); | ||
3099 | skb_trim(skb, skb->len - len); | ||
3100 | } | ||
3101 | |||
3102 | static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, | ||
3103 | u8 *probe_rsp_data, | ||
3104 | size_t probe_rsp_len, | ||
3105 | u32 rates) | ||
3106 | { | ||
3107 | struct ieee80211_bss_conf *bss_conf = &wl->vif->bss_conf; | ||
3108 | u8 probe_rsp_templ[WL1271_CMD_TEMPL_MAX_SIZE]; | ||
3109 | int ssid_ie_offset, ie_offset, templ_len; | ||
3110 | const u8 *ptr; | ||
3111 | |||
3112 | /* no need to change probe response if the SSID is set correctly */ | ||
3113 | if (wl->ssid_len > 0) | ||
3114 | return wl1271_cmd_template_set(wl, | ||
3115 | CMD_TEMPL_AP_PROBE_RESPONSE, | ||
3116 | probe_rsp_data, | ||
3117 | probe_rsp_len, 0, | ||
3118 | rates); | ||
3119 | |||
3120 | if (probe_rsp_len + bss_conf->ssid_len > WL1271_CMD_TEMPL_MAX_SIZE) { | ||
3121 | wl1271_error("probe_rsp template too big"); | ||
3122 | return -EINVAL; | ||
3123 | } | ||
3124 | |||
3125 | /* start searching from IE offset */ | ||
3126 | ie_offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); | ||
3127 | |||
3128 | ptr = cfg80211_find_ie(WLAN_EID_SSID, probe_rsp_data + ie_offset, | ||
3129 | probe_rsp_len - ie_offset); | ||
3130 | if (!ptr) { | ||
3131 | wl1271_error("No SSID in beacon!"); | ||
3132 | return -EINVAL; | ||
3133 | } | ||
3134 | |||
3135 | ssid_ie_offset = ptr - probe_rsp_data; | ||
3136 | ptr += (ptr[1] + 2); | ||
3137 | |||
3138 | memcpy(probe_rsp_templ, probe_rsp_data, ssid_ie_offset); | ||
3139 | |||
3140 | /* insert SSID from bss_conf */ | ||
3141 | probe_rsp_templ[ssid_ie_offset] = WLAN_EID_SSID; | ||
3142 | probe_rsp_templ[ssid_ie_offset + 1] = bss_conf->ssid_len; | ||
3143 | memcpy(probe_rsp_templ + ssid_ie_offset + 2, | ||
3144 | bss_conf->ssid, bss_conf->ssid_len); | ||
3145 | templ_len = ssid_ie_offset + 2 + bss_conf->ssid_len; | ||
3146 | |||
3147 | memcpy(probe_rsp_templ + ssid_ie_offset + 2 + bss_conf->ssid_len, | ||
3148 | ptr, probe_rsp_len - (ptr - probe_rsp_data)); | ||
3149 | templ_len += probe_rsp_len - (ptr - probe_rsp_data); | ||
3150 | |||
3151 | return wl1271_cmd_template_set(wl, | ||
3152 | CMD_TEMPL_AP_PROBE_RESPONSE, | ||
3153 | probe_rsp_templ, | ||
3154 | templ_len, 0, | ||
3155 | rates); | ||
3156 | } | ||
3157 | |||
3072 | static int wl1271_bss_erp_info_changed(struct wl1271 *wl, | 3158 | static int wl1271_bss_erp_info_changed(struct wl1271 *wl, |
3073 | struct ieee80211_bss_conf *bss_conf, | 3159 | struct ieee80211_bss_conf *bss_conf, |
3074 | u32 changed) | 3160 | u32 changed) |
@@ -3125,6 +3211,7 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, | |||
3125 | 3211 | ||
3126 | if ((changed & BSS_CHANGED_BEACON)) { | 3212 | if ((changed & BSS_CHANGED_BEACON)) { |
3127 | struct ieee80211_hdr *hdr; | 3213 | struct ieee80211_hdr *hdr; |
3214 | u32 min_rate; | ||
3128 | int ieoffset = offsetof(struct ieee80211_mgmt, | 3215 | int ieoffset = offsetof(struct ieee80211_mgmt, |
3129 | u.beacon.variable); | 3216 | u.beacon.variable); |
3130 | struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif); | 3217 | struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif); |
@@ -3140,28 +3227,46 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, | |||
3140 | dev_kfree_skb(beacon); | 3227 | dev_kfree_skb(beacon); |
3141 | goto out; | 3228 | goto out; |
3142 | } | 3229 | } |
3230 | min_rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set); | ||
3143 | tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON : | 3231 | tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON : |
3144 | CMD_TEMPL_BEACON; | 3232 | CMD_TEMPL_BEACON; |
3145 | ret = wl1271_cmd_template_set(wl, tmpl_id, | 3233 | ret = wl1271_cmd_template_set(wl, tmpl_id, |
3146 | beacon->data, | 3234 | beacon->data, |
3147 | beacon->len, 0, | 3235 | beacon->len, 0, |
3148 | wl1271_tx_min_rate_get(wl)); | 3236 | min_rate); |
3149 | if (ret < 0) { | 3237 | if (ret < 0) { |
3150 | dev_kfree_skb(beacon); | 3238 | dev_kfree_skb(beacon); |
3151 | goto out; | 3239 | goto out; |
3152 | } | 3240 | } |
3153 | 3241 | ||
3242 | /* remove TIM ie from probe response */ | ||
3243 | wl12xx_remove_ie(beacon, WLAN_EID_TIM, ieoffset); | ||
3244 | |||
3245 | /* | ||
3246 | * remove p2p ie from probe response. | ||
3247 | * the fw reponds to probe requests that don't include | ||
3248 | * the p2p ie. probe requests with p2p ie will be passed, | ||
3249 | * and will be responded by the supplicant (the spec | ||
3250 | * forbids including the p2p ie when responding to probe | ||
3251 | * requests that didn't include it). | ||
3252 | */ | ||
3253 | wl12xx_remove_vendor_ie(beacon, WLAN_OUI_WFA, | ||
3254 | WLAN_OUI_TYPE_WFA_P2P, ieoffset); | ||
3255 | |||
3154 | hdr = (struct ieee80211_hdr *) beacon->data; | 3256 | hdr = (struct ieee80211_hdr *) beacon->data; |
3155 | hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 3257 | hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
3156 | IEEE80211_STYPE_PROBE_RESP); | 3258 | IEEE80211_STYPE_PROBE_RESP); |
3157 | 3259 | if (is_ap) | |
3158 | tmpl_id = is_ap ? CMD_TEMPL_AP_PROBE_RESPONSE : | 3260 | ret = wl1271_ap_set_probe_resp_tmpl(wl, |
3159 | CMD_TEMPL_PROBE_RESPONSE; | 3261 | beacon->data, |
3160 | ret = wl1271_cmd_template_set(wl, | 3262 | beacon->len, |
3161 | tmpl_id, | 3263 | min_rate); |
3162 | beacon->data, | 3264 | else |
3163 | beacon->len, 0, | 3265 | ret = wl1271_cmd_template_set(wl, |
3164 | wl1271_tx_min_rate_get(wl)); | 3266 | CMD_TEMPL_PROBE_RESPONSE, |
3267 | beacon->data, | ||
3268 | beacon->len, 0, | ||
3269 | min_rate); | ||
3165 | dev_kfree_skb(beacon); | 3270 | dev_kfree_skb(beacon); |
3166 | if (ret < 0) | 3271 | if (ret < 0) |
3167 | goto out; | 3272 | goto out; |
@@ -3182,8 +3287,10 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl, | |||
3182 | if ((changed & BSS_CHANGED_BASIC_RATES)) { | 3287 | if ((changed & BSS_CHANGED_BASIC_RATES)) { |
3183 | u32 rates = bss_conf->basic_rates; | 3288 | u32 rates = bss_conf->basic_rates; |
3184 | 3289 | ||
3185 | wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates); | 3290 | wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates, |
3186 | 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); | ||
3187 | 3294 | ||
3188 | ret = wl1271_init_ap_rates(wl); | 3295 | ret = wl1271_init_ap_rates(wl); |
3189 | if (ret < 0) { | 3296 | if (ret < 0) { |
@@ -3365,12 +3472,15 @@ sta_not_found: | |||
3365 | * to use with control frames. | 3472 | * to use with control frames. |
3366 | */ | 3473 | */ |
3367 | rates = bss_conf->basic_rates; | 3474 | rates = bss_conf->basic_rates; |
3368 | wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, | 3475 | wl->basic_rate_set = |
3369 | rates); | 3476 | wl1271_tx_enabled_rates_get(wl, rates, |
3370 | 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); | ||
3371 | if (sta_rate_set) | 3480 | if (sta_rate_set) |
3372 | wl->rate_set = wl1271_tx_enabled_rates_get(wl, | 3481 | wl->rate_set = wl1271_tx_enabled_rates_get(wl, |
3373 | sta_rate_set); | 3482 | sta_rate_set, |
3483 | wl->band); | ||
3374 | ret = wl1271_acx_sta_rate_policies(wl); | 3484 | ret = wl1271_acx_sta_rate_policies(wl); |
3375 | if (ret < 0) | 3485 | if (ret < 0) |
3376 | goto out; | 3486 | goto out; |
@@ -3417,7 +3527,8 @@ sta_not_found: | |||
3417 | 3527 | ||
3418 | /* revert back to minimum rates for the current band */ | 3528 | /* revert back to minimum rates for the current band */ |
3419 | wl1271_set_band_rate(wl); | 3529 | wl1271_set_band_rate(wl); |
3420 | wl->basic_rate = wl1271_tx_min_rate_get(wl); | 3530 | wl->basic_rate = |
3531 | wl1271_tx_min_rate_get(wl, wl->basic_rate_set); | ||
3421 | ret = wl1271_acx_sta_rate_policies(wl); | 3532 | ret = wl1271_acx_sta_rate_policies(wl); |
3422 | if (ret < 0) | 3533 | if (ret < 0) |
3423 | goto out; | 3534 | goto out; |
@@ -3468,11 +3579,13 @@ sta_not_found: | |||
3468 | 3579 | ||
3469 | if (bss_conf->ibss_joined) { | 3580 | if (bss_conf->ibss_joined) { |
3470 | u32 rates = bss_conf->basic_rates; | 3581 | u32 rates = bss_conf->basic_rates; |
3471 | wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, | 3582 | wl->basic_rate_set = |
3472 | rates); | 3583 | wl1271_tx_enabled_rates_get(wl, rates, |
3473 | 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); | ||
3474 | 3587 | ||
3475 | /* by default, use 11b rates */ | 3588 | /* by default, use 11b + OFDM rates */ |
3476 | wl->rate_set = CONF_TX_IBSS_DEFAULT_RATES; | 3589 | wl->rate_set = CONF_TX_IBSS_DEFAULT_RATES; |
3477 | ret = wl1271_acx_sta_rate_policies(wl); | 3590 | ret = wl1271_acx_sta_rate_policies(wl); |
3478 | if (ret < 0) | 3591 | if (ret < 0) |
@@ -3992,6 +4105,29 @@ out: | |||
3992 | return ret; | 4105 | return ret; |
3993 | } | 4106 | } |
3994 | 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 | |||
3995 | static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) | 4131 | static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) |
3996 | { | 4132 | { |
3997 | struct wl1271 *wl = hw->priv; | 4133 | struct wl1271 *wl = hw->priv; |
@@ -4267,6 +4403,7 @@ static const struct ieee80211_ops wl1271_ops = { | |||
4267 | .sta_remove = wl1271_op_sta_remove, | 4403 | .sta_remove = wl1271_op_sta_remove, |
4268 | .ampdu_action = wl1271_op_ampdu_action, | 4404 | .ampdu_action = wl1271_op_ampdu_action, |
4269 | .tx_frames_pending = wl1271_tx_frames_pending, | 4405 | .tx_frames_pending = wl1271_tx_frames_pending, |
4406 | .set_bitrate_mask = wl12xx_set_bitrate_mask, | ||
4270 | CFG80211_TESTMODE_CMD(wl1271_tm_cmd) | 4407 | CFG80211_TESTMODE_CMD(wl1271_tm_cmd) |
4271 | }; | 4408 | }; |
4272 | 4409 | ||
@@ -4585,6 +4722,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void) | |||
4585 | int i, j, ret; | 4722 | int i, j, ret; |
4586 | unsigned int order; | 4723 | unsigned int order; |
4587 | 4724 | ||
4725 | BUILD_BUG_ON(AP_MAX_LINKS > WL12XX_MAX_LINKS); | ||
4726 | |||
4588 | hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); | 4727 | hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); |
4589 | if (!hw) { | 4728 | if (!hw) { |
4590 | wl1271_error("could not alloc ieee80211_hw"); | 4729 | wl1271_error("could not alloc ieee80211_hw"); |
@@ -4687,6 +4826,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void) | |||
4687 | 4826 | ||
4688 | /* Apply default driver configuration. */ | 4827 | /* Apply default driver configuration. */ |
4689 | wl1271_conf_init(wl); | 4828 | wl1271_conf_init(wl); |
4829 | wl->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate; | ||
4830 | wl->bitrate_masks[IEEE80211_BAND_5GHZ] = wl->conf.tx.basic_rate_5; | ||
4690 | 4831 | ||
4691 | order = get_order(WL1271_AGGR_BUFFER_SIZE); | 4832 | order = get_order(WL1271_AGGR_BUFFER_SIZE); |
4692 | wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); | 4833 | 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 eeccc9f095bb..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 | { |
@@ -99,14 +100,18 @@ static int wl1271_get_scan_channels(struct wl1271 *wl, | |||
99 | for (i = 0, j = 0; | 100 | for (i = 0, j = 0; |
100 | i < req->n_channels && j < WL1271_SCAN_MAX_CHANNELS; | 101 | i < req->n_channels && j < WL1271_SCAN_MAX_CHANNELS; |
101 | i++) { | 102 | i++) { |
102 | |||
103 | flags = req->channels[i]->flags; | 103 | flags = req->channels[i]->flags; |
104 | 104 | ||
105 | if (!test_bit(i, wl->scan.scanned_ch) && | 105 | if (!test_bit(i, wl->scan.scanned_ch) && |
106 | !(flags & IEEE80211_CHAN_DISABLED) && | 106 | !(flags & IEEE80211_CHAN_DISABLED) && |
107 | ((!!(flags & IEEE80211_CHAN_PASSIVE_SCAN)) == passive) && | 107 | (req->channels[i]->band == band) && |
108 | (req->channels[i]->band == band)) { | 108 | /* |
109 | 109 | * In passive scans, we scan all remaining | |
110 | * channels, even if not marked as such. | ||
111 | * In active scans, we only scan channels not | ||
112 | * marked as passive. | ||
113 | */ | ||
114 | (passive || !(flags & IEEE80211_CHAN_PASSIVE_SCAN))) { | ||
110 | wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", | 115 | wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", |
111 | req->channels[i]->band, | 116 | req->channels[i]->band, |
112 | req->channels[i]->center_freq); | 117 | req->channels[i]->center_freq); |
@@ -158,6 +163,10 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band, | |||
158 | int ret; | 163 | int ret; |
159 | u16 scan_options = 0; | 164 | u16 scan_options = 0; |
160 | 165 | ||
166 | /* skip active scans if we don't have SSIDs */ | ||
167 | if (!passive && wl->scan.req->n_ssids == 0) | ||
168 | return WL1271_NOTHING_TO_SCAN; | ||
169 | |||
161 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); | 170 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); |
162 | trigger = kzalloc(sizeof(*trigger), GFP_KERNEL); | 171 | trigger = kzalloc(sizeof(*trigger), GFP_KERNEL); |
163 | if (!cmd || !trigger) { | 172 | if (!cmd || !trigger) { |
@@ -165,8 +174,7 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band, | |||
165 | goto out; | 174 | goto out; |
166 | } | 175 | } |
167 | 176 | ||
168 | /* No SSIDs means that we have a forced passive scan */ | 177 | if (passive) |
169 | if (passive || wl->scan.req->n_ssids == 0) | ||
170 | scan_options |= WL1271_SCAN_OPT_PASSIVE; | 178 | scan_options |= WL1271_SCAN_OPT_PASSIVE; |
171 | 179 | ||
172 | if (WARN_ON(wl->role_id == WL12XX_INVALID_ROLE_ID)) { | 180 | if (WARN_ON(wl->role_id == WL12XX_INVALID_ROLE_ID)) { |
@@ -236,14 +244,17 @@ out: | |||
236 | void wl1271_scan_stm(struct wl1271 *wl) | 244 | void wl1271_scan_stm(struct wl1271 *wl) |
237 | { | 245 | { |
238 | int ret = 0; | 246 | int ret = 0; |
247 | enum ieee80211_band band; | ||
248 | u32 rate; | ||
239 | 249 | ||
240 | switch (wl->scan.state) { | 250 | switch (wl->scan.state) { |
241 | case WL1271_SCAN_STATE_IDLE: | 251 | case WL1271_SCAN_STATE_IDLE: |
242 | break; | 252 | break; |
243 | 253 | ||
244 | case WL1271_SCAN_STATE_2GHZ_ACTIVE: | 254 | case WL1271_SCAN_STATE_2GHZ_ACTIVE: |
245 | ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, false, | 255 | band = IEEE80211_BAND_2GHZ; |
246 | 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); | ||
247 | if (ret == WL1271_NOTHING_TO_SCAN) { | 258 | if (ret == WL1271_NOTHING_TO_SCAN) { |
248 | wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE; | 259 | wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE; |
249 | wl1271_scan_stm(wl); | 260 | wl1271_scan_stm(wl); |
@@ -252,8 +263,9 @@ void wl1271_scan_stm(struct wl1271 *wl) | |||
252 | break; | 263 | break; |
253 | 264 | ||
254 | case WL1271_SCAN_STATE_2GHZ_PASSIVE: | 265 | case WL1271_SCAN_STATE_2GHZ_PASSIVE: |
255 | ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true, | 266 | band = IEEE80211_BAND_2GHZ; |
256 | 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); | ||
257 | if (ret == WL1271_NOTHING_TO_SCAN) { | 269 | if (ret == WL1271_NOTHING_TO_SCAN) { |
258 | if (wl->enable_11a) | 270 | if (wl->enable_11a) |
259 | wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE; | 271 | wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE; |
@@ -265,8 +277,9 @@ void wl1271_scan_stm(struct wl1271 *wl) | |||
265 | break; | 277 | break; |
266 | 278 | ||
267 | case WL1271_SCAN_STATE_5GHZ_ACTIVE: | 279 | case WL1271_SCAN_STATE_5GHZ_ACTIVE: |
268 | ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, false, | 280 | band = IEEE80211_BAND_5GHZ; |
269 | 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); | ||
270 | if (ret == WL1271_NOTHING_TO_SCAN) { | 283 | if (ret == WL1271_NOTHING_TO_SCAN) { |
271 | wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE; | 284 | wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE; |
272 | wl1271_scan_stm(wl); | 285 | wl1271_scan_stm(wl); |
@@ -275,8 +288,9 @@ void wl1271_scan_stm(struct wl1271 *wl) | |||
275 | break; | 288 | break; |
276 | 289 | ||
277 | case WL1271_SCAN_STATE_5GHZ_PASSIVE: | 290 | case WL1271_SCAN_STATE_5GHZ_PASSIVE: |
278 | ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, true, | 291 | band = IEEE80211_BAND_5GHZ; |
279 | 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); | ||
280 | if (ret == WL1271_NOTHING_TO_SCAN) { | 294 | if (ret == WL1271_NOTHING_TO_SCAN) { |
281 | wl->scan.state = WL1271_SCAN_STATE_DONE; | 295 | wl->scan.state = WL1271_SCAN_STATE_DONE; |
282 | wl1271_scan_stm(wl); | 296 | wl1271_scan_stm(wl); |
diff --git a/drivers/net/wireless/wl12xx/sdio_test.c b/drivers/net/wireless/wl12xx/sdio_test.c index c3610492852e..f25d5d9212e7 100644 --- a/drivers/net/wireless/wl12xx/sdio_test.c +++ b/drivers/net/wireless/wl12xx/sdio_test.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/mmc/sdio_func.h> | 30 | #include <linux/mmc/sdio_func.h> |
31 | #include <linux/mmc/sdio_ids.h> | 31 | #include <linux/mmc/sdio_ids.h> |
32 | #include <linux/mmc/card.h> | 32 | #include <linux/mmc/card.h> |
33 | #include <linux/mmc/host.h> | ||
33 | #include <linux/gpio.h> | 34 | #include <linux/gpio.h> |
34 | #include <linux/wl12xx.h> | 35 | #include <linux/wl12xx.h> |
35 | #include <linux/kthread.h> | 36 | #include <linux/kthread.h> |
@@ -142,14 +143,23 @@ static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable) | |||
142 | ret = pm_runtime_get_sync(&func->dev); | 143 | ret = pm_runtime_get_sync(&func->dev); |
143 | if (ret < 0) | 144 | if (ret < 0) |
144 | goto out; | 145 | goto out; |
146 | |||
147 | /* Runtime PM might be disabled, power up the card manually */ | ||
148 | ret = mmc_power_restore_host(func->card->host); | ||
149 | if (ret < 0) | ||
150 | goto out; | ||
151 | |||
145 | sdio_claim_host(func); | 152 | sdio_claim_host(func); |
146 | sdio_enable_func(func); | 153 | sdio_enable_func(func); |
147 | sdio_release_host(func); | ||
148 | } else { | 154 | } else { |
149 | sdio_claim_host(func); | ||
150 | sdio_disable_func(func); | 155 | sdio_disable_func(func); |
151 | sdio_release_host(func); | 156 | sdio_release_host(func); |
152 | 157 | ||
158 | /* Runtime PM might be disabled, power off the card manually */ | ||
159 | ret = mmc_power_save_host(func->card->host); | ||
160 | if (ret < 0) | ||
161 | goto out; | ||
162 | |||
153 | /* Power down the card */ | 163 | /* Power down the card */ |
154 | ret = pm_runtime_put_sync(&func->dev); | 164 | ret = pm_runtime_put_sync(&func->dev); |
155 | } | 165 | } |
@@ -433,7 +443,6 @@ static int __devinit wl1271_probe(struct sdio_func *func, | |||
433 | 443 | ||
434 | sdio_set_drvdata(func, wl_test); | 444 | sdio_set_drvdata(func, wl_test); |
435 | 445 | ||
436 | |||
437 | /* power up the device */ | 446 | /* power up the device */ |
438 | ret = wl1271_chip_wakeup(wl); | 447 | ret = wl1271_chip_wakeup(wl); |
439 | if (ret) { | 448 | if (ret) { |
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 9d4157ce0950..bad9e29d49b0 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c | |||
@@ -81,8 +81,7 @@ static int wl1271_tx_update_filters(struct wl1271 *wl, | |||
81 | struct ieee80211_hdr *hdr; | 81 | struct ieee80211_hdr *hdr; |
82 | int ret; | 82 | int ret; |
83 | 83 | ||
84 | hdr = (struct ieee80211_hdr *)(skb->data + | 84 | hdr = (struct ieee80211_hdr *)skb->data; |
85 | sizeof(struct wl1271_tx_hw_descr)); | ||
86 | 85 | ||
87 | /* | 86 | /* |
88 | * stop bssid-based filtering before transmitting authentication | 87 | * stop bssid-based filtering before transmitting authentication |
@@ -181,14 +180,20 @@ u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct sk_buff *skb) | |||
181 | 180 | ||
182 | static u8 wl1271_tx_get_hlid(struct wl1271 *wl, struct sk_buff *skb) | 181 | static u8 wl1271_tx_get_hlid(struct wl1271 *wl, struct sk_buff *skb) |
183 | { | 182 | { |
183 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
184 | |||
184 | if (wl12xx_is_dummy_packet(wl, skb)) | 185 | if (wl12xx_is_dummy_packet(wl, skb)) |
185 | return wl->system_hlid; | 186 | return wl->system_hlid; |
186 | 187 | ||
187 | if (wl->bss_type == BSS_TYPE_AP_BSS) | 188 | if (wl->bss_type == BSS_TYPE_AP_BSS) |
188 | return wl12xx_tx_get_hlid_ap(wl, skb); | 189 | return wl12xx_tx_get_hlid_ap(wl, skb); |
189 | 190 | ||
190 | if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags) || | 191 | wl1271_tx_update_filters(wl, skb); |
191 | test_bit(WL1271_FLAG_IBSS_JOINED, &wl->flags)) | 192 | |
193 | if ((test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags) || | ||
194 | test_bit(WL1271_FLAG_IBSS_JOINED, &wl->flags)) && | ||
195 | !ieee80211_is_auth(hdr->frame_control) && | ||
196 | !ieee80211_is_assoc_req(hdr->frame_control)) | ||
192 | return wl->sta_hlid; | 197 | return wl->sta_hlid; |
193 | else | 198 | else |
194 | return wl->dev_hlid; | 199 | return wl->dev_hlid; |
@@ -423,8 +428,6 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, | |||
423 | if (wl->bss_type == BSS_TYPE_AP_BSS) { | 428 | if (wl->bss_type == BSS_TYPE_AP_BSS) { |
424 | wl1271_tx_ap_update_inconnection_sta(wl, skb); | 429 | wl1271_tx_ap_update_inconnection_sta(wl, skb); |
425 | wl1271_tx_regulate_link(wl, hlid); | 430 | wl1271_tx_regulate_link(wl, hlid); |
426 | } else { | ||
427 | wl1271_tx_update_filters(wl, skb); | ||
428 | } | 431 | } |
429 | 432 | ||
430 | /* | 433 | /* |
@@ -447,13 +450,14 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, | |||
447 | return total_len; | 450 | return total_len; |
448 | } | 451 | } |
449 | 452 | ||
450 | 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) | ||
451 | { | 455 | { |
452 | struct ieee80211_supported_band *band; | 456 | struct ieee80211_supported_band *band; |
453 | u32 enabled_rates = 0; | 457 | u32 enabled_rates = 0; |
454 | int bit; | 458 | int bit; |
455 | 459 | ||
456 | band = wl->hw->wiphy->bands[wl->band]; | 460 | band = wl->hw->wiphy->bands[rate_band]; |
457 | for (bit = 0; bit < band->n_bitrates; bit++) { | 461 | for (bit = 0; bit < band->n_bitrates; bit++) { |
458 | if (rate_set & 0x1) | 462 | if (rate_set & 0x1) |
459 | enabled_rates |= band->bitrates[bit].hw_value; | 463 | enabled_rates |= band->bitrates[bit].hw_value; |
@@ -986,20 +990,10 @@ void wl1271_tx_flush(struct wl1271 *wl) | |||
986 | wl1271_warning("Unable to flush all TX buffers, timed out."); | 990 | wl1271_warning("Unable to flush all TX buffers, timed out."); |
987 | } | 991 | } |
988 | 992 | ||
989 | u32 wl1271_tx_min_rate_get(struct wl1271 *wl) | 993 | u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set) |
990 | { | 994 | { |
991 | int i; | 995 | if (WARN_ON(!rate_set)) |
992 | u32 rate = 0; | 996 | return 0; |
993 | |||
994 | if (!wl->basic_rate_set) { | ||
995 | WARN_ON(1); | ||
996 | wl->basic_rate_set = wl->conf.tx.basic_rate; | ||
997 | } | ||
998 | |||
999 | for (i = 0; !rate; i++) { | ||
1000 | if ((wl->basic_rate_set >> i) & 0x1) | ||
1001 | rate = 1 << i; | ||
1002 | } | ||
1003 | 997 | ||
1004 | return rate; | 998 | return BIT(__ffs(rate_set)); |
1005 | } | 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..997f53245011 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h | |||
@@ -138,7 +138,7 @@ extern u32 wl12xx_debug_level; | |||
138 | #define WL1271_DEFAULT_DTIM_PERIOD 1 | 138 | #define WL1271_DEFAULT_DTIM_PERIOD 1 |
139 | 139 | ||
140 | #define WL12XX_MAX_ROLES 4 | 140 | #define WL12XX_MAX_ROLES 4 |
141 | #define WL12XX_MAX_LINKS 8 | 141 | #define WL12XX_MAX_LINKS 12 |
142 | #define WL12XX_INVALID_ROLE_ID 0xff | 142 | #define WL12XX_INVALID_ROLE_ID 0xff |
143 | #define WL12XX_INVALID_LINK_ID 0xff | 143 | #define WL12XX_INVALID_LINK_ID 0xff |
144 | 144 | ||
@@ -279,7 +279,7 @@ struct wl12xx_fw_status { | |||
279 | 279 | ||
280 | /* Cumulative counter of released Voice memory blocks */ | 280 | /* Cumulative counter of released Voice memory blocks */ |
281 | u8 tx_voice_released_blks; | 281 | u8 tx_voice_released_blks; |
282 | u8 padding_1[7]; | 282 | u8 padding_1[3]; |
283 | __le32 log_start_addr; | 283 | __le32 log_start_addr; |
284 | } __packed; | 284 | } __packed; |
285 | 285 | ||
@@ -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; |