Sfoglia il codice sorgente

qcacld-3.0: Add changes to collect channel info from regulatory

Vendor ACS requires regulatory channel info for each channel.

Add changes to collect channel information of each channel
and save it in sap config.

Change-Id: Ib96c3f7ddfc8476306e9a13127472be9dd0a9488
CRs-Fixed: 1110061
Kapil Gupta 8 anni fa
parent
commit
086c6206de

+ 47 - 2
core/cds/inc/cds_reg_service.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -391,6 +391,41 @@ QDF_STATUS cds_get_channel_list_with_power(struct channel_power
 enum channel_enum cds_get_channel_enum(uint32_t chan_num);
 
 enum channel_state cds_get_channel_state(uint32_t chan_num);
+
+/**
+ * cds_get_channel_reg_power() - get max power based on regulatory
+ * @chan_num: channel number
+ *
+ * Return: tx power
+ */
+int8_t cds_get_channel_reg_power(uint32_t chan_num);
+
+/**
+ * cds_get_channel_flags() - This API returns regulatory channel flags
+ * @chan_num: channel number
+ *
+ * Return: channel flags
+ */
+uint32_t cds_get_channel_flags(uint32_t chan_num);
+
+/**
+ * cds_get_vendor_reg_flags() - This API returns vendor specific regulatory
+ * channel flags
+ * @chan_num: channel number
+ *
+ * Return: channel flags
+ */
+uint32_t cds_get_vendor_reg_flags(uint32_t chan, uint16_t bandwidth,
+				bool is_ht_enabled, bool is_vht_enabled,
+				uint8_t is_sub_20_channel_width);
+
+/**
+ * cds_get_channel_freq() - This API returns frequency for channel
+ * @chan_num: channel number
+ *
+ * Return: frequency
+ */
+uint32_t cds_get_channel_freq(uint32_t chan_num);
 QDF_STATUS cds_get_dfs_region(enum dfs_region *dfs_reg);
 QDF_STATUS cds_put_dfs_region(enum dfs_region dfs_reg);
 
@@ -401,7 +436,17 @@ enum channel_state cds_get_5g_bonded_channel_state(uint16_t chan_num,
 enum channel_state cds_get_2g_bonded_channel_state(uint16_t chan_num,
 						   enum phy_ch_width chan_width,
 						   uint16_t sec_ch);
-
+/**
+ * cds_get_2g_bonded_channel_state() - get the channel bonded channel state
+ * @oper_ch: operating channel
+ * @ch_width: channel width
+ * @sec_ch: secondary channel
+ *
+ * Return: channel state
+ */
+enum channel_state cds_get_bonded_channel_state(uint16_t oper_ch,
+						enum phy_ch_width ch_width,
+						uint16_t sec_ch);
 void cds_set_channel_params(uint16_t oper_ch, uint16_t ht_offset_2g,
 			    struct ch_params_s *ch_params);
 

+ 9 - 1
core/cds/src/cds_ieee80211_common_i.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -226,6 +226,14 @@ enum ieee80211_scanmode {
 #define IEEE80211_CHAN_VHT40PLUS        0x00200000      /* VHT 40 with extension channel above */
 #define IEEE80211_CHAN_VHT40MINUS       0x00400000      /* VHT 40 with extension channel below */
 #define IEEE80211_CHAN_VHT80            0x00800000      /* VHT 80 channel */
+/* HT 40 Intolerant mark bit for ACS use */
+#define IEEE80211_CHAN_HT40INTOLMARK    0x01000000
+/* channel temporarily blocked due to noise */
+#define IEEE80211_CHAN_BLOCKED          0x02000000
+/* VHT 160 channel */
+#define IEEE80211_CHAN_VHT160           0x04000000
+/* VHT 80_80 channel */
+#define IEEE80211_CHAN_VHT80_80         0x08000000
 
 /* flagext */
 #define IEEE80211_CHAN_RADAR_FOUND    0x01

+ 149 - 1
core/cds/src/cds_reg_service.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -37,6 +37,7 @@
 #include "cds_api.h"
 #include "cds_reg_service.h"
 #include "cds_regdomain.h"
+#include "cds_ieee80211_common_i.h"
 #include "sme_api.h"
 
 const struct chan_map chan_mapping[NUM_CHANNELS] = {
@@ -241,6 +242,141 @@ enum channel_state cds_get_channel_state(uint32_t chan_num)
 		return reg_channels[chan_enum].state;
 }
 
+int8_t cds_get_channel_reg_power(uint32_t chan_num)
+{
+	enum channel_enum chan_enum;
+
+	chan_enum = cds_get_channel_enum(chan_num);
+	if (chan_enum == INVALID_CHANNEL)
+		return CHANNEL_STATE_INVALID;
+	else
+		return reg_channels[chan_enum].pwr_limit;
+}
+
+uint32_t cds_get_channel_flags(uint32_t chan_num)
+{
+	enum channel_enum chan_enum;
+
+	chan_enum = cds_get_channel_enum(chan_num);
+	if (chan_enum == INVALID_CHANNEL)
+		return CHANNEL_STATE_INVALID;
+	else
+		return reg_channels[chan_enum].flags;
+}
+
+uint32_t cds_get_vendor_reg_flags(uint32_t chan, uint16_t bandwidth,
+				bool is_ht_enabled, bool is_vht_enabled,
+				uint8_t sub_20_channel_width)
+{
+	uint32_t flags = 0;
+	enum channel_state state;
+	struct ch_params_s ch_params;
+
+	state = cds_get_channel_state(chan);
+	if (state == CHANNEL_STATE_INVALID)
+		return flags;
+	if (state == CHANNEL_STATE_DFS) {
+		flags |= IEEE80211_CHAN_PASSIVE;
+		flags |= IEEE80211_CHAN_DFS;
+	}
+	if (state == CHANNEL_STATE_DISABLE)
+		flags |= IEEE80211_CHAN_BLOCKED;
+
+	if (CDS_IS_CHANNEL_24GHZ(chan)) {
+		if ((bandwidth == CH_WIDTH_80P80MHZ) ||
+			(bandwidth == CH_WIDTH_160MHZ) ||
+			(bandwidth == CH_WIDTH_80MHZ)) {
+			bandwidth = CH_WIDTH_40MHZ;
+		}
+	}
+
+	switch (bandwidth) {
+
+	case CH_WIDTH_80P80MHZ:
+		if (cds_get_5g_bonded_channel_state(chan,
+				  bandwidth) != CHANNEL_STATE_INVALID) {
+			if (is_vht_enabled)
+				flags |= IEEE80211_CHAN_VHT80_80;
+		}
+		bandwidth = CH_WIDTH_160MHZ;
+		/* FALLTHROUGH */
+	case CH_WIDTH_160MHZ:
+		if (cds_get_5g_bonded_channel_state(chan,
+				  bandwidth) != CHANNEL_STATE_INVALID) {
+			if (is_vht_enabled)
+				flags |= IEEE80211_CHAN_VHT160;
+		}
+		bandwidth = CH_WIDTH_80MHZ;
+		/* FALLTHROUGH */
+	case CH_WIDTH_80MHZ:
+		if (cds_get_5g_bonded_channel_state(chan,
+				  bandwidth) != CHANNEL_STATE_INVALID) {
+			if (is_vht_enabled)
+				flags |= IEEE80211_CHAN_VHT80;
+		}
+		bandwidth = CH_WIDTH_40MHZ;
+		/* FALLTHROUGH */
+	case CH_WIDTH_40MHZ:
+		qdf_mem_zero(&ch_params, sizeof(ch_params));
+		ch_params.ch_width = bandwidth;
+		cds_set_channel_params(chan, 0, &ch_params);
+
+		if (cds_get_bonded_channel_state(chan, bandwidth,
+		    ch_params.sec_ch_offset) != CHANNEL_STATE_INVALID) {
+			if (ch_params.sec_ch_offset ==
+			    PHY_DOUBLE_CHANNEL_LOW_PRIMARY) {
+				flags |= IEEE80211_CHAN_HT40PLUS;
+				if (is_vht_enabled)
+					flags |= IEEE80211_CHAN_VHT40PLUS;
+			} else if (ch_params.sec_ch_offset ==
+				   PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) {
+				flags |= IEEE80211_CHAN_HT40MINUS;
+				if (is_vht_enabled)
+					flags |= IEEE80211_CHAN_VHT40MINUS;
+			}
+		}
+
+		bandwidth = CH_WIDTH_20MHZ;
+		/* FALLTHROUGH */
+	case CH_WIDTH_20MHZ:
+		if (is_vht_enabled)
+			flags |= IEEE80211_CHAN_VHT20;
+		if (is_ht_enabled)
+			flags |= IEEE80211_CHAN_HT20;
+		bandwidth = CH_WIDTH_10MHZ;
+		/* FALLTHROUGH */
+	case CH_WIDTH_10MHZ:
+		if ((cds_get_bonded_channel_state(chan,
+			bandwidth, 0) != CHANNEL_STATE_INVALID) &&
+			(sub_20_channel_width ==
+				WLAN_SUB_20_CH_WIDTH_10))
+			flags |= IEEE80211_CHAN_HALF;
+		/* FALLTHROUGH */
+	case CH_WIDTH_5MHZ:
+		if ((cds_get_bonded_channel_state(chan,
+			bandwidth, 0) != CHANNEL_STATE_INVALID) &&
+			(sub_20_channel_width ==
+				WLAN_SUB_20_CH_WIDTH_5))
+			flags |= IEEE80211_CHAN_QUARTER;
+		break;
+	default:
+	QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
+		"invalid channel width value %d", bandwidth);
+	}
+
+	return flags;
+}
+
+uint32_t cds_get_channel_freq(uint32_t chan_num)
+{
+	enum channel_enum chan_enum;
+
+	chan_enum = cds_get_channel_enum(chan_num);
+	if (chan_enum == INVALID_CHANNEL)
+		return CHANNEL_STATE_INVALID;
+	else
+		return chan_mapping[chan_enum].center_freq;
+}
 
 /**
  * cds_search_5g_bonded_chan_array() - get ptr to bonded channel
@@ -324,6 +460,18 @@ static enum channel_state cds_search_5g_bonded_channel(uint32_t chan_num,
 		return cds_get_channel_state(chan_num);
 }
 
+enum channel_state cds_get_bonded_channel_state(uint16_t oper_ch,
+						enum phy_ch_width ch_width,
+						uint16_t sec_ch)
+{
+	if (CDS_IS_CHANNEL_5GHZ(oper_ch))
+		return cds_get_5g_bonded_channel_state(oper_ch,
+							ch_width);
+	else
+		return cds_get_2g_bonded_channel_state(oper_ch,
+							ch_width, sec_ch);
+}
+
 /**
  * cds_get_2g_bonded_channel_state() - get the 2G bonded channel state
  * @oper_ch: operating channel

+ 31 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -1611,6 +1611,34 @@ struct hdd_context_s {
 	uint8_t beacon_probe_rsp_cnt_per_scan;
 };
 
+/**
+ * struct  hdd_channel_info - standard channel info
+ * @freq: Freq in Mhz
+ * @flags: channel info flags
+ * @flagext: extended channel info flags
+ * @ieee_chan_number: channel number
+ * @max_reg_power: max tx power according to regulatory
+ * @max_radio_power: max radio power
+ * @min_radio_power: min radio power
+ * @reg_class_id: regulatory class
+ * @max_antenna_gain: max antenna gain allowed on channel
+ * @vht_center_freq_seg0: vht center freq segment 0
+ * @vht_center_freq_seg1: vht center freq segment 1
+ */
+struct hdd_channel_info {
+	u_int16_t freq;
+	u_int32_t flags;
+	u_int16_t flagext;
+	u_int8_t ieee_chan_number;
+	int8_t max_reg_power;
+	int8_t max_radio_power;
+	int8_t min_radio_power;
+	u_int8_t reg_class_id;
+	u_int8_t max_antenna_gain;
+	u_int8_t vht_center_freq_seg0;
+	u_int8_t vht_center_freq_seg1;
+};
+
 /*
  * Function declarations and documentation
  */
@@ -2031,6 +2059,9 @@ int hdd_enable_disable_ca_event(hdd_context_t *hddctx,
 				uint8_t set_value);
 void wlan_hdd_undo_acs(hdd_adapter_t *adapter);
 
+int hdd_update_reg_chan_info(hdd_adapter_t *adapter,
+			uint32_t channel_count,
+			uint8_t *channel_list);
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0))
 static inline int
 hdd_wlan_nla_put_u64(struct sk_buff *skb, int attrtype, u64 value)

+ 172 - 0
core/hdd/src/wlan_hdd_cfg80211.c

@@ -1389,6 +1389,178 @@ static int wlan_hdd_cfg80211_start_acs(hdd_adapter_t *adapter)
 	return 0;
 }
 
+/**
+ * hdd_update_reg_chan_info : This API contructs channel info
+ * for all the given channel
+ * @adapter: pointer to SAP adapter struct
+ * @channel_count: channel count
+ * @channel_list: channel list
+ *
+ * Return: Status of of channel information updation
+ */
+int hdd_update_reg_chan_info(hdd_adapter_t *adapter,
+			uint32_t channel_count,
+			uint8_t *channel_list)
+{
+	int i;
+	struct hdd_channel_info *icv;
+	struct ch_params_s ch_params;
+	uint8_t bw_offset = 0, chan = 0;
+	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	tsap_Config_t *sap_config = &adapter->sessionCtx.ap.sapConfig;
+
+	/* memory allocation */
+	sap_config->channel_info = qdf_mem_malloc(
+					sizeof(struct hdd_channel_info) *
+					channel_count);
+	if (!sap_config->channel_info) {
+		hdd_err("memory allocation failed");
+		return -ENOMEM;
+
+	}
+	for (i = 0; i < channel_count; i++) {
+		icv = &sap_config->channel_info[i];
+		chan = channel_list[i];
+
+		if (chan == 0)
+			continue;
+
+		if (sap_config->acs_cfg.ch_width == CH_WIDTH_40MHZ)
+			bw_offset = 1 << BW_40_OFFSET_BIT;
+		else if (sap_config->acs_cfg.ch_width == CH_WIDTH_20MHZ)
+			bw_offset = 1 << BW_20_OFFSET_BIT;
+		icv->freq = cds_get_channel_freq(chan);
+		icv->ieee_chan_number = chan;
+		icv->max_reg_power = cds_get_channel_reg_power(chan);
+
+		/* filling demo values */
+		icv->max_radio_power = HDD_MAX_TX_POWER;
+		icv->min_radio_power = HDD_MIN_TX_POWER;
+		/* not supported in current driver */
+		icv->max_antenna_gain = 0;
+
+		icv->reg_class_id = wlan_hdd_find_opclass(
+					WLAN_HDD_GET_HAL_CTX(adapter),
+					chan, bw_offset);
+
+		if (CDS_IS_CHANNEL_5GHZ(chan)) {
+			ch_params.ch_width = sap_config->acs_cfg.ch_width;
+			cds_set_channel_params(chan, 0, &ch_params);
+			icv->vht_center_freq_seg0 = ch_params.center_freq_seg0;
+			icv->vht_center_freq_seg1 = ch_params.center_freq_seg1;
+		}
+		icv->flags = 0;
+		icv->flags = cds_get_vendor_reg_flags(chan,
+				sap_config->acs_cfg.ch_width,
+				sap_config->acs_cfg.is_ht_enabled,
+				sap_config->acs_cfg.is_vht_enabled,
+				hdd_ctx->config->enable_sub_20_channel_width);
+
+		hdd_info("freq %d flags %d flagext %d ieee %d maxreg %d maxpw %d minpw %d regClass %d antenna %d seg0 %d seg1 %d",
+			icv->freq, icv->flags,
+			icv->flagext, icv->ieee_chan_number,
+			icv->max_reg_power, icv->max_radio_power,
+			icv->min_radio_power, icv->reg_class_id,
+			icv->max_antenna_gain, icv->vht_center_freq_seg0,
+			icv->vht_center_freq_seg1);
+	}
+	return 0;
+}
+
+/* Short name for QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_CHAN_INFO event */
+#define CHAN_INFO_ATTR_FLAGS \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAGS
+#define CHAN_INFO_ATTR_FLAG_EXT \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAG_EXT
+#define CHAN_INFO_ATTR_FREQ \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ
+#define CHAN_INFO_ATTR_MAX_REG_POWER \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX_REG_POWER
+#define CHAN_INFO_ATTR_MAX_POWER \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX_POWER
+#define CHAN_INFO_ATTR_MIN_POWER \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MIN_POWER
+#define CHAN_INFO_ATTR_REG_CLASS_ID \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_REG_CLASS_ID
+#define CHAN_INFO_ATTR_ANTENNA_GAIN \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_ANTENNA_GAIN
+#define CHAN_INFO_ATTR_VHT_SEG_0 \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_0
+#define CHAN_INFO_ATTR_VHT_SEG_1 \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_1
+
+/**
+ * hdd_cfg80211_update_channel_info() - add channel info attributes
+ * @skb: pointer to sk buff
+ * @hdd_ctx: pointer to hdd station context
+ * @idx: attribute index
+ *
+ * Return: Success(0) or reason code for failure
+ */
+int32_t
+hdd_cfg80211_update_channel_info(struct sk_buff *skb,
+			   tsap_Config_t *sap_config, int idx)
+{
+	struct nlattr *nla_attr, *channel;
+	struct hdd_channel_info *icv;
+	int i;
+
+	nla_attr = nla_nest_start(skb, idx);
+	if (!nla_attr)
+		goto fail;
+
+	for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++) {
+		channel = nla_nest_start(skb, i);
+		if (!channel)
+			goto fail;
+
+		icv = &sap_config->channel_info[i];
+		if (!icv) {
+			hdd_err("channel info not found");
+			goto fail;
+		}
+		if (nla_put_u16(skb, CHAN_INFO_ATTR_FREQ,
+				icv->freq) ||
+		    nla_put_u32(skb, CHAN_INFO_ATTR_FLAGS,
+				icv->flags) ||
+		    nla_put_u16(skb, CHAN_INFO_ATTR_FLAG_EXT,
+				icv->flagext) ||
+		    nla_put_u8(skb, CHAN_INFO_ATTR_MAX_REG_POWER,
+				icv->max_reg_power) ||
+		    nla_put_u8(skb, CHAN_INFO_ATTR_MAX_POWER,
+				icv->max_radio_power) ||
+		    nla_put_u8(skb, CHAN_INFO_ATTR_MIN_POWER,
+				icv->min_radio_power) ||
+		    nla_put_u8(skb, CHAN_INFO_ATTR_REG_CLASS_ID,
+				icv->reg_class_id) ||
+		    nla_put_u8(skb, CHAN_INFO_ATTR_ANTENNA_GAIN,
+				icv->max_antenna_gain) ||
+		    nla_put_u8(skb, CHAN_INFO_ATTR_VHT_SEG_0,
+				icv->vht_center_freq_seg0) ||
+		    nla_put_u8(skb, CHAN_INFO_ATTR_VHT_SEG_1,
+				icv->vht_center_freq_seg1)) {
+			hdd_err("put fail");
+			goto fail;
+		}
+		nla_nest_end(skb, channel);
+	}
+	nla_nest_end(skb, nla_attr);
+	return 0;
+fail:
+	hdd_err("nl channel update failed");
+	return -EINVAL;
+}
+#undef CHAN_INFO_ATTR_FLAGS
+#undef CHAN_INFO_ATTR_FLAG_EXT
+#undef CHAN_INFO_ATTR_FREQ
+#undef CHAN_INFO_ATTR_MAX_REG_POWER
+#undef CHAN_INFO_ATTR_MAX_POWER
+#undef CHAN_INFO_ATTR_MIN_POWER
+#undef CHAN_INFO_ATTR_REG_CLASS_ID
+#undef CHAN_INFO_ATTR_ANTENNA_GAIN
+#undef CHAN_INFO_ATTR_VHT_SEG_0
+#undef CHAN_INFO_ATTR_VHT_SEG_1
+
 /**
  * __wlan_hdd_cfg80211_do_acs : CFG80211 handler function for DO_ACS Vendor CMD
  * @wiphy:  Linux wiphy struct pointer

+ 44 - 0
core/hdd/src/wlan_hdd_cfg80211.h

@@ -2689,6 +2689,50 @@ enum qca_wlan_vendor_attr_rssi_monitoring {
 		QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_AFTER_LAST - 1,
 };
 
+/**
+ * qca_wlan_vendor_external_acs_event_chan_info_attr: Represents per channel
+ * information. These attributes are sent as part of
+ * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_CHAN_INFO. Each set of the following
+ * attributes correspond to a single channel.
+ * @QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAGS: A bitmask (u16)
+ * with flags specified in qca_wlan_vendor_channel_prop_flags_ext.
+ * @QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAG_EXT: A bitmask (u16)
+ * with flags specified in qca_wlan_vendor_channel_prop_flags_ext.
+ * @QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ: frequency
+ * @QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX_REG_POWER: maximum
+ * regulatory transmission power
+ * @QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX_POWER: maximum
+ * transmission power
+ * @QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MIN_POWER: minimum
+ * transmission power
+ * @QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_REG_CLASS_ID: regulatory
+ * class id
+ * @QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_ANTENNA_GAIN: maximum
+ * antenna gain in dbm
+ * @QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_0: vht segment 0
+ * @QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_1: vht segment 1
+ *
+ */
+enum qca_wlan_vendor_external_acs_event_chan_info_attr {
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_INVALID = 0,
+
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAGS = 1,
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAG_EXT = 2,
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ = 3,
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX_REG_POWER = 4,
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX_POWER = 5,
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MIN_POWER = 6,
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_REG_CLASS_ID = 7,
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_ANTENNA_GAIN = 8,
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_0 = 9,
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_1 = 10,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_LAST,
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX =
+		QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_LAST - 1,
+};
+
 /**
  * enum set_reset_packet_filter - set packet filter control commands
  * @QCA_WLAN_SET_PACKET_FILTER: Set Packet Filter

+ 3 - 0
core/sap/inc/sap_api.h

@@ -498,6 +498,8 @@ struct sap_acs_cfg {
 	uint16_t   ch_width;
 	uint8_t    pcl_channels[QDF_MAX_NUM_CHAN];
 	uint32_t   pcl_ch_count;
+	uint8_t    is_ht_enabled;
+	uint8_t    is_vht_enabled;
 	/* ACS Algo Output */
 	uint8_t    pri_ch;
 	uint8_t    ht_sec_ch;
@@ -603,6 +605,7 @@ typedef struct sap_Config {
 	tSirMacRateSet supported_rates;
 	tSirMacRateSet extended_rates;
 	enum sap_acs_dfs_mode acs_dfs_mode;
+	struct hdd_channel_info *channel_info;
 } tsap_Config_t;
 
 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE

+ 8 - 4
core/wma/inc/wma_dfs_interface.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -73,10 +73,14 @@
 #define IEEE80211_CHAN_VHT40MINUS       0x00400000
 /* VHT 80 channel */
 #define IEEE80211_CHAN_VHT80            0x00800000
-/* VHT 80+80 Channel */
-#define IEEE80211_CHAN_VHT80P80         0x01000000
+/* HT 40 Intolerant mark bit for ACS use */
+#define IEEE80211_CHAN_HT40INTOLMARK    0x01000000
+/* channel temporarily blocked due to noise */
+#define IEEE80211_CHAN_BLOCKED          0x02000000
 /* VHT 160 Channel */
-#define IEEE80211_CHAN_VHT160           0x02000000
+#define IEEE80211_CHAN_VHT160           0x04000000
+/* VHT 80+80 Channel */
+#define IEEE80211_CHAN_VHT80P80         0x08000000
 
 /* token for ``any channel'' */
 #define DFS_IEEE80211_CHAN_ANY      (-1)