cfg80211: enable country IE support to all cfg80211 drivers
authorLuis R. Rodriguez <lrodriguez@atheros.com>
Fri, 31 Jul 2009 00:38:09 +0000 (17:38 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 4 Aug 2009 20:44:19 +0000 (16:44 -0400)
Since the bss is always set now once we are connected, if the
bss has its own information element we refer to it and pass that
instead of relying on mac80211's parsing.

Now all cfg80211 drivers get country IE support, automatically and
we reduce the call overhead that we had on mac80211 which called this
upon every beacon and instead now call this only upon a successfull
connection by a STA on cfg80211.

Acked-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
include/net/cfg80211.h
net/mac80211/mlme.c
net/wireless/reg.c
net/wireless/reg.h
net/wireless/sme.c

index e1b92358242be7bf5a0c7246e2f0451ce7682d3d..fa729979de88b3f13b1f56f1700ea72ae278f244 100644 (file)
@@ -1513,20 +1513,6 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb);
  */
 extern int regulatory_hint(struct wiphy *wiphy, const char *alpha2);
 
-/**
- * regulatory_hint_11d - hints a country IE as a regulatory domain
- * @wiphy: the wireless device giving the hint (used only for reporting
- *     conflicts)
- * @country_ie: pointer to the country IE
- * @country_ie_len: length of the country IE
- *
- * We will intersect the rd with the what CRDA tells us should apply
- * for the alpha2 this country IE belongs to, this prevents APs from
- * sending us incorrect or outdated information against a country.
- */
-extern void regulatory_hint_11d(struct wiphy *wiphy,
-                               u8 *country_ie,
-                               u8 country_ie_len);
 /**
  * wiphy_apply_custom_regulatory - apply a custom driver regulatory domain
  * @wiphy: the wireless device we want to process the regulatory domain on
index 2d5edfda867a668d9a17a31191ad3f2864dddd73..c9e4091cd2bb915ae7d96718654e1ca3d5bba789 100644 (file)
@@ -1845,12 +1845,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
                                               bssid, ap_ht_cap_flags);
        }
 
+       /* Note: country IE parsing is done for us by cfg80211 */
        if (elems.country_elem) {
-               /* Note we are only reviewing this on beacons
-                * for the BSSID we are associated to */
-               regulatory_hint_11d(local->hw.wiphy,
-                       elems.country_elem, elems.country_elem_len);
-
                /* TODO: IBSS also needs this */
                if (elems.pwr_constr_elem)
                        ieee80211_handle_pwr_constr(sdata,
index 6ab56f098de1f8310c2d09af21daf37e8563ea54..b3ac0aace0e5daf80563caadf67a1473813ffc16 100644 (file)
@@ -1822,10 +1822,7 @@ void regulatory_hint_11d(struct wiphy *wiphy,
                env = ENVIRON_OUTDOOR;
 
        /*
-        * We will run this for *every* beacon processed for the BSSID, so
-        * we optimize an early check to exit out early if we don't have to
-        * do anything
-        *
+        * We will run this only upon a successful connection on cfg80211.
         * We leave conflict resolution to the workqueue, where can hold
         * cfg80211_mutex.
         */
@@ -1878,7 +1875,6 @@ free_rd_out:
 out:
        mutex_unlock(&reg_mutex);
 }
-EXPORT_SYMBOL(regulatory_hint_11d);
 
 static bool freq_is_chan_12_13_14(u16 freq)
 {
index e37829a49dc466fad9a6aff92361afcc26371ad7..662a9dad76d5fae628909c26d4f8853087b89db4 100644 (file)
@@ -36,4 +36,19 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy,
                                        struct ieee80211_channel *beacon_chan,
                                        gfp_t gfp);
 
+/**
+ * regulatory_hint_11d - hints a country IE as a regulatory domain
+ * @wiphy: the wireless device giving the hint (used only for reporting
+ *     conflicts)
+ * @country_ie: pointer to the country IE
+ * @country_ie_len: length of the country IE
+ *
+ * We will intersect the rd with the what CRDA tells us should apply
+ * for the alpha2 this country IE belongs to, this prevents APs from
+ * sending us incorrect or outdated information against a country.
+ */
+void regulatory_hint_11d(struct wiphy *wiphy,
+                        u8 *country_ie,
+                        u8 country_ie_len);
+
 #endif  /* __NET_WIRELESS_REG_H */
index 3728d2b88b25b0c8e651f1b31681d0659187fd26..af91192eedf5b2fc5c1fb3083aaa3fbbacf733b8 100644 (file)
@@ -13,6 +13,7 @@
 #include <net/cfg80211.h>
 #include <net/rtnetlink.h>
 #include "nl80211.h"
+#include "reg.h"
 
 struct cfg80211_conn {
        struct cfg80211_connect_params params;
@@ -320,6 +321,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
                               struct cfg80211_bss *bss)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
+       u8 *country_ie;
 #ifdef CONFIG_WIRELESS_EXT
        union iwreq_data wrqu;
 #endif
@@ -401,6 +403,20 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
 
        wdev->sme_state = CFG80211_SME_CONNECTED;
        cfg80211_upload_connect_keys(wdev);
+
+       country_ie = (u8 *) ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
+
+       if (!country_ie)
+               return;
+
+       /*
+        * ieee80211_bss_get_ie() ensures we can access:
+        * - country_ie + 2, the start of the country ie data, and
+        * - and country_ie[1] which is the IE length
+        */
+       regulatory_hint_11d(wdev->wiphy,
+                           country_ie + 2,
+                           country_ie[1]);
 }
 
 void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,