aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2011-02-02 02:59:37 -0500
committerLuciano Coelho <coelho@ti.com>2011-02-08 19:51:42 -0500
commit72c2d9e511846a4f2759389b38ed8a5553579eb3 (patch)
treef0329c44ea13a81a1f69b6bd92e203e720ee6b8f /drivers/net/wireless/wl12xx
parentfe5ef090660de340b52823de7cb65b899bb4f012 (diff)
wl12xx: set supported_rates after association
Instead of looking for supported_rates change on every tx packet, just extract the supported_rates after association completes (station only). Remove wl1271.sta_rate_set and WL1271_FLAG_STA_RATES_CHANGED which are not used anymore. Signed-off-by: Eliad Peller <eliad@wizery.com> Reviewed-by: Juuso Oikarinen <juuso.oikarinen@nokia.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r--drivers/net/wireless/wl12xx/acx.c4
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c11
-rw-r--r--drivers/net/wireless/wl12xx/main.c116
-rw-r--r--drivers/net/wireless/wl12xx/tx.c22
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h35
5 files changed, 73 insertions, 115 deletions
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index 6ea19d75cecc..33840d95d17d 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -783,6 +783,10 @@ int wl1271_acx_sta_rate_policies(struct wl1271 *wl)
783 783
784 acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT); 784 acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT);
785 785
786 wl1271_debug(DEBUG_ACX, "basic_rate: 0x%x, full_rate: 0x%x",
787 acx->rate_class[ACX_TX_BASIC_RATE].enabled_rates,
788 acx->rate_class[ACX_TX_AP_FULL_RATE].enabled_rates);
789
786 ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); 790 ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
787 if (ret < 0) { 791 if (ret < 0) {
788 wl1271_warning("Setting of rate policies failed: %d", ret); 792 wl1271_warning("Setting of rate policies failed: %d", ret);
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index 66d15e77da38..97ffd7aa57a8 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -286,13 +286,7 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
286 join->rx_filter_options = cpu_to_le32(wl->rx_filter); 286 join->rx_filter_options = cpu_to_le32(wl->rx_filter);
287 join->bss_type = bss_type; 287 join->bss_type = bss_type;
288 join->basic_rate_set = cpu_to_le32(wl->basic_rate_set); 288 join->basic_rate_set = cpu_to_le32(wl->basic_rate_set);
289 /* 289 join->supported_rate_set = cpu_to_le32(wl->rate_set);
290 * for supported_rate_set, we should use wl->rate_set. however,
291 * it seems that acx_rate_policies doesn't affect full_rate, and
292 * since we want to avoid additional join, we'll use a 0xffffffff value,
293 * and let the fw find the actual supported rates
294 */
295 join->supported_rate_set = cpu_to_le32(0xffffffff);
296 290
297 if (wl->band == IEEE80211_BAND_5GHZ) 291 if (wl->band == IEEE80211_BAND_5GHZ)
298 join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ; 292 join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ;
@@ -310,6 +304,9 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
310 wl->tx_security_last_seq = 0; 304 wl->tx_security_last_seq = 0;
311 wl->tx_security_seq = 0; 305 wl->tx_security_seq = 0;
312 306
307 wl1271_debug(DEBUG_CMD, "cmd join: basic_rate_set=0x%x, rate_set=0x%x",
308 join->basic_rate_set, join->supported_rate_set);
309
313 ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0); 310 ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0);
314 if (ret < 0) { 311 if (ret < 0) {
315 wl1271_error("failed to initiate cmd join"); 312 wl1271_error("failed to initiate cmd join");
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 24cdc78c00b3..61dea73f5fdc 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -978,39 +978,10 @@ int wl1271_plt_stop(struct wl1271 *wl)
978static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 978static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
979{ 979{
980 struct wl1271 *wl = hw->priv; 980 struct wl1271 *wl = hw->priv;
981 struct ieee80211_conf *conf = &hw->conf;
982 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
983 struct ieee80211_sta *sta = txinfo->control.sta;
984 unsigned long flags; 981 unsigned long flags;
985 int q; 982 int q;
986 983
987 /*
988 * peek into the rates configured in the STA entry.
989 * The rates set after connection stage, The first block only BG sets:
990 * the compare is for bit 0-16 of sta_rate_set. The second block add
991 * HT rates in case of HT supported.
992 */
993 spin_lock_irqsave(&wl->wl_lock, flags); 984 spin_lock_irqsave(&wl->wl_lock, flags);
994 if (sta &&
995 (sta->supp_rates[conf->channel->band] !=
996 (wl->sta_rate_set & HW_BG_RATES_MASK)) &&
997 wl->bss_type != BSS_TYPE_AP_BSS) {
998 wl->sta_rate_set = sta->supp_rates[conf->channel->band];
999 set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
1000 }
1001
1002#ifdef CONFIG_WL12XX_HT
1003 if (sta &&
1004 sta->ht_cap.ht_supported &&
1005 ((wl->sta_rate_set >> HW_HT_RATES_OFFSET) !=
1006 sta->ht_cap.mcs.rx_mask[0])) {
1007 /* Clean MCS bits before setting them */
1008 wl->sta_rate_set &= HW_BG_RATES_MASK;
1009 wl->sta_rate_set |=
1010 (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
1011 set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
1012 }
1013#endif
1014 wl->tx_queue_count++; 985 wl->tx_queue_count++;
1015 spin_unlock_irqrestore(&wl->wl_lock, flags); 986 spin_unlock_irqrestore(&wl->wl_lock, flags);
1016 987
@@ -1245,7 +1216,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
1245 wl->time_offset = 0; 1216 wl->time_offset = 0;
1246 wl->session_counter = 0; 1217 wl->session_counter = 0;
1247 wl->rate_set = CONF_TX_RATE_MASK_BASIC; 1218 wl->rate_set = CONF_TX_RATE_MASK_BASIC;
1248 wl->sta_rate_set = 0;
1249 wl->flags = 0; 1219 wl->flags = 0;
1250 wl->vif = NULL; 1220 wl->vif = NULL;
1251 wl->filters = 0; 1221 wl->filters = 0;
@@ -1432,7 +1402,6 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle)
1432 goto out; 1402 goto out;
1433 } 1403 }
1434 wl->rate_set = wl1271_tx_min_rate_get(wl); 1404 wl->rate_set = wl1271_tx_min_rate_get(wl);
1435 wl->sta_rate_set = 0;
1436 ret = wl1271_acx_sta_rate_policies(wl); 1405 ret = wl1271_acx_sta_rate_policies(wl);
1437 if (ret < 0) 1406 if (ret < 0)
1438 goto out; 1407 goto out;
@@ -2246,6 +2215,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
2246{ 2215{
2247 bool do_join = false, set_assoc = false; 2216 bool do_join = false, set_assoc = false;
2248 bool is_ibss = (wl->bss_type == BSS_TYPE_IBSS); 2217 bool is_ibss = (wl->bss_type == BSS_TYPE_IBSS);
2218 u32 sta_rate_set = 0;
2249 int ret; 2219 int ret;
2250 struct ieee80211_sta *sta; 2220 struct ieee80211_sta *sta;
2251 2221
@@ -2311,6 +2281,49 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
2311 } 2281 }
2312 } 2282 }
2313 2283
2284 rcu_read_lock();
2285 sta = ieee80211_find_sta(vif, bss_conf->bssid);
2286 if (sta) {
2287 /* save the supp_rates of the ap */
2288 sta_rate_set = sta->supp_rates[wl->hw->conf.channel->band];
2289 if (sta->ht_cap.ht_supported)
2290 sta_rate_set |=
2291 (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
2292
2293 /* handle new association with HT and HT information change */
2294 if ((changed & BSS_CHANGED_HT) &&
2295 (bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
2296 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
2297 true);
2298 if (ret < 0) {
2299 wl1271_warning("Set ht cap true failed %d",
2300 ret);
2301 rcu_read_unlock();
2302 goto out;
2303 }
2304 ret = wl1271_acx_set_ht_information(wl,
2305 bss_conf->ht_operation_mode);
2306 if (ret < 0) {
2307 wl1271_warning("Set ht information failed %d",
2308 ret);
2309 rcu_read_unlock();
2310 goto out;
2311 }
2312 }
2313 /* handle new association without HT and disassociation */
2314 else if (changed & BSS_CHANGED_ASSOC) {
2315 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
2316 false);
2317 if (ret < 0) {
2318 wl1271_warning("Set ht cap false failed %d",
2319 ret);
2320 rcu_read_unlock();
2321 goto out;
2322 }
2323 }
2324 }
2325 rcu_read_unlock();
2326
2314 if ((changed & BSS_CHANGED_ASSOC)) { 2327 if ((changed & BSS_CHANGED_ASSOC)) {
2315 if (bss_conf->assoc) { 2328 if (bss_conf->assoc) {
2316 u32 rates; 2329 u32 rates;
@@ -2328,6 +2341,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
2328 wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, 2341 wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl,
2329 rates); 2342 rates);
2330 wl->basic_rate = wl1271_tx_min_rate_get(wl); 2343 wl->basic_rate = wl1271_tx_min_rate_get(wl);
2344 if (sta_rate_set)
2345 wl->rate_set = wl1271_tx_enabled_rates_get(wl,
2346 sta_rate_set);
2331 ret = wl1271_acx_sta_rate_policies(wl); 2347 ret = wl1271_acx_sta_rate_policies(wl);
2332 if (ret < 0) 2348 if (ret < 0)
2333 goto out; 2349 goto out;
@@ -2406,43 +2422,6 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
2406 if (ret < 0) 2422 if (ret < 0)
2407 goto out; 2423 goto out;
2408 2424
2409 rcu_read_lock();
2410 sta = ieee80211_find_sta(vif, bss_conf->bssid);
2411 if (sta) {
2412 /* handle new association with HT and HT information change */
2413 if ((changed & BSS_CHANGED_HT) &&
2414 (bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
2415 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
2416 true);
2417 if (ret < 0) {
2418 wl1271_warning("Set ht cap true failed %d",
2419 ret);
2420 rcu_read_unlock();
2421 goto out;
2422 }
2423 ret = wl1271_acx_set_ht_information(wl,
2424 bss_conf->ht_operation_mode);
2425 if (ret < 0) {
2426 wl1271_warning("Set ht information failed %d",
2427 ret);
2428 rcu_read_unlock();
2429 goto out;
2430 }
2431 }
2432 /* handle new association without HT and disassociation */
2433 else if (changed & BSS_CHANGED_ASSOC) {
2434 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
2435 false);
2436 if (ret < 0) {
2437 wl1271_warning("Set ht cap false failed %d",
2438 ret);
2439 rcu_read_unlock();
2440 goto out;
2441 }
2442 }
2443 }
2444 rcu_read_unlock();
2445
2446 if (changed & BSS_CHANGED_ARP_FILTER) { 2425 if (changed & BSS_CHANGED_ARP_FILTER) {
2447 __be32 addr = bss_conf->arp_addr_list[0]; 2426 __be32 addr = bss_conf->arp_addr_list[0];
2448 WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); 2427 WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
@@ -3330,7 +3309,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
3330 wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC; 3309 wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC;
3331 wl->basic_rate = CONF_TX_RATE_MASK_BASIC; 3310 wl->basic_rate = CONF_TX_RATE_MASK_BASIC;
3332 wl->rate_set = CONF_TX_RATE_MASK_BASIC; 3311 wl->rate_set = CONF_TX_RATE_MASK_BASIC;
3333 wl->sta_rate_set = 0;
3334 wl->band = IEEE80211_BAND_2GHZ; 3312 wl->band = IEEE80211_BAND_2GHZ;
3335 wl->vif = NULL; 3313 wl->vif = NULL;
3336 wl->flags = 0; 3314 wl->flags = 0;
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index 3507c81c7500..67a00946e3dd 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -334,35 +334,13 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
334{ 334{
335 struct sk_buff *skb; 335 struct sk_buff *skb;
336 bool woken_up = false; 336 bool woken_up = false;
337 u32 sta_rates = 0;
338 u32 buf_offset = 0; 337 u32 buf_offset = 0;
339 bool sent_packets = false; 338 bool sent_packets = false;
340 int ret; 339 int ret;
341 340
342 /* check if the rates supported by the AP have changed */
343 if (unlikely(test_and_clear_bit(WL1271_FLAG_STA_RATES_CHANGED,
344 &wl->flags))) {
345 unsigned long flags;
346
347 spin_lock_irqsave(&wl->wl_lock, flags);
348 sta_rates = wl->sta_rate_set;
349 spin_unlock_irqrestore(&wl->wl_lock, flags);
350 }
351
352 if (unlikely(wl->state == WL1271_STATE_OFF)) 341 if (unlikely(wl->state == WL1271_STATE_OFF))
353 goto out; 342 goto out;
354 343
355 /* if rates have changed, re-configure the rate policy */
356 if (unlikely(sta_rates)) {
357 ret = wl1271_ps_elp_wakeup(wl, false);
358 if (ret < 0)
359 goto out;
360 woken_up = true;
361
362 wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates);
363 wl1271_acx_sta_rate_policies(wl);
364 }
365
366 while ((skb = wl1271_skb_dequeue(wl))) { 344 while ((skb = wl1271_skb_dequeue(wl))) {
367 if (!woken_up) { 345 if (!woken_up) {
368 ret = wl1271_ps_elp_wakeup(wl, false); 346 ret = wl1271_ps_elp_wakeup(wl, false);
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 140e26f3bae9..1d6c94304b1a 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -301,6 +301,24 @@ struct wl1271_ap_key {
301 u16 tx_seq_16; 301 u16 tx_seq_16;
302}; 302};
303 303
304enum wl12xx_flags {
305 WL1271_FLAG_STA_ASSOCIATED,
306 WL1271_FLAG_JOINED,
307 WL1271_FLAG_GPIO_POWER,
308 WL1271_FLAG_TX_QUEUE_STOPPED,
309 WL1271_FLAG_IN_ELP,
310 WL1271_FLAG_PSM,
311 WL1271_FLAG_PSM_REQUESTED,
312 WL1271_FLAG_IRQ_PENDING,
313 WL1271_FLAG_IRQ_RUNNING,
314 WL1271_FLAG_IDLE,
315 WL1271_FLAG_IDLE_REQUESTED,
316 WL1271_FLAG_PSPOLL_FAILURE,
317 WL1271_FLAG_STA_STATE_SENT,
318 WL1271_FLAG_FW_TX_BUSY,
319 WL1271_FLAG_AP_STARTED
320};
321
304struct wl1271 { 322struct wl1271 {
305 struct platform_device *plat_dev; 323 struct platform_device *plat_dev;
306 struct ieee80211_hw *hw; 324 struct ieee80211_hw *hw;
@@ -319,22 +337,6 @@ struct wl1271 {
319 enum wl1271_state state; 337 enum wl1271_state state;
320 struct mutex mutex; 338 struct mutex mutex;
321 339
322#define WL1271_FLAG_STA_RATES_CHANGED (0)
323#define WL1271_FLAG_STA_ASSOCIATED (1)
324#define WL1271_FLAG_JOINED (2)
325#define WL1271_FLAG_GPIO_POWER (3)
326#define WL1271_FLAG_TX_QUEUE_STOPPED (4)
327#define WL1271_FLAG_IN_ELP (5)
328#define WL1271_FLAG_PSM (6)
329#define WL1271_FLAG_PSM_REQUESTED (7)
330#define WL1271_FLAG_IRQ_PENDING (8)
331#define WL1271_FLAG_IRQ_RUNNING (9)
332#define WL1271_FLAG_IDLE (10)
333#define WL1271_FLAG_IDLE_REQUESTED (11)
334#define WL1271_FLAG_PSPOLL_FAILURE (12)
335#define WL1271_FLAG_STA_STATE_SENT (13)
336#define WL1271_FLAG_FW_TX_BUSY (14)
337#define WL1271_FLAG_AP_STARTED (15)
338 unsigned long flags; 340 unsigned long flags;
339 341
340 struct wl1271_partition_set part; 342 struct wl1271_partition_set part;
@@ -428,7 +430,6 @@ struct wl1271 {
428 * bits 16-23 - 802.11n MCS index mask 430 * bits 16-23 - 802.11n MCS index mask
429 * support only 1 stream, thus only 8 bits for the MCS rates (0-7). 431 * support only 1 stream, thus only 8 bits for the MCS rates (0-7).
430 */ 432 */
431 u32 sta_rate_set;
432 u32 basic_rate_set; 433 u32 basic_rate_set;
433 u32 basic_rate; 434 u32 basic_rate;
434 u32 rate_set; 435 u32 rate_set;