mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-18 18:01:23 +00:00
413 lines
14 KiB
Diff
413 lines
14 KiB
Diff
From 387b308a6af81ada3643cc1c1658a7756f359b5a Mon Sep 17 00:00:00 2001
|
|
From: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
|
|
Date: Tue, 21 Sep 2021 17:20:23 +0530
|
|
Subject: [PATCH] hostapd: Add 320 MHz support
|
|
|
|
Added 320 MHz channel support in 6GHz band (EHT)
|
|
as define by IEEE P802.11be/D1.1, July 2021
|
|
section 36.3.23.2. It covers channel bringup,
|
|
frequency validation, channel switch and also
|
|
across all channel width and frequency manipulation.
|
|
|
|
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
|
|
Signed-off-by: Ramya Gnanasekar <quic_rgnanase@quicinc.com>
|
|
---
|
|
hostapd/ctrl_iface.c | 31 +++++++++++++++++++++++++++++++
|
|
src/ap/drv_callbacks.c | 6 ++++++
|
|
src/ap/hostapd.c | 9 +++++++++
|
|
src/ap/ieee802_11.c | 4 ++++
|
|
src/ap/ieee802_11_eht.c | 4 +++-
|
|
src/ap/neighbor_db.c | 9 ++++++---
|
|
src/common/defs.h | 1 +
|
|
src/common/hw_features_common.c | 3 +++
|
|
src/common/ieee802_11_common.c | 6 ++++++
|
|
src/common/ieee802_11_defs.h | 6 ++++++
|
|
src/drivers/driver.h | 1 +
|
|
src/drivers/driver_common.c | 4 ++++
|
|
src/drivers/driver_nl80211.c | 5 +++++
|
|
src/drivers/driver_nl80211_capa.c | 3 +++
|
|
src/drivers/driver_nl80211_event.c | 6 ++++++
|
|
src/drivers/nl80211_copy.h | 2 ++
|
|
wpa_supplicant/ctrl_iface.c | 2 ++
|
|
17 files changed, 98 insertions(+), 4 deletions(-)
|
|
|
|
Index: b/hostapd/ctrl_iface.c
|
|
===================================================================
|
|
--- a/hostapd/ctrl_iface.c 2022-08-30 18:41:54.749138965 +0530
|
|
+++ b/hostapd/ctrl_iface.c 2022-08-30 18:41:54.717139244 +0530
|
|
@@ -2637,7 +2637,7 @@ static int hostapd_ctrl_register_frame(s
|
|
#ifdef NEED_AP_MLME
|
|
static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
|
|
{
|
|
- int idx, bw, bw_idx[] = { 20, 40, 80, 160 };
|
|
+ int idx, bw, bw_idx[] = { 20, 40, 80, 160, 320 };
|
|
u32 start_freq;
|
|
|
|
if (is_6ghz_freq(params->freq)) {
|
|
@@ -2749,6 +2749,34 @@ static int hostapd_ctrl_check_freq_param
|
|
return -1;
|
|
}
|
|
break;
|
|
+ case 320:
|
|
+ if (!params->center_freq1 || params->center_freq2 ||
|
|
+ !params->sec_channel_offset)
|
|
+ return -1;
|
|
+
|
|
+ switch (params->sec_channel_offset) {
|
|
+ case 1:
|
|
+ if (params->freq + 150 != params->center_freq1 &&
|
|
+ params->freq + 70 != params->center_freq1 &&
|
|
+ params->freq + 30 != params->center_freq1 &&
|
|
+ params->freq - 10 != params->center_freq1 &&
|
|
+ params->freq - 50 != params->center_freq1 &&
|
|
+ params->freq - 130 != params->center_freq1)
|
|
+ return -1;
|
|
+ break;
|
|
+ case -1:
|
|
+ if (params->freq + 130 != params->center_freq1 &&
|
|
+ params->freq + 50 != params->center_freq1 &&
|
|
+ params->freq + 10 != params->center_freq1 &&
|
|
+ params->freq - 30 != params->center_freq1 &&
|
|
+ params->freq - 70 != params->center_freq1 &&
|
|
+ params->freq - 150 != params->center_freq1)
|
|
+ return -1;
|
|
+ break;
|
|
+ default:
|
|
+ return -1;
|
|
+ }
|
|
+ break;
|
|
default:
|
|
return -1;
|
|
}
|
|
@@ -2872,6 +2900,9 @@ static int hostapd_ctrl_iface_chan_switc
|
|
case 160:
|
|
bandwidth = CHAN_WIDTH_160;
|
|
break;
|
|
+ case 320:
|
|
+ bandwidth = CHAN_WIDTH_320;
|
|
+ break;
|
|
default:
|
|
bandwidth = CHAN_WIDTH_20;
|
|
break;
|
|
Index: b/src/ap/drv_callbacks.c
|
|
===================================================================
|
|
--- a/src/ap/drv_callbacks.c 2022-08-30 18:41:54.749138965 +0530
|
|
+++ b/src/ap/drv_callbacks.c 2022-08-30 18:41:54.721139209 +0530
|
|
@@ -854,6 +854,9 @@ void hostapd_event_sta_opmode_changed(st
|
|
case CHAN_WIDTH_160:
|
|
txt = "160";
|
|
break;
|
|
+ case CHAN_WIDTH_320:
|
|
+ txt = "320";
|
|
+ break;
|
|
default:
|
|
txt = NULL;
|
|
break;
|
|
@@ -917,6 +920,9 @@ void hostapd_event_ch_switch(struct host
|
|
case CHAN_WIDTH_160:
|
|
chwidth = CHANWIDTH_160MHZ;
|
|
break;
|
|
+ case CHAN_WIDTH_320:
|
|
+ chwidth = CHANWIDTH_320MHZ;
|
|
+ break;
|
|
case CHAN_WIDTH_20_NOHT:
|
|
case CHAN_WIDTH_20:
|
|
case CHAN_WIDTH_40:
|
|
@@ -977,7 +983,8 @@ void hostapd_event_ch_switch(struct host
|
|
hapd->iconf->ch_switch_eht_config = 0;
|
|
|
|
if (width == CHAN_WIDTH_40 || width == CHAN_WIDTH_80 ||
|
|
- width == CHAN_WIDTH_80P80 || width == CHAN_WIDTH_160)
|
|
+ width == CHAN_WIDTH_80P80 || width == CHAN_WIDTH_160 ||
|
|
+ width == CHAN_WIDTH_320)
|
|
hapd->iconf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
|
|
else if (width == CHAN_WIDTH_20 || width == CHAN_WIDTH_20_NOHT)
|
|
hapd->iconf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
|
|
Index: b/src/ap/hostapd.c
|
|
===================================================================
|
|
--- a/src/ap/hostapd.c 2022-08-30 18:41:54.749138965 +0530
|
|
+++ b/src/ap/hostapd.c 2022-08-30 18:41:54.725139174 +0530
|
|
@@ -3548,6 +3548,7 @@ static int hostapd_change_config_freq(st
|
|
case 40:
|
|
case 80:
|
|
case 160:
|
|
+ case 320:
|
|
conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
|
|
break;
|
|
default:
|
|
@@ -3569,6 +3570,9 @@ static int hostapd_change_config_freq(st
|
|
case 160:
|
|
hostapd_set_oper_chwidth(conf, CHANWIDTH_160MHZ);
|
|
break;
|
|
+ case 320:
|
|
+ hostapd_set_oper_chwidth(conf, CHANWIDTH_320MHZ);
|
|
+ break;
|
|
default:
|
|
return -1;
|
|
}
|
|
@@ -3617,6 +3621,9 @@ static int hostapd_fill_csa_settings(str
|
|
case 160:
|
|
bandwidth = CHANWIDTH_160MHZ;
|
|
break;
|
|
+ case 320:
|
|
+ bandwidth = CHANWIDTH_320MHZ;
|
|
+ break;
|
|
default:
|
|
bandwidth = CHANWIDTH_USE_HT;
|
|
break;
|
|
@@ -3776,6 +3783,9 @@ hostapd_switch_channel_fallback(struct h
|
|
case 160:
|
|
bw = CHANWIDTH_160MHZ;
|
|
break;
|
|
+ case 320:
|
|
+ bw = CHANWIDTH_320MHZ;
|
|
+ break;
|
|
default:
|
|
wpa_printf(MSG_WARNING, "Unknown CSA bandwidth: %d",
|
|
freq_params->bandwidth);
|
|
Index: b/src/ap/ieee802_11_eht.c
|
|
===================================================================
|
|
--- a/src/ap/ieee802_11_eht.c 2022-08-30 18:41:54.749138965 +0530
|
|
+++ b/src/ap/ieee802_11_eht.c 2022-08-30 18:41:54.725139174 +0530
|
|
@@ -301,7 +301,9 @@ static int check_valid_eht_mcs(struct ho
|
|
u8 mcs_count = 1;
|
|
|
|
switch (hapd->iface->conf->eht_oper_chwidth) {
|
|
- /* TODO CHANWIDTH_320MHZ */
|
|
+ case CHANWIDTH_320MHZ:
|
|
+ mcs_count = 3;
|
|
+ break;
|
|
case CHANWIDTH_80P80MHZ:
|
|
case CHANWIDTH_160MHZ:
|
|
mcs_count = 2;
|
|
Index: b/src/common/defs.h
|
|
===================================================================
|
|
--- a/src/common/defs.h 2022-08-30 18:41:54.749138965 +0530
|
|
+++ b/src/common/defs.h 2022-08-30 18:41:54.725139174 +0530
|
|
@@ -430,6 +430,7 @@ enum chan_width {
|
|
CHAN_WIDTH_4320,
|
|
CHAN_WIDTH_6480,
|
|
CHAN_WIDTH_8640,
|
|
+ CHAN_WIDTH_320,
|
|
CHAN_WIDTH_UNKNOWN
|
|
};
|
|
|
|
Index: b/src/common/hw_features_common.c
|
|
===================================================================
|
|
--- a/src/common/hw_features_common.c 2022-08-30 18:41:54.749138965 +0530
|
|
+++ b/src/common/hw_features_common.c 2022-08-30 18:41:54.729139140 +0530
|
|
@@ -413,6 +413,8 @@ int hostapd_set_freq_params(struct hosta
|
|
else if (oper_chwidth == CHANWIDTH_160MHZ ||
|
|
oper_chwidth == CHANWIDTH_80P80MHZ)
|
|
data->bandwidth = 160;
|
|
+ else if (oper_chwidth == CHANWIDTH_320MHZ)
|
|
+ data->bandwidth = 320;
|
|
else if (sec_channel_offset)
|
|
data->bandwidth = 40;
|
|
else
|
|
@@ -809,6 +811,9 @@ int chan_bw_allowed(const struct hostapd
|
|
case 160:
|
|
bw_mask = HOSTAPD_CHAN_WIDTH_160;
|
|
break;
|
|
+ case 320:
|
|
+ bw_mask = HOSTAPD_CHAN_WIDTH_320;
|
|
+ break;
|
|
default:
|
|
bw_mask = 0;
|
|
break;
|
|
Index: b/src/common/ieee802_11_common.c
|
|
===================================================================
|
|
--- a/src/common/ieee802_11_common.c 2022-08-30 18:41:54.749138965 +0530
|
|
+++ b/src/common/ieee802_11_common.c 2022-08-30 18:41:54.729139140 +0530
|
|
@@ -1164,6 +1164,9 @@ int ieee80211_chaninfo_to_channel(unsign
|
|
case CHAN_WIDTH_8640:
|
|
cw = CHANWIDTH_8640MHZ;
|
|
break;
|
|
+ case CHAN_WIDTH_320:
|
|
+ cw = CHANWIDTH_320MHZ;
|
|
+ break;
|
|
}
|
|
|
|
if (ieee80211_freq_to_channel_ext(freq, sec_channel, cw, op_class,
|
|
@@ -2273,6 +2276,9 @@ int center_idx_to_bw_6ghz(u8 idx)
|
|
/* channels 15, 47, 79...*/
|
|
if ((idx & 0x1f) == 0xf)
|
|
return 3; /* 160 MHz */
|
|
+ /* channels 31, 63, 95, 127, 159, 191. */
|
|
+ if ((idx & 0x1f) == 0x1f)
|
|
+ return 4; /* 320 MHz */
|
|
|
|
return -1;
|
|
}
|
|
Index: b/src/common/ieee802_11_defs.h
|
|
===================================================================
|
|
--- a/src/common/ieee802_11_defs.h 2022-08-30 18:41:54.749138965 +0530
|
|
+++ b/src/common/ieee802_11_defs.h 2022-08-30 18:41:54.729139140 +0530
|
|
@@ -2241,6 +2241,7 @@ enum phy_type {
|
|
/*
|
|
* IEEE P802.11-REVmc/D5.0 Table 9-152 - HT/VHT Operation Information
|
|
* subfields.
|
|
+ * IEEE P802.11be/D1.1 Table 9-322al - EHT Operation Information subfields.
|
|
* Note: These definitions are not the same as other CHANWIDTH_*.
|
|
*/
|
|
enum nr_chan_width {
|
|
Index: b/src/drivers/driver.h
|
|
===================================================================
|
|
--- a/src/drivers/driver.h 2022-08-30 18:41:54.749138965 +0530
|
|
+++ b/src/drivers/driver.h 2022-08-30 18:41:54.729139140 +0530
|
|
@@ -67,6 +67,7 @@ enum hostapd_chan_width_attr {
|
|
HOSTAPD_CHAN_WIDTH_40M = BIT(3),
|
|
HOSTAPD_CHAN_WIDTH_80 = BIT(4),
|
|
HOSTAPD_CHAN_WIDTH_160 = BIT(5),
|
|
+ HOSTAPD_CHAN_WIDTH_320 = BIT(6),
|
|
};
|
|
|
|
/* Filter gratuitous ARP */
|
|
Index: b/src/drivers/driver_common.c
|
|
===================================================================
|
|
--- a/src/drivers/driver_common.c 2022-08-30 18:41:54.749138965 +0530
|
|
+++ b/src/drivers/driver_common.c 2022-08-30 18:41:54.733139105 +0530
|
|
@@ -118,6 +118,8 @@ const char * channel_width_to_string(enu
|
|
return "80+80 MHz";
|
|
case CHAN_WIDTH_160:
|
|
return "160 MHz";
|
|
+ case CHAN_WIDTH_320:
|
|
+ return "320 MHz";
|
|
default:
|
|
return "unknown";
|
|
}
|
|
@@ -137,6 +139,8 @@ int channel_width_to_int(enum chan_width
|
|
case CHAN_WIDTH_80P80:
|
|
case CHAN_WIDTH_160:
|
|
return 160;
|
|
+ case CHAN_WIDTH_320:
|
|
+ return 320;
|
|
default:
|
|
return 0;
|
|
}
|
|
Index: b/src/drivers/driver_nl80211.c
|
|
===================================================================
|
|
--- a/src/drivers/driver_nl80211.c 2022-08-30 18:41:54.749138965 +0530
|
|
+++ b/src/drivers/driver_nl80211.c 2022-08-30 18:41:54.737139070 +0530
|
|
@@ -215,6 +215,8 @@ enum chan_width convert2width(int width)
|
|
return CHAN_WIDTH_80P80;
|
|
case NL80211_CHAN_WIDTH_160:
|
|
return CHAN_WIDTH_160;
|
|
+ case NL80211_CHAN_WIDTH_320:
|
|
+ return CHAN_WIDTH_320;
|
|
}
|
|
return CHAN_WIDTH_UNKNOWN;
|
|
}
|
|
@@ -5020,6 +5022,9 @@ static int nl80211_put_freq_params(struc
|
|
case 160:
|
|
cw = NL80211_CHAN_WIDTH_160;
|
|
break;
|
|
+ case 320:
|
|
+ cw = NL80211_CHAN_WIDTH_320;
|
|
+ break;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
Index: b/src/drivers/driver_nl80211_capa.c
|
|
===================================================================
|
|
--- a/src/drivers/driver_nl80211_capa.c 2022-08-30 18:41:54.749138965 +0530
|
|
+++ b/src/drivers/driver_nl80211_capa.c 2022-08-30 18:41:54.737139070 +0530
|
|
@@ -1628,6 +1628,9 @@ static void phy_info_freq(struct hostapd
|
|
chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_80;
|
|
if (tb_freq[NL80211_FREQUENCY_ATTR_NO_160MHZ])
|
|
chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_160;
|
|
+ if (tb_freq[NL80211_FREQUENCY_ATTR_NO_320MHZ])
|
|
+ chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_320;
|
|
+
|
|
|
|
if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]) {
|
|
enum nl80211_dfs_state state =
|
|
Index: b/src/drivers/driver_nl80211_event.c
|
|
===================================================================
|
|
--- a/src/drivers/driver_nl80211_event.c 2022-08-30 18:41:54.749138965 +0530
|
|
+++ b/src/drivers/driver_nl80211_event.c 2022-08-30 18:41:54.741139036 +0530
|
|
@@ -675,6 +675,9 @@ static int calculate_chan_offset(int wid
|
|
case CHAN_WIDTH_80P80:
|
|
freq1 = cf1 - 30;
|
|
break;
|
|
+ case CHAN_WIDTH_320:
|
|
+ freq1 = cf1 - 150;
|
|
+ break;
|
|
case CHAN_WIDTH_UNKNOWN:
|
|
case CHAN_WIDTH_2160:
|
|
case CHAN_WIDTH_4320:
|
|
@@ -2825,6 +2828,9 @@ static void nl80211_sta_opmode_change_ev
|
|
case NL80211_CHAN_WIDTH_160:
|
|
ed.sta_opmode.chan_width = CHAN_WIDTH_160;
|
|
break;
|
|
+ case NL80211_CHAN_WIDTH_320:
|
|
+ ed.sta_opmode.chan_width = CHAN_WIDTH_320;
|
|
+ break;
|
|
default:
|
|
ed.sta_opmode.chan_width = CHAN_WIDTH_UNKNOWN;
|
|
break;
|
|
Index: b/src/drivers/nl80211_copy.h
|
|
===================================================================
|
|
--- a/src/drivers/nl80211_copy.h 2022-08-30 18:41:54.749138965 +0530
|
|
+++ b/src/drivers/nl80211_copy.h 2022-08-30 18:42:13.980971726 +0530
|
|
@@ -3947,6 +3947,9 @@ enum nl80211_frequency_attr {
|
|
NL80211_FREQUENCY_ATTR_4MHZ,
|
|
NL80211_FREQUENCY_ATTR_8MHZ,
|
|
NL80211_FREQUENCY_ATTR_16MHZ,
|
|
+ NL80211_FREQUENCY_ATTR_PSD,
|
|
+ NL80211_FREQUENCY_ATTR_NO_320MHZ,
|
|
+ NL80211_FREQUENCY_ATTR_NO_EHT,
|
|
|
|
/* keep last */
|
|
__NL80211_FREQUENCY_ATTR_AFTER_LAST,
|
|
@@ -4682,6 +4685,7 @@ enum nl80211_chan_width {
|
|
NL80211_CHAN_WIDTH_4,
|
|
NL80211_CHAN_WIDTH_8,
|
|
NL80211_CHAN_WIDTH_16,
|
|
+ NL80211_CHAN_WIDTH_320,
|
|
|
|
/* keep last */
|
|
__NL80211_CHAN_WIDTH_NUM,
|
|
Index: b/wpa_supplicant/ctrl_iface.c
|
|
===================================================================
|
|
--- a/wpa_supplicant/ctrl_iface.c 2022-08-30 18:41:54.749138965 +0530
|
|
+++ b/wpa_supplicant/ctrl_iface.c 2022-08-30 18:41:54.745139000 +0530
|
|
@@ -5993,6 +5993,8 @@ static int parse_freq(int chwidth, int f
|
|
return CHANWIDTH_80MHZ;
|
|
case 160:
|
|
return CHANWIDTH_160MHZ;
|
|
+ case 320:
|
|
+ return CHANWIDTH_320MHZ;
|
|
default:
|
|
wpa_printf(MSG_DEBUG, "Unknown max oper bandwidth: %d",
|
|
chwidth);
|
|
Index: b/src/ap/ap_config.h
|
|
===================================================================
|
|
--- a/src/ap/ap_config.h 2022-08-30 18:41:54.749138965 +0530
|
|
+++ b/src/ap/ap_config.h 2022-08-30 18:41:54.745139000 +0530
|
|
@@ -1186,7 +1186,8 @@ hostapd_set_oper_chwidth(struct hostapd_
|
|
conf->eht_oper_chwidth = oper_chwidth;
|
|
#endif /* CONFIG_IEEE80211BE */
|
|
#ifdef CONFIG_IEEE80211AX
|
|
- if (conf->ieee80211ax)
|
|
+ if (conf->ieee80211ax &&
|
|
+ oper_chwidth < CHANWIDTH_320MHZ)
|
|
conf->he_oper_chwidth = oper_chwidth;
|
|
#endif /* CONFIG_IEEE80211AX */
|
|
conf->vht_oper_chwidth = oper_chwidth;
|
|
Index: b/src/ap/ieee802_11_he.c
|
|
===================================================================
|
|
--- a/src/ap/ieee802_11_he.c 2022-08-30 18:41:54.749138965 +0530
|
|
+++ b/src/ap/ieee802_11_he.c 2022-08-30 18:41:54.749138965 +0530
|
|
@@ -219,8 +219,8 @@ u8 * hostapd_eid_he_operation(struct hos
|
|
pos += 6; /* skip the fixed part */
|
|
|
|
if (is_6ghz_op_class(hapd->iconf->op_class)) {
|
|
- u8 seg0 = hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf);
|
|
- u8 seg1 = hostapd_get_oper_centr_freq_seg1_idx(hapd->iconf);
|
|
+ u8 seg0 = hapd->iface->conf->he_oper_centr_freq_seg0_idx;
|
|
+ u8 seg1 = hapd->iface->conf->he_oper_centr_freq_seg1_idx;
|
|
|
|
if (hapd->iconf->ru_punct_bitmap) {
|
|
hapd->iconf->he_oper_chwidth =
|