From 5d3c4496fb884a25e50fc028c4f95b5be407f119 Mon Sep 17 00:00:00 2001 From: Shay Bar Date: Wed, 10 Feb 2021 13:07:17 +0200 Subject: [PATCH] Make VHT Transmit Power Envelope element helper more generic According to latest IEEE 802.11 standard, Transmit Power Envelope element is also relevant to IEEE 802.11ax and is no longer called VHT Transmit Power Envelope. Remove the VHT naming from the element and move hostapd_eid_txpower_envelope() from ieee802_11_vht.c to ieee802_11.c in preparation of using it with HE. Signed-off-by: Shay Bar --- src/ap/ieee802_11.c | 112 +++++++++++++++++++++++++++++++++++ src/ap/ieee802_11_vht.c | 112 ----------------------------------- src/common/ieee802_11_defs.h | 2 +- 3 files changed, 113 insertions(+), 113 deletions(-) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 76a7ffa9e..13fa450df 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -6766,6 +6766,118 @@ void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src, } +u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid) +{ + struct hostapd_iface *iface = hapd->iface; + struct hostapd_config *iconf = iface->conf; + struct hostapd_hw_modes *mode = iface->current_mode; + struct hostapd_channel_data *chan; + int dfs, i; + u8 channel, tx_pwr_count, local_pwr_constraint; + int max_tx_power; + u8 tx_pwr; + + if (!mode) + return eid; + + if (ieee80211_freq_to_chan(iface->freq, &channel) == NUM_HOSTAPD_MODES) + return eid; + + for (i = 0; i < mode->num_channels; i++) { + if (mode->channels[i].freq == iface->freq) + break; + } + if (i == mode->num_channels) + return eid; + + switch (iface->conf->vht_oper_chwidth) { + case CHANWIDTH_USE_HT: + if (iconf->secondary_channel == 0) { + /* Max Transmit Power count = 0 (20 MHz) */ + tx_pwr_count = 0; + } else { + /* Max Transmit Power count = 1 (20, 40 MHz) */ + tx_pwr_count = 1; + } + break; + case CHANWIDTH_80MHZ: + /* Max Transmit Power count = 2 (20, 40, and 80 MHz) */ + tx_pwr_count = 2; + break; + case CHANWIDTH_80P80MHZ: + case CHANWIDTH_160MHZ: + /* Max Transmit Power count = 3 (20, 40, 80, 160/80+80 MHz) */ + tx_pwr_count = 3; + break; + default: + return eid; + } + + /* + * Below local_pwr_constraint logic is referred from + * hostapd_eid_pwr_constraint. + * + * Check if DFS is required by regulatory. + */ + dfs = hostapd_is_dfs_required(hapd->iface); + if (dfs < 0) + dfs = 0; + + /* + * In order to meet regulations when TPC is not implemented using + * a transmit power that is below the legal maximum (including any + * mitigation factor) should help. In this case, indicate 3 dB below + * maximum allowed transmit power. + */ + if (hapd->iconf->local_pwr_constraint == -1) + local_pwr_constraint = (dfs == 0) ? 0 : 3; + else + local_pwr_constraint = hapd->iconf->local_pwr_constraint; + + /* + * A STA that is not an AP shall use a transmit power less than or + * equal to the local maximum transmit power level for the channel. + * The local maximum transmit power can be calculated from the formula: + * local max TX pwr = max TX pwr - local pwr constraint + * Where max TX pwr is maximum transmit power level specified for + * channel in Country element and local pwr constraint is specified + * for channel in this Power Constraint element. + */ + chan = &mode->channels[i]; + max_tx_power = chan->max_tx_power - local_pwr_constraint; + + /* + * Local Maximum Transmit power is encoded as two's complement + * with a 0.5 dB step. + */ + max_tx_power *= 2; /* in 0.5 dB steps */ + if (max_tx_power > 127) { + /* 63.5 has special meaning of 63.5 dBm or higher */ + max_tx_power = 127; + } + if (max_tx_power < -128) + max_tx_power = -128; + if (max_tx_power < 0) + tx_pwr = 0x80 + max_tx_power + 128; + else + tx_pwr = max_tx_power; + + *eid++ = WLAN_EID_TRANSMIT_POWER_ENVELOPE; + *eid++ = 2 + tx_pwr_count; + + /* + * Max Transmit Power count and + * Max Transmit Power units = 0 (EIRP) + */ + *eid++ = tx_pwr_count; + + for (i = 0; i <= tx_pwr_count; i++) + *eid++ = tx_pwr; + + return eid; +} + + u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid) { u8 bw, chan1, chan2 = 0; diff --git a/src/ap/ieee802_11_vht.c b/src/ap/ieee802_11_vht.c index c925bf12c..d0370229c 100644 --- a/src/ap/ieee802_11_vht.c +++ b/src/ap/ieee802_11_vht.c @@ -167,118 +167,6 @@ static int check_valid_vht_mcs(struct hostapd_hw_modes *mode, } -u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid) -{ - struct hostapd_iface *iface = hapd->iface; - struct hostapd_config *iconf = iface->conf; - struct hostapd_hw_modes *mode = iface->current_mode; - struct hostapd_channel_data *chan; - int dfs, i; - u8 channel, tx_pwr_count, local_pwr_constraint; - int max_tx_power; - u8 tx_pwr; - - if (!mode) - return eid; - - if (ieee80211_freq_to_chan(iface->freq, &channel) == NUM_HOSTAPD_MODES) - return eid; - - for (i = 0; i < mode->num_channels; i++) { - if (mode->channels[i].freq == iface->freq) - break; - } - if (i == mode->num_channels) - return eid; - - switch (iface->conf->vht_oper_chwidth) { - case CHANWIDTH_USE_HT: - if (iconf->secondary_channel == 0) { - /* Max Transmit Power count = 0 (20 MHz) */ - tx_pwr_count = 0; - } else { - /* Max Transmit Power count = 1 (20, 40 MHz) */ - tx_pwr_count = 1; - } - break; - case CHANWIDTH_80MHZ: - /* Max Transmit Power count = 2 (20, 40, and 80 MHz) */ - tx_pwr_count = 2; - break; - case CHANWIDTH_80P80MHZ: - case CHANWIDTH_160MHZ: - /* Max Transmit Power count = 3 (20, 40, 80, 160/80+80 MHz) */ - tx_pwr_count = 3; - break; - default: - return eid; - } - - /* - * Below local_pwr_constraint logic is referred from - * hostapd_eid_pwr_constraint. - * - * Check if DFS is required by regulatory. - */ - dfs = hostapd_is_dfs_required(hapd->iface); - if (dfs < 0) - dfs = 0; - - /* - * In order to meet regulations when TPC is not implemented using - * a transmit power that is below the legal maximum (including any - * mitigation factor) should help. In this case, indicate 3 dB below - * maximum allowed transmit power. - */ - if (hapd->iconf->local_pwr_constraint == -1) - local_pwr_constraint = (dfs == 0) ? 0 : 3; - else - local_pwr_constraint = hapd->iconf->local_pwr_constraint; - - /* - * A STA that is not an AP shall use a transmit power less than or - * equal to the local maximum transmit power level for the channel. - * The local maximum transmit power can be calculated from the formula: - * local max TX pwr = max TX pwr - local pwr constraint - * Where max TX pwr is maximum transmit power level specified for - * channel in Country element and local pwr constraint is specified - * for channel in this Power Constraint element. - */ - chan = &mode->channels[i]; - max_tx_power = chan->max_tx_power - local_pwr_constraint; - - /* - * Local Maximum Transmit power is encoded as two's complement - * with a 0.5 dB step. - */ - max_tx_power *= 2; /* in 0.5 dB steps */ - if (max_tx_power > 127) { - /* 63.5 has special meaning of 63.5 dBm or higher */ - max_tx_power = 127; - } - if (max_tx_power < -128) - max_tx_power = -128; - if (max_tx_power < 0) - tx_pwr = 0x80 + max_tx_power + 128; - else - tx_pwr = max_tx_power; - - *eid++ = WLAN_EID_VHT_TRANSMIT_POWER_ENVELOPE; - *eid++ = 2 + tx_pwr_count; - - /* - * Max Transmit Power count and - * Max Transmit Power units = 0 (EIRP) - */ - *eid++ = tx_pwr_count; - - for (i = 0; i <= tx_pwr_count; i++) - *eid++ = tx_pwr; - - return eid; -} - - u16 copy_sta_vht_capab(struct hostapd_data *hapd, struct sta_info *sta, const u8 *vht_capab) { diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 4fdc3b2d9..87d01d58a 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -434,7 +434,7 @@ #define WLAN_EID_VHT_OPERATION 192 #define WLAN_EID_VHT_EXTENDED_BSS_LOAD 193 #define WLAN_EID_VHT_WIDE_BW_CHSWITCH 194 -#define WLAN_EID_VHT_TRANSMIT_POWER_ENVELOPE 195 +#define WLAN_EID_TRANSMIT_POWER_ENVELOPE 195 #define WLAN_EID_VHT_CHANNEL_SWITCH_WRAPPER 196 #define WLAN_EID_VHT_AID 197 #define WLAN_EID_VHT_QUIET_CHANNEL 198