[PATCH] hostapd: Add ACS support for broadcom device (Xinrui Sun)
Xinrui Sun
xinrui.sun at broadcom.com
Mon Jul 13 23:41:03 EDT 2020
Hi,
Modified issue of BRCM_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL, and add
support for HW_MODE_ANY
Update new patch.
>From b1391e12be13fa29c19b625602ba39cd81f2226e Mon Sep 17 00:00:00 2001
From: Xinrui Sun <xinrui.sun at broadcom.com>
Date: Fri, 12 Jun 2020 20:49:07 +0800
Subject: [PATCH] Add ACS support for Broadcom device
BRCM vendor command used to trigger ACS scan. After ACS finished,
DHD driver will send results by event BRCM_VENDOR_EVENT_ACS.
Signed-off-by: Xinrui Sun <xinrui.sun at broadcom.com>
---
hostapd/android.config | 5 +-
src/ap/hw_features.c | 8 ++
src/common/brcm_vendor.h | 156 +++++++++++++++++++++++++++++
src/drivers/driver_nl80211.c | 104 +++++++++++++++++++
src/drivers/driver_nl80211_capa.c | 12 +++
src/drivers/driver_nl80211_event.c | 93 +++++++++++++++++
src/drivers/drivers.mak | 4 +
src/drivers/drivers.mk | 3 +
8 files changed, 384 insertions(+), 1 deletion(-)
create mode 100644 src/common/brcm_vendor.h
diff --git a/hostapd/android.config b/hostapd/android.config
index 94a9bb47b..34b42d389 100644
--- a/hostapd/android.config
+++ b/hostapd/android.config
@@ -26,7 +26,10 @@
CONFIG_LIBNL20=y
# QCA vendor extensions to nl80211
-CONFIG_DRIVER_NL80211_QCA=y
+#CONFIG_DRIVER_NL80211_QCA=y
+
+# Broadcom vendor extensions to nl80211
+CONFIG_DRIVER_NL80211_BRCM=y
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
#CONFIG_DRIVER_BSD=y
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index f6e69030d..e94f557af 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -972,6 +972,14 @@ int hostapd_acs_completed(struct hostapd_iface
*iface, int err)
wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO,
ACS_EVENT_COMPLETED "freq=%d channel=%d",
iface->freq, iface->conf->channel);
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ /* Driver already do the scan for different band width,
+ * And send final results directly.
+ * don't need to check ht cap and do scan for bw40 again.
+ */
+ ret = 0;
+ goto out;
+#endif
break;
case HOSTAPD_CHAN_ACS:
wpa_printf(MSG_ERROR, "ACS error - reported complete, but
no result available");
diff --git a/src/common/brcm_vendor.h b/src/common/brcm_vendor.h
new file mode 100644
index 000000000..f163dea73
--- /dev/null
+++ b/src/common/brcm_vendor.h
@@ -0,0 +1,156 @@
+/*
+ * Broadcom Corporation OUI and vendor specific assignments
+ * Copyright (c) 2020, Broadcom Corporation.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef BRCM_VENDOR_H
+#define BRCM_VENDOR_H
+
+/*
+ * This file is a registry of identifier assignments from the Broadcom
+ * OUI 00:10:18 for purposes other than MAC address assignment. New
identifiers
+ * can be assigned through normal review process for changes to the
upstream
+ * hostap.git repository.
+ */
+
+#define OUI_BRCM 0x001018
+
+/**
+ * enum brcm_nl80211_vendor_subcmds - BRCM nl80211 vendor command
identifiers
+ *
+ * @BRCM_VENDOR_SCMD_UNSPEC: Reserved value 0
+ *
+ * @BRCM_VENDOR_SCMD_PRIV_STR: Provide vendor private cmds to send to FW.
+ *
+ * @BRCM_VENDOR_SCMD_BCM_STR: Provide vendor cmds to BCMDHD driver.
+ *
+ * @BRCM_VENDOR_SCMD_BCM_PSK: Used to set SAE password.
+ *
+ * @BRCM_VENDOR_SCMD_SET_PMK: Command to check driver support
+ * for DFS offloading.
+ *
+ * @BRCM_VENDOR_SCMD_GET_FEATURES: Command to get the features
+ * supported by the driver.
+ *
+ * @BRCM_VENDOR_SCMD_SET_MAC: Set random mac address for P2P interface.
+ *
+ * @BRCM_VENDOR_SCMD_SET_CONNECT_PARAMS: Set some connect parameters.
+ * Used for the case that FW handle SAE.
+ *
+ * @BRCM_VENDOR_SCMD_SET_START_AP_PARAMS: Set SoftAP paramters.
+ * Used for the case that FW handle SAE.
+ *
+ * @BRCM_VENDOR_SCMD_ACS: ACS command/event which is used to
+ * invoke the ACS function in device and pass selected channels to
+ * hostapd. Uses enum qca_wlan_vendor_attr_acs_offload attributes.
+ *
+ * @BRCM_VENDOR_SCMD_MAX: This acts as a the tail of cmds list.
+ * Make sure it located at the end of the list.
+ *
+ */
+enum brcm_nl80211_vendor_subcmds {
+ BRCM_VENDOR_SCMD_UNSPEC = 0,
+ BRCM_VENDOR_SCMD_PRIV_STR = 1,
+ BRCM_VENDOR_SCMD_BCM_STR = 2,
+ BRCM_VENDOR_SCMD_BCM_PSK = 3,
+ BRCM_VENDOR_SCMD_SET_PMK = 4,
+ BRCM_VENDOR_SCMD_GET_FEATURES = 5,
+ BRCM_VENDOR_SCMD_SET_MAC = 6,
+ BRCM_VENDOR_SCMD_SET_CONNECT_PARAMS = 7,
+ BRCM_VENDOR_SCMD_SET_START_AP_PARAMS = 8,
+ BRCM_VENDOR_SCMD_ACS = 9,
+ BRCM_VENDOR_SCMD_MAX = 10
+};
+
+/**
+ * enum brcm_nl80211_vendor_events - BRCM nl80211 asynchoronous event
identifiers
+ *
+ * @BRCM_VENDOR_EVENT_UNSPEC: Reserved value 0
+ *
+ * @BRCM_VENDOR_EVENT_PRIV_STR: String command/event
+ */
+enum brcm_nl80211_vendor_events {
+ BRCM_VENDOR_EVENT_UNSPEC = 0,
+ BRCM_VENDOR_EVENT_PRIV_STR = 1,
+ GOOGLE_GSCAN_SIGNIFICANT_EVENT = 2,
+ GOOGLE_GSCAN_GEOFENCE_FOUND_EVENT = 3,
+ GOOGLE_GSCAN_BATCH_SCAN_EVENT = 4,
+ GOOGLE_SCAN_FULL_RESULTS_EVENT = 5,
+ GOOGLE_RTT_COMPLETE_EVENT = 6,
+ GOOGLE_SCAN_COMPLETE_EVENT = 7,
+ GOOGLE_GSCAN_GEOFENCE_LOST_EVENT = 8,
+ GOOGLE_SCAN_EPNO_EVENT = 9,
+ GOOGLE_DEBUG_RING_EVENT = 10,
+ GOOGLE_FW_DUMP_EVENT = 11,
+ GOOGLE_PNO_HOTSPOT_FOUND_EVENT = 12,
+ GOOGLE_RSSI_MONITOR_EVENT = 13,
+ GOOGLE_MKEEP_ALIVE_EVENT = 14,
+
+ /*
+ * BRCM specific events should be placed after
+ * the Generic events so that enums don't mismatch
+ * between the DHD and HAL
+ */
+ GOOGLE_NAN_EVENT_ENABLED = 15,
+ GOOGLE_NAN_EVENT_DISABLED = 16,
+ GOOGLE_NAN_EVENT_SUBSCRIBE_MATCH = 17,
+ GOOGLE_NAN_EVENT_REPLIED = 18,
+ GOOGLE_NAN_EVENT_PUBLISH_TERMINATED = 19,
+ GOOGLE_NAN_EVENT_SUBSCRIBE_TERMINATED = 20,
+ GOOGLE_NAN_EVENT_DE_EVENT = 21,
+ GOOGLE_NAN_EVENT_FOLLOWUP = 22,
+ GOOGLE_NAN_EVENT_TRANSMIT_FOLLOWUP_IND = 23,
+ GOOGLE_NAN_EVENT_DATA_REQUEST = 24,
+ GOOGLE_NAN_EVENT_DATA_CONFIRMATION = 25,
+ GOOGLE_NAN_EVENT_DATA_END = 26,
+ GOOGLE_NAN_EVENT_BEACON = 27,
+ GOOGLE_NAN_EVENT_SDF = 28,
+ GOOGLE_NAN_EVENT_TCA = 29,
+ GOOGLE_NAN_EVENT_SUBSCRIBE_UNMATCH = 30,
+ GOOGLE_NAN_EVENT_UNKNOWN = 31,
+ GOOGLE_ROAM_EVENT_START = 32,
+ BRCM_VENDOR_EVENT_HANGED = 33,
+ BRCM_VENDOR_EVENT_SAE_KEY = 34,
+ BRCM_VENDOR_EVENT_BEACON_RECV = 35,
+ BRCM_VENDOR_EVENT_PORT_AUTHORIZED = 36,
+ GOOGLE_FILE_DUMP_EVENT = 37,
+ BRCM_VENDOR_EVENT_CU = 38,
+ BRCM_VENDOR_EVENT_WIPS = 39,
+ NAN_ASYNC_RESPONSE_DISABLED = 40,
+ BRCM_VENDOR_EVENT_RCC_INFO = 41,
+ BRCM_VENDOR_EVENT_ACS = 42,
+ BRCM_VENDOR_EVENT_LAST
+
+};
+
+#ifdef CONFIG_BRCM_SAE
+enum wifi_sae_key_attr {
+ BRCM_SAE_KEY_ATTR_BSSID,
+ BRCM_SAE_KEY_ATTR_PMK,
+ BRCM_SAE_KEY_ATTR_PMKID
+};
+#endif /* CONFIG_BRCM_SAE */
+
+enum wl_vendor_attr_acs_offload {
+ BRCM_VENDOR_ATTR_ACS_CHANNEL_INVALID = 0,
+ BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ,
+ BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ,
+ BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL,
+ BRCM_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL,
+
+ BRCM_VENDOR_ATTR_ACS_HW_MODE,
+ BRCM_VENDOR_ATTR_ACS_HT_ENABLED,
+ BRCM_VENDOR_ATTR_ACS_HT40_ENABLED,
+ BRCM_VENDOR_ATTR_ACS_VHT_ENABLED,
+ BRCM_VENDOR_ATTR_ACS_CHWIDTH,
+ BRCM_VENDOR_ATTR_ACS_CH_LIST,
+ BRCM_VENDOR_ATTR_ACS_FREQ_LIST,
+
+ BRCM_VENDOR_ATTR_ACS_LAST
+};
+
+
+#endif /* BRCM_VENDOR_H */
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 72189da24..de9b4651f 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -38,6 +38,10 @@
#include "rfkill.h"
#include "driver_nl80211.h"
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+#include "common/brcm_vendor.h"
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
+
#ifndef NETLINK_CAP_ACK
#define NETLINK_CAP_ACK 10
@@ -11212,6 +11216,103 @@ fail:
#endif /* CONFIG_DRIVER_NL80211_QCA */
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+static int wpa_driver_do_broadcom_acs(void *priv, struct drv_acs_params
*params)
+{
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ struct nl_msg *msg;
+ struct nlattr *data;
+ int freq_list_len;
+ int ret = 0;
+
+ do {
+ freq_list_len = int_array_len(params->freq_list);
+ wpa_printf(MSG_DEBUG, "%s: freq_list_len=%d",
+ __FUNCTION__, freq_list_len);
+
+ msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
+ if (!msg) {
+ wpa_printf(MSG_ERROR, "%s: *errof, no memory for
msg",
+ __FUNCTION__);
+ return ret;
+ }
+ if ((nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_BRCM)))
{
+ wpa_printf(MSG_ERROR, "%s: *errof,
NL80211_ATTR_VENDOR_ID",
+ __FUNCTION__);
+ nlmsg_free(msg);
+ return ret;
+ }
+ if ((nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
BRCM_VENDOR_SCMD_ACS))) {
+ wpa_printf(MSG_ERROR, "%s: *errof,
NL80211_ATTR_VENDOR_SUBCMD",
+ __FUNCTION__);
+ nlmsg_free(msg);
+ return ret;
+ }
+ if (!(data = nla_nest_start(msg,
NL80211_ATTR_VENDOR_DATA))) {
+ wpa_printf(MSG_ERROR, "%s: *errof,
NL80211_ATTR_VENDOR_DATA",
+ __FUNCTION__);
+ nlmsg_free(msg);
+ return ret;
+ }
+ if ((nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_HW_MODE,
params->hw_mode))) {
+ wpa_printf(MSG_ERROR, "%s: *errof,
BRCM_VENDOR_ATTR_ACS_HW_MODE",
+ __FUNCTION__);
+ nlmsg_free(msg);
+ return ret;
+ }
+ if ((nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_HT_ENABLED,
params->ht_enabled))) {
+ wpa_printf(MSG_ERROR, "%s: *errof,
BRCM_VENDOR_ATTR_ACS_HT_ENABLED",
+ __FUNCTION__);
+ nlmsg_free(msg);
+ return ret;
+ }
+ if ((nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_HT40_ENABLED,
params->ht40_enabled))) {
+ wpa_printf(MSG_ERROR, "%s: *errof,
BRCM_VENDOR_ATTR_ACS_HT40_ENABLED",
+ __FUNCTION__);
+ nlmsg_free(msg);
+ return ret;
+ }
+ if ((nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_VHT_ENABLED,
params->vht_enabled))) {
+ wpa_printf(MSG_ERROR, "%s: *errof,
BRCM_VENDOR_ATTR_ACS_VHT_ENABLED",
+ __FUNCTION__);
+ nlmsg_free(msg);
+ return ret;
+ }
+ if ((nla_put_u16(msg, BRCM_VENDOR_ATTR_ACS_CHWIDTH,
params->ch_width))) {
+ wpa_printf(MSG_ERROR, "%s: *errof,
BRCM_VENDOR_ATTR_ACS_CHWIDTH",
+ __FUNCTION__);
+ nlmsg_free(msg);
+ return ret;
+ }
+ wpa_printf(MSG_DEBUG, "%s: ht40=%d, ch_width=%d\n",
__FUNCTION__,
+ params->ht40_enabled, params->ch_width);
+ if ((freq_list_len > 0)
+ && (nla_put(msg, BRCM_VENDOR_ATTR_ACS_FREQ_LIST,
sizeof(int) * freq_list_len,
+ params->freq_list))) {
+ wpa_printf(MSG_ERROR, "%s: *errof,
BRCM_VENDOR_ATTR_ACS_FREQ_LIST, list_len=%d",
+ __FUNCTION__, freq_list_len);
+ nlmsg_free(msg);
+ return ret;
+ }
+
+ nla_nest_end(msg, data);
+
+ wpa_printf(MSG_DEBUG,
+ "nl80211: ACS Params: HW_MODE: %d HT: %d HT40: %d
VHT: %d BW: %d",
+ params->hw_mode, params->ht_enabled, params->ht40_enabled,
+ params->vht_enabled, params->ch_width);
+ ret = send_and_recv_msgs(drv, msg, NULL, NULL);
+ if (ret) {
+ wpa_printf(MSG_ERROR,
+ "nl80211: BRCM Failed to invoke driver ACS
function: %s",
+ strerror(errno));
+ }
+ } while (0);
+
+ return ret;
+}
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
static int nl80211_write_to_file(const char *name, unsigned int val)
{
@@ -11649,6 +11750,9 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops
= {
.set_bssid_blacklist = nl80211_set_bssid_blacklist,
.add_sta_node = nl80211_add_sta_node,
#endif /* CONFIG_DRIVER_NL80211_QCA */
+#if defined(CONFIG_DRIVER_NL80211_BRCM)
+ .do_acs = wpa_driver_do_broadcom_acs,
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
.configure_data_frame_filters =
nl80211_configure_data_frame_filters,
.get_ext_capab = nl80211_get_ext_capab,
.update_connect_params = nl80211_update_connection_params,
diff --git a/src/drivers/driver_nl80211_capa.c
b/src/drivers/driver_nl80211_capa.c
index b9eb6e220..9d6e461f0 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -18,6 +18,9 @@
#include "common/qca-vendor-attr.h"
#include "driver_nl80211.h"
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+#include "common/brcm_vendor.h"
+#endif
static int protocol_feature_handler(struct nl_msg *msg, void *arg)
{
@@ -991,6 +994,15 @@ static int wiphy_info_handler(struct nl_msg *msg,
void *arg)
break;
#endif /* CONFIG_DRIVER_NL80211_QCA */
}
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ } else if (vinfo->vendor_id == OUI_BRCM) {
+ switch (vinfo->subcmd) {
+ case BRCM_VENDOR_SCMD_ACS:
+ drv->capa.flags |=
WPA_DRIVER_FLAGS_ACS_OFFLOAD;
+ drv->capa.flags |=
WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY;
+ wpa_printf(MSG_DEBUG, "Enabled
BRCM ACS\n");
+ }
+#endif /*CONFIG_DRIVER_NL80211_BRCM */
}
wpa_printf(MSG_DEBUG, "nl80211: Supported vendor
command: vendor_id=0x%x subcmd=%u",
diff --git a/src/drivers/driver_nl80211_event.c
b/src/drivers/driver_nl80211_event.c
index 6a2de1f3c..9ec2622f3 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -19,6 +19,9 @@
#include "common/ieee802_11_common.h"
#include "driver_nl80211.h"
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+#include "common/brcm_vendor.h"
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
static const char * nl80211_command_to_string(enum nl80211_commands cmd)
{
@@ -2228,6 +2231,90 @@ static void nl80211_vendor_event_qca(struct
wpa_driver_nl80211_data *drv,
}
}
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+static void brcm_nl80211_acs_select_ch(struct wpa_driver_nl80211_data
*drv,
+ const u8 *data, size_t len)
+{
+ struct nlattr *tb[BRCM_VENDOR_ATTR_ACS_LAST + 1];
+ union wpa_event_data event;
+
+ wpa_printf(MSG_DEBUG,
+ "nl80211: BRCM ACS channel selection vendor event
received");
+
+ if (nla_parse(tb, BRCM_VENDOR_ATTR_ACS_LAST, (struct nlattr *)
data, len, NULL)
+ || (!tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ])
+ || (!tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ])) {
+ return;
+ }
+
+ os_memset(&event, 0, sizeof(event));
+ if (tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ]) {
+ event.acs_selected_channels.pri_freq =
nla_get_u32(tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ]);
+ }
+ wpa_printf(MSG_DEBUG, "got pri_freq=%d\n",
event.acs_selected_channels.pri_freq );
+ if (tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ]) {
+ event.acs_selected_channels.sec_freq =
nla_get_u32(tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ]);
+ }
+ wpa_printf(MSG_DEBUG, "got sec_freq=%d\n",
event.acs_selected_channels.sec_freq );
+ if (tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]) {
+ event.acs_selected_channels.vht_seg0_center_ch =
nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]);
+ }
+ if (tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL]) {
+ event.acs_selected_channels.vht_seg1_center_ch =
nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL]);
+ }
+ if (tb[BRCM_VENDOR_ATTR_ACS_CHWIDTH]) {
+ event.acs_selected_channels.ch_width =
nla_get_u16(tb[BRCM_VENDOR_ATTR_ACS_CHWIDTH]);
+ }
+ if (tb[BRCM_VENDOR_ATTR_ACS_HW_MODE]) {
+ event.acs_selected_channels.hw_mode =
nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_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",
+ event.acs_selected_channels.hw_mode);
+ return;
+ }
+ }
+
+ wpa_printf(MSG_INFO,
+ "nl80211: ACS Results: PCH: %d SCH: %d BW: %d VHT0: %d
VHT1: %d HW_MODE: %d",
+ event.acs_selected_channels.pri_freq,
+ event.acs_selected_channels.sec_freq,
+ 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.hw_mode);
+
+ wpa_supplicant_event(drv->ctx, EVENT_ACS_CHANNEL_SELECTED,
&event);
+}
+
+static void nl80211_vendor_event_brcm( struct wpa_driver_nl80211_data
*drv,
+ u32 subcmd, u8 *data, size_t len)
+{
+ union wpa_event_data event;
+
+ wpa_printf(MSG_DEBUG, "got vendor event %d", subcmd);
+ memset(&event, 0, sizeof(event));
+ switch (subcmd) {
+ case BRCM_VENDOR_EVENT_PRIV_STR:
+ case BRCM_VENDOR_EVENT_HANGED:
+ /* Dump the event on to the console */
+ wpa_msg(NULL, MSG_INFO, "%s", data);
+ break;
+
+ case BRCM_VENDOR_EVENT_ACS:
+ wpa_msg(NULL, MSG_INFO, "%s", data);
+ brcm_nl80211_acs_select_ch(drv, data, len);
+ break;
+
+ default:
+ wpa_printf(MSG_ERROR, "%s-%d: Ignore unsupported BRCM
vendor event %u",
+ __FUNCTION__, __LINE__, subcmd);
+ break;
+ }
+}
+
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv,
struct nlattr **tb)
@@ -2267,6 +2354,12 @@ static void nl80211_vendor_event(struct
wpa_driver_nl80211_data *drv,
case OUI_QCA:
nl80211_vendor_event_qca(drv, subcmd, data, len);
break;
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ case OUI_BRCM:
+ wpa_printf(MSG_DEBUG, "BRCM event");
+ nl80211_vendor_event_brcm(drv, subcmd, data, len);
+ break;
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
default:
wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported vendor
event");
break;
diff --git a/src/drivers/drivers.mak b/src/drivers/drivers.mak
index 55a98ef86..a03d4a034 100644
--- a/src/drivers/drivers.mak
+++ b/src/drivers/drivers.mak
@@ -26,6 +26,10 @@ NEED_LIBNL=y
CONFIG_LIBNL3_ROUTE=y
endif
+ifdef CONFIG_DRIVER_NL80211_BRCM
+DRV_CFLAGS += -DCONFIG_DRIVER_NL80211_BRCM
+endif
+
ifdef CONFIG_DRIVER_MACSEC_QCA
DRV_CFLAGS += -DCONFIG_DRIVER_MACSEC_QCA
DRV_OBJS += ../src/drivers/driver_macsec_qca.o
diff --git a/src/drivers/drivers.mk b/src/drivers/drivers.mk
index 5a32a2422..10eab6a92 100644
--- a/src/drivers/drivers.mk
+++ b/src/drivers/drivers.mk
@@ -41,6 +41,9 @@ DRV_OBJS += src/drivers/driver_nl80211_scan.c
ifdef CONFIG_DRIVER_NL80211_QCA
DRV_CFLAGS += -DCONFIG_DRIVER_NL80211_QCA
endif
+ifdef CONFIG_DRIVER_NL80211_BRCM
+DRV_CFLAGS += -DCONFIG_DRIVER_NL80211_BRCM
+endif
NEED_SME=y
NEED_AP_MLME=y
NEED_NETLINK=y
--
2.17.2
-----Original Message-----
From: Hostap [mailto:hostap-bounces at lists.infradead.org] On Behalf Of
hostap-request at lists.infradead.org
Sent: Sunday, June 14, 2020 3:00 AM
To: hostap at lists.infradead.org
Subject: Hostap Digest, Vol 57, Issue 21
Send Hostap mailing list submissions to
hostap at lists.infradead.org
To subscribe or unsubscribe via the World Wide Web, visit
http://lists.infradead.org/mailman/listinfo/hostap
or, via email, send a message with subject or body 'help' to
hostap-request at lists.infradead.org
You can reach the person managing the list at
hostap-owner at lists.infradead.org
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Hostap digest..."
Today's Topics:
1. [PATCH] hostapd: Add ACS support for broadcom device (Xinrui Sun)
----------------------------------------------------------------------
Message: 1
Date: Sat, 13 Jun 2020 09:03:03 +0800
From: Xinrui Sun <xinrui.sun at broadcom.com>
To: hostap at lists.infradead.org
Subject: [PATCH] hostapd: Add ACS support for broadcom device
Message-ID: <59ffe473aef1756a2ed567e046a3f2ad at mail.gmail.com>
Content-Type: text/plain; charset="UTF-8"
>From b9efc86587a14c0165dfda8ded5070703decc75b Mon Sep 17 00:00:00 2001
From: Xinrui Sun <xinrui.sun at broadcom.com>
Date: Fri, 12 Jun 2020 20:49:07 +0800
Subject: [PATCH] Add ACS support for Broadcom device
BRCM vendor command used to trigger ACS scan. After ACS finished,
DHD driver will send results by event BRCM_VENDOR_EVENT_ACS.
Signed-off-by: Xinrui Sun <xinrui.sun at broadcom.com>
---
hostapd/android.config | 5 +-
src/common/brcm_vendor.h | 156 +++++++++++++++++++++++++++++
src/drivers/driver_nl80211.c | 104 +++++++++++++++++++
src/drivers/driver_nl80211_capa.c | 11 ++
src/drivers/driver_nl80211_event.c | 93 +++++++++++++++++
src/drivers/drivers.mak | 4 +
src/drivers/drivers.mk | 3 +
7 files changed, 375 insertions(+), 1 deletion(-)
create mode 100644 src/common/brcm_vendor.h
diff --git a/hostapd/android.config b/hostapd/android.config
index 94a9bb47b..34b42d389 100644
--- a/hostapd/android.config
+++ b/hostapd/android.config
@@ -26,7 +26,10 @@
CONFIG_LIBNL20=y
# QCA vendor extensions to nl80211
-CONFIG_DRIVER_NL80211_QCA=y
+#CONFIG_DRIVER_NL80211_QCA=y
+
+# Broadcom vendor extensions to nl80211
+CONFIG_DRIVER_NL80211_BRCM=y
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
#CONFIG_DRIVER_BSD=y
diff --git a/src/common/brcm_vendor.h b/src/common/brcm_vendor.h
new file mode 100644
index 000000000..f163dea73
--- /dev/null
+++ b/src/common/brcm_vendor.h
@@ -0,0 +1,156 @@
+/*
+ * Broadcom Corporation OUI and vendor specific assignments
+ * Copyright (c) 2020, Broadcom Corporation.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef BRCM_VENDOR_H
+#define BRCM_VENDOR_H
+
+/*
+ * This file is a registry of identifier assignments from the Broadcom
+ * OUI 00:10:18 for purposes other than MAC address assignment. New
identifiers
+ * can be assigned through normal review process for changes to the
upstream
+ * hostap.git repository.
+ */
+
+#define OUI_BRCM 0x001018
+
+/**
+ * enum brcm_nl80211_vendor_subcmds - BRCM nl80211 vendor command
identifiers
+ *
+ * @BRCM_VENDOR_SCMD_UNSPEC: Reserved value 0
+ *
+ * @BRCM_VENDOR_SCMD_PRIV_STR: Provide vendor private cmds to send to FW.
+ *
+ * @BRCM_VENDOR_SCMD_BCM_STR: Provide vendor cmds to BCMDHD driver.
+ *
+ * @BRCM_VENDOR_SCMD_BCM_PSK: Used to set SAE password.
+ *
+ * @BRCM_VENDOR_SCMD_SET_PMK: Command to check driver support
+ * for DFS offloading.
+ *
+ * @BRCM_VENDOR_SCMD_GET_FEATURES: Command to get the features
+ * supported by the driver.
+ *
+ * @BRCM_VENDOR_SCMD_SET_MAC: Set random mac address for P2P interface.
+ *
+ * @BRCM_VENDOR_SCMD_SET_CONNECT_PARAMS: Set some connect parameters.
+ * Used for the case that FW handle SAE.
+ *
+ * @BRCM_VENDOR_SCMD_SET_START_AP_PARAMS: Set SoftAP paramters.
+ * Used for the case that FW handle SAE.
+ *
+ * @BRCM_VENDOR_SCMD_ACS: ACS command/event which is used to
+ * invoke the ACS function in device and pass selected channels to
+ * hostapd. Uses enum qca_wlan_vendor_attr_acs_offload attributes.
+ *
+ * @BRCM_VENDOR_SCMD_MAX: This acts as a the tail of cmds list.
+ * Make sure it located at the end of the list.
+ *
+ */
+enum brcm_nl80211_vendor_subcmds {
+ BRCM_VENDOR_SCMD_UNSPEC = 0,
+ BRCM_VENDOR_SCMD_PRIV_STR = 1,
+ BRCM_VENDOR_SCMD_BCM_STR = 2,
+ BRCM_VENDOR_SCMD_BCM_PSK = 3,
+ BRCM_VENDOR_SCMD_SET_PMK = 4,
+ BRCM_VENDOR_SCMD_GET_FEATURES = 5,
+ BRCM_VENDOR_SCMD_SET_MAC = 6,
+ BRCM_VENDOR_SCMD_SET_CONNECT_PARAMS = 7,
+ BRCM_VENDOR_SCMD_SET_START_AP_PARAMS = 8,
+ BRCM_VENDOR_SCMD_ACS = 9,
+ BRCM_VENDOR_SCMD_MAX = 10
+};
+
+/**
+ * enum brcm_nl80211_vendor_events - BRCM nl80211 asynchoronous event
identifiers
+ *
+ * @BRCM_VENDOR_EVENT_UNSPEC: Reserved value 0
+ *
+ * @BRCM_VENDOR_EVENT_PRIV_STR: String command/event
+ */
+enum brcm_nl80211_vendor_events {
+ BRCM_VENDOR_EVENT_UNSPEC = 0,
+ BRCM_VENDOR_EVENT_PRIV_STR = 1,
+ GOOGLE_GSCAN_SIGNIFICANT_EVENT = 2,
+ GOOGLE_GSCAN_GEOFENCE_FOUND_EVENT = 3,
+ GOOGLE_GSCAN_BATCH_SCAN_EVENT = 4,
+ GOOGLE_SCAN_FULL_RESULTS_EVENT = 5,
+ GOOGLE_RTT_COMPLETE_EVENT = 6,
+ GOOGLE_SCAN_COMPLETE_EVENT = 7,
+ GOOGLE_GSCAN_GEOFENCE_LOST_EVENT = 8,
+ GOOGLE_SCAN_EPNO_EVENT = 9,
+ GOOGLE_DEBUG_RING_EVENT = 10,
+ GOOGLE_FW_DUMP_EVENT = 11,
+ GOOGLE_PNO_HOTSPOT_FOUND_EVENT = 12,
+ GOOGLE_RSSI_MONITOR_EVENT = 13,
+ GOOGLE_MKEEP_ALIVE_EVENT = 14,
+
+ /*
+ * BRCM specific events should be placed after
+ * the Generic events so that enums don't mismatch
+ * between the DHD and HAL
+ */
+ GOOGLE_NAN_EVENT_ENABLED = 15,
+ GOOGLE_NAN_EVENT_DISABLED = 16,
+ GOOGLE_NAN_EVENT_SUBSCRIBE_MATCH = 17,
+ GOOGLE_NAN_EVENT_REPLIED = 18,
+ GOOGLE_NAN_EVENT_PUBLISH_TERMINATED = 19,
+ GOOGLE_NAN_EVENT_SUBSCRIBE_TERMINATED = 20,
+ GOOGLE_NAN_EVENT_DE_EVENT = 21,
+ GOOGLE_NAN_EVENT_FOLLOWUP = 22,
+ GOOGLE_NAN_EVENT_TRANSMIT_FOLLOWUP_IND = 23,
+ GOOGLE_NAN_EVENT_DATA_REQUEST = 24,
+ GOOGLE_NAN_EVENT_DATA_CONFIRMATION = 25,
+ GOOGLE_NAN_EVENT_DATA_END = 26,
+ GOOGLE_NAN_EVENT_BEACON = 27,
+ GOOGLE_NAN_EVENT_SDF = 28,
+ GOOGLE_NAN_EVENT_TCA = 29,
+ GOOGLE_NAN_EVENT_SUBSCRIBE_UNMATCH = 30,
+ GOOGLE_NAN_EVENT_UNKNOWN = 31,
+ GOOGLE_ROAM_EVENT_START = 32,
+ BRCM_VENDOR_EVENT_HANGED = 33,
+ BRCM_VENDOR_EVENT_SAE_KEY = 34,
+ BRCM_VENDOR_EVENT_BEACON_RECV = 35,
+ BRCM_VENDOR_EVENT_PORT_AUTHORIZED = 36,
+ GOOGLE_FILE_DUMP_EVENT = 37,
+ BRCM_VENDOR_EVENT_CU = 38,
+ BRCM_VENDOR_EVENT_WIPS = 39,
+ NAN_ASYNC_RESPONSE_DISABLED = 40,
+ BRCM_VENDOR_EVENT_RCC_INFO = 41,
+ BRCM_VENDOR_EVENT_ACS = 42,
+ BRCM_VENDOR_EVENT_LAST
+
+};
+
+#ifdef CONFIG_BRCM_SAE
+enum wifi_sae_key_attr {
+ BRCM_SAE_KEY_ATTR_BSSID,
+ BRCM_SAE_KEY_ATTR_PMK,
+ BRCM_SAE_KEY_ATTR_PMKID
+};
+#endif /* CONFIG_BRCM_SAE */
+
+enum wl_vendor_attr_acs_offload {
+ BRCM_VENDOR_ATTR_ACS_CHANNEL_INVALID = 0,
+ BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ,
+ BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ,
+ BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL,
+ BRCM_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL,
+
+ BRCM_VENDOR_ATTR_ACS_HW_MODE,
+ BRCM_VENDOR_ATTR_ACS_HT_ENABLED,
+ BRCM_VENDOR_ATTR_ACS_HT40_ENABLED,
+ BRCM_VENDOR_ATTR_ACS_VHT_ENABLED,
+ BRCM_VENDOR_ATTR_ACS_CHWIDTH,
+ BRCM_VENDOR_ATTR_ACS_CH_LIST,
+ BRCM_VENDOR_ATTR_ACS_FREQ_LIST,
+
+ BRCM_VENDOR_ATTR_ACS_LAST
+};
+
+
+#endif /* BRCM_VENDOR_H */
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 72189da24..de9b4651f 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -38,6 +38,10 @@
#include "rfkill.h"
#include "driver_nl80211.h"
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+#include "common/brcm_vendor.h"
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
+
#ifndef NETLINK_CAP_ACK
#define NETLINK_CAP_ACK 10
@@ -11212,6 +11216,103 @@ fail:
#endif /* CONFIG_DRIVER_NL80211_QCA */
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+static int wpa_driver_do_broadcom_acs(void *priv, struct drv_acs_params
*params)
+{
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ struct nl_msg *msg;
+ struct nlattr *data;
+ int freq_list_len;
+ int ret = 0;
+
+ do {
+ freq_list_len = int_array_len(params->freq_list);
+ wpa_printf(MSG_DEBUG, "%s: freq_list_len=%d",
+ __FUNCTION__, freq_list_len);
+
+ msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
+ if (!msg) {
+ wpa_printf(MSG_ERROR, "%s: *errof, no memory for
msg",
+ __FUNCTION__);
+ return ret;
+ }
+ if ((nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_BRCM)))
{
+ wpa_printf(MSG_ERROR, "%s: *errof,
NL80211_ATTR_VENDOR_ID",
+ __FUNCTION__);
+ nlmsg_free(msg);
+ return ret;
+ }
+ if ((nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
BRCM_VENDOR_SCMD_ACS))) {
+ wpa_printf(MSG_ERROR, "%s: *errof,
NL80211_ATTR_VENDOR_SUBCMD",
+ __FUNCTION__);
+ nlmsg_free(msg);
+ return ret;
+ }
+ if (!(data = nla_nest_start(msg,
NL80211_ATTR_VENDOR_DATA))) {
+ wpa_printf(MSG_ERROR, "%s: *errof,
NL80211_ATTR_VENDOR_DATA",
+ __FUNCTION__);
+ nlmsg_free(msg);
+ return ret;
+ }
+ if ((nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_HW_MODE,
params->hw_mode))) {
+ wpa_printf(MSG_ERROR, "%s: *errof,
BRCM_VENDOR_ATTR_ACS_HW_MODE",
+ __FUNCTION__);
+ nlmsg_free(msg);
+ return ret;
+ }
+ if ((nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_HT_ENABLED,
params->ht_enabled))) {
+ wpa_printf(MSG_ERROR, "%s: *errof,
BRCM_VENDOR_ATTR_ACS_HT_ENABLED",
+ __FUNCTION__);
+ nlmsg_free(msg);
+ return ret;
+ }
+ if ((nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_HT40_ENABLED,
params->ht40_enabled))) {
+ wpa_printf(MSG_ERROR, "%s: *errof,
BRCM_VENDOR_ATTR_ACS_HT40_ENABLED",
+ __FUNCTION__);
+ nlmsg_free(msg);
+ return ret;
+ }
+ if ((nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_VHT_ENABLED,
params->vht_enabled))) {
+ wpa_printf(MSG_ERROR, "%s: *errof,
BRCM_VENDOR_ATTR_ACS_VHT_ENABLED",
+ __FUNCTION__);
+ nlmsg_free(msg);
+ return ret;
+ }
+ if ((nla_put_u16(msg, BRCM_VENDOR_ATTR_ACS_CHWIDTH,
params->ch_width))) {
+ wpa_printf(MSG_ERROR, "%s: *errof,
BRCM_VENDOR_ATTR_ACS_CHWIDTH",
+ __FUNCTION__);
+ nlmsg_free(msg);
+ return ret;
+ }
+ wpa_printf(MSG_DEBUG, "%s: ht40=%d, ch_width=%d\n",
__FUNCTION__,
+ params->ht40_enabled, params->ch_width);
+ if ((freq_list_len > 0)
+ && (nla_put(msg, BRCM_VENDOR_ATTR_ACS_FREQ_LIST,
sizeof(int) * freq_list_len,
+ params->freq_list))) {
+ wpa_printf(MSG_ERROR, "%s: *errof,
BRCM_VENDOR_ATTR_ACS_FREQ_LIST, list_len=%d",
+ __FUNCTION__, freq_list_len);
+ nlmsg_free(msg);
+ return ret;
+ }
+
+ nla_nest_end(msg, data);
+
+ wpa_printf(MSG_DEBUG,
+ "nl80211: ACS Params: HW_MODE: %d HT: %d HT40: %d
VHT: %d BW: %d",
+ params->hw_mode, params->ht_enabled, params->ht40_enabled,
+ params->vht_enabled, params->ch_width);
+ ret = send_and_recv_msgs(drv, msg, NULL, NULL);
+ if (ret) {
+ wpa_printf(MSG_ERROR,
+ "nl80211: BRCM Failed to invoke driver ACS
function: %s",
+ strerror(errno));
+ }
+ } while (0);
+
+ return ret;
+}
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
static int nl80211_write_to_file(const char *name, unsigned int val)
{
@@ -11649,6 +11750,9 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops
= {
.set_bssid_blacklist = nl80211_set_bssid_blacklist,
.add_sta_node = nl80211_add_sta_node,
#endif /* CONFIG_DRIVER_NL80211_QCA */
+#if defined(CONFIG_DRIVER_NL80211_BRCM)
+ .do_acs = wpa_driver_do_broadcom_acs,
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
.configure_data_frame_filters =
nl80211_configure_data_frame_filters,
.get_ext_capab = nl80211_get_ext_capab,
.update_connect_params = nl80211_update_connection_params,
diff --git a/src/drivers/driver_nl80211_capa.c
b/src/drivers/driver_nl80211_capa.c
index b9eb6e220..067bf96f0 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -18,6 +18,9 @@
#include "common/qca-vendor-attr.h"
#include "driver_nl80211.h"
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+#include "common/brcm_vendor.h"
+#endif
static int protocol_feature_handler(struct nl_msg *msg, void *arg)
{
@@ -991,6 +994,14 @@ static int wiphy_info_handler(struct nl_msg *msg,
void *arg)
break;
#endif /* CONFIG_DRIVER_NL80211_QCA */
}
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ } else if (vinfo->vendor_id == OUI_BRCM) {
+ switch (vinfo->subcmd) {
+ case BRCM_VENDOR_SCMD_ACS:
+ drv->capa.flags |=
WPA_DRIVER_FLAGS_ACS_OFFLOAD;
+ wpa_printf(MSG_DEBUG, "Enabled
BRCM ACS\n");
+ }
+#endif /*CONFIG_DRIVER_NL80211_BRCM */
}
wpa_printf(MSG_DEBUG, "nl80211: Supported vendor
command: vendor_id=0x%x subcmd=%u",
diff --git a/src/drivers/driver_nl80211_event.c
b/src/drivers/driver_nl80211_event.c
index 6a2de1f3c..93ae11321 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -19,6 +19,9 @@
#include "common/ieee802_11_common.h"
#include "driver_nl80211.h"
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+#include "common/brcm_vendor.h"
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
static const char * nl80211_command_to_string(enum nl80211_commands cmd)
{
@@ -2228,6 +2231,90 @@ static void nl80211_vendor_event_qca(struct
wpa_driver_nl80211_data *drv,
}
}
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+static void brcm_nl80211_acs_select_ch(struct wpa_driver_nl80211_data
*drv,
+ const u8 *data, size_t len)
+{
+ struct nlattr *tb[BRCM_VENDOR_ATTR_ACS_LAST + 1];
+ union wpa_event_data event;
+
+ wpa_printf(MSG_DEBUG,
+ "nl80211: BRCM ACS channel selection vendor event
received");
+
+ if (nla_parse(tb, BRCM_VENDOR_ATTR_ACS_LAST, (struct nlattr *)
data, len, NULL)
+ || (!tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ])
+ || (!tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ])) {
+ return;
+ }
+
+ os_memset(&event, 0, sizeof(event));
+ if (tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ]) {
+ event.acs_selected_channels.pri_freq =
nla_get_u32(tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ]);
+ }
+ wpa_printf(MSG_DEBUG, "got pri_freq=%d\n",
event.acs_selected_channels.pri_freq );
+ if (tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ]) {
+ event.acs_selected_channels.sec_freq =
nla_get_u32(tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ]);
+ }
+ wpa_printf(MSG_DEBUG, "got sec_freq=%d\n",
event.acs_selected_channels.sec_freq );
+ if (tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]) {
+ event.acs_selected_channels.vht_seg0_center_ch =
nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]);
+ }
+ if (tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]) {
+ event.acs_selected_channels.vht_seg1_center_ch =
nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL]);
+ }
+ if (tb[BRCM_VENDOR_ATTR_ACS_CHWIDTH]) {
+ event.acs_selected_channels.ch_width =
nla_get_u16(tb[BRCM_VENDOR_ATTR_ACS_CHWIDTH]);
+ }
+ if (tb[BRCM_VENDOR_ATTR_ACS_HW_MODE]) {
+ event.acs_selected_channels.hw_mode =
nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_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",
+ event.acs_selected_channels.hw_mode);
+ return;
+ }
+ }
+
+ wpa_printf(MSG_INFO,
+ "nl80211: ACS Results: PCH: %d SCH: %d BW: %d VHT0: %d
VHT1: %d HW_MODE: %d",
+ event.acs_selected_channels.pri_freq,
+ event.acs_selected_channels.sec_freq,
+ 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.hw_mode);
+
+ wpa_supplicant_event(drv->ctx, EVENT_ACS_CHANNEL_SELECTED,
&event);
+}
+
+static void nl80211_vendor_event_brcm( struct wpa_driver_nl80211_data
*drv,
+ u32 subcmd, u8 *data, size_t len)
+{
+ union wpa_event_data event;
+
+ wpa_printf(MSG_DEBUG, "got vendor event %d", subcmd);
+ memset(&event, 0, sizeof(event));
+ switch (subcmd) {
+ case BRCM_VENDOR_EVENT_PRIV_STR:
+ case BRCM_VENDOR_EVENT_HANGED:
+ /* Dump the event on to the console */
+ wpa_msg(NULL, MSG_INFO, "%s", data);
+ break;
+
+ case BRCM_VENDOR_EVENT_ACS:
+ wpa_msg(NULL, MSG_INFO, "%s", data);
+ brcm_nl80211_acs_select_ch(drv, data, len);
+ break;
+
+ default:
+ wpa_printf(MSG_ERROR, "%s-%d: Ignore unsupported BRCM
vendor event %u",
+ __FUNCTION__, __LINE__, subcmd);
+ break;
+ }
+}
+
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv,
struct nlattr **tb)
@@ -2267,6 +2354,12 @@ static void nl80211_vendor_event(struct
wpa_driver_nl80211_data *drv,
case OUI_QCA:
nl80211_vendor_event_qca(drv, subcmd, data, len);
break;
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ case OUI_BRCM:
+ wpa_printf(MSG_DEBUG, "BRCM event");
+ nl80211_vendor_event_brcm(drv, subcmd, data, len);
+ break;
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
default:
wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported vendor
event");
break;
diff --git a/src/drivers/drivers.mak b/src/drivers/drivers.mak
index 55a98ef86..a03d4a034 100644
--- a/src/drivers/drivers.mak
+++ b/src/drivers/drivers.mak
@@ -26,6 +26,10 @@ NEED_LIBNL=y
CONFIG_LIBNL3_ROUTE=y
endif
+ifdef CONFIG_DRIVER_NL80211_BRCM
+DRV_CFLAGS += -DCONFIG_DRIVER_NL80211_BRCM
+endif
+
ifdef CONFIG_DRIVER_MACSEC_QCA
DRV_CFLAGS += -DCONFIG_DRIVER_MACSEC_QCA
DRV_OBJS += ../src/drivers/driver_macsec_qca.o
diff --git a/src/drivers/drivers.mk b/src/drivers/drivers.mk
index 5a32a2422..10eab6a92 100644
--- a/src/drivers/drivers.mk
+++ b/src/drivers/drivers.mk
@@ -41,6 +41,9 @@ DRV_OBJS += src/drivers/driver_nl80211_scan.c
ifdef CONFIG_DRIVER_NL80211_QCA
DRV_CFLAGS += -DCONFIG_DRIVER_NL80211_QCA
endif
+ifdef CONFIG_DRIVER_NL80211_BRCM
+DRV_CFLAGS += -DCONFIG_DRIVER_NL80211_BRCM
+endif
NEED_SME=y
NEED_AP_MLME=y
NEED_NETLINK=y
--
2.17.2
------------------------------
Subject: Digest Footer
_______________________________________________
Hostap mailing list
Hostap at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/hostap
------------------------------
End of Hostap Digest, Vol 57, Issue 21
**************************************
More information about the Hostap
mailing list