Cumulative patch from commit dc1a341dec54c28c3351ee7edab9ccaf7b68861f
dc1a341 P2P: Add manufacturer info into D-Bus peer interface
3330395 P2P: Add P2P Cancel method over D-Bus interface
87d3c62 WPS: Add WPS Cancel method over D-Bus interface
eda9d84 P2P: Fix a potential memory leak in a P2P+NFC corner case
701d972 Add libwpa_client build option to use a dynamic library
ccad05a P2P: Restart group formation timer upon receiving new Inv Req
4d3be9c Postpone updating of wpa_s->current_bss till association event
3784c05 Extend hw_mode to support any band for offloaded ACS case
1b748e6 HS 2.0: hs20-client: Fix hostname extraction from URL
dba68f2 HS 2.0: Fix hs20_spp_server compile error
e4a43a9 HS 2.0: spp-client: Warn user if xml file cannot be found
Change-Id: If4acdda6f6e6a07bf87216d34b2c89486a4a3078
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index 80e4c2e..6ecd094 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -532,7 +532,7 @@
static void hostapd_acs_channel_selected(struct hostapd_data *hapd,
struct acs_selected_channels *acs_res)
{
- int ret;
+ int ret, i;
if (hapd->iconf->channel) {
wpa_printf(MSG_INFO, "ACS: Channel was already set to %d",
@@ -540,6 +540,24 @@
return;
}
+ if (!hapd->iface->current_mode) {
+ for (i = 0; i < hapd->iface->num_hw_features; i++) {
+ struct hostapd_hw_modes *mode =
+ &hapd->iface->hw_features[i];
+
+ if (mode->mode == acs_res->hw_mode) {
+ hapd->iface->current_mode = mode;
+ break;
+ }
+ }
+ if (!hapd->iface->current_mode) {
+ hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
+ HOSTAPD_LEVEL_WARNING,
+ "driver selected to bad hw_mode");
+ return;
+ }
+ }
+
hapd->iface->freq = hostapd_hw_get_freq(hapd, acs_res->pri_channel);
if (!acs_res->pri_channel) {
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index 96744c4..069d1ae 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -895,14 +895,18 @@
}
if (iface->current_mode == NULL) {
- wpa_printf(MSG_ERROR, "Hardware does not support configured "
- "mode");
- hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
- HOSTAPD_LEVEL_WARNING,
- "Hardware does not support configured mode "
- "(%d) (hw_mode in hostapd.conf)",
- (int) iface->conf->hw_mode);
- return -2;
+ if (!(iface->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) ||
+ !(iface->drv_flags & WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY))
+ {
+ wpa_printf(MSG_ERROR,
+ "Hardware does not support configured mode");
+ hostapd_logger(iface->bss[0], NULL,
+ HOSTAPD_MODULE_IEEE80211,
+ HOSTAPD_LEVEL_WARNING,
+ "Hardware does not support configured mode (%d) (hw_mode in hostapd.conf)",
+ (int) iface->conf->hw_mode);
+ return -2;
+ }
}
switch (hostapd_check_chans(iface)) {
diff --git a/src/common/defs.h b/src/common/defs.h
index 24f80ad..5b2d7c4 100644
--- a/src/common/defs.h
+++ b/src/common/defs.h
@@ -295,6 +295,7 @@
HOSTAPD_MODE_IEEE80211G,
HOSTAPD_MODE_IEEE80211A,
HOSTAPD_MODE_IEEE80211AD,
+ HOSTAPD_MODE_IEEE80211ANY,
NUM_HOSTAPD_MODES
};
diff --git a/src/common/qca-vendor.h b/src/common/qca-vendor.h
index 140295c..3c35e79 100644
--- a/src/common/qca-vendor.h
+++ b/src/common/qca-vendor.h
@@ -221,6 +221,7 @@
QCA_ACS_MODE_IEEE80211G,
QCA_ACS_MODE_IEEE80211A,
QCA_ACS_MODE_IEEE80211AD,
+ QCA_ACS_MODE_IEEE80211ANY,
};
/**
@@ -230,10 +231,13 @@
* management offload, a mechanism where the station's firmware
* does the exchange with the AP to establish the temporal keys
* after roaming, rather than having the user space wpa_supplicant do it.
+ * @QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY: Device supports automatic
+ * band selection based on channel selection results.
* @NUM_QCA_WLAN_VENDOR_FEATURES: Number of assigned feature bits
*/
enum qca_wlan_vendor_features {
QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD = 0,
+ QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY = 1,
NUM_QCA_WLAN_VENDOR_FEATURES /* keep last */
};
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index f7da636..0324339 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1212,6 +1212,8 @@
#define WPA_DRIVER_FLAGS_HT_IBSS 0x0000001000000000ULL
/** Driver supports IBSS with VHT datarates */
#define WPA_DRIVER_FLAGS_VHT_IBSS 0x0000002000000000ULL
+/** Driver supports automatic band selection */
+#define WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY 0x0000004000000000ULL
u64 flags;
#define WPA_DRIVER_SMPS_MODE_STATIC 0x00000001
@@ -4563,6 +4565,7 @@
* @ch_width: Selected Channel width by driver. Driver may choose to
* change hostapd configured ACS channel width due driver internal
* channel restrictions.
+ * hw_mode: Selected band (used with hw_mode=any)
*/
struct acs_selected_channels {
u8 pri_channel;
@@ -4570,6 +4573,7 @@
u8 vht_seg0_center_ch;
u8 vht_seg1_center_ch;
u16 ch_width;
+ enum hostapd_hw_mode hw_mode;
} acs_selected_channels;
};
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 26e4984..590731d 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -8365,6 +8365,8 @@
return QCA_ACS_MODE_IEEE80211A;
case HOSTAPD_MODE_IEEE80211AD:
return QCA_ACS_MODE_IEEE80211AD;
+ case HOSTAPD_MODE_IEEE80211ANY:
+ return QCA_ACS_MODE_IEEE80211ANY;
default:
return -1;
}
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
index ba1e240..e23c57e 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -813,6 +813,9 @@
if (check_feature(QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD, &info))
drv->capa.flags |= WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD;
+
+ if (check_feature(QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY, &info))
+ drv->capa.flags |= WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY;
}
diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
index 8cebfb2..7b0f721 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -1491,6 +1491,25 @@
}
+static enum hostapd_hw_mode get_qca_hw_mode(u8 hw_mode)
+{
+ switch (hw_mode) {
+ case QCA_ACS_MODE_IEEE80211B:
+ return HOSTAPD_MODE_IEEE80211B;
+ case QCA_ACS_MODE_IEEE80211G:
+ return HOSTAPD_MODE_IEEE80211G;
+ case QCA_ACS_MODE_IEEE80211A:
+ return HOSTAPD_MODE_IEEE80211A;
+ case QCA_ACS_MODE_IEEE80211AD:
+ return HOSTAPD_MODE_IEEE80211AD;
+ case QCA_ACS_MODE_IEEE80211ANY:
+ return HOSTAPD_MODE_IEEE80211ANY;
+ default:
+ return NUM_HOSTAPD_MODES;
+ }
+}
+
+
static void qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
const u8 *data, size_t len)
{
@@ -1520,14 +1539,28 @@
if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH])
event.acs_selected_channels.ch_width =
nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH]);
+ if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]) {
+ u8 hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
+
+ event.acs_selected_channels.hw_mode = get_qca_hw_mode(hw_mode);
+ if (event.acs_selected_channels.hw_mode == NUM_HOSTAPD_MODES ||
+ event.acs_selected_channels.hw_mode ==
+ HOSTAPD_MODE_IEEE80211ANY) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Invalid hw_mode %d in ACS selection event",
+ hw_mode);
+ return;
+ }
+ }
wpa_printf(MSG_INFO,
- "nl80211: ACS Results: PCH: %d SCH: %d BW: %d VHT0: %d VHT1: %d",
+ "nl80211: ACS Results: PCH: %d SCH: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d",
event.acs_selected_channels.pri_channel,
event.acs_selected_channels.sec_channel,
event.acs_selected_channels.ch_width,
event.acs_selected_channels.vht_seg0_center_ch,
- event.acs_selected_channels.vht_seg1_center_ch);
+ event.acs_selected_channels.vht_seg1_center_ch,
+ event.acs_selected_channels.hw_mode);
/* Ignore ACS channel list check for backwards compatibility */