cfg80211: honor NL80211_RRF_NO_HT40{MINUS,PLUS}
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Wed, 6 Sep 2017 10:45:40 +0000 (13:45 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 6 Sep 2017 10:56:31 +0000 (12:56 +0200)
Honor the NL80211_RRF_NO_HT40{MINUS,PLUS} flags in
reg_process_ht_flags_channel. Not doing so leads can lead
to a firmware assert in iwlwifi for example.

Fixes: b0d7aa59592b ("cfg80211: allow wiphy specific regdomain management")
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/wireless/reg.c

index 5fae296a6a583256f9874319dfaa9ee87e977fff..6e94f6934a0e7a47fbac086586701d07c9bb5487 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright 2007      Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
  * Copyright 2013-2014  Intel Mobile Communications GmbH
+ * Copyright      2017  Intel Deutschland GmbH
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -1483,7 +1484,9 @@ static void reg_process_ht_flags_channel(struct wiphy *wiphy,
 {
        struct ieee80211_supported_band *sband = wiphy->bands[channel->band];
        struct ieee80211_channel *channel_before = NULL, *channel_after = NULL;
+       const struct ieee80211_regdomain *regd;
        unsigned int i;
+       u32 flags;
 
        if (!is_ht40_allowed(channel)) {
                channel->flags |= IEEE80211_CHAN_NO_HT40;
@@ -1503,17 +1506,30 @@ static void reg_process_ht_flags_channel(struct wiphy *wiphy,
                        channel_after = c;
        }
 
+       flags = 0;
+       regd = get_wiphy_regdom(wiphy);
+       if (regd) {
+               const struct ieee80211_reg_rule *reg_rule =
+                       freq_reg_info_regd(MHZ_TO_KHZ(channel->center_freq),
+                                          regd, MHZ_TO_KHZ(20));
+
+               if (!IS_ERR(reg_rule))
+                       flags = reg_rule->flags;
+       }
+
        /*
         * Please note that this assumes target bandwidth is 20 MHz,
         * if that ever changes we also need to change the below logic
         * to include that as well.
         */
-       if (!is_ht40_allowed(channel_before))
+       if (!is_ht40_allowed(channel_before) ||
+           flags & NL80211_RRF_NO_HT40MINUS)
                channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
        else
                channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
 
-       if (!is_ht40_allowed(channel_after))
+       if (!is_ht40_allowed(channel_after) ||
+           flags & NL80211_RRF_NO_HT40PLUS)
                channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
        else
                channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;