From patchwork Mon Nov 8 03:04:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryder Lee X-Patchwork-Id: 1552115 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=TdjSI8dB; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Hnbbl2GBWz9sR4 for ; Mon, 8 Nov 2021 14:06:11 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:CC :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=jJbGlY/UjiOWDJu0LYiULCtBponRgB2rvIsYJaolOJc=; b=TdjSI8dBSKP247 l5QD34cAO9uWzUWoVC+tdBlaW1aby3k85d/nEEMtTcHWs4iVB1XkTTDnizxiADCA8QmZs4avo49De FuPTgYekOV5QrTcMCYXQbUs4MP+J0t9IRB8nzfg9ZPmjK8os5S8X6Ofa+5FZqr/NAqltHVaVTXDUs HOrKINWu1ER8b2CnrBV1aEMyR8CZB3jXELW/zvAB3eyzeMUQ3F3i5cXlOVKjoyHarqJ7KyolLh/zk FdnmnVeKttaTQGaJbW45XnCwowirMKa+rwvGf7aC0Vogxms+teN/9QNnUkE6q2VdgHGgbiciEzkSF Ez5Fi4ll8M2oap6VJaRg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mjuxn-00FLFN-D3; Mon, 08 Nov 2021 03:04:51 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mjuxc-00FLDp-GA for hostap@lists.infradead.org; Mon, 08 Nov 2021 03:04:42 +0000 X-UUID: 2f3a392f63dc4f7596cff8bcd834ff56-20211107 X-UUID: 2f3a392f63dc4f7596cff8bcd834ff56-20211107 Received: from mtkcas68.mediatek.inc [(172.29.94.19)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 238529206; Sun, 07 Nov 2021 20:04:34 -0700 Received: from MTKMBS07N2.mediatek.inc (172.21.101.141) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Sun, 7 Nov 2021 19:04:32 -0800 Received: from mtkmbs10n1.mediatek.inc (172.21.101.34) by mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 8 Nov 2021 11:04:31 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkmbs10n1.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.792.15 via Frontend Transport; Mon, 8 Nov 2021 11:04:31 +0800 From: Ryder Lee To: Jouni Malinen CC: Felix Fietkau , Lorenzo Bianconi , Shayne Chen , "Evelyn Tsai" , , John Crispin , Lorenzo Bianconi , Ryder Lee Subject: [PATCH v2 1/5] bss coloring: add support for handling collision events and triggering CCA Date: Mon, 8 Nov 2021 11:04:22 +0800 Message-ID: <2d69afce2fd6f44ae08ac75d5715fa9e43fe2a77.1636093546.git.ryder.lee@mediatek.com> X-Mailer: git-send-email 2.18.0 MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211107_190440_578484_445A5D3D X-CRM114-Status: GOOD ( 27.51 ) X-Spam-Score: 0.0 (/) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: John Crispin Add the core code for handling bss color collision events and triggering CCA inside the kernel. The caller of hostapd_switch_color() will be added in the following commits. Content analysis details: (0.0 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay lines X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: John Crispin Add the core code for handling bss color collision events and triggering CCA inside the kernel. The caller of hostapd_switch_color() will be added in the following commits. Tested-by: Peter Chiu Co-developed-by: Lorenzo Bianconi Signed-off-by: Lorenzo Bianconi Signed-off-by: John Crispin Signed-off-by: Ryder Lee --- changes since v2 - - use os_get_reltime and os_reltime instead. - use bool cca_in_progress. - use random BSS color to avoid hardcoded BSS color value of 1. - modify comment for DOT11BSS_COLOR_COLLISION_AP_PERIOD. - add a note for collision behavior. - fix compiler warnings. - Be clear in the commit message regarding hostapd_switch_color(). --- src/ap/ap_drv_ops.h | 12 ++++ src/ap/hostapd.c | 134 ++++++++++++++++++++++++++++++++++- src/ap/hostapd.h | 16 +++++ src/common/ieee802_11_defs.h | 6 ++ src/drivers/driver.h | 31 ++++++++ 5 files changed, 198 insertions(+), 1 deletion(-) diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h index 61c8f64eb..003f0daf7 100644 --- a/src/ap/ap_drv_ops.h +++ b/src/ap/ap_drv_ops.h @@ -299,6 +299,18 @@ static inline int hostapd_drv_switch_channel(struct hostapd_data *hapd, return hapd->driver->switch_channel(hapd->drv_priv, settings); } +#ifdef CONFIG_IEEE80211AX +static inline int hostapd_drv_switch_color(struct hostapd_data *hapd, + struct cca_settings *settings) +{ + if (hapd->driver == NULL || hapd->driver->switch_color == NULL || + hapd->drv_priv == NULL) + return -1; + + return hapd->driver->switch_color(hapd->drv_priv, settings); +} +#endif + static inline int hostapd_drv_status(struct hostapd_data *hapd, char *buf, size_t buflen) { diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 913a8e29e..4ec3ee62d 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -66,7 +66,10 @@ static int setup_interface2(struct hostapd_iface *iface); static void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx); static void hostapd_interface_setup_failure_handler(void *eloop_ctx, void *timeout_ctx); - +#ifdef CONFIG_IEEE80211AX +static void +hostapd_switch_color_timeout_handler(void *eloop_data, void *user_ctx); +#endif int hostapd_for_each_interface(struct hapd_interfaces *interfaces, int (*cb)(struct hostapd_iface *iface, @@ -462,6 +465,9 @@ void hostapd_free_hapd_data(struct hostapd_data *hapd) } eloop_cancel_timeout(auth_sae_process_commit, hapd, NULL); #endif /* CONFIG_SAE */ +#ifdef CONFIG_IEEE80211AX + eloop_cancel_timeout(hostapd_switch_color_timeout_handler, hapd, NULL); +#endif } @@ -3691,6 +3697,132 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface, hostapd_enable_iface(iface); } + +#ifdef CONFIG_IEEE80211AX +void hostapd_cleanup_cca_params(struct hostapd_data *hapd) +{ + hapd->cca_count = 0; + hapd->cca_color = 0; + hapd->cca_c_off_beacon = 0; + hapd->cca_c_off_proberesp = 0; + hapd->cca_in_progress = false; +} + + +static int hostapd_fill_cca_settings(struct hostapd_data *hapd, + struct cca_settings *settings) +{ + struct hostapd_iface *iface = hapd->iface; + u8 old_color; + int ret; + + if (!iface || iface->conf->he_op.he_bss_color_disabled) + return -1; + + old_color = iface->conf->he_op.he_bss_color; + iface->conf->he_op.he_bss_color = hapd->cca_color; + ret = hostapd_build_beacon_data(hapd, &settings->beacon_after); + iface->conf->he_op.he_bss_color = old_color; + + settings->cca_count = hapd->cca_count; + settings->cca_color = hapd->cca_color, + hapd->cca_in_progress = true; + + ret = hostapd_build_beacon_data(hapd, &settings->beacon_cca); + if (ret) { + free_beacon_data(&settings->beacon_after); + return ret; + } + + settings->counter_offset_beacon = hapd->cca_c_off_beacon; + settings->counter_offset_presp = hapd->cca_c_off_proberesp; + + return 0; +} + + +static void +hostapd_switch_color_timeout_handler(void *eloop_data, void *user_ctx) +{ + struct hostapd_data *hapd = (struct hostapd_data *) eloop_data; + struct cca_settings settings; + struct os_reltime now; + unsigned int b; + int i, r, ret; + + if (os_get_reltime(&now)) + return; + + /* 10s window is the approximate margin of collision persistent + * as an initial implementation. CCA can only be triggered once + * handler constantly receives collision events to update the + * last_color_collision.sec. How does it work - + * + * 1. BSS color collision persistent for at least 50 seconds. + * 2. The BSS Color Disabled subfield is set to 1. + * 3. CCA. + * + * TODO: implement other 'persistent' computation methods. + */ + if (now.sec - hapd->last_color_collision.sec >= 10) + return; + + r = os_random() % HE_OPERATION_BSS_COLOR_MAX; + for (i = 0; i < HE_OPERATION_BSS_COLOR_MAX; i++) { + if (r && (hapd->color_collision_bitmap & (1 << r)) == 0) + break; + r = (r + 1) % HE_OPERATION_BSS_COLOR_MAX; + } + + if (i == HE_OPERATION_BSS_COLOR_MAX) { + /* there are no free colors so turn bss coloring off */ + wpa_printf(MSG_INFO, "no free colors left, turning of BSS coloring"); + hapd->iface->conf->he_op.he_bss_color_disabled = 1; + hapd->iface->conf->he_op.he_bss_color = os_random() % 63 + 1; + for (b = 0; b < hapd->iface->num_bss; b++) + ieee802_11_set_beacon(hapd->iface->bss[b]); + return; + } + + for (b = 0; b < hapd->iface->num_bss; b++) { + struct hostapd_data *bss = hapd->iface->bss[b]; + + hostapd_cleanup_cca_params(bss); + bss->cca_color = r; + bss->cca_count = 10; + + if (hostapd_fill_cca_settings(bss, &settings)) { + hostapd_cleanup_cca_params(bss); + continue; + } + + ret = hostapd_drv_switch_color(bss, &settings); + free_beacon_data(&settings.beacon_cca); + free_beacon_data(&settings.beacon_after); + + if (ret) + hostapd_cleanup_cca_params(bss); + } +} + + +void +hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap) +{ + if (hapd->cca_in_progress) + return; + + if (os_get_reltime(&hapd->last_color_collision)) + return; + + hapd->color_collision_bitmap = bitmap; + + if (!eloop_is_timeout_registered(hostapd_switch_color_timeout_handler, hapd, NULL)) + eloop_register_timeout(DOT11BSS_COLOR_COLLISION_AP_PERIOD, 0, + hostapd_switch_color_timeout_handler, hapd, NULL); +} +#endif + #endif /* NEED_AP_MLME */ diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 07d0aaa92..70ae05291 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -292,6 +292,16 @@ struct hostapd_data { unsigned int cs_c_off_ecsa_beacon; unsigned int cs_c_off_ecsa_proberesp; +#ifdef CONFIG_IEEE80211AX + bool cca_in_progress; + u8 cca_count; + u8 cca_color; + unsigned int cca_c_off_beacon; + unsigned int cca_c_off_proberesp; + struct os_reltime last_color_collision; + u64 color_collision_bitmap; +#endif + #ifdef CONFIG_P2P struct p2p_data *p2p; struct p2p_group *p2p_group; @@ -645,6 +655,12 @@ void hostapd_periodic_iface(struct hostapd_iface *iface); int hostapd_owe_trans_get_info(struct hostapd_data *hapd); void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx); + +#ifdef CONFIG_IEEE80211AX +void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap); +void hostapd_cleanup_cca_params(struct hostapd_data *hapd); +#endif + /* utils.c */ int hostapd_register_probereq_cb(struct hostapd_data *hapd, int (*cb)(void *ctx, const u8 *sa, diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 24dbfa8bd..adb89d111 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -2305,6 +2305,7 @@ struct ieee80211_spatial_reuse { #define HE_OPERATION_BSS_COLOR_PARTIAL ((u32) BIT(30)) #define HE_OPERATION_BSS_COLOR_DISABLED ((u32) BIT(31)) #define HE_OPERATION_BSS_COLOR_OFFSET 24 +#define HE_OPERATION_BSS_COLOR_MAX 64 /* Spatial Reuse defines */ #define SPATIAL_REUSE_SRP_DISALLOWED BIT(0) @@ -2450,6 +2451,11 @@ enum mscs_description_subelem { */ #define FD_MAX_INTERVAL_6GHZ 20 /* TUs */ +/* IEEE802.11/D6.0 - 26.17.3.5.1, AP needs to wait and see the collision + * persists for at least the minimum default timeout + */ +#define DOT11BSS_COLOR_COLLISION_AP_PERIOD 50 + /* Protected Vendor-specific QoS Management Action frame identifiers - WFA */ #define QM_ACTION_VENDOR_TYPE 0x506f9a1a #define QM_ACTION_OUI_TYPE 0x1a diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 2020184c5..f762ccccc 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -2395,6 +2395,26 @@ struct csa_settings { u16 counter_offset_presp[2]; }; +/** + * struct cca_settings - Settings for color switch command + * @cca_count: Count in Beacon frames (TBTT) to perform the switch + * @cca_color: The new color that we are switching to + * @beacon_cca: Beacon/probe resp/asooc resp info for color switch period + * @beacon_after: Next beacon/probe resp/asooc resp info + * @counter_offset_beacon: Offset to the count field in beacon's tail + * @counter_offset_presp: Offset to the count field in probe resp. + */ +struct cca_settings { + u8 cca_count; + u8 cca_color; + + struct beacon_data beacon_cca; + struct beacon_data beacon_after; + + u16 counter_offset_beacon; + u16 counter_offset_presp; +}; + /* TDLS peer capabilities for send_tdls_mgmt() */ enum tdls_peer_capability { TDLS_PEER_HT = BIT(0), @@ -3977,6 +3997,17 @@ struct wpa_driver_ops { */ int (*switch_channel)(void *priv, struct csa_settings *settings); + /** + * switch_color - Announce color switch and migrate the BSS to the + * given color + * @priv: Private driver interface data + * @settings: Settings for CCA period and new color + * Returns: 0 on success, -1 on failure + * + * This function is used to move the BSS to its new color. + */ + int (*switch_color)(void *priv, struct cca_settings *settings); + /** * add_tx_ts - Add traffic stream * @priv: Private driver interface data