--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -14,10 +14,27 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/moduleparam.h>
 #include <linux/etherdevice.h>
+#include <net/netlink.h>
 #include "wil6210.h"
 #include "wmi.h"
 
+static unsigned short scan_dwell_time  = WMI_SCAN_DWELL_TIME_MS;
+module_param(scan_dwell_time, ushort, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(scan_dwell_time, " Scan dwell time");
+
+static unsigned short acs_ch_weight[4] = {120, 100, 100, 100};
+module_param_array(acs_ch_weight, ushort, NULL, 0);
+MODULE_PARM_DESC(acs_ch_weight, " Channel weight in %. This is channel priority for ACS");
+
+/* in case of channels' noise values all zero, applying weights will not work.
+ * to avoid such a case, we will add some small positive value to
+ * all channels' noise calculation */
+#define ACS_CH_NOISE_INIT_VAL (100)
+
+#define ACS_DEFAULT_BEST_CHANNEL 2
+
 #define WIL_MAX_ROC_DURATION_MS 5000
 
 #define CHAN60G(_channel, _flags) {				\
@@ -36,6 +53,72 @@ static struct ieee80211_channel wil_60gh
 /* channel 4 not supported yet */
 };
 
+/* Vendor id to be used in vendor specific command and events
+ * to user space.
+ * NOTE: The authoritative place for definition of QCA_NL80211_VENDOR_ID,
+ * vendor subcmd definitions prefixed with QCA_NL80211_VENDOR_SUBCMD, and
+ * qca_wlan_vendor_attr is open source file src/common/qca-vendor.h in
+ * git://w1.fi/srv/git/hostap.git; the values here are just a copy of that
+ */
+
+#define QCA_NL80211_VENDOR_ID	0x001374
+
+enum qca_wlan_vendor_attr_acs_offload {
+	QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL,
+	QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL,
+	QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE,
+	QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED,
+	QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED,
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_ACS_MAX =
+	QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST - 1
+};
+
+enum qca_wlan_vendor_acs_hw_mode {
+	QCA_ACS_MODE_IEEE80211B,
+	QCA_ACS_MODE_IEEE80211G,
+	QCA_ACS_MODE_IEEE80211A,
+	QCA_ACS_MODE_IEEE80211AD,
+};
+
+static const struct
+nla_policy qca_wlan_acs_vendor_attr[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE] = { .type = NLA_U8 },
+};
+
+enum qca_nl80211_vendor_subcmds {
+	QCA_NL80211_VENDOR_SUBCMD_DO_ACS = 54,
+};
+
+enum qca_nl80211_vendor_subcmds_index {
+	QCA_NL80211_VENDOR_SUBCMD_DO_ACS_INDEX,
+};
+
+static int wil_do_acs(struct wiphy *wiphy, struct wireless_dev *wdev,
+		      const void *data, int data_len);
+
+/* vendor specific commands */
+static const struct wiphy_vendor_command wil_nl80211_vendor_commands[] = {
+	[QCA_NL80211_VENDOR_SUBCMD_DO_ACS_INDEX] = {
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DO_ACS,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV |
+			 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wil_do_acs
+	},
+};
+
+/* vendor specific events */
+static const struct nl80211_vendor_cmd_info wil_nl80211_vendor_events[] = {
+	[QCA_NL80211_VENDOR_SUBCMD_DO_ACS_INDEX] = {
+			.vendor_id = QCA_NL80211_VENDOR_ID,
+			.subcmd = QCA_NL80211_VENDOR_SUBCMD_DO_ACS
+	},
+};
+
 static struct ieee80211_supported_band wil_band_60ghz = {
 	.channels = wil_60ghz_channels,
 	.n_channels = ARRAY_SIZE(wil_60ghz_channels),
@@ -1562,6 +1645,11 @@ static void wil_wiphy_init(struct wiphy
 	wiphy->n_cipher_suites = ARRAY_SIZE(wil_cipher_suites);
 	wiphy->mgmt_stypes = wil_mgmt_stypes;
 	wiphy->features |= NL80211_FEATURE_SK_TX_STATUS;
+
+	wiphy->n_vendor_commands = ARRAY_SIZE(wil_nl80211_vendor_commands);
+	wiphy->vendor_commands = wil_nl80211_vendor_commands;
+	wiphy->vendor_events = wil_nl80211_vendor_events;
+	wiphy->n_vendor_events = ARRAY_SIZE(wil_nl80211_vendor_events);
 }
 
 struct wireless_dev *wil_cfg80211_init(struct device *dev)
@@ -1620,3 +1708,299 @@ void wil_p2p_wdev_free(struct wil6210_pr
 		kfree(p2p_wdev);
 	}
 }
+
+static int wil_start_acs_survey(struct wil6210_priv *wil, uint dwell_time,
+				struct ieee80211_channel *channels,
+				u8 num_channels)
+{
+	int rc, i;
+	struct {
+		struct wmi_start_scan_cmd cmd;
+		struct {
+			u8 channel;
+			u8 reserved;
+		} channel_list[4];
+	} __packed scan_cmd = {
+		.cmd = {
+			.scan_type = WMI_PASSIVE_SCAN,
+			.dwell_time = cpu_to_le32(dwell_time),
+			.num_channels = min_t(u8, num_channels,
+					      ARRAY_SIZE(wil_60ghz_channels)),
+		},
+	};
+
+	wil->survey_ready = false;
+	memset(&wil->survey_reply, 0, sizeof(wil->survey_reply));
+
+	for (i = 0; i < scan_cmd.cmd.num_channels; i++) {
+		u8 ch = channels[i].hw_value;
+
+		if (ch == 0) {
+			wil_err(wil, "ACS requested for wrong channel\n");
+			return -EINVAL;
+		}
+		wil_dbg_misc(wil, "ACS channel %d : %d MHz\n",
+			     ch, channels[i].center_freq);
+		scan_cmd.channel_list[i].channel = ch - 1;
+	}
+
+	/* send scan command with the requested channel and wait
+	 * for results
+	 */
+	rc = wmi_send(wil, WMI_START_SCAN_CMDID, &scan_cmd, sizeof(scan_cmd));
+	if (rc) {
+		wil_err(wil, "ACS passive Scan failed (0x%08x)\n", rc);
+		return rc;
+	}
+
+	if (wait_event_interruptible_timeout(wil->wq, wil->survey_ready,
+				msecs_to_jiffies(WMI_SURVEY_TIMEOUT_MS)) < 0) {
+		wil_err(wil, "%s: ACS survey interrupted\n", __func__);
+		return -ERESTARTSYS;
+	}
+
+	if (!wil->survey_ready) {
+		wil_err(wil, "ACS survey time out\n");
+		return -ETIME;
+	}
+
+	/* The results in survey_reply */
+	wil_dbg_misc(wil, "ACS scan success, filled mask: 0x%08X\n",
+		     le16_to_cpu(wil->survey_reply.evt.filled));
+
+	return 0;
+}
+
+static u8 wil_acs_calc_channel(struct wil6210_priv *wil)
+{
+	int i, best_channel = ACS_DEFAULT_BEST_CHANNEL - 1;
+	struct scan_acs_info *ch;
+	u64 dwell_time = le32_to_cpu(wil->survey_reply.evt.dwell_time);
+	u16 filled = le16_to_cpu(wil->survey_reply.evt.filled);
+	u8 num_channels = wil->survey_reply.evt.num_scanned_channels;
+	u64 busy_time, tx_time;
+	u64 min_i_ch = (u64)-1, cur_i_ch;
+	u8 p_min = 0, ch_noise;
+
+	wil_dbg_misc(wil, "%s: filled info: 0x%04X, for %u channels\n",
+		     __func__, filled, num_channels);
+
+	if (!num_channels) {
+		wil_err(wil, "%s: received results with no channel info\n",
+			__func__);
+		return 0;
+	}
+
+	/* find P_min */
+	if (filled & WMI_ACS_INFO_BITMASK_NOISE) {
+		p_min = wil->survey_reply.ch_info[0].noise;
+
+		for (i = 1; i < num_channels; i++)
+			p_min = min(p_min, wil->survey_reply.ch_info[i].noise);
+	}
+
+	wil_dbg_misc(wil, "%s: p_min is %u\n", __func__, p_min);
+
+	/* Choosing channel according to the following formula:
+	 * 16 bit fixed point math
+	 * I_ch = { [ (T_busy - T_tx) << 16 ] /
+	 *        (T_dwell - T_tx) } * 2^(P_rx - P_min)
+	 */
+	for (i = 0; i < num_channels; i++) {
+		ch = &wil->survey_reply.ch_info[i];
+
+		if (ch->channel > 3) {
+			wil_err(wil,
+				"%s: invalid channel number %d\n",
+				__func__, ch->channel + 1);
+			continue;
+		}
+
+		busy_time = filled & WMI_ACS_INFO_BITMASK_BUSY_TIME ?
+				le16_to_cpu(ch->busy_time) : 0;
+
+		tx_time = filled & WMI_ACS_INFO_BITMASK_TX_TIME ?
+				le16_to_cpu(ch->tx_time) : 0;
+
+		ch_noise = filled & WMI_ACS_INFO_BITMASK_NOISE ? ch->noise : 0;
+
+		wil_dbg_misc(wil,
+			     "%s: Ch[%d]: busy %llu, tx %llu, noise %u, dwell %llu\n",
+			     __func__, ch->channel + 1, busy_time, tx_time, ch_noise,
+			     dwell_time);
+
+		if (dwell_time == tx_time) {
+			wil_err(wil,
+				"%s: Ch[%d] dwell_time == tx_time: %llu\n",
+				__func__, ch->channel + 1, dwell_time);
+			continue;
+		}
+
+		cur_i_ch = (busy_time - tx_time) << 16;
+		do_div(cur_i_ch,
+		       ((dwell_time - tx_time) << (ch_noise - p_min)));
+
+		/* Apply channel priority */
+		cur_i_ch = (cur_i_ch + ACS_CH_NOISE_INIT_VAL) *
+			   acs_ch_weight[ch->channel];
+		do_div(cur_i_ch, 100);
+
+		wil_dbg_misc(wil, "%s: Ch[%d] w %u, I_ch %llu\n", __func__,
+			     ch->channel + 1, acs_ch_weight[ch->channel], cur_i_ch);
+
+		if (i == 0 || cur_i_ch < min_i_ch) {
+			min_i_ch = cur_i_ch;
+			best_channel = ch->channel;
+		}
+	}
+
+	wil_dbg_misc(wil, "%s: best channel %d with I_ch of %llu\n", __func__,
+		     best_channel + 1, min_i_ch);
+
+	return best_channel;
+}
+
+static void wil_acs_report_channel(struct wil6210_priv *wil)
+{
+	struct sk_buff *vendor_event;
+	int ret_val;
+	struct nlattr *nla;
+	u8 channel = wil_acs_calc_channel(wil);
+
+	vendor_event = cfg80211_vendor_event_alloc(wil_to_wiphy(wil), NULL,
+			2 * sizeof(u8) + 4 + NLMSG_HDRLEN,
+			QCA_NL80211_VENDOR_SUBCMD_DO_ACS_INDEX,
+			GFP_KERNEL);
+	if (!vendor_event) {
+		wil_err(wil, "cfg80211_vendor_event_alloc failed\n");
+		return;
+	}
+
+	/* Send the IF INDEX to differentiate the ACS event for each interface
+	 * TODO: To be update once cfg80211 APIs are updated to accept if_index
+	 */
+	nla_nest_cancel(vendor_event, ((void **)vendor_event->cb)[2]);
+
+	ret_val = nla_put_u32(vendor_event, NL80211_ATTR_IFINDEX,
+			      wil_to_ndev(wil)->ifindex);
+	if (ret_val) {
+		wil_err(wil, "NL80211_ATTR_IFINDEX put fail\n");
+		kfree_skb(vendor_event);
+		return;
+	}
+
+	nla = nla_nest_start(vendor_event, NL80211_ATTR_VENDOR_DATA);
+	((void **)vendor_event->cb)[2] = nla;
+
+	/* channel indices used by fw are zero based and those used upper
+	 * layers are 1 based: must add 1 */
+	ret_val = nla_put_u8(vendor_event,
+			     QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL,
+			     channel + 1);
+	if (ret_val) {
+		wil_err(wil,
+			"QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL put fail\n");
+		kfree_skb(vendor_event);
+		return;
+	}
+
+	/* must report secondary channel always, 0 is harmless*/
+	ret_val = nla_put_u8(vendor_event,
+			     QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL, 0);
+	if (ret_val) {
+		wil_err(wil,
+			"QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL put fail\n");
+		kfree_skb(vendor_event);
+		return;
+	}
+
+	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+}
+
+static int wil_do_acs(struct wiphy *wiphy, struct wireless_dev *wdev,
+		      const void *data, int data_len)
+{
+	struct wil6210_priv *wil = wdev_to_wil(wdev);
+	struct sk_buff *temp_skbuff;
+	int rc;
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1];
+	u8 hw_mode;
+	struct ieee80211_channel reg_channels[ARRAY_SIZE(wil_60ghz_channels)];
+	int num_channels;
+	const struct ieee80211_reg_rule *reg_rule;
+	int i;
+
+	rc = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_MAX, data, data_len,
+		       qca_wlan_acs_vendor_attr);
+	if (rc) {
+		wil_err(wil, "%s: Invalid ATTR\n", __func__);
+		goto out;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]) {
+		wil_err(wil, "%s: Attr hw_mode failed\n", __func__);
+		goto out;
+	}
+
+	hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
+
+	if (hw_mode != QCA_ACS_MODE_IEEE80211AD) {
+		wil_err(wil, "%s: Illegal HW mode (%d), must be %d (11AD)\n",
+			__func__, hw_mode, QCA_ACS_MODE_IEEE80211AD);
+		goto out;
+	}
+
+	/* get list of channels allowed by regulatory */
+	num_channels = 0;
+	for (i = 0; i < ARRAY_SIZE(wil_60ghz_channels); i++) {
+		u32 ch_center_freq =
+				MHZ_TO_KHZ(wil_60ghz_channels[i].center_freq);
+		reg_rule = freq_reg_info(wiphy, ch_center_freq);
+		if (IS_ERR(reg_rule)) {
+			wil_dbg_misc(wil,
+				     "%s: channel %d (%d) reg db err %ld\n",
+				     __func__, wil_60ghz_channels[i].hw_value,
+				     wil_60ghz_channels[i].center_freq,
+				     PTR_ERR(reg_rule));
+			continue;
+		}
+
+		/* we assume if active scan allowed, we can use the
+		 * channel to start AP on it */
+		if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) {
+			reg_channels[num_channels] = wil_60ghz_channels[i];
+			num_channels++;
+			wil_dbg_misc(wil, "%s: Adding ch %d to ACS scan\n",
+				     __func__, wil_60ghz_channels[i].hw_value);
+		} else {
+			wil_dbg_misc(wil,
+				     "%s: channel %d (%d) can't be used: 0x%08X\n",
+				     __func__, wil_60ghz_channels[i].hw_value,
+				     wil_60ghz_channels[i].center_freq,
+				     reg_rule->flags);
+		}
+	}
+
+	if (!num_channels) {
+		wil_err(wil,
+			"ACS aborted. Couldn't find channels allowed by regulatory\n");
+		rc = -EPERM;
+		goto out;
+	}
+
+	/* start acs survey*/
+	rc = wil_start_acs_survey(wil, scan_dwell_time, reg_channels,
+				  num_channels);
+
+	if (!rc)
+		wil_acs_report_channel(wil);
+out:
+	if (0 == rc) {
+		temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
+								  NLMSG_HDRLEN);
+		if (temp_skbuff != NULL)
+			return cfg80211_vendor_cmd_reply(temp_skbuff);
+	}
+	return rc;
+}
+
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -1603,6 +1603,65 @@ static const struct file_operations fops
 	.llseek		= seq_lseek,
 };
 
+/*---------Survey results------------*/
+static int wil_survey_debugfs_show(struct seq_file *s, void *data)
+{
+	struct wil6210_priv *wil = s->private;
+	int i, n_ch;
+	u16 filled;
+
+	if (!wil->survey_ready) {
+		seq_puts(s, "Survey not ready\n");
+		return 0;
+	}
+	seq_printf(s, "dwell_time : %d\n",
+		   le32_to_cpu(wil->survey_reply.evt.dwell_time));
+	filled = le16_to_cpu(wil->survey_reply.evt.filled);
+	n_ch = min_t(int, wil->survey_reply.evt.num_scanned_channels,
+		     ARRAY_SIZE(wil->survey_reply.ch_info));
+
+#define ACS_FILLED(x) (filled & WMI_ACS_INFO_BITMASK_ ## x) ? \
+	" " __stringify(x) : ""
+	seq_printf(s, "Filled : 0x%04x%s%s%s%s%s\n", filled,
+		   ACS_FILLED(BEACON_FOUND),
+		   ACS_FILLED(BUSY_TIME),
+		   ACS_FILLED(TX_TIME),
+		   ACS_FILLED(RX_TIME),
+		   ACS_FILLED(NOISE)
+		  );
+#undef ACS_FILLED
+	seq_printf(s, "Channels [%d] {\n", n_ch);
+	for (i = 0; i < n_ch; i++) {
+		struct scan_acs_info *ch = &wil->survey_reply.ch_info[i];
+
+		seq_printf(s, "  [%d]", ch->channel);
+#define ACS_PRINT(x, str, field) do { if (filled & WMI_ACS_INFO_BITMASK_ ## x) \
+		seq_printf(s, " %s : %d", str, field); \
+	} while (0)
+		ACS_PRINT(BEACON_FOUND, "bcon", ch->beacon_found);
+		ACS_PRINT(BUSY_TIME, "busy", le16_to_cpu(ch->busy_time));
+		ACS_PRINT(TX_TIME, "tx", le16_to_cpu(ch->tx_time));
+		ACS_PRINT(RX_TIME, "rx", le16_to_cpu(ch->rx_time));
+		ACS_PRINT(NOISE, "noise", ch->noise);
+#undef ACS_PRINT
+		seq_puts(s, "\n");
+	}
+	seq_puts(s, "}\n");
+	return 0;
+}
+
+static int wil_survey_seq_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, wil_survey_debugfs_show, inode->i_private);
+}
+
+static const struct file_operations fops_survey = {
+	.open		= wil_survey_seq_open,
+	.release	= single_release,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+};
+
 /*----------------*/
 static void wil6210_debugfs_init_blobs(struct wil6210_priv *wil,
 				       struct dentry *dbg)
@@ -1655,6 +1714,7 @@ static const struct {
 	{"led_blink_time",	S_IRUGO | S_IWUSR,	&fops_led_blink_time},
 	{"fw_capabilities",	S_IRUGO,	&fops_fw_capabilities},
 	{"fw_version",	S_IRUGO,		&fops_fw_version},
+	{"survey",      S_IRUGO,                &fops_survey},
 };
 
 static void wil6210_debugfs_init_files(struct wil6210_priv *wil,
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -673,6 +673,11 @@ struct wil6210_priv {
 #if defined(CPTCFG_WIL6210_NSS_SUPPORT)
 	void *nss_ctx;
 #endif
+	bool survey_ready;
+	struct {
+		struct wmi_acs_passive_scan_complete_event evt;
+		struct scan_acs_info ch_info[4];
+	} __packed survey_reply;
 
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM_SLEEP
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -462,6 +462,27 @@ static void wmi_evt_scan_complete(struct
 	mutex_unlock(&wil->p2p_wdev_mutex);
 }
 
+static void wmi_evt_survey_complete(struct wil6210_priv *wil, int id,
+		  void *d, int len)
+{
+	struct wmi_acs_passive_scan_complete_event *evt =
+			(struct wmi_acs_passive_scan_complete_event *)d;
+
+	int expected_size = sizeof(struct wmi_acs_passive_scan_complete_event) +
+			    evt->num_scanned_channels *
+			    sizeof(struct scan_acs_info);
+
+	if (len < expected_size) {
+		wil_err(wil, "Survey event size is too small (%d): expected %d channels\n",
+			len, evt->num_scanned_channels);
+		return;
+	}
+
+	memcpy(&wil->survey_reply, d, sizeof(wil->survey_reply));
+	wil->survey_ready = true;
+	wake_up_interruptible(&wil->wq);
+}
+
 static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
 {
 	struct net_device *ndev = wil_to_ndev(wil);
@@ -804,18 +825,19 @@ static const struct {
 	void (*handler)(struct wil6210_priv *wil, int eventid,
 			void *data, int data_len);
 } wmi_evt_handlers[] = {
-	{WMI_READY_EVENTID,		wmi_evt_ready},
+	{WMI_READY_EVENTID,			wmi_evt_ready},
 	{WMI_FW_READY_EVENTID,			wmi_evt_ignore},
-	{WMI_RX_MGMT_PACKET_EVENTID,	wmi_evt_rx_mgmt},
+	{WMI_RX_MGMT_PACKET_EVENTID,		wmi_evt_rx_mgmt},
 	{WMI_TX_MGMT_PACKET_EVENTID,		wmi_evt_tx_mgmt},
-	{WMI_SCAN_COMPLETE_EVENTID,	wmi_evt_scan_complete},
-	{WMI_CONNECT_EVENTID,		wmi_evt_connect},
-	{WMI_DISCONNECT_EVENTID,	wmi_evt_disconnect},
-	{WMI_EAPOL_RX_EVENTID,		wmi_evt_eapol_rx},
-	{WMI_BA_STATUS_EVENTID,		wmi_evt_ba_status},
-	{WMI_RCP_ADDBA_REQ_EVENTID,	wmi_evt_addba_rx_req},
-	{WMI_DELBA_EVENTID,		wmi_evt_delba},
-	{WMI_VRING_EN_EVENTID,		wmi_evt_vring_en},
+	{WMI_SCAN_COMPLETE_EVENTID,		wmi_evt_scan_complete},
+	{WMI_ACS_PASSIVE_SCAN_COMPLETE_EVENTID, wmi_evt_survey_complete},
+	{WMI_CONNECT_EVENTID,			wmi_evt_connect},
+	{WMI_DISCONNECT_EVENTID,		wmi_evt_disconnect},
+	{WMI_EAPOL_RX_EVENTID,			wmi_evt_eapol_rx},
+	{WMI_BA_STATUS_EVENTID,			wmi_evt_ba_status},
+	{WMI_RCP_ADDBA_REQ_EVENTID,		wmi_evt_addba_rx_req},
+	{WMI_DELBA_EVENTID,			wmi_evt_delba},
+	{WMI_VRING_EN_EVENTID,			wmi_evt_vring_en},
 	{WMI_DATA_PORT_OPEN_EVENTID,		wmi_evt_ignore},
 };
 
--- a/drivers/net/wireless/ath/wil6210/wmi.h
+++ b/drivers/net/wireless/ath/wil6210/wmi.h
@@ -35,7 +35,9 @@
 #define WMI_MAC_LEN			(6)
 #define WMI_PROX_RANGE_NUM		(3)
 #define WMI_MAX_LOSS_DMG_BEACONS	(20)
+#define WMI_SCAN_DWELL_TIME_MS		(100)
 #define MAX_NUM_OF_SECTORS		(128)
+#define WMI_SURVEY_TIMEOUT_MS		(10000)
 
 /* Mailbox interface
  * used for commands and events
