From adfeda849198b33ffa7a7ef233ae8a4df22bbc2d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 14 Jul 2023 10:01:30 +0200 Subject: [PATCH] hostapd: add fix for dealing with VHT 160 MHz via ext nss bw Signed-off-by: Felix Fietkau --- ...tapd-update-cfs0-and-cfs1-for-160MHz.patch | 141 ++++++++++++++++++ .../services/hostapd/patches/300-noscan.patch | 6 +- ...tapd-config-support-random-BSS-color.patch | 2 +- .../hostapd/patches/700-wifi-reload.patch | 4 +- .../hostapd/patches/710-vlan_no_bridge.patch | 2 +- .../patches/711-wds_bridge_force.patch | 2 +- .../patches/720-iface_max_num_sta.patch | 2 +- .../hostapd/patches/730-ft_iface.patch | 2 +- .../hostapd/patches/740-snoop_iface.patch | 2 +- ...750-qos_map_set_without_interworking.patch | 6 +- .../hostapd/patches/760-dynamic_own_ip.patch | 2 +- 11 files changed, 156 insertions(+), 15 deletions(-) create mode 100644 package/network/services/hostapd/patches/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch diff --git a/package/network/services/hostapd/patches/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch b/package/network/services/hostapd/patches/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch new file mode 100644 index 000000000000..710a3c851e11 --- /dev/null +++ b/package/network/services/hostapd/patches/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch @@ -0,0 +1,141 @@ +From d4c4ef302f98fd6bce173b8636e7e350d8b44981 Mon Sep 17 00:00:00 2001 +From: P Praneesh +Date: Fri, 19 Mar 2021 12:17:27 +0530 +Subject: [PATCH] hostapd: update cfs0 and cfs1 for 160MHz + +As per standard Draft P802.11ax_D8.0,( Table 26-9—Setting +of the VHT Channel Width and VHT NSS at an HE STA +transmitting the OM Control subfield ), center frequency of +160MHz should be published in HT information subset 2 of +HT information when EXT NSS BW field is enabled. + +If the supported number of NSS in 160MHz is at least max NSS +support, then center_freq_seg0 indicates the center frequency of 80MHz and +center_freq_seg1 indicates the center frequency of 160MHz. + +If the supported number of NSS in 160MHz is less than max NSS +support, then center_freq_seg0 indicates the center frequency of 80MHz and +center_freq_seg1 is 0. The center frequency of 160MHz is published in HT +operation information element instead. + +Signed-off-by: P Praneesh +--- + hostapd/config_file.c | 2 ++ + src/ap/ieee802_11_ht.c | 7 +++++++ + src/ap/ieee802_11_vht.c | 16 ++++++++++++++++ + src/common/hw_features_common.c | 1 + + src/common/ieee802_11_defs.h | 1 + + 5 files changed, 27 insertions(+) + +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c +@@ -1153,6 +1153,8 @@ static int hostapd_config_vht_capab(stru + conf->vht_capab |= VHT_CAP_RX_ANTENNA_PATTERN; + if (os_strstr(capab, "[TX-ANTENNA-PATTERN]")) + conf->vht_capab |= VHT_CAP_TX_ANTENNA_PATTERN; ++ if (os_strstr(capab, "[EXT-NSS-BW-SUPP]")) ++ conf->vht_capab |= VHT_CAP_EXTENDED_NSS_BW_SUPPORT; + return 0; + } + #endif /* CONFIG_IEEE80211AC */ +--- a/src/ap/ieee802_11_ht.c ++++ b/src/ap/ieee802_11_ht.c +@@ -82,7 +82,9 @@ u8 * hostapd_eid_ht_capabilities(struct + u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid) + { + struct ieee80211_ht_operation *oper; ++ le32 vht_capabilities_info; + u8 *pos = eid; ++ u8 chwidth; + + if (!hapd->iconf->ieee80211n || hapd->conf->disable_11n || + is_6ghz_op_class(hapd->iconf->op_class)) +@@ -103,6 +105,13 @@ u8 * hostapd_eid_ht_operation(struct hos + oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW | + HT_INFO_HT_PARAM_STA_CHNL_WIDTH; + ++ vht_capabilities_info = host_to_le32(hapd->iface->current_mode->vht_capab); ++ chwidth = hostapd_get_oper_chwidth(hapd->iconf); ++ if (vht_capabilities_info & VHT_CAP_EXTENDED_NSS_BW_SUPPORT ++ && ((chwidth == CHANWIDTH_160MHZ) || (chwidth == CHANWIDTH_80P80MHZ))) { ++ oper->operation_mode = host_to_le16(hapd->iconf->vht_oper_centr_freq_seg0_idx << 5); ++ } ++ + pos += sizeof(*oper); + + return pos; +--- a/src/ap/ieee802_11_vht.c ++++ b/src/ap/ieee802_11_vht.c +@@ -25,6 +25,7 @@ u8 * hostapd_eid_vht_capabilities(struct + struct ieee80211_vht_capabilities *cap; + struct hostapd_hw_modes *mode = hapd->iface->current_mode; + u8 *pos = eid; ++ u8 chwidth; + + if (!mode || is_6ghz_op_class(hapd->iconf->op_class)) + return eid; +@@ -62,6 +63,17 @@ u8 * hostapd_eid_vht_capabilities(struct + host_to_le32(nsts << VHT_CAP_BEAMFORMEE_STS_OFFSET); + } + ++ chwidth = hostapd_get_oper_chwidth(hapd->iconf); ++ if (((host_to_le32(mode->vht_capab)) & VHT_CAP_EXTENDED_NSS_BW_SUPPORT) ++ && ((chwidth == CHANWIDTH_160MHZ) || (chwidth == CHANWIDTH_80P80MHZ))) { ++ cap->vht_capabilities_info |= VHT_CAP_EXTENDED_NSS_BW_SUPPORT; ++ cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)); ++ cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)); ++ cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_MASK)); ++ } else { ++ cap->vht_capabilities_info &= ~VHT_CAP_EXTENDED_NSS_BW_SUPPORT_MASK; ++ } ++ + /* Supported MCS set comes from hw */ + os_memcpy(&cap->vht_supported_mcs_set, mode->vht_mcs_set, 8); + +@@ -74,6 +86,7 @@ u8 * hostapd_eid_vht_capabilities(struct + u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid) + { + struct ieee80211_vht_operation *oper; ++ le32 vht_capabilities_info; + u8 *pos = eid; + enum oper_chan_width oper_chwidth = + hostapd_get_oper_chwidth(hapd->iconf); +@@ -106,6 +119,7 @@ u8 * hostapd_eid_vht_operation(struct ho + oper->vht_op_info_chan_center_freq_seg1_idx = seg1; + + oper->vht_op_info_chwidth = oper_chwidth; ++ vht_capabilities_info = host_to_le32(hapd->iface->current_mode->vht_capab); + if (oper_chwidth == CONF_OPER_CHWIDTH_160MHZ) { + /* + * Convert 160 MHz channel width to new style as interop +@@ -119,6 +133,9 @@ u8 * hostapd_eid_vht_operation(struct ho + oper->vht_op_info_chan_center_freq_seg0_idx -= 8; + else + oper->vht_op_info_chan_center_freq_seg0_idx += 8; ++ ++ if (vht_capabilities_info & VHT_CAP_EXTENDED_NSS_BW_SUPPORT) ++ oper->vht_op_info_chan_center_freq_seg1_idx = 0; + } else if (oper_chwidth == CONF_OPER_CHWIDTH_80P80MHZ) { + /* + * Convert 80+80 MHz channel width to new style as interop +--- a/src/common/hw_features_common.c ++++ b/src/common/hw_features_common.c +@@ -808,6 +808,7 @@ int ieee80211ac_cap_check(u32 hw, u32 co + VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB); + VHT_CAP_CHECK(VHT_CAP_RX_ANTENNA_PATTERN); + VHT_CAP_CHECK(VHT_CAP_TX_ANTENNA_PATTERN); ++ VHT_CAP_CHECK(VHT_CAP_EXTENDED_NSS_BW_SUPPORT); + + #undef VHT_CAP_CHECK + #undef VHT_CAP_CHECK_MAX +--- a/src/common/ieee802_11_defs.h ++++ b/src/common/ieee802_11_defs.h +@@ -1348,6 +1348,8 @@ struct ieee80211_ampe_ie { + #define VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB ((u32) BIT(26) | BIT(27)) + #define VHT_CAP_RX_ANTENNA_PATTERN ((u32) BIT(28)) + #define VHT_CAP_TX_ANTENNA_PATTERN ((u32) BIT(29)) ++#define VHT_CAP_EXTENDED_NSS_BW_SUPPORT ((u32) BIT(30)) ++#define VHT_CAP_EXTENDED_NSS_BW_SUPPORT_MASK ((u32) BIT(30) | BIT(31)) + + #define VHT_OPMODE_CHANNEL_WIDTH_MASK ((u8) BIT(0) | BIT(1)) + #define VHT_OPMODE_CHANNEL_RxNSS_MASK ((u8) BIT(4) | BIT(5) | \ diff --git a/package/network/services/hostapd/patches/300-noscan.patch b/package/network/services/hostapd/patches/300-noscan.patch index c6f9eba9d538..1ea89043e896 100644 --- a/package/network/services/hostapd/patches/300-noscan.patch +++ b/package/network/services/hostapd/patches/300-noscan.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3446,6 +3446,10 @@ static int hostapd_config_fill(struct ho +@@ -3448,6 +3448,10 @@ static int hostapd_config_fill(struct ho if (bss->ocv && !bss->ieee80211w) bss->ieee80211w = 1; #endif /* CONFIG_OCV */ @@ -36,7 +36,7 @@ hostapd_set_state(iface, HAPD_IFACE_HT_SCAN); --- a/src/ap/ieee802_11_ht.c +++ b/src/ap/ieee802_11_ht.c -@@ -230,6 +230,9 @@ void hostapd_2040_coex_action(struct hos +@@ -239,6 +239,9 @@ void hostapd_2040_coex_action(struct hos return; } @@ -46,7 +46,7 @@ if (len < IEEE80211_HDRLEN + 2 + sizeof(*bc_ie)) { wpa_printf(MSG_DEBUG, "Ignore too short 20/40 BSS Coexistence Management frame"); -@@ -390,6 +393,9 @@ void ht40_intolerant_add(struct hostapd_ +@@ -399,6 +402,9 @@ void ht40_intolerant_add(struct hostapd_ if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G) return; diff --git a/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch b/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch index ada77853feea..7d3d94648e19 100644 --- a/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch +++ b/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch @@ -13,7 +13,7 @@ Signed-off-by: David Bauer --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3498,6 +3498,8 @@ static int hostapd_config_fill(struct ho +@@ -3500,6 +3500,8 @@ static int hostapd_config_fill(struct ho } else if (os_strcmp(buf, "he_bss_color") == 0) { conf->he_op.he_bss_color = atoi(pos) & 0x3f; conf->he_op.he_bss_color_disabled = 0; diff --git a/package/network/services/hostapd/patches/700-wifi-reload.patch b/package/network/services/hostapd/patches/700-wifi-reload.patch index e0da149c443d..0c7627645f69 100644 --- a/package/network/services/hostapd/patches/700-wifi-reload.patch +++ b/package/network/services/hostapd/patches/700-wifi-reload.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -2418,6 +2418,8 @@ static int hostapd_config_fill(struct ho +@@ -2420,6 +2420,8 @@ static int hostapd_config_fill(struct ho bss->isolate = atoi(pos); } else if (os_strcmp(buf, "ap_max_inactivity") == 0) { bss->ap_max_inactivity = atoi(pos); @@ -9,7 +9,7 @@ } else if (os_strcmp(buf, "skip_inactivity_poll") == 0) { bss->skip_inactivity_poll = atoi(pos); } else if (os_strcmp(buf, "config_id") == 0) { -@@ -3128,6 +3130,8 @@ static int hostapd_config_fill(struct ho +@@ -3130,6 +3132,8 @@ static int hostapd_config_fill(struct ho } } else if (os_strcmp(buf, "acs_exclude_dfs") == 0) { conf->acs_exclude_dfs = atoi(pos); diff --git a/package/network/services/hostapd/patches/710-vlan_no_bridge.patch b/package/network/services/hostapd/patches/710-vlan_no_bridge.patch index f625f4bda4b4..61f33acb6e8e 100644 --- a/package/network/services/hostapd/patches/710-vlan_no_bridge.patch +++ b/package/network/services/hostapd/patches/710-vlan_no_bridge.patch @@ -30,7 +30,7 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3353,6 +3353,8 @@ static int hostapd_config_fill(struct ho +@@ -3355,6 +3355,8 @@ static int hostapd_config_fill(struct ho #ifndef CONFIG_NO_VLAN } else if (os_strcmp(buf, "dynamic_vlan") == 0) { bss->ssid.dynamic_vlan = atoi(pos); diff --git a/package/network/services/hostapd/patches/711-wds_bridge_force.patch b/package/network/services/hostapd/patches/711-wds_bridge_force.patch index e04ae6253845..c0f2c31c4482 100644 --- a/package/network/services/hostapd/patches/711-wds_bridge_force.patch +++ b/package/network/services/hostapd/patches/711-wds_bridge_force.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -2316,6 +2316,8 @@ static int hostapd_config_fill(struct ho +@@ -2318,6 +2318,8 @@ static int hostapd_config_fill(struct ho sizeof(conf->bss[0]->iface)); } else if (os_strcmp(buf, "bridge") == 0) { os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); diff --git a/package/network/services/hostapd/patches/720-iface_max_num_sta.patch b/package/network/services/hostapd/patches/720-iface_max_num_sta.patch index bf7e8e761754..0bb00f955547 100644 --- a/package/network/services/hostapd/patches/720-iface_max_num_sta.patch +++ b/package/network/services/hostapd/patches/720-iface_max_num_sta.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -2848,6 +2848,14 @@ static int hostapd_config_fill(struct ho +@@ -2850,6 +2850,14 @@ static int hostapd_config_fill(struct ho line, bss->max_num_sta, MAX_STA_COUNT); return 1; } diff --git a/package/network/services/hostapd/patches/730-ft_iface.patch b/package/network/services/hostapd/patches/730-ft_iface.patch index 0795ed15a140..563fe5b5fbbd 100644 --- a/package/network/services/hostapd/patches/730-ft_iface.patch +++ b/package/network/services/hostapd/patches/730-ft_iface.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3007,6 +3007,8 @@ static int hostapd_config_fill(struct ho +@@ -3009,6 +3009,8 @@ static int hostapd_config_fill(struct ho wpa_printf(MSG_INFO, "Line %d: Obsolete peerkey parameter ignored", line); #ifdef CONFIG_IEEE80211R_AP diff --git a/package/network/services/hostapd/patches/740-snoop_iface.patch b/package/network/services/hostapd/patches/740-snoop_iface.patch index a11664473653..6b6cc0fad799 100644 --- a/package/network/services/hostapd/patches/740-snoop_iface.patch +++ b/package/network/services/hostapd/patches/740-snoop_iface.patch @@ -55,7 +55,7 @@ "x_snoop: Failed to initialize L2 packet processing %s", --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -2320,6 +2320,8 @@ static int hostapd_config_fill(struct ho +@@ -2322,6 +2322,8 @@ static int hostapd_config_fill(struct ho os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge)); } else if (os_strcmp(buf, "bridge_hairpin") == 0) { bss->bridge_hairpin = atoi(pos); diff --git a/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch b/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch index e06e36c37d19..124f5ea6bae5 100644 --- a/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch +++ b/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -1602,6 +1602,8 @@ static int parse_anqp_elem(struct hostap +@@ -1604,6 +1604,8 @@ static int parse_anqp_elem(struct hostap return 0; } @@ -9,7 +9,7 @@ static int parse_qos_map_set(struct hostapd_bss_config *bss, char *buf, int line) -@@ -1643,8 +1645,6 @@ static int parse_qos_map_set(struct host +@@ -1645,8 +1647,6 @@ static int parse_qos_map_set(struct host return 0; } @@ -18,7 +18,7 @@ #ifdef CONFIG_HS20 static int hs20_parse_conn_capab(struct hostapd_bss_config *bss, char *buf, -@@ -4064,10 +4064,10 @@ static int hostapd_config_fill(struct ho +@@ -4066,10 +4066,10 @@ static int hostapd_config_fill(struct ho bss->gas_frag_limit = val; } else if (os_strcmp(buf, "gas_comeback_delay") == 0) { bss->gas_comeback_delay = atoi(pos); diff --git a/package/network/services/hostapd/patches/760-dynamic_own_ip.patch b/package/network/services/hostapd/patches/760-dynamic_own_ip.patch index 2c705a68cf0a..946b4533bf24 100644 --- a/package/network/services/hostapd/patches/760-dynamic_own_ip.patch +++ b/package/network/services/hostapd/patches/760-dynamic_own_ip.patch @@ -98,7 +98,7 @@ hapd->conf->own_ip_addr.af == AF_INET && --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -2688,6 +2688,8 @@ static int hostapd_config_fill(struct ho +@@ -2690,6 +2690,8 @@ static int hostapd_config_fill(struct ho } else if (os_strcmp(buf, "iapp_interface") == 0) { wpa_printf(MSG_INFO, "DEPRECATED: iapp_interface not used"); #endif /* CONFIG_IAPP */ -- 2.30.2