diff options
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 70 |
1 files changed, 66 insertions, 4 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 290b0017ef2..5ba721b6a39 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -309,7 +309,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ); mgmt->u.assoc_req.capab_info = cpu_to_le16(capab); - mgmt->u.reassoc_req.listen_interval = + mgmt->u.assoc_req.listen_interval = cpu_to_le16(local->hw.conf.listen_interval); } @@ -744,6 +744,17 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, bss_info_changed |= BSS_CHANGED_BASIC_RATES; ieee80211_bss_info_change_notify(sdata, bss_info_changed); + if (local->powersave) { + if (local->dynamic_ps_timeout > 0) + mod_timer(&local->dynamic_ps_timer, jiffies + + msecs_to_jiffies(local->dynamic_ps_timeout)); + else { + conf->flags |= IEEE80211_CONF_PS; + ieee80211_hw_config(local, + IEEE80211_CONF_CHANGE_PS); + } + } + netif_tx_start_all_queues(sdata->dev); netif_carrier_on(sdata->dev); @@ -812,7 +823,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, { struct ieee80211_local *local = sdata->local; struct sta_info *sta; - u32 changed = 0; + u32 changed = 0, config_changed = 0; rcu_read_lock(); @@ -858,8 +869,18 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, rcu_read_unlock(); local->hw.conf.ht.enabled = false; - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT); + local->oper_channel_type = NL80211_CHAN_NO_HT; + config_changed |= IEEE80211_CONF_CHANGE_HT; + + del_timer_sync(&local->dynamic_ps_timer); + cancel_work_sync(&local->dynamic_ps_enable_work); + if (local->hw.conf.flags & IEEE80211_CONF_PS) { + local->hw.conf.flags &= ~IEEE80211_CONF_PS; + config_changed |= IEEE80211_CONF_CHANGE_PS; + } + + ieee80211_hw_config(local, config_changed); ieee80211_bss_info_change_notify(sdata, changed); rcu_read_lock(); @@ -1612,8 +1633,13 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, * e.g: at 1 MBit that means mactime is 192 usec earlier * (=24 bytes * 8 usecs/byte) than the beacon timestamp. */ - int rate = local->hw.wiphy->bands[band]-> + int rate; + if (rx_status->flag & RX_FLAG_HT) { + rate = 65; /* TODO: HT rates */ + } else { + rate = local->hw.wiphy->bands[band]-> bitrates[rx_status->rate_idx].bitrate; + } rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate); } else if (local && local->ops && local->ops->get_tsf) /* second best option: get current TSF */ @@ -2576,3 +2602,39 @@ void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local) ieee80211_restart_sta_timer(sdata); rcu_read_unlock(); } + +void ieee80211_dynamic_ps_disable_work(struct work_struct *work) +{ + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, + dynamic_ps_disable_work); + + if (local->hw.conf.flags & IEEE80211_CONF_PS) { + local->hw.conf.flags &= ~IEEE80211_CONF_PS; + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); + } + + ieee80211_wake_queues_by_reason(&local->hw, + IEEE80211_QUEUE_STOP_REASON_PS); +} + +void ieee80211_dynamic_ps_enable_work(struct work_struct *work) +{ + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, + dynamic_ps_enable_work); + + if (local->hw.conf.flags & IEEE80211_CONF_PS) + return; + + local->hw.conf.flags |= IEEE80211_CONF_PS; + + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); +} + +void ieee80211_dynamic_ps_timer(unsigned long data) +{ + struct ieee80211_local *local = (void *) data; + + queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work); +} |