blob: d1e24d53e020873609c1b29b0087b0581e4725f2 [file] [log] [blame]
developer1a173672023-12-21 14:49:33 +08001From 5daee94e29d5d7a3db5b8c8f03b15aa4a914f85f Mon Sep 17 00:00:00 2001
developerbd9fa1e2023-10-16 11:04:00 +08002From: Michael-CY Lee <michael-cy.lee@mediatek.com>
3Date: Thu, 24 Aug 2023 10:04:15 +0800
developer1a173672023-12-21 14:49:33 +08004Subject: [PATCH 41/54] mtk: hostapd: refactor the flow to create Wide
5 Bandwidth Channel Switch IE
developerbd9fa1e2023-10-16 11:04:00 +08006
7This patch changes the flow to create Wide Bandwidth Channel Switch IE:
81. 2 GHz: Wide Bandwidth Channel Switch IE should not present.
92. 5 GHz: fill the subfields according to VHT operation.
103. 6 GHz: fill the subfields according to VHT operation and HE operation
11 in HE mode and EHT mode, respectively.
12 This is because the definition of the subfields of Wide Bandwidth
13 Channel Switch IE is ambiguous:
14 1. 802.11ac: the definition of subfields follows VHT operation
15 (IEEE80211-2020 9.4.2.160)
16 2. 802.11ax: the definition of subfields is not specified
17 3. 802.11be: the definition of subfields follows VHT operation in 5
18 GHz and HE operation in 6 GHz (IEEE P802.11be D3.2 9.4.2.159)
19
20To support 320 MHz
21 channel switch, set width to 4
22
23Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
24---
25 src/ap/ieee802_11.c | 99 ++++++++++++++++++++++++++++++++++-----------
26 1 file changed, 76 insertions(+), 23 deletions(-)
27
28diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
developer1a173672023-12-21 14:49:33 +080029index 38fce3e82..d46c5a42b 100644
developerbd9fa1e2023-10-16 11:04:00 +080030--- a/src/ap/ieee802_11.c
31+++ b/src/ap/ieee802_11.c
developer1a173672023-12-21 14:49:33 +080032@@ -7083,57 +7083,110 @@ u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid)
developerbd9fa1e2023-10-16 11:04:00 +080033
34 u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
35 {
36- u8 bw, chan1, chan2 = 0;
37- int freq1;
38+ u8 new_bw_field, ccfs0_chan, ccfs1_chan = 0;
39+ int ccfs0_freq = 0, ccfs1_freq = 0;
40+ int control_freq, center_freq1, center_freq2, bandwidth;
41+ int base_freq, offset;
42+ bool is_6ghz, use_he_oper;
43
44 if (!hapd->cs_freq_params.channel ||
45+ hapd->cs_freq_params.bandwidth == 20 ||
46 (!hapd->cs_freq_params.vht_enabled &&
47 !hapd->cs_freq_params.he_enabled &&
48 !hapd->cs_freq_params.eht_enabled))
49 return eid;
50
51- /* bandwidth: 0: 40, 1: 80, 2: 160, 3: 80+80, 4: 320 */
52- switch (hapd->cs_freq_params.bandwidth) {
53+ control_freq = hapd->cs_freq_params.freq;
54+ center_freq1 = hapd->cs_freq_params.center_freq1;
55+ center_freq2 = hapd->cs_freq_params.center_freq2;
56+ bandwidth = hapd->cs_freq_params.bandwidth;
57+
58+ /* center_freq2 is used if and only if bandwidth is
59+ * 80+80 MHz and phy mode is not EHT
60+ */
61+ if (center_freq2 &&
62+ (bandwidth != 80 || hapd->cs_freq_params.eht_enabled))
63+ return eid;
64+
65+ is_6ghz = is_6ghz_freq(control_freq);
66+ use_he_oper = is_6ghz && hapd->cs_freq_params.eht_enabled;
67+ base_freq = is_6ghz ? 5955 : 5180;
68+
69+ /* About the subfields of the Wide Bandwidth Channel Switch IE,
70+ * IEEE802.11-2020 9.4.2.160 specifies that the subfields New
71+ * Channel Width, New Channel Center Frequency Segment 0 and New
72+ * Channel Center Frequency Segment 1 have the same definition as
73+ * they are in the VHT operation information field.
74+ * However, the standard does not specify the definition of these
75+ * subfields when it comes to HE phy-mode in 6 GHz.
76+ * And in IEEE P802.11be D3.2 9.4.2.159, it specifies that the
77+ * defition should follow VHT operation in 5 GHz, and follow HE
78+ * oepration in 6 GHz.
79+ * Problem happens here for some HE STAs in 6 GHz, they might still
80+ * use VHT operation to parse these subfields.
81+ *
82+ * Here we follow the new Standard to build the IE, meanwhile we have
83+ * a workaround for HE mode in 6 GHz.
84+ *
85+ * 5 GHz: VHT operation
86+ * HE mode in 6 GHz: VHT operation
87+ * EHT mode in 6 GHz: HE operation
88+ */
89+ ccfs0_freq = center_freq1;
90+ ccfs1_freq = center_freq2;
91+ switch (bandwidth) {
92 case 40:
93- bw = 0;
94+ new_bw_field = use_he_oper ? 1 : 0;
95 break;
96 case 80:
97- /* check if it's 80+80 */
98- if (!hapd->cs_freq_params.center_freq2)
99- bw = 1;
100+ if (ccfs1_freq)
101+ new_bw_field = use_he_oper ? 3 : 1;
102 else
103- bw = 3;
104+ new_bw_field = use_he_oper ? 2 : 1;
105 break;
106 case 160:
107- bw = 2;
108+ new_bw_field = use_he_oper ? 3 : 1;
109+
110+ /* ccfs0 is primary 80 MHz
111+ * ccfs1 is center frequency
112+ */
113+ offset = (control_freq - base_freq) / 20;
114+ ccfs0_freq = control_freq + 30 - (offset & 3) * 20;
115+ ccfs1_freq = center_freq1;
116 break;
117 case 320:
118- bw = 4;
119+ /* TODO switch to bandwidth 320 MHz should be
120+ * indicated by Bandwidth indication IE.
121+ */
122+ new_bw_field = 4;
123+
124+ /* ccfs0 is primary 160 MHz
125+ * ccfs1 is center frequency
126+ */
127+ offset = (control_freq - base_freq) / 20;
128+ ccfs0_freq = control_freq + 70 - (offset & 7) * 20;
129+ ccfs1_freq = center_freq1;
130 break;
131 default:
132- /* not valid VHT bandwidth or not in CSA */
133+ /* not a valid VHT/HE bandwidth or not in CSA */
134 return eid;
135 }
136
137- freq1 = hapd->cs_freq_params.center_freq1 ?
138- hapd->cs_freq_params.center_freq1 :
139- hapd->cs_freq_params.freq;
140- if (ieee80211_freq_to_chan(freq1, &chan1) !=
141- HOSTAPD_MODE_IEEE80211A)
142+ if (ieee80211_freq_to_chan(ccfs0_freq, &ccfs0_chan) !=
143+ HOSTAPD_MODE_IEEE80211A)
144 return eid;
145
146- if (hapd->cs_freq_params.center_freq2 &&
147- ieee80211_freq_to_chan(hapd->cs_freq_params.center_freq2,
148- &chan2) != HOSTAPD_MODE_IEEE80211A)
149+ if (ccfs1_freq && ieee80211_freq_to_chan(ccfs1_freq, &ccfs1_chan) !=
150+ HOSTAPD_MODE_IEEE80211A)
151 return eid;
152
153 *eid++ = WLAN_EID_CHANNEL_SWITCH_WRAPPER;
154 *eid++ = 5; /* Length of Channel Switch Wrapper */
155 *eid++ = WLAN_EID_WIDE_BW_CHSWITCH;
156 *eid++ = 3; /* Length of Wide Bandwidth Channel Switch element */
157- *eid++ = bw; /* New Channel Width */
158- *eid++ = chan1; /* New Channel Center Frequency Segment 0 */
159- *eid++ = chan2; /* New Channel Center Frequency Segment 1 */
160+ *eid++ = new_bw_field; /* New Channel Width */
161+ *eid++ = ccfs0_chan; /* New Channel Center Frequency Segment 0 */
162+ *eid++ = ccfs1_chan; /* New Channel Center Frequency Segment 1 */
163
164 return eid;
165 }
166--
developer1a173672023-12-21 14:49:33 +08001672.18.0
developerbd9fa1e2023-10-16 11:04:00 +0800168