nl80211: Add frequency configuration (including HT40)

This patch adds new NL80211_CMD_SET_WIPHY attributes
NL80211_ATTR_WIPHY_FREQ and NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET to allow
userspace to set the operating channel (e.g., hostapd for AP mode).

Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index cec9b6d..29c3ecf 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -195,19 +195,41 @@
 	struct ieee80211_channel *chan;
 	int ret = 0;
 	int power;
+	enum nl80211_sec_chan_offset sec_chan_offset;
 
 	might_sleep();
 
-	if (local->sw_scanning)
+	if (local->sw_scanning) {
 		chan = local->scan_channel;
-	else
+		sec_chan_offset = NL80211_SEC_CHAN_NO_HT;
+	} else {
 		chan = local->oper_channel;
-
-	if (chan != local->hw.conf.channel) {
-		local->hw.conf.channel = chan;
-		changed |= IEEE80211_CONF_CHANGE_CHANNEL;
+		sec_chan_offset = local->oper_sec_chan_offset;
 	}
 
+	if (chan != local->hw.conf.channel ||
+	    sec_chan_offset != local->hw.conf.ht.sec_chan_offset) {
+		local->hw.conf.channel = chan;
+		switch (sec_chan_offset) {
+		case NL80211_SEC_CHAN_NO_HT:
+			local->hw.conf.ht.enabled = false;
+			local->hw.conf.ht.sec_chan_offset = 0;
+			break;
+		case NL80211_SEC_CHAN_DISABLED:
+			local->hw.conf.ht.enabled = true;
+			local->hw.conf.ht.sec_chan_offset = 0;
+			break;
+		case NL80211_SEC_CHAN_BELOW:
+			local->hw.conf.ht.enabled = true;
+			local->hw.conf.ht.sec_chan_offset = -1;
+			break;
+		case NL80211_SEC_CHAN_ABOVE:
+			local->hw.conf.ht.enabled = true;
+			local->hw.conf.ht.sec_chan_offset = 1;
+			break;
+		}
+		changed |= IEEE80211_CONF_CHANGE_CHANNEL;
+	}
 
 	if (!local->hw.conf.power_level)
 		power = chan->max_power;