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>
This commit is contained in:
parent
fe5ef09066
commit
72c2d9e511
@ -783,6 +783,10 @@ int wl1271_acx_sta_rate_policies(struct wl1271 *wl)
|
||||
|
||||
acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT);
|
||||
|
||||
wl1271_debug(DEBUG_ACX, "basic_rate: 0x%x, full_rate: 0x%x",
|
||||
acx->rate_class[ACX_TX_BASIC_RATE].enabled_rates,
|
||||
acx->rate_class[ACX_TX_AP_FULL_RATE].enabled_rates);
|
||||
|
||||
ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
|
||||
if (ret < 0) {
|
||||
wl1271_warning("Setting of rate policies failed: %d", ret);
|
||||
|
@ -286,13 +286,7 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
|
||||
join->rx_filter_options = cpu_to_le32(wl->rx_filter);
|
||||
join->bss_type = bss_type;
|
||||
join->basic_rate_set = cpu_to_le32(wl->basic_rate_set);
|
||||
/*
|
||||
* for supported_rate_set, we should use wl->rate_set. however,
|
||||
* it seems that acx_rate_policies doesn't affect full_rate, and
|
||||
* since we want to avoid additional join, we'll use a 0xffffffff value,
|
||||
* and let the fw find the actual supported rates
|
||||
*/
|
||||
join->supported_rate_set = cpu_to_le32(0xffffffff);
|
||||
join->supported_rate_set = cpu_to_le32(wl->rate_set);
|
||||
|
||||
if (wl->band == IEEE80211_BAND_5GHZ)
|
||||
join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ;
|
||||
@ -310,6 +304,9 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
|
||||
wl->tx_security_last_seq = 0;
|
||||
wl->tx_security_seq = 0;
|
||||
|
||||
wl1271_debug(DEBUG_CMD, "cmd join: basic_rate_set=0x%x, rate_set=0x%x",
|
||||
join->basic_rate_set, join->supported_rate_set);
|
||||
|
||||
ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0);
|
||||
if (ret < 0) {
|
||||
wl1271_error("failed to initiate cmd join");
|
||||
|
@ -978,39 +978,10 @@ int wl1271_plt_stop(struct wl1271 *wl)
|
||||
static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
{
|
||||
struct wl1271 *wl = hw->priv;
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_sta *sta = txinfo->control.sta;
|
||||
unsigned long flags;
|
||||
int q;
|
||||
|
||||
/*
|
||||
* peek into the rates configured in the STA entry.
|
||||
* The rates set after connection stage, The first block only BG sets:
|
||||
* the compare is for bit 0-16 of sta_rate_set. The second block add
|
||||
* HT rates in case of HT supported.
|
||||
*/
|
||||
spin_lock_irqsave(&wl->wl_lock, flags);
|
||||
if (sta &&
|
||||
(sta->supp_rates[conf->channel->band] !=
|
||||
(wl->sta_rate_set & HW_BG_RATES_MASK)) &&
|
||||
wl->bss_type != BSS_TYPE_AP_BSS) {
|
||||
wl->sta_rate_set = sta->supp_rates[conf->channel->band];
|
||||
set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_WL12XX_HT
|
||||
if (sta &&
|
||||
sta->ht_cap.ht_supported &&
|
||||
((wl->sta_rate_set >> HW_HT_RATES_OFFSET) !=
|
||||
sta->ht_cap.mcs.rx_mask[0])) {
|
||||
/* Clean MCS bits before setting them */
|
||||
wl->sta_rate_set &= HW_BG_RATES_MASK;
|
||||
wl->sta_rate_set |=
|
||||
(sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
|
||||
set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
|
||||
}
|
||||
#endif
|
||||
wl->tx_queue_count++;
|
||||
spin_unlock_irqrestore(&wl->wl_lock, flags);
|
||||
|
||||
@ -1245,7 +1216,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
|
||||
wl->time_offset = 0;
|
||||
wl->session_counter = 0;
|
||||
wl->rate_set = CONF_TX_RATE_MASK_BASIC;
|
||||
wl->sta_rate_set = 0;
|
||||
wl->flags = 0;
|
||||
wl->vif = NULL;
|
||||
wl->filters = 0;
|
||||
@ -1432,7 +1402,6 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle)
|
||||
goto out;
|
||||
}
|
||||
wl->rate_set = wl1271_tx_min_rate_get(wl);
|
||||
wl->sta_rate_set = 0;
|
||||
ret = wl1271_acx_sta_rate_policies(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
@ -2246,6 +2215,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
|
||||
{
|
||||
bool do_join = false, set_assoc = false;
|
||||
bool is_ibss = (wl->bss_type == BSS_TYPE_IBSS);
|
||||
u32 sta_rate_set = 0;
|
||||
int ret;
|
||||
struct ieee80211_sta *sta;
|
||||
|
||||
@ -2311,6 +2281,49 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
|
||||
}
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
sta = ieee80211_find_sta(vif, bss_conf->bssid);
|
||||
if (sta) {
|
||||
/* save the supp_rates of the ap */
|
||||
sta_rate_set = sta->supp_rates[wl->hw->conf.channel->band];
|
||||
if (sta->ht_cap.ht_supported)
|
||||
sta_rate_set |=
|
||||
(sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
|
||||
|
||||
/* handle new association with HT and HT information change */
|
||||
if ((changed & BSS_CHANGED_HT) &&
|
||||
(bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
|
||||
ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
|
||||
true);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("Set ht cap true failed %d",
|
||||
ret);
|
||||
rcu_read_unlock();
|
||||
goto out;
|
||||
}
|
||||
ret = wl1271_acx_set_ht_information(wl,
|
||||
bss_conf->ht_operation_mode);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("Set ht information failed %d",
|
||||
ret);
|
||||
rcu_read_unlock();
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/* handle new association without HT and disassociation */
|
||||
else if (changed & BSS_CHANGED_ASSOC) {
|
||||
ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
|
||||
false);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("Set ht cap false failed %d",
|
||||
ret);
|
||||
rcu_read_unlock();
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
if ((changed & BSS_CHANGED_ASSOC)) {
|
||||
if (bss_conf->assoc) {
|
||||
u32 rates;
|
||||
@ -2328,6 +2341,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
|
||||
wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl,
|
||||
rates);
|
||||
wl->basic_rate = wl1271_tx_min_rate_get(wl);
|
||||
if (sta_rate_set)
|
||||
wl->rate_set = wl1271_tx_enabled_rates_get(wl,
|
||||
sta_rate_set);
|
||||
ret = wl1271_acx_sta_rate_policies(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
@ -2406,43 +2422,6 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
rcu_read_lock();
|
||||
sta = ieee80211_find_sta(vif, bss_conf->bssid);
|
||||
if (sta) {
|
||||
/* handle new association with HT and HT information change */
|
||||
if ((changed & BSS_CHANGED_HT) &&
|
||||
(bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
|
||||
ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
|
||||
true);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("Set ht cap true failed %d",
|
||||
ret);
|
||||
rcu_read_unlock();
|
||||
goto out;
|
||||
}
|
||||
ret = wl1271_acx_set_ht_information(wl,
|
||||
bss_conf->ht_operation_mode);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("Set ht information failed %d",
|
||||
ret);
|
||||
rcu_read_unlock();
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/* handle new association without HT and disassociation */
|
||||
else if (changed & BSS_CHANGED_ASSOC) {
|
||||
ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
|
||||
false);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("Set ht cap false failed %d",
|
||||
ret);
|
||||
rcu_read_unlock();
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
if (changed & BSS_CHANGED_ARP_FILTER) {
|
||||
__be32 addr = bss_conf->arp_addr_list[0];
|
||||
WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
|
||||
@ -3330,7 +3309,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
|
||||
wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC;
|
||||
wl->basic_rate = CONF_TX_RATE_MASK_BASIC;
|
||||
wl->rate_set = CONF_TX_RATE_MASK_BASIC;
|
||||
wl->sta_rate_set = 0;
|
||||
wl->band = IEEE80211_BAND_2GHZ;
|
||||
wl->vif = NULL;
|
||||
wl->flags = 0;
|
||||
|
@ -334,35 +334,13 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
bool woken_up = false;
|
||||
u32 sta_rates = 0;
|
||||
u32 buf_offset = 0;
|
||||
bool sent_packets = false;
|
||||
int ret;
|
||||
|
||||
/* check if the rates supported by the AP have changed */
|
||||
if (unlikely(test_and_clear_bit(WL1271_FLAG_STA_RATES_CHANGED,
|
||||
&wl->flags))) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&wl->wl_lock, flags);
|
||||
sta_rates = wl->sta_rate_set;
|
||||
spin_unlock_irqrestore(&wl->wl_lock, flags);
|
||||
}
|
||||
|
||||
if (unlikely(wl->state == WL1271_STATE_OFF))
|
||||
goto out;
|
||||
|
||||
/* if rates have changed, re-configure the rate policy */
|
||||
if (unlikely(sta_rates)) {
|
||||
ret = wl1271_ps_elp_wakeup(wl, false);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
woken_up = true;
|
||||
|
||||
wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates);
|
||||
wl1271_acx_sta_rate_policies(wl);
|
||||
}
|
||||
|
||||
while ((skb = wl1271_skb_dequeue(wl))) {
|
||||
if (!woken_up) {
|
||||
ret = wl1271_ps_elp_wakeup(wl, false);
|
||||
|
@ -301,6 +301,24 @@ struct wl1271_ap_key {
|
||||
u16 tx_seq_16;
|
||||
};
|
||||
|
||||
enum wl12xx_flags {
|
||||
WL1271_FLAG_STA_ASSOCIATED,
|
||||
WL1271_FLAG_JOINED,
|
||||
WL1271_FLAG_GPIO_POWER,
|
||||
WL1271_FLAG_TX_QUEUE_STOPPED,
|
||||
WL1271_FLAG_IN_ELP,
|
||||
WL1271_FLAG_PSM,
|
||||
WL1271_FLAG_PSM_REQUESTED,
|
||||
WL1271_FLAG_IRQ_PENDING,
|
||||
WL1271_FLAG_IRQ_RUNNING,
|
||||
WL1271_FLAG_IDLE,
|
||||
WL1271_FLAG_IDLE_REQUESTED,
|
||||
WL1271_FLAG_PSPOLL_FAILURE,
|
||||
WL1271_FLAG_STA_STATE_SENT,
|
||||
WL1271_FLAG_FW_TX_BUSY,
|
||||
WL1271_FLAG_AP_STARTED
|
||||
};
|
||||
|
||||
struct wl1271 {
|
||||
struct platform_device *plat_dev;
|
||||
struct ieee80211_hw *hw;
|
||||
@ -319,22 +337,6 @@ struct wl1271 {
|
||||
enum wl1271_state state;
|
||||
struct mutex mutex;
|
||||
|
||||
#define WL1271_FLAG_STA_RATES_CHANGED (0)
|
||||
#define WL1271_FLAG_STA_ASSOCIATED (1)
|
||||
#define WL1271_FLAG_JOINED (2)
|
||||
#define WL1271_FLAG_GPIO_POWER (3)
|
||||
#define WL1271_FLAG_TX_QUEUE_STOPPED (4)
|
||||
#define WL1271_FLAG_IN_ELP (5)
|
||||
#define WL1271_FLAG_PSM (6)
|
||||
#define WL1271_FLAG_PSM_REQUESTED (7)
|
||||
#define WL1271_FLAG_IRQ_PENDING (8)
|
||||
#define WL1271_FLAG_IRQ_RUNNING (9)
|
||||
#define WL1271_FLAG_IDLE (10)
|
||||
#define WL1271_FLAG_IDLE_REQUESTED (11)
|
||||
#define WL1271_FLAG_PSPOLL_FAILURE (12)
|
||||
#define WL1271_FLAG_STA_STATE_SENT (13)
|
||||
#define WL1271_FLAG_FW_TX_BUSY (14)
|
||||
#define WL1271_FLAG_AP_STARTED (15)
|
||||
unsigned long flags;
|
||||
|
||||
struct wl1271_partition_set part;
|
||||
@ -428,7 +430,6 @@ struct wl1271 {
|
||||
* bits 16-23 - 802.11n MCS index mask
|
||||
* support only 1 stream, thus only 8 bits for the MCS rates (0-7).
|
||||
*/
|
||||
u32 sta_rate_set;
|
||||
u32 basic_rate_set;
|
||||
u32 basic_rate;
|
||||
u32 rate_set;
|
||||
|
Loading…
Reference in New Issue
Block a user