diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 93 |
1 files changed, 34 insertions, 59 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 1e36fb3..7d9b21d 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -19,7 +19,7 @@ #include <linux/if_arp.h> #include <linux/rtnetlink.h> #include <linux/bitmap.h> -#include <linux/pm_qos_params.h> +#include <linux/pm_qos.h> #include <linux/inetdevice.h> #include <net/net_namespace.h> #include <net/cfg80211.h> @@ -92,47 +92,6 @@ static void ieee80211_reconfig_filter(struct work_struct *work) ieee80211_configure_filter(local); } -/* - * Returns true if we are logically configured to be on - * the operating channel AND the hardware-conf is currently - * configured on the operating channel. Compares channel-type - * as well. - */ -bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local) -{ - struct ieee80211_channel *chan, *scan_chan; - enum nl80211_channel_type channel_type; - - /* This logic needs to match logic in ieee80211_hw_config */ - if (local->scan_channel) { - chan = local->scan_channel; - /* If scanning on oper channel, use whatever channel-type - * is currently in use. - */ - if (chan == local->oper_channel) - channel_type = local->_oper_channel_type; - else - channel_type = NL80211_CHAN_NO_HT; - } else if (local->tmp_channel) { - chan = scan_chan = local->tmp_channel; - channel_type = local->tmp_channel_type; - } else { - chan = local->oper_channel; - channel_type = local->_oper_channel_type; - } - - if (chan != local->oper_channel || - channel_type != local->_oper_channel_type) - return false; - - /* Check current hardware-config against oper_channel. */ - if ((local->oper_channel != local->hw.conf.channel) || - (local->_oper_channel_type != local->hw.conf.channel_type)) - return false; - - return true; -} - int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) { struct ieee80211_channel *chan, *scan_chan; @@ -145,9 +104,6 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) scan_chan = local->scan_channel; - /* If this off-channel logic ever changes, ieee80211_on_oper_channel - * may need to change as well. - */ offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; if (scan_chan) { chan = scan_chan; @@ -158,19 +114,17 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) channel_type = local->_oper_channel_type; else channel_type = NL80211_CHAN_NO_HT; - } else if (local->tmp_channel) { + local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; + } else if (local->tmp_channel && + local->oper_channel != local->tmp_channel) { chan = scan_chan = local->tmp_channel; channel_type = local->tmp_channel_type; + local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; } else { chan = local->oper_channel; channel_type = local->_oper_channel_type; - } - - if (chan != local->oper_channel || - channel_type != local->_oper_channel_type) - local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; - else local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL; + } offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; @@ -279,7 +233,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, if (changed & BSS_CHANGED_BEACON_ENABLED) { if (local->quiescing || !ieee80211_sdata_running(sdata) || - test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) { + test_bit(SCAN_SW_SCANNING, &local->scanning)) { sdata->vif.bss_conf.enable_beacon = false; } else { /* @@ -325,6 +279,8 @@ u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) static void ieee80211_tasklet_handler(unsigned long data) { struct ieee80211_local *local = (struct ieee80211_local *) data; + struct sta_info *sta, *tmp; + struct skb_eosp_msg_data *eosp_data; struct sk_buff *skb; while ((skb = skb_dequeue(&local->skb_queue)) || @@ -340,6 +296,18 @@ static void ieee80211_tasklet_handler(unsigned long data) skb->pkt_type = 0; ieee80211_tx_status(local_to_hw(local), skb); break; + case IEEE80211_EOSP_MSG: + eosp_data = (void *)skb->cb; + for_each_sta_info(local, eosp_data->sta, sta, tmp) { + /* skip wrong virtual interface */ + if (memcmp(eosp_data->iface, + sta->sdata->vif.addr, ETH_ALEN)) + continue; + clear_sta_flag(sta, WLAN_STA_SP); + break; + } + dev_kfree_skb(skb); + break; default: WARN(1, "mac80211: Packet is of unknown type %d\n", skb->pkt_type); @@ -608,6 +576,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, local->hw.max_rates = 1; local->hw.max_report_rates = 0; local->hw.max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF; + local->hw.max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF; local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; local->user_power_level = -1; @@ -742,6 +711,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (!local->int_scan_req) return -ENOMEM; + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { + if (!local->hw.wiphy->bands[band]) + continue; + local->int_scan_req->rates[band] = (u32) -1; + } + /* if low-level driver supports AP, we also support VLAN */ if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); @@ -862,6 +837,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (local->ops->sched_scan_start) local->hw.wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; + /* mac80211 based drivers don't support internal TDLS setup */ + if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) + local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; + result = wiphy_register(local->hw.wiphy); if (result < 0) goto fail_wiphy_register; @@ -885,12 +864,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) * and we need some headroom for passing the frame to monitor * interfaces, but never both at the same time. */ -#ifndef __CHECKER__ - BUILD_BUG_ON(IEEE80211_TX_STATUS_HEADROOM != - sizeof(struct ieee80211_tx_status_rtap_hdr)); -#endif local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom, - sizeof(struct ieee80211_tx_status_rtap_hdr)); + IEEE80211_TX_STATUS_HEADROOM); debugfs_hw_add(local); @@ -1012,7 +987,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) cancel_work_sync(&local->reconfig_filter); ieee80211_clear_tx_pending(local); - sta_info_stop(local); rate_control_deinitialize(local); if (skb_queue_len(&local->skb_queue) || @@ -1024,6 +998,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) destroy_workqueue(local->workqueue); wiphy_unregister(local->hw.wiphy); + sta_info_stop(local); ieee80211_wep_free(local); ieee80211_led_exit(local); kfree(local->int_scan_req); |