aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/main.c
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2011-10-10 04:13:15 -0400
committerLuciano Coelho <coelho@ti.com>2011-10-11 08:28:02 -0400
commite5a359f873f50cc123d5ca97637caa30fa095bb9 (patch)
tree68eb06e69870e7637667042aa25a3b745f59bd4f /drivers/net/wireless/wl12xx/main.c
parentf02774343030c2794bb58b6150420dfefc31c39f (diff)
wl12xx: use dynamic rate policies
allocate the rate policies dynamically, instead of using hardcoded indexes. this is needed for proper multi-role configuration. Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/main.c')
-rw-r--r--drivers/net/wireless/wl12xx/main.c52
1 files changed, 47 insertions, 5 deletions
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
1913static 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
1925static 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
1913static u8 wl12xx_get_role_type(struct wl1271 *wl, struct wl12xx_vif *wlvif) 1934static 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)
1937static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif) 1958static 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 }
2228deinit: 2257deinit:
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);