[wpa_supplicant] cumilative patch from commit bb945b98f
Bug: 275651698
Test: Connect to open, WPA2, WPA3 and passpoint network
Test: Establish P2P connection
Test: Basic SoftAp tests
Test: Regression test (b/275948027)
BYPASS_INCLUSIVE_LANGUAGE_REASON=Merged from opne source
bb945b98f Add 40 and 80 MHz channels 165 and 173 for 5 GHz IBSS/mesh
0059fa5ba 6 GHz: Fix secondary channel setting
744295c8b Add 6 GHz channel validation during channel switching
5349a45d3 Set interface state as inactive if mesh bringup fails
a4af79624 Handle signal termination in hostapd_cli for all cases
cf8f13ac8 Add support to send 320 MHz bandwidth through vendor subcmd
a0403c023 EHT: Validate the puncturing bitmap for ACS
af0f60e7d EHT: Calculate puncturing bitmap for ACS
f3206fbe9 EHT: Configuration option for ACS puncturing threshold
e3621867c EHT: Process puncturing bitmap from channel switch event
e277e577c nl80211: Send EHT puncturing bitmap to the driver for switch command
29a882bed EHT: Configure puncturing bitmap during channel switch
4942b19ff EHT: Send puncturing bitmap to the driver for AP bring up
f9fc2eabb EHT: Add puncturing bitmap to EHT Operation element
46a5d989d EHT: Downgrade bandwidths for VHT and HE when using puncturing
7618269ec EHT: Validate puncturing bitmap
9102fda31 EHT: Add configuration option for puncturing in AP mode
9e79439fc nl80211: Retrieve driver support for EHT puncturing
507be376c Sync with wireless-next.git include/uapi/linux/nl80211.h
591256a8c FILS: 320 MHz support in FD frame
903e3a1e6 FILS: Fix maximum NSS calculation for FD frame
ecae45ff6 FILS: Make HE a requirement for FILS discovery
4e86692ff AP: Fix 6 GHz AP setup after disable-enable
a34b8477a ml80211: Put wiphy idx to obtain correct country code
1491fc64a Define QCA vendor per-enum 64-bit pad attributes
55e31699e qca-vendor: Add QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NF_CAL_VAL
b1f85957c Add QCA vendor commands to set and get MLO links state information
44b32a752 mesh: Add EHT support
c4cb62ca8 WPA_AUTH: MLO: Add functions to get the AA and SPA
cab963e9f AP: Split check_assoc_ies()
7a7a2256c common: Support parsing link specific association request
b39e35693 common: Add support for clearing elements
0b2fc4268 common: Split ieee8021_parse_elems()
df6561ec0 nl80211: AP MLD support for adding multi link stations
b8b4ceb8d nl80211: Properly stop and deinit MLO AP
2f8fc46ed nl80211: Provide link_id in EAPOL_RX and RX_MGMT events
821374d43 nl80211: Introduce and implement a callback to add an MLO link for AP MLD
47269be36 nl80211: Refactor i802_bss to support multiple links
eb146ee80 AP: Add some bridge port attribute settings
f628e6b30 nl80211: Make sure scan frequency debug buffer is NUL terminated
41d23254b nl80211: Fix frequencies array boundary check for scanned frequencies
a9012070a Android: Add wowlan_disconnect_on_deinit to template configuration
e2ea0fd70 EST: Write the RSA private key using the standard PRIVATE KEY format
bfd236df2 webkit2: Avoid deprecated function call
2c3202682 P2P: Filter out 6 GHz frequencies if not allowed for P2P connection
b2bf7e39e Update PMK in wpa_sm when roam+auth event indicated with authorized flag
6b9c86466 nl80211: Replace the channel flags for VHT support
6f63aca7b DPP: Allow both STA and AP configObject to be set
7292e30b7 DPP: Fix @CONF-OBJ-SEP@ parsing for multiple configs
c31600ce1 P2P: Allow GO BSSID to be specified for P2P_GROUP_ADD commands
0430756e6 P2P: Optimize join scan frequency
b3921db42 nl80211: Add frequency info in start AP command
40c139664 macsec_linux: Add support for MACsec hardware offload
6d24673ab mka: Allow configuration of MACsec hardware offload
3081a9cb6 hostapd: Output country_code and country3 when using STATUS
91ad7a309 FT: Store PTKSA entry for the correct BSSID in the FT protocol case
3f3e356fa Mark addr argument to storing PTKSA const
242c3ad99 FT: Store PTKSA from FT protocol
ba6954874 Mark wpa_auth_remove_ptksa() static
3b1ad1334 FT: Include KDK in FT specific PTK derivation on the AP
870a5bdc0 nl80211: Report guard interval and dual carrier modulation
edcad193a dbus: Add inactive time to D-Bus signal info
a678a510f dbus: Add D-Bus signal for PSK mismatch heuristics
691f729d5 P2P: Make invitation flow less aggressive
f4a7e2a07 Rework IBSS/mesh 80 MHz channel selection
f91f971bd Fix creating 6 GHz IBSS/mesh on 5/6 GHz-capable PHYs
c623cee42 Make arrays static const in ibss_mesh_select_*()
64043e615 Split ibss_mesh_setup_freq() into multiple functions
8085a7e65 wpa_supplicant: Add option to explicitly set 4addr mode
1ffc7d1c6 Apply bias towards 6 GHz in roaming
faa410292 WNM: Event report handling for BSS color collision and in-use
97405be96 Small textual improvements to wpa_supplicant man page
ec02a0e93 hostapd: Output hw_mode when using STATUS
390e24c6c EAP-TTLS server: Add Ident field to MS-CHAP-Error
4ae798a22 P2P: Pick the best driver pref freq for invitation process
6c75f1dfa Send broadcast Probe Response frames on the 6 GHz band
edfcb2f1a MLD STA: Indicate MLO support in NL80211_CMD_CONNECT
c91852044 MLD STA: Add support for SAE external authentication offload to userspace
575712450 qca-vendor: Add QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_LOW_LATENCY
ba150059d FT: Store PMK-R0/PMK-R1 after EAPOL-Key msg 2/4 MIC validation
56662f36d Refine vendor subcmd QCA_NL80211_VENDOR_SUBCMD_ROAM_STATS
72b8193f4 MACsec: Remove EAP Session-Id length constraint
3915e8834 hostapd: Report error on unknown ACCEPT_ACL/DENY_ACL commands
2cff340d1 utils: Move log2pcap to python3
12de8112b Fix BSS age underflow
d31c2b43a Fix segfault in case of an invalid configuration
a32b424a3 MLD STA: Use AP MLD address in PMKSA cache attempts for driver-SME case
8c4790cef MLD STA: Store PMKSA with AP MLD address for MLO connection event
bf124a03d SAE: Update PT value at later point for SME cases, if needed
1aadcca0a P2P: Enable SAE-H2E for client when joining a 6 GHz group
37f8257c4 SAE: Extend automatic enabling of H2E on 6 GHz to additional cases
89377c6b9 OCV: Fix build without CONFIG_OCV=y
2e47ea22c P2P: Fix handling Service Discovery Response received by GO device
dc7e330e0 Set OCV capability based on Association Request frame RSNE
831be6514 WPS: Do not indicate incorrect PBC overlap based on partner link
c9fc12425 P2P: Make wpas_p2p_notif_pbc_overlap() static
Change-Id: I1eb61fc82b98b937a2ff37a30e60e28129fe143d
Merged-In: I1eb61fc82b98b937a2ff37a30e60e28129fe143d
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index e53f0dc..0142ee4 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -3652,40 +3652,34 @@
}
-static int check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
- const u8 *ies, size_t ies_len, int reassoc)
+static int __check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
+ const u8 *ies, size_t ies_len,
+ struct ieee802_11_elems *elems, int reassoc)
{
- struct ieee802_11_elems elems;
int resp;
const u8 *wpa_ie;
size_t wpa_ie_len;
const u8 *p2p_dev_addr = NULL;
- if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) {
- hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
- HOSTAPD_LEVEL_INFO, "Station sent an invalid "
- "association request");
- return WLAN_STATUS_UNSPECIFIED_FAILURE;
- }
-
- resp = check_ssid(hapd, sta, elems.ssid, elems.ssid_len);
+ resp = check_ssid(hapd, sta, elems->ssid, elems->ssid_len);
if (resp != WLAN_STATUS_SUCCESS)
return resp;
- resp = check_wmm(hapd, sta, elems.wmm, elems.wmm_len);
+ resp = check_wmm(hapd, sta, elems->wmm, elems->wmm_len);
if (resp != WLAN_STATUS_SUCCESS)
return resp;
- resp = check_ext_capab(hapd, sta, elems.ext_capab, elems.ext_capab_len);
+ resp = check_ext_capab(hapd, sta, elems->ext_capab,
+ elems->ext_capab_len);
if (resp != WLAN_STATUS_SUCCESS)
return resp;
- resp = copy_supp_rates(hapd, sta, &elems);
+ resp = copy_supp_rates(hapd, sta, elems);
if (resp != WLAN_STATUS_SUCCESS)
return resp;
- resp = check_multi_ap(hapd, sta, elems.multi_ap, elems.multi_ap_len);
+ resp = check_multi_ap(hapd, sta, elems->multi_ap, elems->multi_ap_len);
if (resp != WLAN_STATUS_SUCCESS)
return resp;
- resp = copy_sta_ht_capab(hapd, sta, elems.ht_capabilities);
+ resp = copy_sta_ht_capab(hapd, sta, elems->ht_capabilities);
if (resp != WLAN_STATUS_SUCCESS)
return resp;
if (hapd->iconf->ieee80211n && hapd->iconf->require_ht &&
@@ -3698,11 +3692,11 @@
#ifdef CONFIG_IEEE80211AC
if (hapd->iconf->ieee80211ac) {
- resp = copy_sta_vht_capab(hapd, sta, elems.vht_capabilities);
+ resp = copy_sta_vht_capab(hapd, sta, elems->vht_capabilities);
if (resp != WLAN_STATUS_SUCCESS)
return resp;
- resp = set_sta_vht_opmode(hapd, sta, elems.vht_opmode_notif);
+ resp = set_sta_vht_opmode(hapd, sta, elems->vht_opmode_notif);
if (resp != WLAN_STATUS_SUCCESS)
return resp;
}
@@ -3715,9 +3709,9 @@
return WLAN_STATUS_ASSOC_DENIED_NO_VHT;
}
- if (hapd->conf->vendor_vht && !elems.vht_capabilities) {
- resp = copy_sta_vendor_vht(hapd, sta, elems.vendor_vht,
- elems.vendor_vht_len);
+ if (hapd->conf->vendor_vht && !elems->vht_capabilities) {
+ resp = copy_sta_vendor_vht(hapd, sta, elems->vendor_vht,
+ elems->vendor_vht_len);
if (resp != WLAN_STATUS_SUCCESS)
return resp;
}
@@ -3725,8 +3719,8 @@
#ifdef CONFIG_IEEE80211AX
if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
resp = copy_sta_he_capab(hapd, sta, IEEE80211_MODE_AP,
- elems.he_capabilities,
- elems.he_capabilities_len);
+ elems->he_capabilities,
+ elems->he_capabilities_len);
if (resp != WLAN_STATUS_SUCCESS)
return resp;
@@ -3747,7 +3741,7 @@
return WLAN_STATUS_DENIED_HE_NOT_SUPPORTED;
}
resp = copy_sta_he_6ghz_capab(hapd, sta,
- elems.he_6ghz_band_cap);
+ elems->he_6ghz_band_cap);
if (resp != WLAN_STATUS_SUCCESS)
return resp;
}
@@ -3756,17 +3750,17 @@
#ifdef CONFIG_IEEE80211BE
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
resp = copy_sta_eht_capab(hapd, sta, IEEE80211_MODE_AP,
- elems.he_capabilities,
- elems.he_capabilities_len,
- elems.eht_capabilities,
- elems.eht_capabilities_len);
+ elems->he_capabilities,
+ elems->he_capabilities_len,
+ elems->eht_capabilities,
+ elems->eht_capabilities_len);
if (resp != WLAN_STATUS_SUCCESS)
return resp;
}
#endif /* CONFIG_IEEE80211BE */
#ifdef CONFIG_P2P
- if (elems.p2p) {
+ if (elems->p2p && ies && ies_len) {
wpabuf_free(sta->p2p_ie);
sta->p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
P2P_IE_VENDOR_TYPE);
@@ -3778,13 +3772,13 @@
}
#endif /* CONFIG_P2P */
- if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems.rsn_ie) {
- wpa_ie = elems.rsn_ie;
- wpa_ie_len = elems.rsn_ie_len;
+ if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems->rsn_ie) {
+ wpa_ie = elems->rsn_ie;
+ wpa_ie_len = elems->rsn_ie_len;
} else if ((hapd->conf->wpa & WPA_PROTO_WPA) &&
- elems.wpa_ie) {
- wpa_ie = elems.wpa_ie;
- wpa_ie_len = elems.wpa_ie_len;
+ elems->wpa_ie) {
+ wpa_ie = elems->wpa_ie;
+ wpa_ie_len = elems->wpa_ie_len;
} else {
wpa_ie = NULL;
wpa_ie_len = 0;
@@ -3792,7 +3786,7 @@
#ifdef CONFIG_WPS
sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
- if (hapd->conf->wps_state && elems.wps_ie) {
+ if (hapd->conf->wps_state && elems->wps_ie && ies && ies_len) {
wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)Association "
"Request - assume WPS is used");
if (check_sa_query(hapd, sta, reassoc))
@@ -3846,10 +3840,12 @@
res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
hapd->iface->freq,
wpa_ie, wpa_ie_len,
- elems.rsnxe ? elems.rsnxe - 2 : NULL,
- elems.rsnxe ? elems.rsnxe_len + 2 : 0,
- elems.mdie, elems.mdie_len,
- elems.owe_dh, elems.owe_dh_len);
+ elems->rsnxe ? elems->rsnxe - 2 :
+ NULL,
+ elems->rsnxe ? elems->rsnxe_len + 2 :
+ 0,
+ elems->mdie, elems->mdie_len,
+ elems->owe_dh, elems->owe_dh_len);
resp = wpa_res_to_status_code(res);
if (resp != WLAN_STATUS_SUCCESS)
return resp;
@@ -3906,7 +3902,7 @@
if (hapd->conf->sae_pwe == SAE_PWE_BOTH &&
sta->auth_alg == WLAN_AUTH_SAE &&
sta->sae && !sta->sae->h2e &&
- ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
+ ieee802_11_rsnx_capab_len(elems->rsnxe, elems->rsnxe_len,
WLAN_RSNX_CAPAB_SAE_H2E)) {
wpa_printf(MSG_INFO, "SAE: " MACSTR
" indicates support for SAE H2E, but did not use it",
@@ -3918,9 +3914,9 @@
#ifdef CONFIG_OWE
if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_OWE &&
- elems.owe_dh) {
- resp = owe_process_assoc_req(hapd, sta, elems.owe_dh,
- elems.owe_dh_len);
+ elems->owe_dh) {
+ resp = owe_process_assoc_req(hapd, sta, elems->owe_dh,
+ elems->owe_dh_len);
if (resp != WLAN_STATUS_SUCCESS)
return resp;
}
@@ -3934,7 +3930,7 @@
(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) &&
hapd->conf->dpp_netaccesskey && sta->wpa_sm &&
wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_DPP &&
- elems.owe_dh) {
+ elems->owe_dh) {
sta->dpp_pfs = dpp_pfs_init(
wpabuf_head(hapd->conf->dpp_netaccesskey),
wpabuf_len(hapd->conf->dpp_netaccesskey));
@@ -3945,8 +3941,8 @@
goto pfs_fail;
}
- if (dpp_pfs_process(sta->dpp_pfs, elems.owe_dh,
- elems.owe_dh_len) < 0) {
+ if (dpp_pfs_process(sta->dpp_pfs, elems->owe_dh,
+ elems->owe_dh_len) < 0) {
dpp_pfs_free(sta->dpp_pfs);
sta->dpp_pfs = NULL;
return WLAN_STATUS_UNSPECIFIED_FAILURE;
@@ -3969,7 +3965,7 @@
}
#ifdef CONFIG_HS20
} else if (hapd->conf->osen) {
- if (elems.osen == NULL) {
+ if (!elems->osen) {
hostapd_logger(
hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_INFO,
@@ -3987,7 +3983,7 @@
return WLAN_STATUS_UNSPECIFIED_FAILURE;
}
if (wpa_validate_osen(hapd->wpa_auth, sta->wpa_sm,
- elems.osen - 2, elems.osen_len + 2) < 0)
+ elems->osen - 2, elems->osen_len + 2) < 0)
return WLAN_STATUS_INVALID_IE;
#endif /* CONFIG_HS20 */
} else
@@ -3999,12 +3995,12 @@
#ifdef CONFIG_HS20
wpabuf_free(sta->hs20_ie);
- if (elems.hs20 && elems.hs20_len > 4) {
+ if (elems->hs20 && elems->hs20_len > 4) {
int release;
- sta->hs20_ie = wpabuf_alloc_copy(elems.hs20 + 4,
- elems.hs20_len - 4);
- release = ((elems.hs20[4] >> 4) & 0x0f) + 1;
+ sta->hs20_ie = wpabuf_alloc_copy(elems->hs20 + 4,
+ elems->hs20_len - 4);
+ release = ((elems->hs20[4] >> 4) & 0x0f) + 1;
if (release >= 2 && !wpa_auth_uses_mfp(sta->wpa_sm) &&
hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
wpa_printf(MSG_DEBUG,
@@ -4017,10 +4013,10 @@
}
wpabuf_free(sta->roaming_consortium);
- if (elems.roaming_cons_sel)
+ if (elems->roaming_cons_sel)
sta->roaming_consortium = wpabuf_alloc_copy(
- elems.roaming_cons_sel + 4,
- elems.roaming_cons_sel_len - 4);
+ elems->roaming_cons_sel + 4,
+ elems->roaming_cons_sel_len - 4);
else
sta->roaming_consortium = NULL;
#endif /* CONFIG_HS20 */
@@ -4028,16 +4024,16 @@
#ifdef CONFIG_FST
wpabuf_free(sta->mb_ies);
if (hapd->iface->fst)
- sta->mb_ies = mb_ies_by_info(&elems.mb_ies);
+ sta->mb_ies = mb_ies_by_info(&elems->mb_ies);
else
sta->mb_ies = NULL;
#endif /* CONFIG_FST */
#ifdef CONFIG_MBO
- mbo_ap_check_sta_assoc(hapd, sta, &elems);
+ mbo_ap_check_sta_assoc(hapd, sta, elems);
if (hapd->conf->mbo_enabled && (hapd->conf->wpa & 2) &&
- elems.mbo && sta->cell_capa && !(sta->flags & WLAN_STA_MFP) &&
+ elems->mbo && sta->cell_capa && !(sta->flags & WLAN_STA_MFP) &&
hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
wpa_printf(MSG_INFO,
"MBO: Reject WPA2 association without PMF");
@@ -4067,7 +4063,7 @@
&tx_seg1_idx) < 0)
return WLAN_STATUS_UNSPECIFIED_FAILURE;
- res = ocv_verify_tx_params(elems.oci, elems.oci_len, &ci,
+ res = ocv_verify_tx_params(elems->oci, elems->oci_len, &ci,
tx_chanwidth, tx_seg1_idx);
if (wpa_auth_uses_ocv(sta->wpa_sm) == 2 &&
res == OCI_NOT_FOUND) {
@@ -4086,18 +4082,18 @@
}
#endif /* CONFIG_FILS && CONFIG_OCV */
- ap_copy_sta_supp_op_classes(sta, elems.supp_op_classes,
- elems.supp_op_classes_len);
+ ap_copy_sta_supp_op_classes(sta, elems->supp_op_classes,
+ elems->supp_op_classes_len);
if ((sta->capability & WLAN_CAPABILITY_RADIO_MEASUREMENT) &&
- elems.rrm_enabled &&
- elems.rrm_enabled_len >= sizeof(sta->rrm_enabled_capa))
- os_memcpy(sta->rrm_enabled_capa, elems.rrm_enabled,
+ elems->rrm_enabled &&
+ elems->rrm_enabled_len >= sizeof(sta->rrm_enabled_capa))
+ os_memcpy(sta->rrm_enabled_capa, elems->rrm_enabled,
sizeof(sta->rrm_enabled_capa));
- if (elems.power_capab) {
- sta->min_tx_power = elems.power_capab[0];
- sta->max_tx_power = elems.power_capab[1];
+ if (elems->power_capab) {
+ sta->min_tx_power = elems->power_capab[0];
+ sta->max_tx_power = elems->power_capab[1];
sta->power_capab = 1;
} else {
sta->power_capab = 0;
@@ -4107,6 +4103,22 @@
}
+static int check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
+ const u8 *ies, size_t ies_len, int reassoc)
+{
+ struct ieee802_11_elems elems;
+
+ if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) {
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
+ HOSTAPD_LEVEL_INFO,
+ "Station sent an invalid association request");
+ return WLAN_STATUS_UNSPECIFIED_FAILURE;
+ }
+
+ return __check_assoc_ies(hapd, sta, ies, ies_len, &elems, reassoc);
+}
+
+
static void send_deauth(struct hostapd_data *hapd, const u8 *addr,
u16 reason_code)
{
@@ -4266,6 +4278,8 @@
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP);
buflen += 3 + sizeof(struct ieee80211_eht_operation);
+ if (hapd->iconf->punct_bitmap)
+ buflen += EHT_OPER_DISABLED_SUBCHAN_BITMAP_SIZE;
}
#endif /* CONFIG_IEEE80211BE */
@@ -5330,10 +5344,10 @@
pos = &mgmt->u.action.u.public_action.action;
end = ((const u8 *) mgmt) + len;
- gas_query_ap_rx(hapd->gas, mgmt->sa,
- mgmt->u.action.category,
- pos, end - pos, freq);
- return 1;
+ if (gas_query_ap_rx(hapd->gas, mgmt->sa,
+ mgmt->u.action.category,
+ pos, end - pos, freq) == 0)
+ return 1;
}
#endif /* CONFIG_DPP */
if (hapd->public_action_cb) {
@@ -7015,4 +7029,73 @@
return eid;
}
+
+static void punct_update_legacy_bw_80(u8 bitmap, u8 pri_chan, u8 *seg0)
+{
+ u8 first_chan = *seg0 - 6, sec_chan;
+
+ switch (bitmap) {
+ case 0x6:
+ *seg0 = 0;
+ return;
+ case 0x8:
+ case 0x4:
+ case 0x2:
+ case 0x1:
+ case 0xC:
+ case 0x3:
+ if (pri_chan < *seg0)
+ *seg0 -= 4;
+ else
+ *seg0 += 4;
+ break;
+ }
+
+ if (pri_chan < *seg0)
+ sec_chan = pri_chan + 4;
+ else
+ sec_chan = pri_chan - 4;
+
+ if (bitmap & BIT((sec_chan - first_chan) / 4))
+ *seg0 = 0;
+}
+
+
+static void punct_update_legacy_bw_160(u8 bitmap, u8 pri,
+ enum oper_chan_width *width, u8 *seg0)
+{
+ if (pri < *seg0) {
+ *seg0 -= 8;
+ if (bitmap & 0x0F) {
+ *width = 0;
+ punct_update_legacy_bw_80(bitmap & 0xF, pri, seg0);
+ }
+ } else {
+ *seg0 += 8;
+ if (bitmap & 0xF0) {
+ *width = 0;
+ punct_update_legacy_bw_80((bitmap & 0xF0) >> 4, pri,
+ seg0);
+ }
+ }
+}
+
+
+void punct_update_legacy_bw(u16 bitmap, u8 pri, enum oper_chan_width *width,
+ u8 *seg0, u8 *seg1)
+{
+ if (*width == CONF_OPER_CHWIDTH_80MHZ && (bitmap & 0xF)) {
+ *width = CONF_OPER_CHWIDTH_USE_HT;
+ punct_update_legacy_bw_80(bitmap & 0xF, pri, seg0);
+ }
+
+ if (*width == CONF_OPER_CHWIDTH_160MHZ && (bitmap & 0xFF)) {
+ *width = CONF_OPER_CHWIDTH_80MHZ;
+ *seg1 = 0;
+ punct_update_legacy_bw_160(bitmap & 0xFF, pri, width, seg0);
+ }
+
+ /* TODO: 320 MHz */
+}
+
#endif /* CONFIG_NATIVE_WINDOWS */