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>
This commit is contained in:
parent
f027743430
commit
e5a359f873
@ -766,7 +766,7 @@ int wl1271_acx_sta_rate_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif)
|
||||
wlvif->basic_rate, wlvif->rate_set);
|
||||
|
||||
/* configure one basic rate class */
|
||||
acx->rate_policy_idx = cpu_to_le32(ACX_TX_BASIC_RATE);
|
||||
acx->rate_policy_idx = cpu_to_le32(wlvif->sta.basic_rate_idx);
|
||||
acx->rate_policy.enabled_rates = cpu_to_le32(wlvif->basic_rate);
|
||||
acx->rate_policy.short_retry_limit = c->short_retry_limit;
|
||||
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)
|
||||
}
|
||||
|
||||
/* configure one AP supported rate class */
|
||||
acx->rate_policy_idx = cpu_to_le32(ACX_TX_AP_FULL_RATE);
|
||||
acx->rate_policy_idx = cpu_to_le32(wlvif->sta.ap_rate_idx);
|
||||
acx->rate_policy.enabled_rates = cpu_to_le32(wlvif->rate_set);
|
||||
acx->rate_policy.short_retry_limit = c->short_retry_limit;
|
||||
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)
|
||||
* (p2p packets should always go out with OFDM rates, even
|
||||
* if we are currently connected to 11b AP)
|
||||
*/
|
||||
acx->rate_policy_idx = cpu_to_le32(ACX_TX_BASIC_RATE_P2P);
|
||||
acx->rate_policy_idx = cpu_to_le32(wlvif->sta.p2p_rate_idx);
|
||||
acx->rate_policy.enabled_rates =
|
||||
cpu_to_le32(CONF_TX_RATE_MASK_BASIC_P2P);
|
||||
acx->rate_policy.short_retry_limit = c->short_retry_limit;
|
||||
|
@ -654,11 +654,6 @@ struct acx_rate_class {
|
||||
u8 reserved;
|
||||
};
|
||||
|
||||
#define ACX_TX_BASIC_RATE 0
|
||||
#define ACX_TX_AP_FULL_RATE 1
|
||||
#define ACX_TX_BASIC_RATE_P2P 2
|
||||
#define ACX_TX_AP_MODE_MGMT_RATE 4
|
||||
#define ACX_TX_AP_MODE_BCST_RATE 5
|
||||
struct acx_rate_policy {
|
||||
struct acx_header header;
|
||||
|
||||
|
@ -434,7 +434,7 @@ int wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif)
|
||||
rc.long_retry_limit = 10;
|
||||
rc.short_retry_limit = 10;
|
||||
rc.aflags = 0;
|
||||
ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_MGMT_RATE);
|
||||
ret = wl1271_acx_ap_rate_policy(wl, &rc, wlvif->ap.mgmt_rate_idx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -443,7 +443,7 @@ int wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif)
|
||||
rc.short_retry_limit = 10;
|
||||
rc.long_retry_limit = 10;
|
||||
rc.aflags = 0;
|
||||
ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_BCST_RATE);
|
||||
ret = wl1271_acx_ap_rate_policy(wl, &rc, wlvif->ap.bcast_rate_idx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -465,7 +465,8 @@ int wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif)
|
||||
rc.short_retry_limit = 10;
|
||||
rc.long_retry_limit = 10;
|
||||
rc.aflags = 0;
|
||||
ret = wl1271_acx_ap_rate_policy(wl, &rc, i);
|
||||
ret = wl1271_acx_ap_rate_policy(wl, &rc,
|
||||
wlvif->ap.ucast_rate_idx[i]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
@ -1910,6 +1910,27 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
|
||||
mutex_unlock(&wl->mutex);
|
||||
}
|
||||
|
||||
static int wl12xx_allocate_rate_policy(struct wl1271 *wl, u8 *idx)
|
||||
{
|
||||
u8 policy = find_first_zero_bit(wl->rate_policies_map,
|
||||
WL12XX_MAX_RATE_POLICIES);
|
||||
if (policy >= WL12XX_MAX_RATE_POLICIES)
|
||||
return -EBUSY;
|
||||
|
||||
__set_bit(policy, wl->rate_policies_map);
|
||||
*idx = policy;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wl12xx_free_rate_policy(struct wl1271 *wl, u8 *idx)
|
||||
{
|
||||
if (WARN_ON(*idx >= WL12XX_MAX_RATE_POLICIES))
|
||||
return;
|
||||
|
||||
__clear_bit(*idx, wl->rate_policies_map);
|
||||
*idx = WL12XX_MAX_RATE_POLICIES;
|
||||
}
|
||||
|
||||
static u8 wl12xx_get_role_type(struct wl1271 *wl, struct wl12xx_vif *wlvif)
|
||||
{
|
||||
switch (wlvif->bss_type) {
|
||||
@ -1937,6 +1958,7 @@ static u8 wl12xx_get_role_type(struct wl1271 *wl, struct wl12xx_vif *wlvif)
|
||||
static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
|
||||
{
|
||||
struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
|
||||
int i;
|
||||
|
||||
/* clear everything but the persistent data */
|
||||
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)
|
||||
wlvif->bss_type == BSS_TYPE_IBSS) {
|
||||
/* init sta/ibss data */
|
||||
wlvif->sta.hlid = WL12XX_INVALID_LINK_ID;
|
||||
|
||||
wl12xx_allocate_rate_policy(wl, &wlvif->sta.basic_rate_idx);
|
||||
wl12xx_allocate_rate_policy(wl, &wlvif->sta.ap_rate_idx);
|
||||
wl12xx_allocate_rate_policy(wl, &wlvif->sta.p2p_rate_idx);
|
||||
} else {
|
||||
/* init ap data */
|
||||
wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID;
|
||||
wlvif->ap.global_hlid = WL12XX_INVALID_LINK_ID;
|
||||
wl12xx_allocate_rate_policy(wl, &wlvif->ap.mgmt_rate_idx);
|
||||
wl12xx_allocate_rate_policy(wl, &wlvif->ap.bcast_rate_idx);
|
||||
for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++)
|
||||
wl12xx_allocate_rate_policy(wl,
|
||||
&wlvif->ap.ucast_rate_idx[i]);
|
||||
}
|
||||
|
||||
wlvif->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate;
|
||||
@ -2181,7 +2210,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
|
||||
bool reset_tx_queues)
|
||||
{
|
||||
struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
|
||||
int ret;
|
||||
int i, ret;
|
||||
|
||||
wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
|
||||
|
||||
@ -2227,10 +2256,23 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
|
||||
}
|
||||
deinit:
|
||||
/* clear all hlids (except system_hlid) */
|
||||
wlvif->sta.hlid = WL12XX_INVALID_LINK_ID;
|
||||
wlvif->dev_hlid = WL12XX_INVALID_LINK_ID;
|
||||
wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID;
|
||||
wlvif->ap.global_hlid = WL12XX_INVALID_LINK_ID;
|
||||
|
||||
if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
|
||||
wlvif->bss_type == BSS_TYPE_IBSS) {
|
||||
wlvif->sta.hlid = WL12XX_INVALID_LINK_ID;
|
||||
wl12xx_free_rate_policy(wl, &wlvif->sta.basic_rate_idx);
|
||||
wl12xx_free_rate_policy(wl, &wlvif->sta.ap_rate_idx);
|
||||
wl12xx_free_rate_policy(wl, &wlvif->sta.p2p_rate_idx);
|
||||
} else {
|
||||
wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID;
|
||||
wlvif->ap.global_hlid = WL12XX_INVALID_LINK_ID;
|
||||
wl12xx_free_rate_policy(wl, &wlvif->ap.mgmt_rate_idx);
|
||||
wl12xx_free_rate_policy(wl, &wlvif->ap.bcast_rate_idx);
|
||||
for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++)
|
||||
wl12xx_free_rate_policy(wl,
|
||||
&wlvif->ap.ucast_rate_idx[i]);
|
||||
}
|
||||
|
||||
wl12xx_tx_reset_wlvif(wl, wlvif);
|
||||
wl1271_free_ap_keys(wl, wlvif);
|
||||
|
@ -339,16 +339,16 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
send them with AP rate policies, otherwise use default
|
||||
basic rates */
|
||||
if (control->control.sta)
|
||||
rate_idx = ACX_TX_AP_FULL_RATE;
|
||||
rate_idx = wlvif->sta.ap_rate_idx;
|
||||
else
|
||||
rate_idx = ACX_TX_BASIC_RATE;
|
||||
rate_idx = wlvif->sta.basic_rate_idx;
|
||||
} else {
|
||||
if (hlid == wlvif->ap.global_hlid)
|
||||
rate_idx = ACX_TX_AP_MODE_MGMT_RATE;
|
||||
rate_idx = wlvif->ap.mgmt_rate_idx;
|
||||
else if (hlid == wlvif->ap.bcast_hlid)
|
||||
rate_idx = ACX_TX_AP_MODE_BCST_RATE;
|
||||
rate_idx = wlvif->ap.bcast_rate_idx;
|
||||
else
|
||||
rate_idx = ac;
|
||||
rate_idx = wlvif->ap.ucast_rate_idx[ac];
|
||||
}
|
||||
|
||||
tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY;
|
||||
|
@ -142,6 +142,8 @@ extern u32 wl12xx_debug_level;
|
||||
#define WL12XX_INVALID_ROLE_ID 0xff
|
||||
#define WL12XX_INVALID_LINK_ID 0xff
|
||||
|
||||
#define WL12XX_MAX_RATE_POLICIES 16
|
||||
|
||||
/* Defined by FW as 0. Will not be freed or allocated. */
|
||||
#define WL12XX_SYSTEM_HLID 0
|
||||
|
||||
@ -396,8 +398,11 @@ struct wl1271 {
|
||||
unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)];
|
||||
unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
|
||||
unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
|
||||
unsigned long rate_policies_map[
|
||||
BITS_TO_LONGS(WL12XX_MAX_RATE_POLICIES)];
|
||||
|
||||
struct list_head wlvif_list;
|
||||
|
||||
u8 sta_count;
|
||||
u8 ap_count;
|
||||
|
||||
@ -569,6 +574,10 @@ struct wl12xx_vif {
|
||||
struct {
|
||||
u8 hlid;
|
||||
u8 ba_rx_bitmap;
|
||||
|
||||
u8 basic_rate_idx;
|
||||
u8 ap_rate_idx;
|
||||
u8 p2p_rate_idx;
|
||||
} sta;
|
||||
struct {
|
||||
u8 global_hlid;
|
||||
@ -580,6 +589,10 @@ struct wl12xx_vif {
|
||||
|
||||
/* recoreded keys - set here before AP startup */
|
||||
struct wl1271_ap_key *recorded_keys[MAX_NUM_KEYS];
|
||||
|
||||
u8 mgmt_rate_idx;
|
||||
u8 bcast_rate_idx;
|
||||
u8 ucast_rate_idx[CONF_TX_MAX_AC_COUNT];
|
||||
} ap;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user