[][MAC80211][hostapd][refactor AP/STA CSA handling flow]

[Description]
Refactor AP/STA CSA handling flow.

There were two problems in the original CSA handling flow.
1. STA could not differentiate 20 MHz from 40 MHz when parsing CSA IE.
2. STA did not support a channel switch to 320 MHz.

These problems were mostly caused by hostapd/ma`c80211 not following new
802.11 standard.
To fix above two problems, a new CSA flow that follows new 802.11
standard is added.

In the AP side:
1. when creating Wide Bandwidth Channel Switch IE, fill the subfields
   according to band and PHY mode
   a. 2 GHz: no such IE
   b. 5 GHz: VHT operation
   c. 6 GHz: VHT operation in HE mode and HE operation in EHT mode

In the STA side:
1. Add the utilities to convert op_class to nl80211_chan_def
2. There are two way to convert CSA-related IEs to
   nl80211_chan_def
    a. use the subfield op_class from ECSA, then convert it to
       nl80211_chan_def by utilities added in item 1.
    b. use the Wide Bandwidth Channel Switch IE to fill VHT/HE
       operation, then convert it to nl80211_chan_def. This way is
       prefered. This way is used only if the ECSA IE is not presented.

In 6 GHz, because of the ambiguous definition of the subfields of the
Wide Bandwidth Channel Switch IE, we check the combination of new
channel width, ccfs0 and ccfs1 to build the correct chandef.

[Release-log]
N/A

Change-Id: I36ca00b30987de53914c0c3122dcef62de996fc3
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7921181
diff --git a/autobuild_mac80211_release/package/kernel/mac80211_dev/patches/subsys/mtk-0022-mac80211-mtk-Add-utilities-for-converting-op_class.patch b/autobuild_mac80211_release/package/kernel/mac80211_dev/patches/subsys/mtk-0022-mac80211-mtk-Add-utilities-for-converting-op_class.patch
new file mode 100644
index 0000000..e32ba2f
--- /dev/null
+++ b/autobuild_mac80211_release/package/kernel/mac80211_dev/patches/subsys/mtk-0022-mac80211-mtk-Add-utilities-for-converting-op_class.patch
@@ -0,0 +1,201 @@
+From 979c688e54a73cfedb8757881a95c4f6c795023a Mon Sep 17 00:00:00 2001
+From: Michael-CY Lee <michael-cy.lee@mediatek.com>
+Date: Mon, 14 Aug 2023 18:03:29 +0800
+Subject: mac80211: mtk: Add utilities for converting op_class
+
+These utilities include converting op_class to nl80211 channel width and
+center frequency.
+
+Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
+---
+ include/net/cfg80211.h |  25 ++++++++
+ net/wireless/util.c    | 130 ++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 154 insertions(+), 1 deletion(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index cfaa3d6..bea7d25 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -8693,6 +8693,31 @@ void cfg80211_ch_switch_started_notify(struct net_device *dev,
+ bool ieee80211_operating_class_to_band(u8 operating_class,
+ 				       enum nl80211_band *band);
+ 
++/**
++ * ieee80211_operating_class_to_center_freq - convert operating class to
++ * center frequency
++ *
++ * @operating_class: the operating class to convert
++ * @chan: the ieee80211_channel to convert
++ * @center_freq1: cneter frequency 1 pointer to fill
++ * @center_freq2: cneter frequency 2 pointer to fill
++ *
++ * Returns %true if the conversion was successful, %false otherwise.
++ */
++bool ieee80211_operating_class_to_center_freq(u8 operating_class,
++					      struct ieee80211_channel *chan,
++					      u32 *center_freq1,
++					      u32 *center_freq2);
++
++/**
++ * ieee80211_operating_class_to_chan_width - convert operating class to
++ * nl80211 channel width
++ *
++ * @operating_class: the operating class to convert
++ */
++enum nl80211_chan_width
++ieee80211_operating_class_to_chan_width(u8 operating_class);
++
+ /**
+  * ieee80211_chandef_to_operating_class - convert chandef to operation class
+  *
+diff --git a/net/wireless/util.c b/net/wireless/util.c
+index 1783ab9..13cb986 100644
+--- a/net/wireless/util.c
++++ b/net/wireless/util.c
+@@ -1981,7 +1981,7 @@ bool ieee80211_operating_class_to_band(u8 operating_class,
+ 	case 128 ... 130:
+ 		*band = NL80211_BAND_5GHZ;
+ 		return true;
+-	case 131 ... 135:
++	case 131 ... 137:
+ 		*band = NL80211_BAND_6GHZ;
+ 		return true;
+ 	case 81:
+@@ -1999,6 +1999,134 @@ bool ieee80211_operating_class_to_band(u8 operating_class,
+ }
+ EXPORT_SYMBOL(ieee80211_operating_class_to_band);
+ 
++bool ieee80211_operating_class_to_center_freq(u8 operating_class,
++					      struct ieee80211_channel *chan,
++					      u32 *center_freq1,
++					      u32 *center_freq2)
++{
++	u32 control_freq, offset;
++	enum nl80211_band band;
++
++	control_freq = chan->center_freq;
++	if (!ieee80211_operating_class_to_band(operating_class, &band))
++		return false;
++
++	if (band != chan->band)
++		return false;
++
++	if (control_freq >= 5955)
++		offset = control_freq - 5955;
++	else if (control_freq >= 5745)
++		offset = control_freq - 5745;
++	else if (control_freq >= 5180)
++		offset = control_freq - 5180;
++	offset /= 20;
++
++	*center_freq2 = 0;
++	switch (operating_class) {
++	case 81:  /* 2 GHz band; 20 MHz; channels 1..13 */
++	case 82:  /* 2 GHz band; 20 MHz; channel 14 */
++	case 115: /* 5 GHz band; 20 MHz; channels 36,40,44,48 */
++	case 118: /* 5 GHz band; 20 MHz; channels 52,56,60,64 */
++	case 121: /* 5 GHz band; 20 MHz; channels 100..144 */
++	case 124: /* 5 GHz band; 20 MHz; channels 149,153,157,161 */
++	case 125: /* 5 GHz band; 20 MHz; channels 149..177 */
++	case 131: /* 6 GHz band; 20 MHz; channels 1..233*/
++	case 136: /* 6 GHz band; 20 MHz; channel 2 */
++		*center_freq1 = control_freq;
++		return true;
++	case 83:  /* 2 GHz band; 40 MHz; channels 1..9 */
++	case 116: /* 5 GHz band; 40 MHz; channels 36,44 */
++	case 119: /* 5 GHz band; 40 MHz; channels 52,60 */
++	case 122: /* 5 GHz band; 40 MHz; channels 100,108,116,124,132,140 */
++	case 126: /* 5 GHz band; 40 MHz; channels 149,157,165,173 */
++		*center_freq1 = control_freq + 10;
++		return true;
++	case 84:  /* 2 GHz band; 40 MHz; channels 5..13 */
++	case 117: /* 5 GHz band; 40 MHz; channels 40,48 */
++	case 120: /* 5 GHz band; 40 MHz; channels 56,64 */
++	case 123: /* 5 GHz band; 40 MHz; channels 104,112,120,128,136,144 */
++	case 127: /* 5 GHz band; 40 MHz; channels 153,161,169,177 */
++		*center_freq1 = control_freq - 10;
++		return true;
++	case 132: /* 6 GHz band; 40 MHz; channels 1,5,..,229*/
++		*center_freq1 = control_freq + 10 - (offset & 1) * 20;
++		return true;
++	case 128: /* 5 GHz band; 80 MHz; channels 36..64,100..144,149..177 */
++		*center_freq1 = control_freq + 30 - (offset & 3) * 20;
++		return true;
++	case 130: /* 5 GHz band; 80+80 MHz; channels 36..64,100..144,149..177 */
++		/* TODO How to know the center_freq2 of 80+80 MHz?*/
++		*center_freq1 = 0;
++		return false;
++	case 133: /* 6 GHz band; 80 MHz; channels 1,5,..,229 */
++		*center_freq1 = control_freq + 30 - (offset & 3) * 20;
++		return true;
++	case 129: /* 5 GHz band; 160 MHz; channels 36..64,100..144,149..177 */
++		*center_freq1 = control_freq + 70 - (offset & 7) * 20;
++		return true;
++	case 134: /* 6 GHz band; 160 MHz; channels 1,5,..,229 */
++		*center_freq1 = control_freq + 70 - (offset & 7) * 20;
++		return true;
++	case 135: /* 6 GHz band; 80+80 MHz; channels 1,5,..,229 */
++		/* TODO How to know the center_freq2 of 80+80 MHz?*/
++		*center_freq1 = 0;
++		return false;
++	case 137: /* 6 GHz band; 320 MHz; channels 1,5,..,229 */
++		/* TODO it's 320-1 or 320-2 channelization? */
++		/* Currently convert to 320-1 */
++		*center_freq1 = control_freq + 150 - (offset & 15) * 20;
++		return true;
++	default:
++		return false;
++	}
++}
++EXPORT_SYMBOL(ieee80211_operating_class_to_center_freq);
++
++enum nl80211_chan_width
++ieee80211_operating_class_to_chan_width(u8 operating_class)
++{
++	switch (operating_class) {
++	case 81:  /* 2 GHz band; 20 MHz; channels 1..13 */
++	case 82:  /* 2 GHz band; 20 MHz; channel 14 */
++	case 115: /* 5 GHz band; 20 MHz; channels 36,40,44,48 */
++	case 118: /* 5 GHz band; 20 MHz; channels 52,56,60,64 */
++	case 121: /* 5 GHz band; 20 MHz; channels 100..144 */
++	case 124: /* 5 GHz band; 20 MHz; channels 149,153,157,161 */
++	case 125: /* 5 GHz band; 20 MHz; channels 149..177 */
++	case 131: /* 6 GHz band; 20 MHz; channels 1..233*/
++	case 136: /* 6 GHz band; 20 MHz; channel 2 */
++		return NL80211_CHAN_WIDTH_20;
++	case 83:  /* 2 GHz band; 40 MHz; channels 1..9 */
++	case 84:  /* 2 GHz band; 40 MHz; channels 5..13 */
++	case 116: /* 5 GHz band; 40 MHz; channels 36,44 */
++	case 117: /* 5 GHz band; 40 MHz; channels 40,48 */
++	case 119: /* 5 GHz band; 40 MHz; channels 52,60 */
++	case 120: /* 5 GHz band; 40 MHz; channels 56,64 */
++	case 122: /* 5 GHz band; 40 MHz; channels 100,108,116,124,132,140 */
++	case 123: /* 5 GHz band; 40 MHz; channels 104,112,120,128,136,144 */
++	case 126: /* 5 GHz band; 40 MHz; channels 149,157,165,173 */
++	case 127: /* 5 GHz band; 40 MHz; channels 153,161,169,177 */
++	case 132: /* 6 GHz band; 40 MHz; channels 1,5,..,229*/
++		return NL80211_CHAN_WIDTH_40;
++	case 128: /* 5 GHz band; 80 MHz; channels 36..64,100..144,149..177 */
++	case 133: /* 6 GHz band; 80 MHz; channels 1,5,..,229 */
++		return NL80211_CHAN_WIDTH_80;
++	case 130: /* 5 GHz band; 80+80 MHz; channels 36..64,100..144,149..177 */
++	case 135: /* 6 GHz band; 80+80 MHz; channels 1,5,..,229 */
++		return NL80211_CHAN_WIDTH_80P80;
++	case 129: /* 5 GHz band; 160 MHz; channels 36..64,100..144,149..177 */
++	case 134: /* 6 GHz band; 160 MHz; channels 1,5,..,229 */
++		return NL80211_CHAN_WIDTH_160;
++	case 137: /* 6 GHz band; 320 MHz; channels 1,5,..,229 */
++		return NL80211_CHAN_WIDTH_320;
++	default:
++		WARN_ON(1);
++		return NL80211_CHAN_WIDTH_20_NOHT;
++	}
++}
++EXPORT_SYMBOL(ieee80211_operating_class_to_chan_width);
++
+ bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef,
+ 					  u8 *op_class)
+ {
+-- 
+2.25.1
+