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