cfg80211: combine iwfreq implementations
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / wireless / wext-compat.c
index 5d01763385398be785c25aca99089d4ccf962ed0..fc2e7768967d70eab8ad375caae689c8e199c928 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/etherdevice.h>
 #include <net/iw_handler.h>
 #include <net/cfg80211.h>
+#include "wext-compat.h"
 #include "core.h"
 
 int cfg80211_wext_giwname(struct net_device *dev,
@@ -300,7 +301,6 @@ struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
                return ERR_PTR(-EINVAL);
        return chan;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_freq);
 
 int cfg80211_wext_siwrts(struct net_device *dev,
                         struct iw_request_info *info,
@@ -531,7 +531,8 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
                        wdev->wext.keys->data[idx];
        }
 
-       if (params->cipher != WLAN_CIPHER_SUITE_AES_CMAC &&
+       if ((params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+            params->cipher == WLAN_CIPHER_SUITE_WEP104) &&
            (tx_key || (!addr && wdev->wext.default_key == -1))) {
                if (wdev->current_bss)
                        err = rdev->ops->set_default_key(&rdev->wiphy,
@@ -758,6 +759,58 @@ int cfg80211_wext_giwencode(struct net_device *dev,
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode);
 
+int cfg80211_wext_siwfreq(struct net_device *dev,
+                         struct iw_request_info *info,
+                         struct iw_freq *freq, char *extra)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+       struct ieee80211_channel *chan;
+       int err;
+
+       switch (wdev->iftype) {
+       case NL80211_IFTYPE_STATION:
+               return cfg80211_mgd_wext_siwfreq(dev, info, freq, extra);
+       case NL80211_IFTYPE_ADHOC:
+               return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
+       default:
+               chan = cfg80211_wext_freq(wdev->wiphy, freq);
+               if (!chan)
+                       return -EINVAL;
+               if (IS_ERR(chan))
+                       return PTR_ERR(chan);
+               err = rdev->ops->set_channel(wdev->wiphy, chan,
+                                            NL80211_CHAN_NO_HT);
+               if (err)
+                       return err;
+               rdev->channel = chan;
+               return 0;
+       }
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq);
+
+int cfg80211_wext_giwfreq(struct net_device *dev,
+                         struct iw_request_info *info,
+                         struct iw_freq *freq, char *extra)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+
+       switch (wdev->iftype) {
+       case NL80211_IFTYPE_STATION:
+               return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
+       case NL80211_IFTYPE_ADHOC:
+               return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
+       default:
+               if (!rdev->channel)
+                       return -EINVAL;
+               freq->m = rdev->channel->center_freq;
+               freq->e = 6;
+               return 0;
+       }
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwfreq);
+
 int cfg80211_wext_siwtxpower(struct net_device *dev,
                             struct iw_request_info *info,
                             union iwreq_data *data, char *extra)
@@ -880,9 +933,19 @@ static int cfg80211_set_wpa_version(struct wireless_dev *wdev, u32 wpa_versions)
        wdev->wext.connect.crypto.wpa_versions = 0;
 
        if (wpa_versions & ~(IW_AUTH_WPA_VERSION_WPA |
-                            IW_AUTH_WPA_VERSION_WPA2))
+                            IW_AUTH_WPA_VERSION_WPA2|
+                            IW_AUTH_WPA_VERSION_DISABLED))
                return -EINVAL;
 
+       if ((wpa_versions & IW_AUTH_WPA_VERSION_DISABLED) &&
+           (wpa_versions & (IW_AUTH_WPA_VERSION_WPA|
+                            IW_AUTH_WPA_VERSION_WPA2)))
+               return -EINVAL;
+
+       if (wpa_versions & IW_AUTH_WPA_VERSION_DISABLED)
+               wdev->wext.connect.crypto.wpa_versions &=
+                       ~(NL80211_WPA_VERSION_1|NL80211_WPA_VERSION_2);
+
        if (wpa_versions & IW_AUTH_WPA_VERSION_WPA)
                wdev->wext.connect.crypto.wpa_versions |=
                        NL80211_WPA_VERSION_1;
@@ -1209,7 +1272,7 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
        /* we are under RTNL - globally locked - so can use static structs */
        static struct iw_statistics wstats;
        static struct station_info sinfo;
-       u8 *addr;
+       u8 bssid[ETH_ALEN];
 
        if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION)
                return NULL;
@@ -1217,11 +1280,16 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
        if (!rdev->ops->get_station)
                return NULL;
 
-       addr = wdev->wext.connect.bssid;
-       if (!addr)
+       /* Grab BSSID of current BSS, if any */
+       wdev_lock(wdev);
+       if (!wdev->current_bss) {
+               wdev_unlock(wdev);
                return NULL;
+       }
+       memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
+       wdev_unlock(wdev);
 
-       if (rdev->ops->get_station(&rdev->wiphy, dev, addr, &sinfo))
+       if (rdev->ops->get_station(&rdev->wiphy, dev, bssid, &sinfo))
                return NULL;
 
        memset(&wstats, 0, sizeof(wstats));