]> Pileus Git - ~andy/linux/blobdiff - net/mac80211/util.c
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville...
[~andy/linux] / net / mac80211 / util.c
index d3fe2d2374859566d0c968a949aff2536dadf60d..5bfb80cba634496ed67025aed8ab70f17c0ca258 100644 (file)
@@ -1018,7 +1018,8 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
 struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
                                          u8 *dst,
                                          const u8 *ssid, size_t ssid_len,
-                                         const u8 *ie, size_t ie_len)
+                                         const u8 *ie, size_t ie_len,
+                                         bool directed)
 {
        struct ieee80211_local *local = sdata->local;
        struct sk_buff *skb;
@@ -1035,8 +1036,16 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
                return NULL;
        }
 
-       chan = ieee80211_frequency_to_channel(
-               local->hw.conf.channel->center_freq);
+       /*
+        * Do not send DS Channel parameter for directed probe requests
+        * in order to maximize the chance that we get a response.  Some
+        * badly-behaved APs don't respond when this parameter is included.
+        */
+       if (directed)
+               chan = 0;
+       else
+               chan = ieee80211_frequency_to_channel(
+                       local->hw.conf.channel->center_freq);
 
        buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len,
                                           local->hw.conf.channel->band,
@@ -1062,11 +1071,13 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
 
 void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
                              const u8 *ssid, size_t ssid_len,
-                             const u8 *ie, size_t ie_len)
+                             const u8 *ie, size_t ie_len,
+                             bool directed)
 {
        struct sk_buff *skb;
 
-       skb = ieee80211_build_probe_req(sdata, dst, ssid, ssid_len, ie, ie_len);
+       skb = ieee80211_build_probe_req(sdata, dst, ssid, ssid_len, ie, ie_len,
+                                       directed);
        if (skb)
                ieee80211_tx_skb(sdata, skb);
 }
@@ -1276,7 +1287,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                if (ieee80211_sdata_running(sdata))
                        ieee80211_enable_keys(sdata);
 
+#ifdef CONFIG_PM
  wake_up:
+#endif
        ieee80211_wake_queues_by_reason(hw,
                        IEEE80211_QUEUE_STOP_REASON_SUSPEND);
 
@@ -1321,6 +1334,33 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        return 0;
 }
 
+void ieee80211_resume_disconnect(struct ieee80211_vif *vif)
+{
+       struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_local *local;
+       struct ieee80211_key *key;
+
+       if (WARN_ON(!vif))
+               return;
+
+       sdata = vif_to_sdata(vif);
+       local = sdata->local;
+
+       if (WARN_ON(!local->resuming))
+               return;
+
+       if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
+               return;
+
+       sdata->flags |= IEEE80211_SDATA_DISCONNECT_RESUME;
+
+       mutex_lock(&local->key_mtx);
+       list_for_each_entry(key, &sdata->key_list, list)
+               key->flags |= KEY_FLAG_TAINTED;
+       mutex_unlock(&local->key_mtx);
+}
+EXPORT_SYMBOL_GPL(ieee80211_resume_disconnect);
+
 static int check_mgd_smps(struct ieee80211_if_managed *ifmgd,
                          enum ieee80211_smps_mode *smps_mode)
 {
@@ -1437,3 +1477,43 @@ size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset)
 
        return pos;
 }
+
+static void _ieee80211_enable_rssi_reports(struct ieee80211_sub_if_data *sdata,
+                                           int rssi_min_thold,
+                                           int rssi_max_thold)
+{
+       trace_api_enable_rssi_reports(sdata, rssi_min_thold, rssi_max_thold);
+
+       if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
+               return;
+
+       /*
+        * Scale up threshold values before storing it, as the RSSI averaging
+        * algorithm uses a scaled up value as well. Change this scaling
+        * factor if the RSSI averaging algorithm changes.
+        */
+       sdata->u.mgd.rssi_min_thold = rssi_min_thold*16;
+       sdata->u.mgd.rssi_max_thold = rssi_max_thold*16;
+}
+
+void ieee80211_enable_rssi_reports(struct ieee80211_vif *vif,
+                                   int rssi_min_thold,
+                                   int rssi_max_thold)
+{
+       struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+
+       WARN_ON(rssi_min_thold == rssi_max_thold ||
+               rssi_min_thold > rssi_max_thold);
+
+       _ieee80211_enable_rssi_reports(sdata, rssi_min_thold,
+                                      rssi_max_thold);
+}
+EXPORT_SYMBOL(ieee80211_enable_rssi_reports);
+
+void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif)
+{
+       struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+
+       _ieee80211_enable_rssi_reports(sdata, 0, 0);
+}
+EXPORT_SYMBOL(ieee80211_disable_rssi_reports);