[PATCH] hostap: Transmit Power Envelope also for 11ax

Shay Bar shay.bar at celeno.com
Tue Dec 8 10:20:19 EST 2020


According to latest IEEE802.11 spec, Transmit Power Envelope element should
also be added to 11ax and is no longer called VHT Transmit Power Envelope.

Remove the VHT naming from the element.
move hostapd_eid_txpower_envelope() from ieee802_11_vht.c to ieee802_11.c.
use hostapd_get_oper_chwidth(iconf) instead of iface->conf->vht_oper_chwidth.

Signed-off-by: Shay Bar <shay.bar at celeno.com>
---
 src/ap/beacon.c              |  10 ++--
 src/ap/ieee802_11.c          | 112 +++++++++++++++++++++++++++++++++++
 src/ap/ieee802_11_vht.c      | 112 -----------------------------------
 src/common/ieee802_11_defs.h |   2 +-
 4 files changed, 119 insertions(+), 117 deletions(-)

diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 47b260e81..c6597c6cd 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -559,13 +559,14 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 	    !is_6ghz_op_class(hapd->iconf->op_class)) {
 		pos = hostapd_eid_vht_capabilities(hapd, pos, 0);
 		pos = hostapd_eid_vht_operation(hapd, pos);
-		pos = hostapd_eid_txpower_envelope(hapd, pos);
 	}
 #endif /* CONFIG_IEEE80211AC */
 
 	if ((hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) ||
-	    (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax))
+	    (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax)) {
 		pos = hostapd_eid_wb_chsw_wrapper(hapd, pos);
+		pos = hostapd_eid_txpower_envelope(hapd, pos);
+	}
 
 	pos = hostapd_eid_fils_indic(hapd, pos, 0);
 	pos = hostapd_get_rsnxe(hapd, pos, epos - pos);
@@ -1287,13 +1288,14 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 	if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
 		tailpos = hostapd_eid_vht_capabilities(hapd, tailpos, 0);
 		tailpos = hostapd_eid_vht_operation(hapd, tailpos);
-		tailpos = hostapd_eid_txpower_envelope(hapd, tailpos);
 	}
 #endif /* CONFIG_IEEE80211AC */
 
 	if ((hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) ||
-	    (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax))
+	    (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax)) {
 		tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos);
+		tailpos = hostapd_eid_txpower_envelope(hapd, tailpos);
+	}
 
 	tailpos = hostapd_eid_fils_indic(hapd, tailpos, 0);
 	tailpos = hostapd_get_rsnxe(hapd, tailpos, tailend - tailpos);
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 114d1f574..024020ca0 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -5641,4 +5641,116 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
 	return eid;
 }
 
+
+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 (hostapd_get_oper_chwidth(iconf)) {
+	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;
+}
+
 #endif /* CONFIG_NATIVE_WINDOWS */
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 9518a7afe..96154a40a 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -432,7 +432,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
-- 
2.17.1




More information about the Hostap mailing list