diff options
author | Eliad Peller <eliad@wizery.com> | 2011-02-02 02:59:37 -0500 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2011-02-08 19:51:42 -0500 |
commit | 72c2d9e511846a4f2759389b38ed8a5553579eb3 (patch) | |
tree | f0329c44ea13a81a1f69b6bd92e203e720ee6b8f /drivers/net/wireless/wl12xx | |
parent | fe5ef090660de340b52823de7cb65b899bb4f012 (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.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/cmd.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 116 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl12xx.h | 35 |
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) | |||
978 | static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 978 | static 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 | ||
304 | enum 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 | |||
304 | struct wl1271 { | 322 | struct 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; |