191094Sdes/*
2115619Sdes * Operating classes
3228690Sdes * Copyright(c) 2015 Intel Deutschland GmbH
491094Sdes * Contact Information:
591094Sdes * Intel Linux Wireless <ilw@linux.intel.com>
691094Sdes * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
799158Sdes *
899158Sdes * This software may be distributed under the terms of the BSD license.
999158Sdes * See README for more details.
1091094Sdes */
1191094Sdes
1291094Sdes#include "utils/includes.h"
1391094Sdes
1491094Sdes#include "utils/common.h"
1591094Sdes#include "common/ieee802_11_common.h"
1691094Sdes#include "wpa_supplicant_i.h"
1791094Sdes#include "bss.h"
1891094Sdes
1991094Sdes
2091094Sdesstatic enum chan_allowed allow_channel(struct hostapd_hw_modes *mode,
2191094Sdes				       u8 op_class, u8 chan,
2291094Sdes				       unsigned int *flags)
2391094Sdes{
2491094Sdes	int i;
2591094Sdes	bool is_6ghz = op_class >= 131 && op_class <= 136;
2691094Sdes
2791094Sdes	for (i = 0; i < mode->num_channels; i++) {
2891094Sdes		bool chan_is_6ghz;
2991094Sdes
3091094Sdes		chan_is_6ghz = mode->channels[i].freq >= 5935 &&
3191094Sdes			mode->channels[i].freq <= 7115;
3291094Sdes		if (is_6ghz == chan_is_6ghz && mode->channels[i].chan == chan)
3391094Sdes			break;
3491094Sdes	}
35255376Sdes
3691094Sdes	if (i == mode->num_channels ||
3791094Sdes	    (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED))
38228690Sdes		return NOT_ALLOWED;
39228690Sdes
40228690Sdes	if (flags)
41228690Sdes		*flags = mode->channels[i].flag;
4291094Sdes
4391094Sdes	if (mode->channels[i].flag & HOSTAPD_CHAN_NO_IR)
4491094Sdes		return NO_IR;
4591094Sdes
4691094Sdes	return ALLOWED;
4791094Sdes}
4891094Sdes
4991094Sdes
5091094Sdesstatic int get_center_80mhz(struct hostapd_hw_modes *mode, u8 channel,
5191094Sdes			    const u8 *center_channels, size_t num_chan)
5291094Sdes{
5391094Sdes	size_t i;
5491094Sdes
5591094Sdes	if (mode->mode != HOSTAPD_MODE_IEEE80211A)
5691094Sdes		return 0;
5791094Sdes
5891094Sdes	for (i = 0; i < num_chan; i++) {
5991094Sdes		/*
6091094Sdes		 * In 80 MHz, the bandwidth "spans" 12 channels (e.g., 36-48),
6191094Sdes		 * so the center channel is 6 channels away from the start/end.
62107937Sdes		 */
6391094Sdes		if (channel >= center_channels[i] - 6 &&
64107937Sdes		    channel <= center_channels[i] + 6)
6591094Sdes			return center_channels[i];
6691094Sdes	}
6791094Sdes
6891094Sdes	return 0;
6991094Sdes}
7091094Sdes
71115619Sdes
72115619Sdesstatic enum chan_allowed verify_80mhz(struct hostapd_hw_modes *mode,
7391094Sdes				      u8 op_class, u8 channel)
7491094Sdes{
7591094Sdes	u8 center_chan;
76116520Sdes	unsigned int i;
77116520Sdes	unsigned int no_ir = 0;
78116520Sdes	const u8 *center_channels;
79116520Sdes	size_t num_chan;
80115619Sdes	const u8 center_channels_5ghz[] = { 42, 58, 106, 122, 138, 155, 171 };
8191094Sdes	const u8 center_channels_6ghz[] = { 7, 23, 39, 55, 71, 87, 103, 119,
8291094Sdes					    135, 151, 167, 183, 199, 215 };
8395908Sdes
8491094Sdes	if (is_6ghz_op_class(op_class)) {
8591094Sdes		center_channels = center_channels_6ghz;
8691094Sdes		num_chan = ARRAY_SIZE(center_channels_6ghz);
8791094Sdes	} else {
8891094Sdes		center_channels = center_channels_5ghz;
89115619Sdes		num_chan = ARRAY_SIZE(center_channels_5ghz);
9091094Sdes	}
91107937Sdes
9291094Sdes	center_chan = get_center_80mhz(mode, channel, center_channels,
9391100Sdes				       num_chan);
9491100Sdes	if (!center_chan)
9591100Sdes		return NOT_ALLOWED;
9691100Sdes
9791100Sdes	/* check all the channels are available */
9891100Sdes	for (i = 0; i < 4; i++) {
9991100Sdes		unsigned int flags;
10091100Sdes		u8 adj_chan = center_chan - 6 + i * 4;
10191100Sdes
10291100Sdes		if (allow_channel(mode, op_class, adj_chan, &flags) ==
10391100Sdes		    NOT_ALLOWED)
10491100Sdes			return NOT_ALLOWED;
10591100Sdes
10691100Sdes		if ((i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_70)) ||
107		    (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_50)) ||
108		    (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_30)) ||
109		    (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_10)))
110			return NOT_ALLOWED;
111
112		if (flags & HOSTAPD_CHAN_NO_IR)
113			no_ir = 1;
114	}
115
116	if (no_ir)
117		return NO_IR;
118
119	return ALLOWED;
120}
121
122
123static int get_center_160mhz(struct hostapd_hw_modes *mode, u8 channel,
124			     const u8 *center_channels, size_t num_chan)
125{
126	unsigned int i;
127
128	if (mode->mode != HOSTAPD_MODE_IEEE80211A)
129		return 0;
130
131	for (i = 0; i < num_chan; i++) {
132		/*
133		 * In 160 MHz, the bandwidth "spans" 28 channels (e.g., 36-64),
134		 * so the center channel is 14 channels away from the start/end.
135		 */
136		if (channel >= center_channels[i] - 14 &&
137		    channel <= center_channels[i] + 14)
138			return center_channels[i];
139	}
140
141	return 0;
142}
143
144
145static enum chan_allowed verify_160mhz(struct hostapd_hw_modes *mode,
146				       u8 op_class, u8 channel)
147{
148	u8 center_chan;
149	unsigned int i;
150	unsigned int no_ir = 0;
151	const u8 *center_channels;
152	size_t num_chan;
153	const u8 center_channels_5ghz[] = { 50, 114, 163 };
154	const u8 center_channels_6ghz[] = { 15, 47, 79, 111, 143, 175, 207 };
155
156	if (is_6ghz_op_class(op_class)) {
157		center_channels = center_channels_6ghz;
158		num_chan = ARRAY_SIZE(center_channels_6ghz);
159	} else {
160		center_channels = center_channels_5ghz;
161		num_chan = ARRAY_SIZE(center_channels_5ghz);
162	}
163
164	center_chan = get_center_160mhz(mode, channel, center_channels,
165					num_chan);
166	if (!center_chan)
167		return NOT_ALLOWED;
168
169	/* Check all the channels are available */
170	for (i = 0; i < 8; i++) {
171		unsigned int flags;
172		u8 adj_chan = center_chan - 14 + i * 4;
173
174		if (allow_channel(mode, op_class, adj_chan, &flags) ==
175		    NOT_ALLOWED)
176			return NOT_ALLOWED;
177
178		if ((i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_150)) ||
179		    (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_130)) ||
180		    (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_110)) ||
181		    (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_90)) ||
182		    (i == 4 && !(flags & HOSTAPD_CHAN_VHT_90_70)) ||
183		    (i == 5 && !(flags & HOSTAPD_CHAN_VHT_110_50)) ||
184		    (i == 6 && !(flags & HOSTAPD_CHAN_VHT_130_30)) ||
185		    (i == 7 && !(flags & HOSTAPD_CHAN_VHT_150_10)))
186			return NOT_ALLOWED;
187
188		if (flags & HOSTAPD_CHAN_NO_IR)
189			no_ir = 1;
190	}
191
192	if (no_ir)
193		return NO_IR;
194
195	return ALLOWED;
196}
197
198
199enum chan_allowed verify_channel(struct hostapd_hw_modes *mode, u8 op_class,
200				 u8 channel, u8 bw)
201{
202	unsigned int flag = 0;
203	enum chan_allowed res, res2;
204
205	res2 = res = allow_channel(mode, op_class, channel, &flag);
206	if (bw == BW40MINUS || (bw == BW40 && (((channel - 1) / 4) % 2))) {
207		if (!(flag & HOSTAPD_CHAN_HT40MINUS))
208			return NOT_ALLOWED;
209		res2 = allow_channel(mode, op_class, channel - 4, NULL);
210	} else if (bw == BW40PLUS) {
211		if (!(flag & HOSTAPD_CHAN_HT40PLUS))
212			return NOT_ALLOWED;
213		res2 = allow_channel(mode, op_class, channel + 4, NULL);
214	} else if (is_6ghz_op_class(op_class) && bw == BW40) {
215		if (get_6ghz_sec_channel(channel) < 0)
216			res2 = allow_channel(mode, op_class, channel - 4, NULL);
217		else
218			res2 = allow_channel(mode, op_class, channel + 4, NULL);
219	} else if (bw == BW80) {
220		/*
221		 * channel is a center channel and as such, not necessarily a
222		 * valid 20 MHz channels. Override earlier allow_channel()
223		 * result and use only the 80 MHz specific version.
224		 */
225		res2 = res = verify_80mhz(mode, op_class, channel);
226	} else if (bw == BW160) {
227		/*
228		 * channel is a center channel and as such, not necessarily a
229		 * valid 20 MHz channels. Override earlier allow_channel()
230		 * result and use only the 160 MHz specific version.
231		 */
232		res2 = res = verify_160mhz(mode, op_class, channel);
233	} else if (bw == BW80P80) {
234		/*
235		 * channel is a center channel and as such, not necessarily a
236		 * valid 20 MHz channels. Override earlier allow_channel()
237		 * result and use only the 80 MHz specific version.
238		 */
239		res2 = res = verify_80mhz(mode, op_class, channel);
240	}
241
242	if (res == NOT_ALLOWED || res2 == NOT_ALLOWED)
243		return NOT_ALLOWED;
244
245	if (res == NO_IR || res2 == NO_IR)
246		return NO_IR;
247
248	return ALLOWED;
249}
250
251
252static int wpas_op_class_supported(struct wpa_supplicant *wpa_s,
253				   struct wpa_ssid *ssid,
254				   const struct oper_class_map *op_class)
255{
256	int chan;
257	size_t i;
258	struct hostapd_hw_modes *mode;
259	int found;
260	int z;
261	int freq2 = 0;
262	int freq5 = 0;
263
264	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op_class->mode,
265			is_6ghz_op_class(op_class->op_class));
266	if (!mode)
267		return 0;
268
269	/* If we are configured to disable certain things, take that into
270	 * account here. */
271	if (ssid && ssid->freq_list && ssid->freq_list[0]) {
272		for (z = 0; ; z++) {
273			int f = ssid->freq_list[z];
274
275			if (f == 0)
276				break; /* end of list */
277			if (f > 4000 && f < 6000)
278				freq5 = 1;
279			else if (f > 2400 && f < 2500)
280				freq2 = 1;
281		}
282	} else {
283		/* No frequencies specified, can use anything hardware supports.
284		 */
285		freq2 = freq5 = 1;
286	}
287
288	if (op_class->op_class >= 115 && op_class->op_class <= 130 && !freq5)
289		return 0;
290	if (op_class->op_class >= 81 && op_class->op_class <= 84 && !freq2)
291		return 0;
292
293#ifdef CONFIG_HT_OVERRIDES
294	if (ssid && ssid->disable_ht) {
295		switch (op_class->op_class) {
296		case 83:
297		case 84:
298		case 104:
299		case 105:
300		case 116:
301		case 117:
302		case 119:
303		case 120:
304		case 122:
305		case 123:
306		case 126:
307		case 127:
308		case 128:
309		case 129:
310		case 130:
311			/* Disable >= 40 MHz channels if HT is disabled */
312			return 0;
313		}
314	}
315#endif /* CONFIG_HT_OVERRIDES */
316
317#ifdef CONFIG_VHT_OVERRIDES
318	if (ssid && ssid->disable_vht) {
319		if (op_class->op_class >= 128 && op_class->op_class <= 130) {
320			/* Disable >= 80 MHz channels if VHT is disabled */
321			return 0;
322		}
323	}
324#endif /* CONFIG_VHT_OVERRIDES */
325
326	if (op_class->op_class == 128) {
327		u8 channels[] = { 42, 58, 106, 122, 138, 155, 171 };
328
329		for (i = 0; i < ARRAY_SIZE(channels); i++) {
330			if (verify_channel(mode, op_class->op_class,
331					   channels[i], op_class->bw) !=
332			    NOT_ALLOWED)
333				return 1;
334		}
335
336		return 0;
337	}
338
339	if (op_class->op_class == 129) {
340		/* Check if either 160 MHz channels is allowed */
341		return verify_channel(mode, op_class->op_class, 50,
342				      op_class->bw) != NOT_ALLOWED ||
343			verify_channel(mode, op_class->op_class, 114,
344				       op_class->bw) != NOT_ALLOWED ||
345			verify_channel(mode, op_class->op_class, 163,
346				       op_class->bw) != NOT_ALLOWED;
347	}
348
349	if (op_class->op_class == 130) {
350		/* Need at least two non-contiguous 80 MHz segments */
351		found = 0;
352
353		if (verify_channel(mode, op_class->op_class, 42,
354				   op_class->bw) != NOT_ALLOWED ||
355		    verify_channel(mode, op_class->op_class, 58,
356				   op_class->bw) != NOT_ALLOWED)
357			found++;
358		if (verify_channel(mode, op_class->op_class, 106,
359				   op_class->bw) != NOT_ALLOWED ||
360		    verify_channel(mode, op_class->op_class, 122,
361				   op_class->bw) != NOT_ALLOWED ||
362		    verify_channel(mode, op_class->op_class, 138,
363				   op_class->bw) != NOT_ALLOWED ||
364		    verify_channel(mode, op_class->op_class, 155,
365				   op_class->bw) != NOT_ALLOWED ||
366		    verify_channel(mode, op_class->op_class, 171,
367				   op_class->bw) != NOT_ALLOWED)
368			found++;
369		if (verify_channel(mode, op_class->op_class, 106,
370				   op_class->bw) != NOT_ALLOWED &&
371		    verify_channel(mode, op_class->op_class, 138,
372				   op_class->bw) != NOT_ALLOWED)
373			found++;
374		if (verify_channel(mode, op_class->op_class, 122,
375				   op_class->bw) != NOT_ALLOWED &&
376		    verify_channel(mode, op_class->op_class, 155,
377				   op_class->bw) != NOT_ALLOWED)
378			found++;
379		if (verify_channel(mode, op_class->op_class, 138,
380				   op_class->bw) != NOT_ALLOWED &&
381		    verify_channel(mode, op_class->op_class, 171,
382				   op_class->bw) != NOT_ALLOWED)
383			found++;
384
385		if (found >= 2)
386			return 1;
387
388		return 0;
389	}
390
391	if (op_class->op_class == 135) {
392		/* Need at least two 80 MHz segments which do not fall under the
393		 * same 160 MHz segment to support 80+80 in 6 GHz.
394		 */
395		int first_seg = 0;
396		int curr_seg = 0;
397
398		for (chan = op_class->min_chan; chan <= op_class->max_chan;
399		     chan += op_class->inc) {
400			curr_seg++;
401			if (verify_channel(mode, op_class->op_class, chan,
402					   op_class->bw) != NOT_ALLOWED) {
403				if (!first_seg) {
404					first_seg = curr_seg;
405					continue;
406				}
407
408				/* Supported if at least two non-consecutive 80
409				 * MHz segments allowed.
410				 */
411				if ((curr_seg - first_seg) > 1)
412					return 1;
413
414				/* Supported even if the 80 MHz segments are
415				 * consecutive when they do not fall under the
416				 * same 160 MHz segment.
417				 */
418				if ((first_seg % 2) == 0)
419					return 1;
420			}
421		}
422
423		return 0;
424	}
425
426	found = 0;
427	for (chan = op_class->min_chan; chan <= op_class->max_chan;
428	     chan += op_class->inc) {
429		if (verify_channel(mode, op_class->op_class, chan,
430				   op_class->bw) != NOT_ALLOWED) {
431			found = 1;
432			break;
433		}
434	}
435
436	return found;
437}
438
439
440static int wpas_sta_secondary_channel_offset(struct wpa_bss *bss, u8 *current,
441					     u8 *channel)
442{
443
444	const u8 *ies;
445	u8 phy_type;
446	size_t ies_len;
447
448	if (!bss)
449		return -1;
450	ies = wpa_bss_ie_ptr(bss);
451	ies_len = bss->ie_len ? bss->ie_len : bss->beacon_ie_len;
452	return wpas_get_op_chan_phy(bss->freq, ies, ies_len, current,
453				    channel, &phy_type);
454}
455
456
457size_t wpas_supp_op_class_ie(struct wpa_supplicant *wpa_s,
458			     struct wpa_ssid *ssid,
459			     struct wpa_bss *bss, u8 *pos, size_t len)
460{
461	struct wpabuf *buf;
462	u8 op, current, chan;
463	u8 *ie_len;
464	size_t res;
465
466	/*
467	 * Determine the current operating class correct mode based on
468	 * advertised BSS capabilities, if available. Fall back to a less
469	 * accurate guess based on frequency if the needed IEs are not available
470	 * or used.
471	 */
472	if (wpas_sta_secondary_channel_offset(bss, &current, &chan) < 0 &&
473	    ieee80211_freq_to_channel_ext(bss->freq, 0, CHANWIDTH_USE_HT,
474					  &current, &chan) == NUM_HOSTAPD_MODES)
475		return 0;
476
477	/*
478	 * Need 3 bytes for EID, length, and current operating class, plus
479	 * 1 byte for every other supported operating class.
480	 */
481	buf = wpabuf_alloc(global_op_class_size + 3);
482	if (!buf)
483		return 0;
484
485	wpabuf_put_u8(buf, WLAN_EID_SUPPORTED_OPERATING_CLASSES);
486	/* Will set the length later, putting a placeholder */
487	ie_len = wpabuf_put(buf, 1);
488	wpabuf_put_u8(buf, current);
489
490	for (op = 0; global_op_class[op].op_class; op++) {
491		if (wpas_op_class_supported(wpa_s, ssid, &global_op_class[op]))
492			wpabuf_put_u8(buf, global_op_class[op].op_class);
493	}
494
495	*ie_len = wpabuf_len(buf) - 2;
496	if (*ie_len < 2) {
497		wpa_printf(MSG_DEBUG,
498			   "No supported operating classes IE to add");
499		res = 0;
500	} else if (wpabuf_len(buf) > len) {
501		wpa_printf(MSG_ERROR,
502			   "Supported operating classes IE exceeds maximum buffer length");
503		res = 0;
504	} else {
505		os_memcpy(pos, wpabuf_head(buf), wpabuf_len(buf));
506		res = wpabuf_len(buf);
507		wpa_hexdump_buf(MSG_DEBUG,
508				"Added supported operating classes IE", buf);
509	}
510
511	wpabuf_free(buf);
512	return res;
513}
514
515
516int * wpas_supp_op_classes(struct wpa_supplicant *wpa_s)
517{
518	int op;
519	unsigned int pos, max_num = 0;
520	int *classes;
521
522	for (op = 0; global_op_class[op].op_class; op++)
523		max_num++;
524	classes = os_zalloc((max_num + 1) * sizeof(int));
525	if (!classes)
526		return NULL;
527
528	for (op = 0, pos = 0; global_op_class[op].op_class; op++) {
529		if (wpas_op_class_supported(wpa_s, NULL, &global_op_class[op]))
530			classes[pos++] = global_op_class[op].op_class;
531	}
532
533	return classes;
534}
535