From: Ilan Peer <ilan.peer@xxxxxxxxx> 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@xxxxxxxxx> Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@xxxxxxxxx> --- 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(-) 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); -- 2.28.0 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap