[PATCH] hostapd: Add ACS support for broadcom device (Xinrui Sun)

Xinrui Sun xinrui.sun at broadcom.com
Sun Jun 28 21:38:41 EDT 2020


Dear ,
New tests showed when  driver return a bw40 channel, wpa_supplicant will
trigger new scan.
Wifi driver already scan bw40 channel info, so it is not necessary to do
new scan again.
And driver already switch to AP mode, scan is not allowed in this moment.

Update patch below:

>From 96e4151a2e9ad5e6b52b5827ea675998b26c7502 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  |  11 ++
 src/drivers/driver_nl80211_event.c |  93 +++++++++++++++++
 src/drivers/drivers.mak            |   4 +
 src/drivers/drivers.mk             |   3 +
 8 files changed, 383 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..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..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




------------------------------

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