diff mbox series

hw_feature: Correctly select mode in case of 6GHz

Message ID 20201022110025.16987-1-andrei.otcheretianski@intel.com
State Accepted
Headers show
Series hw_feature: Correctly select mode in case of 6GHz | expand

Commit Message

Andrei Otcheretianski Oct. 22, 2020, 11 a.m. UTC
From: Ilan Peer <ilan.peer@intel.com>

There are 2 HW modes with IEEE80211_MODE_A: one for the 5GHz channels
and one for 6GHz channels. Since hw_get_chan() checks all the compatible
hw modes, eventually, an incorrect hw mode is selected.

To fix this, add a function that checks if a specific mode supports
the requested frequency and if so use it as the current mode.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
---
 src/ap/hw_features.c            |  7 +++---
 src/common/hw_features_common.c | 38 ++++++++++++++++++++++-----------
 src/common/hw_features_common.h |  3 +++
 3 files changed, 32 insertions(+), 16 deletions(-)

Comments

Jouni Malinen Feb. 7, 2021, 11:14 p.m. UTC | #1
On Thu, Oct 22, 2020 at 02:00:25PM +0300, Andrei Otcheretianski wrote:
> There are 2 HW modes with IEEE80211_MODE_A: one for the 5GHz channels
> and one for 6GHz channels. Since hw_get_chan() checks all the compatible
> hw modes, eventually, an incorrect hw mode is selected.
> 
> To fix this, add a function that checks if a specific mode supports
> the requested frequency and if so use it as the current mode.

Thanks, applied.
diff mbox series

Patch

diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index f6e69030d7..ebcc60520b 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -1029,12 +1029,13 @@  int hostapd_select_hw_mode(struct hostapd_iface *iface)
 	iface->current_mode = NULL;
 	for (i = 0; i < iface->num_hw_features; i++) {
 		struct hostapd_hw_modes *mode = &iface->hw_features[i];
+		int chan;
+
 		if (mode->mode == iface->conf->hw_mode) {
 			if (iface->freq > 0 &&
-			    !hw_get_chan(mode->mode, iface->freq,
-					 iface->hw_features,
-					 iface->num_hw_features))
+			    !hw_mode_get_channel(mode, iface->freq, &chan))
 				continue;
+
 			iface->current_mode = mode;
 			break;
 		}
diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c
index 511e68f9ec..54da8eb301 100644
--- a/src/common/hw_features_common.c
+++ b/src/common/hw_features_common.c
@@ -39,12 +39,30 @@  struct hostapd_channel_data * hw_get_channel_chan(struct hostapd_hw_modes *mode,
 	return NULL;
 }
 
+struct hostapd_channel_data *
+hw_mode_get_channel(struct hostapd_hw_modes *mode, int freq, int *chan)
+{
+	int i;
+
+	for (i = 0; i < mode->num_channels; i++) {
+		struct hostapd_channel_data *ch = &mode->channels[i];
+
+		if (ch->freq == freq) {
+			if (chan)
+				*chan = ch->chan;
+			return ch;
+		}
+	}
+
+	return NULL;
+}
 
 struct hostapd_channel_data *
 hw_get_channel_freq(enum hostapd_hw_mode mode, int freq, int *chan,
 		    struct hostapd_hw_modes *hw_features, int num_hw_features)
 {
-	int i, j;
+	struct hostapd_channel_data *chan_data;
+	int i;
 
 	if (chan)
 		*chan = 0;
@@ -52,21 +70,15 @@  hw_get_channel_freq(enum hostapd_hw_mode mode, int freq, int *chan,
 	if (!hw_features)
 		return NULL;
 
-	for (j = 0; j < num_hw_features; j++) {
-		struct hostapd_hw_modes *curr_mode = &hw_features[j];
+	for (i = 0; i < num_hw_features; i++) {
+		struct hostapd_hw_modes *curr_mode = &hw_features[i];
 
 		if (curr_mode->mode != mode)
 			continue;
-		for (i = 0; i < curr_mode->num_channels; i++) {
-			struct hostapd_channel_data *ch =
-				&curr_mode->channels[i];
-
-			if (ch->freq == freq) {
-				if (chan)
-					*chan = ch->chan;
-				return ch;
-			}
-		}
+
+		chan_data = hw_mode_get_channel(curr_mode, freq, chan);
+		if (chan_data)
+			return chan_data;
 	}
 
 	return NULL;
diff --git a/src/common/hw_features_common.h b/src/common/hw_features_common.h
index e57a8d65cc..ddde36b992 100644
--- a/src/common/hw_features_common.h
+++ b/src/common/hw_features_common.h
@@ -14,6 +14,9 @@ 
 
 struct hostapd_channel_data * hw_get_channel_chan(struct hostapd_hw_modes *mode,
 						  int chan, int *freq);
+struct hostapd_channel_data *
+hw_mode_get_channel(struct hostapd_hw_modes *mode, int freq, int *chan);
+
 struct hostapd_channel_data *
 hw_get_channel_freq(enum hostapd_hw_mode mode, int freq, int *chan,
 		    struct hostapd_hw_modes *hw_features, int num_hw_features);