From 02645e533ed703233f8084232ee333d7148cb8e8 Mon Sep 17 00:00:00 2001 From: Nagarajan Maran Date: Thu, 21 Apr 2022 15:00:52 +0530 Subject: [PATCH] hostapd: UL-MUMIMO param support Adding new params for he and eht to enable/disable ul mumimo. Set 0 to disable or 1 to enable. If param isn't specified, the driver/underlying hardware decides its default behaviour. Following param fields are supported in hostapd conf file, HE: "he_ul_mumimo" EHT: "eht_ulmumimo_80mhz", "eht_ulmumimo_160mhz", "eht_ulmumimo_320mhz" Signed-off-by: Pradeep Kumar Chitrapu Signed-off-by: Nagarajan Maran Signed-off-by: Sidhanta Sahu --- hostapd/config_file.c | 10 ++++++++++ hostapd/hostapd.conf | 5 +++++ src/ap/ap_config.c | 2 ++ src/ap/ap_config.h | 5 +++++ src/ap/hw_features.c | 28 ++++++++++++++++++++++++++++ src/ap/ieee802_11_eht.c | 14 +++++++++++++- src/ap/ieee802_11_he.c | 7 +++++++ src/common/ieee802_11_defs.h | 8 +++++++- 8 files changed, 77 insertions(+), 2 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 9ac681d..4f2e01c 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -3422,6 +3422,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, conf->he_phy_capab.he_su_beamformee = atoi(pos); } else if (os_strcmp(buf, "he_mu_beamformer") == 0) { conf->he_phy_capab.he_mu_beamformer = atoi(pos); + } else if (os_strcmp(buf, "he_ul_mumimo") == 0) { + conf->he_phy_capab.he_ul_mumimo = atoi(pos); } else if (os_strcmp(buf, "he_bss_color") == 0) { conf->he_op.he_bss_color = atoi(pos); if (conf->he_op.he_bss_color > 63) @@ -4689,6 +4691,14 @@ static int hostapd_config_fill(struct hostapd_config *conf, conf->eht_phy_capab.su_beamformee = atoi(pos); } else if (os_strcmp(buf, "eht_mu_beamformer") == 0) { conf->eht_phy_capab.mu_beamformer = atoi(pos); + } else if (os_strcmp(buf, "eht_part_dl_mu_mimo") == 0) { + conf->eht_phy_capab.partial_bw_dl_mu_mimo = atoi(pos); + } else if (os_strcmp(buf, "eht_ulmumimo_80mhz") == 0) { + conf->eht_phy_capab.non_ofdma_ulmumimo_80mhz = atoi(pos); + } else if (os_strcmp(buf, "eht_ulmumimo_160mhz") == 0) { + conf->eht_phy_capab.non_ofdma_ulmumimo_160mhz = atoi(pos); + } else if (os_strcmp(buf, "eht_ulmumimo_320mhz") == 0) { + conf->eht_phy_capab.non_ofdma_ulmumimo_320mhz = atoi(pos); } else if (os_strcmp(buf, "ru_punct_bitmap") == 0) { conf->ru_punct_bitmap = atoi(pos); } else if (os_strcmp(buf, "ru_punct_ofdma") == 0) { diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 5fda6c6..2502767 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -832,6 +832,11 @@ wmm_ac_vo_acm=0 # 1 = supported #he_mu_beamformer=1 +#he_ul_mumimo: HE Uplink multiple user MIMO support +# -1 or unspecified = Decided by firmware or underlying hardware(Default) +# 0 = not supported +# 1 = supported + # he_bss_color: # 0 = disable # 1-63 = pre-defined color diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index f036eb6..a237e72 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -273,6 +273,8 @@ struct hostapd_config * hostapd_config_defaults(void) HE_OPERATION_RTS_THRESHOLD_OFFSET; /* Set default basic MCS/NSS set to single stream MCS 0-7 */ conf->he_op.he_basic_mcs_nss_set = 0xfffc; + /* Set default to be decided by Driver/underlying HW */ + conf->he_phy_capab.he_ul_mumimo = -1; conf->he_op.he_bss_color_disabled = 1; conf->he_op.he_bss_color_partial = 0; conf->he_op.he_bss_color = os_random() % 63 + 1; diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index f082f14..04cd6fb 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -922,6 +922,7 @@ struct he_phy_capabilities_info { bool he_su_beamformer; bool he_su_beamformee; bool he_mu_beamformer; + int he_ul_mumimo; }; /** @@ -958,6 +959,10 @@ struct eht_phy_capabilities_info { bool su_beamformer; bool su_beamformee; bool mu_beamformer; + bool partial_bw_dl_mu_mimo; + bool non_ofdma_ulmumimo_80mhz; + bool non_ofdma_ulmumimo_160mhz; + bool non_ofdma_ulmumimo_320mhz; }; /** diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c index d24672c..1dcd0d0 100644 --- a/src/ap/hw_features.c +++ b/src/ap/hw_features.c @@ -677,8 +677,36 @@ static int ieee80211ac_supported_vht_capab(struct hostapd_iface *iface) #ifdef CONFIG_IEEE80211AX + +static int _ieee80211he_cap_check(u8 *hw, u32 offset, u8 bits) +{ + if (bits & hw[offset]) + return 1; + + return 0; +} + static int ieee80211ax_supported_he_capab(struct hostapd_iface *iface) { + + struct hostapd_hw_modes *mode = iface->current_mode; + struct he_capabilities *hw = &mode->he_capab[IEEE80211_MODE_AP]; + struct hostapd_config *conf = iface->conf; + +#define HE_CAP_CHECK(hw_cap, cap, bytes, conf) \ + do { \ + if (conf && !_ieee80211he_cap_check(hw_cap, bytes, cap)) { \ + wpa_printf(MSG_ERROR, "Driver does not support configured" \ + " HE capability [%s]", #cap); \ + return 0; \ + } \ + } while (0) + + if (conf->he_phy_capab.he_ul_mumimo != -1) + HE_CAP_CHECK(hw->phy_cap, HE_PHYCAP_UL_MUMIMO_CAPB, + HE_PHYCAP_UL_MUMIMO_CAPB_IDX, + conf->he_phy_capab.he_ul_mumimo); + return 1; } #endif /* CONFIG_IEEE80211AX */ diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c index 1fcd5de..8973cfd 100644 --- a/src/ap/ieee802_11_eht.c +++ b/src/ap/ieee802_11_eht.c @@ -141,9 +141,21 @@ u8 * hostapd_eid_eht_capab(struct hostapd_data *hapd, u8 *eid, ~EHT_PHYCAP_SU_BEAMFORMEE; if (!hapd->iface->conf->eht_phy_capab.mu_beamformer) - cap->phy_cap[EHT_PHYCAP_MU_BEAMFORMER_IDX] &= + cap->phy_cap[EHT_PHYCAP_MU_CAPABILITY_IDX] &= ~EHT_PHYCAP_MU_BEAMFORMER_MASK; + if (!hapd->iface->conf->eht_phy_capab.non_ofdma_ulmumimo_80mhz) + cap->phy_cap[EHT_PHYCAP_MU_CAPABILITY_IDX] &= + ~EHT_PHYCAP_NON_OFDMA_UL_MU_MIMO_80MHZ; + + if (!hapd->iface->conf->eht_phy_capab.non_ofdma_ulmumimo_160mhz) + cap->phy_cap[EHT_PHYCAP_MU_CAPABILITY_IDX] &= + ~EHT_PHYCAP_NON_OFDMA_UL_MU_MIMO_160MHZ; + + if (!hapd->iface->conf->eht_phy_capab.non_ofdma_ulmumimo_320mhz) + cap->phy_cap[EHT_PHYCAP_MU_CAPABILITY_IDX] &= + ~EHT_PHYCAP_NON_OFDMA_UL_MU_MIMO_320MHZ; + pos = cap->optional; mcs_nss_len = ieee80211_eht_mcs_set_size(mode->he_capab[opmode].phy_cap, diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c index 03b8711..6751526 100644 --- a/src/ap/ieee802_11_he.c +++ b/src/ap/ieee802_11_he.c @@ -153,6 +153,13 @@ u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid, cap->he_phy_capab_info[HE_PHYCAP_MU_BEAMFORMER_CAPAB_IDX] &= ~HE_PHYCAP_MU_BEAMFORMER_CAPAB; + if (hapd->iface->conf->he_phy_capab.he_ul_mumimo == 1) + cap->he_phy_capab_info[HE_PHYCAP_UL_MUMIMO_CAPB_IDX] |= + HE_PHYCAP_UL_MUMIMO_CAPB; + else if (hapd->iface->conf->he_phy_capab.he_ul_mumimo == 0) + cap->he_phy_capab_info[HE_PHYCAP_UL_MUMIMO_CAPB_IDX] &= + ~HE_PHYCAP_UL_MUMIMO_CAPB; + cap->he_phy_capab_info[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &= he_oper_chwidth; diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index cfe25c8..e4b891c 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -2346,6 +2346,9 @@ struct ieee80211_spatial_reuse { #define HE_PHYCAP_MU_BEAMFORMER_CAPAB_IDX 4 #define HE_PHYCAP_MU_BEAMFORMER_CAPAB ((u8) BIT(1)) +#define HE_PHYCAP_UL_MUMIMO_CAPB_IDX 2 +#define HE_PHYCAP_UL_MUMIMO_CAPB ((u8) BIT(6)) + #define HE_PHYCAP_PPE_THRESHOLD_PRESENT_IDX 6 #define HE_PHYCAP_PPE_THRESHOLD_PRESENT ((u8) BIT(7)) @@ -2500,7 +2503,10 @@ struct ieee80211_eht_operation { #define EHT_PHYCAP_PPE_THRESHOLD_PRESENT_IDX 5 -#define EHT_PHYCAP_MU_BEAMFORMER_IDX 7 +#define EHT_PHYCAP_MU_CAPABILITY_IDX 7 +#define EHT_PHYCAP_NON_OFDMA_UL_MU_MIMO_80MHZ ((u8) BIT(1)) +#define EHT_PHYCAP_NON_OFDMA_UL_MU_MIMO_160MHZ ((u8) BIT(2)) +#define EHT_PHYCAP_NON_OFDMA_UL_MU_MIMO_320MHZ ((u8) BIT(3)) #define EHT_PHYCAP_MU_BEAMFORMER_80MHZ ((u8) BIT(4)) #define EHT_PHYCAP_MU_BEAMFORMER_160MHZ ((u8) BIT(5)) #define EHT_PHYCAP_MU_BEAMFORMER_320MHZ ((u8) BIT(6)) -- 2.17.1