diff mbox series

[02/10] cfg80211: validate 6 GHz chandef

Message ID 1587768108-25248-3-git-send-email-rmanohar@codeaurora.org
State New
Headers show
Series mac80211: add 6 GHz IEs support | expand

Commit Message

Rajkumar Manoharan April 24, 2020, 10:41 p.m. UTC
Validate the params of set_channel against 6 GHz frequency range
and bandwidth allowed.

Signed-off-by: Rajkumar Manoharan <rmanohar@codeaurora.org>
---
 include/net/cfg80211.h | 14 ++++++++++++++
 net/wireless/chan.c    | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)
diff mbox series

Patch

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 70e48f66dac8..13d3d8f92c99 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -730,6 +730,20 @@  cfg80211_chandef_is_edmg(const struct cfg80211_chan_def *chandef)
 }
 
 /**
+ * cfg80211_chandef_is_6ghz - check if chandef represents an 6 GHz channel
+ *
+ * @chandef: the channel definition
+ *
+ * Return: %true if frequency is in 6 GHz range, %false otherwise.
+ */
+static inline bool
+cfg80211_chandef_is_6ghz(const struct cfg80211_chan_def *chandef)
+{
+	return (chandef->center_freq1 > 5940 && chandef->center_freq1 < 7105);
+}
+
+
+/**
  * cfg80211_chandef_compatible - check if two channel definitions are compatible
  * @chandef1: first channel definition
  * @chandef2: second channel definition
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index fcac5c6366e1..42d27cada237 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -19,6 +19,29 @@  static bool cfg80211_valid_60g_freq(u32 freq)
 	return freq >= 58320 && freq <= 70200;
 }
 
+static bool cfg80211_is_6ghz_freq(u32 freq)
+{
+	return (freq > 5940 && freq < 7105);
+}
+
+static enum nl80211_chan_width cfg80211_chan_to_bw_6ghz(u8 idx)
+{
+	/* channels: 1, 5, 9, 13... */
+	if ((idx & 0x3) == 0x1)
+		return NL80211_CHAN_WIDTH_20;
+	/* channels 3, 11, 19... */
+	if ((idx & 0x7) == 0x3)
+		return NL80211_CHAN_WIDTH_40;
+	/* channels 7, 23, 39.. */
+	if ((idx & 0xf) == 0x7)
+		return NL80211_CHAN_WIDTH_80;
+	/* channels 15, 47, 79...*/
+	if ((idx & 0x1f) == 0xf)
+		return NL80211_CHAN_WIDTH_160;
+
+	return NL80211_CHAN_WIDTH_20;
+}
+
 void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
 			     struct ieee80211_channel *chan,
 			     enum nl80211_channel_type chan_type)
@@ -139,6 +162,25 @@  static bool cfg80211_edmg_chandef_valid(const struct cfg80211_chan_def *chandef)
 	return true;
 }
 
+static bool cfg80211_6ghz_chandef_valid(const struct cfg80211_chan_def *chandef)
+{
+	enum nl80211_chan_width bw;
+	int chan_idx;
+
+	if (!cfg80211_is_6ghz_freq(chandef->center_freq1))
+		return false;
+
+	chan_idx = ieee80211_frequency_to_channel(chandef->center_freq1);
+	if (chan_idx <= 0)
+		return false;
+
+	bw = cfg80211_chan_to_bw_6ghz(chan_idx);
+	if (bw != chandef->width)
+		return false;
+
+	return true;
+}
+
 bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
 {
 	u32 control_freq;
@@ -213,6 +255,10 @@  bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
 	    !cfg80211_edmg_chandef_valid(chandef))
 		return false;
 
+	if (cfg80211_chandef_is_6ghz(chandef) &&
+	    !cfg80211_6ghz_chandef_valid(chandef))
+		return false;
+
 	return true;
 }
 EXPORT_SYMBOL(cfg80211_chandef_valid);