diff options
-rw-r--r-- | drivers/net/wireless/wl12xx/acx.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/acx.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/init.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 52 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl12xx.h | 13 |
6 files changed, 72 insertions, 21 deletions
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 21e74ca4ddb2..e2e46705059d 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c | |||
@@ -766,7 +766,7 @@ int wl1271_acx_sta_rate_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
766 | wlvif->basic_rate, wlvif->rate_set); | 766 | wlvif->basic_rate, wlvif->rate_set); |
767 | 767 | ||
768 | /* configure one basic rate class */ | 768 | /* configure one basic rate class */ |
769 | acx->rate_policy_idx = cpu_to_le32(ACX_TX_BASIC_RATE); | 769 | acx->rate_policy_idx = cpu_to_le32(wlvif->sta.basic_rate_idx); |
770 | acx->rate_policy.enabled_rates = cpu_to_le32(wlvif->basic_rate); | 770 | acx->rate_policy.enabled_rates = cpu_to_le32(wlvif->basic_rate); |
771 | acx->rate_policy.short_retry_limit = c->short_retry_limit; | 771 | acx->rate_policy.short_retry_limit = c->short_retry_limit; |
772 | acx->rate_policy.long_retry_limit = c->long_retry_limit; | 772 | acx->rate_policy.long_retry_limit = c->long_retry_limit; |
@@ -779,7 +779,7 @@ int wl1271_acx_sta_rate_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
779 | } | 779 | } |
780 | 780 | ||
781 | /* configure one AP supported rate class */ | 781 | /* configure one AP supported rate class */ |
782 | acx->rate_policy_idx = cpu_to_le32(ACX_TX_AP_FULL_RATE); | 782 | acx->rate_policy_idx = cpu_to_le32(wlvif->sta.ap_rate_idx); |
783 | acx->rate_policy.enabled_rates = cpu_to_le32(wlvif->rate_set); | 783 | acx->rate_policy.enabled_rates = cpu_to_le32(wlvif->rate_set); |
784 | acx->rate_policy.short_retry_limit = c->short_retry_limit; | 784 | acx->rate_policy.short_retry_limit = c->short_retry_limit; |
785 | acx->rate_policy.long_retry_limit = c->long_retry_limit; | 785 | acx->rate_policy.long_retry_limit = c->long_retry_limit; |
@@ -796,7 +796,7 @@ int wl1271_acx_sta_rate_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
796 | * (p2p packets should always go out with OFDM rates, even | 796 | * (p2p packets should always go out with OFDM rates, even |
797 | * if we are currently connected to 11b AP) | 797 | * if we are currently connected to 11b AP) |
798 | */ | 798 | */ |
799 | acx->rate_policy_idx = cpu_to_le32(ACX_TX_BASIC_RATE_P2P); | 799 | acx->rate_policy_idx = cpu_to_le32(wlvif->sta.p2p_rate_idx); |
800 | acx->rate_policy.enabled_rates = | 800 | acx->rate_policy.enabled_rates = |
801 | cpu_to_le32(CONF_TX_RATE_MASK_BASIC_P2P); | 801 | cpu_to_le32(CONF_TX_RATE_MASK_BASIC_P2P); |
802 | acx->rate_policy.short_retry_limit = c->short_retry_limit; | 802 | acx->rate_policy.short_retry_limit = c->short_retry_limit; |
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index c06119b053e3..b2d85bea6378 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h | |||
@@ -654,11 +654,6 @@ struct acx_rate_class { | |||
654 | u8 reserved; | 654 | u8 reserved; |
655 | }; | 655 | }; |
656 | 656 | ||
657 | #define ACX_TX_BASIC_RATE 0 | ||
658 | #define ACX_TX_AP_FULL_RATE 1 | ||
659 | #define ACX_TX_BASIC_RATE_P2P 2 | ||
660 | #define ACX_TX_AP_MODE_MGMT_RATE 4 | ||
661 | #define ACX_TX_AP_MODE_BCST_RATE 5 | ||
662 | struct acx_rate_policy { | 657 | struct acx_rate_policy { |
663 | struct acx_header header; | 658 | struct acx_header header; |
664 | 659 | ||
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index 74f569099b53..ba286d0a74a8 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c | |||
@@ -434,7 +434,7 @@ int wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
434 | rc.long_retry_limit = 10; | 434 | rc.long_retry_limit = 10; |
435 | rc.short_retry_limit = 10; | 435 | rc.short_retry_limit = 10; |
436 | rc.aflags = 0; | 436 | rc.aflags = 0; |
437 | ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_MGMT_RATE); | 437 | ret = wl1271_acx_ap_rate_policy(wl, &rc, wlvif->ap.mgmt_rate_idx); |
438 | if (ret < 0) | 438 | if (ret < 0) |
439 | return ret; | 439 | return ret; |
440 | 440 | ||
@@ -443,7 +443,7 @@ int wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
443 | rc.short_retry_limit = 10; | 443 | rc.short_retry_limit = 10; |
444 | rc.long_retry_limit = 10; | 444 | rc.long_retry_limit = 10; |
445 | rc.aflags = 0; | 445 | rc.aflags = 0; |
446 | ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_BCST_RATE); | 446 | ret = wl1271_acx_ap_rate_policy(wl, &rc, wlvif->ap.bcast_rate_idx); |
447 | if (ret < 0) | 447 | if (ret < 0) |
448 | return ret; | 448 | return ret; |
449 | 449 | ||
@@ -465,7 +465,8 @@ int wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
465 | rc.short_retry_limit = 10; | 465 | rc.short_retry_limit = 10; |
466 | rc.long_retry_limit = 10; | 466 | rc.long_retry_limit = 10; |
467 | rc.aflags = 0; | 467 | rc.aflags = 0; |
468 | ret = wl1271_acx_ap_rate_policy(wl, &rc, i); | 468 | ret = wl1271_acx_ap_rate_policy(wl, &rc, |
469 | wlvif->ap.ucast_rate_idx[i]); | ||
469 | if (ret < 0) | 470 | if (ret < 0) |
470 | return ret; | 471 | return ret; |
471 | } | 472 | } |
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 433a06fae40b..cd2722562e60 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -1910,6 +1910,27 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) | |||
1910 | mutex_unlock(&wl->mutex); | 1910 | mutex_unlock(&wl->mutex); |
1911 | } | 1911 | } |
1912 | 1912 | ||
1913 | static int wl12xx_allocate_rate_policy(struct wl1271 *wl, u8 *idx) | ||
1914 | { | ||
1915 | u8 policy = find_first_zero_bit(wl->rate_policies_map, | ||
1916 | WL12XX_MAX_RATE_POLICIES); | ||
1917 | if (policy >= WL12XX_MAX_RATE_POLICIES) | ||
1918 | return -EBUSY; | ||
1919 | |||
1920 | __set_bit(policy, wl->rate_policies_map); | ||
1921 | *idx = policy; | ||
1922 | return 0; | ||
1923 | } | ||
1924 | |||
1925 | static void wl12xx_free_rate_policy(struct wl1271 *wl, u8 *idx) | ||
1926 | { | ||
1927 | if (WARN_ON(*idx >= WL12XX_MAX_RATE_POLICIES)) | ||
1928 | return; | ||
1929 | |||
1930 | __clear_bit(*idx, wl->rate_policies_map); | ||
1931 | *idx = WL12XX_MAX_RATE_POLICIES; | ||
1932 | } | ||
1933 | |||
1913 | static u8 wl12xx_get_role_type(struct wl1271 *wl, struct wl12xx_vif *wlvif) | 1934 | static u8 wl12xx_get_role_type(struct wl1271 *wl, struct wl12xx_vif *wlvif) |
1914 | { | 1935 | { |
1915 | switch (wlvif->bss_type) { | 1936 | switch (wlvif->bss_type) { |
@@ -1937,6 +1958,7 @@ static u8 wl12xx_get_role_type(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
1937 | static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif) | 1958 | static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif) |
1938 | { | 1959 | { |
1939 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | 1960 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); |
1961 | int i; | ||
1940 | 1962 | ||
1941 | /* clear everything but the persistent data */ | 1963 | /* clear everything but the persistent data */ |
1942 | memset(wlvif, 0, offsetof(struct wl12xx_vif, persistent)); | 1964 | memset(wlvif, 0, offsetof(struct wl12xx_vif, persistent)); |
@@ -1970,11 +1992,18 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif) | |||
1970 | wlvif->bss_type == BSS_TYPE_IBSS) { | 1992 | wlvif->bss_type == BSS_TYPE_IBSS) { |
1971 | /* init sta/ibss data */ | 1993 | /* init sta/ibss data */ |
1972 | wlvif->sta.hlid = WL12XX_INVALID_LINK_ID; | 1994 | wlvif->sta.hlid = WL12XX_INVALID_LINK_ID; |
1973 | 1995 | wl12xx_allocate_rate_policy(wl, &wlvif->sta.basic_rate_idx); | |
1996 | wl12xx_allocate_rate_policy(wl, &wlvif->sta.ap_rate_idx); | ||
1997 | wl12xx_allocate_rate_policy(wl, &wlvif->sta.p2p_rate_idx); | ||
1974 | } else { | 1998 | } else { |
1975 | /* init ap data */ | 1999 | /* init ap data */ |
1976 | wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID; | 2000 | wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID; |
1977 | wlvif->ap.global_hlid = WL12XX_INVALID_LINK_ID; | 2001 | wlvif->ap.global_hlid = WL12XX_INVALID_LINK_ID; |
2002 | wl12xx_allocate_rate_policy(wl, &wlvif->ap.mgmt_rate_idx); | ||
2003 | wl12xx_allocate_rate_policy(wl, &wlvif->ap.bcast_rate_idx); | ||
2004 | for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++) | ||
2005 | wl12xx_allocate_rate_policy(wl, | ||
2006 | &wlvif->ap.ucast_rate_idx[i]); | ||
1978 | } | 2007 | } |
1979 | 2008 | ||
1980 | wlvif->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate; | 2009 | wlvif->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate; |
@@ -2181,7 +2210,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, | |||
2181 | bool reset_tx_queues) | 2210 | bool reset_tx_queues) |
2182 | { | 2211 | { |
2183 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | 2212 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); |
2184 | int ret; | 2213 | int i, ret; |
2185 | 2214 | ||
2186 | wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); | 2215 | wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); |
2187 | 2216 | ||
@@ -2227,10 +2256,23 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, | |||
2227 | } | 2256 | } |
2228 | deinit: | 2257 | deinit: |
2229 | /* clear all hlids (except system_hlid) */ | 2258 | /* clear all hlids (except system_hlid) */ |
2230 | wlvif->sta.hlid = WL12XX_INVALID_LINK_ID; | ||
2231 | wlvif->dev_hlid = WL12XX_INVALID_LINK_ID; | 2259 | wlvif->dev_hlid = WL12XX_INVALID_LINK_ID; |
2232 | wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID; | 2260 | |
2233 | wlvif->ap.global_hlid = WL12XX_INVALID_LINK_ID; | 2261 | if (wlvif->bss_type == BSS_TYPE_STA_BSS || |
2262 | wlvif->bss_type == BSS_TYPE_IBSS) { | ||
2263 | wlvif->sta.hlid = WL12XX_INVALID_LINK_ID; | ||
2264 | wl12xx_free_rate_policy(wl, &wlvif->sta.basic_rate_idx); | ||
2265 | wl12xx_free_rate_policy(wl, &wlvif->sta.ap_rate_idx); | ||
2266 | wl12xx_free_rate_policy(wl, &wlvif->sta.p2p_rate_idx); | ||
2267 | } else { | ||
2268 | wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID; | ||
2269 | wlvif->ap.global_hlid = WL12XX_INVALID_LINK_ID; | ||
2270 | wl12xx_free_rate_policy(wl, &wlvif->ap.mgmt_rate_idx); | ||
2271 | wl12xx_free_rate_policy(wl, &wlvif->ap.bcast_rate_idx); | ||
2272 | for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++) | ||
2273 | wl12xx_free_rate_policy(wl, | ||
2274 | &wlvif->ap.ucast_rate_idx[i]); | ||
2275 | } | ||
2234 | 2276 | ||
2235 | wl12xx_tx_reset_wlvif(wl, wlvif); | 2277 | wl12xx_tx_reset_wlvif(wl, wlvif); |
2236 | wl1271_free_ap_keys(wl, wlvif); | 2278 | wl1271_free_ap_keys(wl, wlvif); |
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 185a65d971ff..69ac03f5d54b 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c | |||
@@ -339,16 +339,16 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
339 | send them with AP rate policies, otherwise use default | 339 | send them with AP rate policies, otherwise use default |
340 | basic rates */ | 340 | basic rates */ |
341 | if (control->control.sta) | 341 | if (control->control.sta) |
342 | rate_idx = ACX_TX_AP_FULL_RATE; | 342 | rate_idx = wlvif->sta.ap_rate_idx; |
343 | else | 343 | else |
344 | rate_idx = ACX_TX_BASIC_RATE; | 344 | rate_idx = wlvif->sta.basic_rate_idx; |
345 | } else { | 345 | } else { |
346 | if (hlid == wlvif->ap.global_hlid) | 346 | if (hlid == wlvif->ap.global_hlid) |
347 | rate_idx = ACX_TX_AP_MODE_MGMT_RATE; | 347 | rate_idx = wlvif->ap.mgmt_rate_idx; |
348 | else if (hlid == wlvif->ap.bcast_hlid) | 348 | else if (hlid == wlvif->ap.bcast_hlid) |
349 | rate_idx = ACX_TX_AP_MODE_BCST_RATE; | 349 | rate_idx = wlvif->ap.bcast_rate_idx; |
350 | else | 350 | else |
351 | rate_idx = ac; | 351 | rate_idx = wlvif->ap.ucast_rate_idx[ac]; |
352 | } | 352 | } |
353 | 353 | ||
354 | tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY; | 354 | tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY; |
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 2689522ba4ed..d169d52f6d1c 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h | |||
@@ -142,6 +142,8 @@ extern u32 wl12xx_debug_level; | |||
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 | ||
145 | #define WL12XX_MAX_RATE_POLICIES 16 | ||
146 | |||
145 | /* Defined by FW as 0. Will not be freed or allocated. */ | 147 | /* Defined by FW as 0. Will not be freed or allocated. */ |
146 | #define WL12XX_SYSTEM_HLID 0 | 148 | #define WL12XX_SYSTEM_HLID 0 |
147 | 149 | ||
@@ -396,8 +398,11 @@ struct wl1271 { | |||
396 | unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)]; | 398 | unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)]; |
397 | unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)]; | 399 | unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)]; |
398 | unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)]; | 400 | unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)]; |
401 | unsigned long rate_policies_map[ | ||
402 | BITS_TO_LONGS(WL12XX_MAX_RATE_POLICIES)]; | ||
399 | 403 | ||
400 | struct list_head wlvif_list; | 404 | struct list_head wlvif_list; |
405 | |||
401 | u8 sta_count; | 406 | u8 sta_count; |
402 | u8 ap_count; | 407 | u8 ap_count; |
403 | 408 | ||
@@ -569,6 +574,10 @@ struct wl12xx_vif { | |||
569 | struct { | 574 | struct { |
570 | u8 hlid; | 575 | u8 hlid; |
571 | u8 ba_rx_bitmap; | 576 | u8 ba_rx_bitmap; |
577 | |||
578 | u8 basic_rate_idx; | ||
579 | u8 ap_rate_idx; | ||
580 | u8 p2p_rate_idx; | ||
572 | } sta; | 581 | } sta; |
573 | struct { | 582 | struct { |
574 | u8 global_hlid; | 583 | u8 global_hlid; |
@@ -580,6 +589,10 @@ struct wl12xx_vif { | |||
580 | 589 | ||
581 | /* recoreded keys - set here before AP startup */ | 590 | /* recoreded keys - set here before AP startup */ |
582 | struct wl1271_ap_key *recorded_keys[MAX_NUM_KEYS]; | 591 | struct wl1271_ap_key *recorded_keys[MAX_NUM_KEYS]; |
592 | |||
593 | u8 mgmt_rate_idx; | ||
594 | u8 bcast_rate_idx; | ||
595 | u8 ucast_rate_idx[CONF_TX_MAX_AC_COUNT]; | ||
583 | } ap; | 596 | } ap; |
584 | }; | 597 | }; |
585 | 598 | ||