瀏覽代碼

qcacld-3.0: Changes to correct channel flags for vendor ACS

In the reg channel info which is sent to external channel
selection daemon, Some channel flags are missing which causes
application to select wrong channel.

Add changes to correct channel flags.

Change-Id: I80834dd7f5f4bfbd2fce88084a938356a741140c
CRs-Fixed: 2068354
Kapil Gupta 7 年之前
父節點
當前提交
c1224bf234

+ 13 - 3
core/cds/src/cds_reg_service.c

@@ -46,13 +46,13 @@ uint32_t cds_get_vendor_reg_flags(struct wlan_objmgr_pdev *pdev,
 	uint32_t flags = 0;
 	enum channel_state state;
 	struct ch_params ch_params;
+	int sec_channel;
 
 	state = wlan_reg_get_channel_state(pdev, 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;
@@ -63,7 +63,9 @@ uint32_t cds_get_vendor_reg_flags(struct wlan_objmgr_pdev *pdev,
 		    (bandwidth == CH_WIDTH_80MHZ)) {
 			bandwidth = CH_WIDTH_40MHZ;
 		}
-	}
+		flags |= IEEE80211_CHAN_2GHZ;
+	} else
+		flags |= IEEE80211_CHAN_5GHZ;
 
 	switch (bandwidth) {
 	case CH_WIDTH_80P80MHZ:
@@ -95,8 +97,15 @@ uint32_t cds_get_vendor_reg_flags(struct wlan_objmgr_pdev *pdev,
 		ch_params.ch_width = bandwidth;
 		wlan_reg_set_channel_params(pdev, chan, 0, &ch_params);
 
+		if (ch_params.sec_ch_offset == LOW_PRIMARY_CH)
+			sec_channel = chan + 4;
+		else if (ch_params.sec_ch_offset == HIGH_PRIMARY_CH)
+			sec_channel = chan - 4;
+		else
+			sec_channel = 0;
+
 		if (wlan_reg_get_bonded_channel_state(pdev, chan, bandwidth,
-					ch_params.sec_ch_offset) !=
+					sec_channel) !=
 				CHANNEL_STATE_INVALID) {
 			if (ch_params.sec_ch_offset == LOW_PRIMARY_CH) {
 				flags |= IEEE80211_CHAN_HT40PLUS;
@@ -124,6 +133,7 @@ uint32_t cds_get_vendor_reg_flags(struct wlan_objmgr_pdev *pdev,
 				(sub_20_channel_width ==
 				 WLAN_SUB_20_CH_WIDTH_10))
 			flags |= IEEE80211_CHAN_HALF;
+		bandwidth = CH_WIDTH_5MHZ;
 	/* FALLTHROUGH */
 	case CH_WIDTH_5MHZ:
 		if ((wlan_reg_get_bonded_channel_state(pdev, chan, bandwidth,

+ 22 - 11
core/hdd/src/wlan_hdd_cfg80211.c

@@ -1706,6 +1706,8 @@ static int hdd_update_reg_chan_info(hdd_adapter_t *adapter,
 				sap_config->acs_cfg.is_ht_enabled,
 				sap_config->acs_cfg.is_vht_enabled,
 				hdd_ctx->config->enable_sub_20_channel_width);
+		if (icv->flags & IEEE80211_CHAN_PASSIVE)
+			icv->flagext |= IEEE80211_CHAN_DFS;
 
 		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,
@@ -1863,12 +1865,12 @@ static void hdd_get_scan_band(hdd_context_t *hdd_ctx,
 	int i, temp_count = 0;
 	int acs_list_count = sap_config->acs_cfg.ch_list_count;
 	/* Get scan band */
-	if ((sap_config->acs_cfg.hw_mode == QCA_ACS_MODE_IEEE80211B) ||
-	   (sap_config->acs_cfg.hw_mode == QCA_ACS_MODE_IEEE80211G)) {
+	if ((sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211B) ||
+	   (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211G)) {
 		*band = eCSR_BAND_24;
-	} else if (sap_config->acs_cfg.hw_mode == QCA_ACS_MODE_IEEE80211A) {
+	} else if (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211A) {
 		*band = eCSR_BAND_5G;
-	} else if (sap_config->acs_cfg.hw_mode == QCA_ACS_MODE_IEEE80211ANY) {
+	} else if (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211ANY) {
 		*band = eCSR_BAND_ALL;
 	}
 	/* Auto is not supported currently */
@@ -1956,7 +1958,7 @@ void hdd_cfg80211_update_acs_config(hdd_adapter_t *adapter,
 	hdd_update_reg_chan_info(adapter, channel_count, channel_list);
 	hdd_get_freq_list(channel_list, freq_list, channel_count);
 	/* Get phymode */
-	phy_mode = sme_get_phy_mode(WLAN_HDD_GET_HAL_CTX(adapter));
+	phy_mode = adapter->sessionCtx.ap.sapConfig.acs_cfg.hw_mode;
 
 	skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
 			&(adapter->wdev),
@@ -2161,6 +2163,7 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
 		goto out;
 	}
 	hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
+	/* This value will be overwritten in wlan_hdd_set_acs_ch_range */
 	sap_config->acs_cfg.hw_mode = hw_mode;
 
 	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED])
@@ -2175,6 +2178,7 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
 	else
 		ht40_enabled = 0;
 
+	hdd_debug("ht40_enabled %d", ht40_enabled);
 	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED])
 		vht_enabled =
 			nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED]);
@@ -2203,6 +2207,7 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
 			ch_width = 20;
 	}
 
+	hdd_debug("channel width =%d", ch_width);
 	if (ch_width == 80)
 		sap_config->acs_cfg.ch_width = CH_WIDTH_80MHZ;
 	else if (ch_width == 40)
@@ -2277,28 +2282,34 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
 				  pcl_channels_weight_list[i]);
 		}
 
+	wlan_hdd_set_acs_ch_range(sap_config, ht_enabled, vht_enabled);
 	/* ACS override for android */
+
+	sap_config->acs_cfg.band = hw_mode;
 	if (hdd_ctx->config->sap_p2p_11ac_override && ht_enabled &&
 	    !hdd_ctx->config->sap_force_11n_for_11ac) {
-		hdd_debug("ACS Config override for 11AC");
+		hdd_debug("ACS Config override for 11AC vhtChannelWidth %d",
+			hdd_ctx->config->vhtChannelWidth);
 		vht_enabled = 1;
 		sap_config->acs_cfg.hw_mode = eCSR_DOT11_MODE_11ac;
 		sap_config->acs_cfg.ch_width =
 					hdd_ctx->config->vhtChannelWidth;
+		ch_width = 80;
 		/* No VHT80 in 2.4G so perform ACS accordingly */
 		if (sap_config->acs_cfg.end_ch <= 14 &&
 		    sap_config->acs_cfg.ch_width == eHT_CHANNEL_WIDTH_80MHZ) {
 			sap_config->acs_cfg.ch_width = eHT_CHANNEL_WIDTH_40MHZ;
 			ch_width = 40;
+			hdd_debug("resetting to 40Mhz in 2.4Ghz");
 		}
 	}
 
-	wlan_hdd_set_acs_ch_range(sap_config, ht_enabled, vht_enabled);
 
-	hdd_debug("ACS Config for wlan%d: HW_MODE: %d ACS_BW: %d HT: %d VHT: %d START_CH: %d END_CH: %d",
-		adapter->dev->ifindex, sap_config->acs_cfg.hw_mode,
+	hdd_debug("ACS Config for %s: HW_MODE: %d ACS_BW: %d HT: %d VHT: %d START_CH: %d END_CH: %d band %d",
+		adapter->dev->name, sap_config->acs_cfg.hw_mode,
 		ch_width, ht_enabled, vht_enabled,
-		sap_config->acs_cfg.start_ch, sap_config->acs_cfg.end_ch);
+		sap_config->acs_cfg.start_ch, sap_config->acs_cfg.end_ch,
+		sap_config->acs_cfg.band);
 
 	sap_config->acs_cfg.is_ht_enabled = ht_enabled;
 	sap_config->acs_cfg.is_vht_enabled = vht_enabled;
@@ -2325,7 +2336,6 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
 	} else {
 		/* Check if vendor specific acs is enabled */
 		if (hdd_ctx->config->vendor_acs_support) {
-			sap_config->acs_cfg.hw_mode = hw_mode;
 			hdd_create_acs_timer(adapter);
 			hdd_update_acs_timer_reason(adapter,
 				QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT);
@@ -8200,6 +8210,7 @@ int wlan_hdd_sap_get_valid_channellist(hdd_adapter_t *adapter,
 		hdd_err("Failed to get channel list");
 		return -EINVAL;
 	}
+
 	for (i = 0; i < chan_count; i++) {
 		if (*channel_count < QDF_MAX_NUM_CHAN) {
 			if ((eCSR_BAND_24 == band) &&

+ 13 - 1
core/hdd/src/wlan_hdd_hostapd.c

@@ -1420,12 +1420,23 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
 		}
 		break;
 	case eSAP_DFS_RADAR_DETECT:
+	{
+		int i;
+		tsap_Config_t *sap_config =
+				&pHostapdAdapter->sessionCtx.ap.sapConfig;
+
 		hdd_dfs_indicate_radar(pHddCtx);
 		wlan_hdd_send_svc_nlink_msg(pHddCtx->radio_index,
 					WLAN_SVC_DFS_RADAR_DETECT_IND,
 					    &dfs_info,
 					    sizeof(struct wlan_dfs_info));
 		pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
+		for (i = 0; i < sap_config->channel_info_count; i++) {
+			if (sap_config->channel_info[i].ieee_chan_number
+							== dfs_info.channel)
+				sap_config->channel_info[i].flags |=
+					IEEE80211_CHAN_RADAR_DFS;
+		}
 		if (QDF_STATUS_SUCCESS !=
 			hdd_send_radar_event(pHddCtx, eSAP_DFS_RADAR_DETECT,
 				dfs_info, &pHostapdAdapter->wdev)) {
@@ -1434,6 +1445,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
 			hdd_debug("Sent radar detected to user space");
 		}
 		break;
+	}
 	case eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC:
 		hdd_debug("notification for radar detect during pre cac:%d",
 			pHostapdAdapter->sessionId);
@@ -8070,7 +8082,7 @@ error:
 	return ret;
 }
 
-static int hdd_destroy_acs_timer(hdd_adapter_t *adapter)
+int hdd_destroy_acs_timer(hdd_adapter_t *adapter)
 {
 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
 

+ 2 - 0
core/hdd/src/wlan_hdd_hostapd.h

@@ -152,6 +152,8 @@ int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
 				    struct net_device *dev,
 				    struct cfg80211_beacon_data *params);
 
+int hdd_destroy_acs_timer(hdd_adapter_t *adapter);
+
 QDF_STATUS wlan_hdd_config_acs(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter);
 void hdd_sap_indicate_disconnect_for_sta(hdd_adapter_t *adapter);
 void hdd_sap_destroy_events(hdd_adapter_t *adapter);

+ 1 - 0
core/hdd/src/wlan_hdd_main.c

@@ -4127,6 +4127,7 @@ QDF_STATUS hdd_stop_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
 
 		hdd_deregister_tx_flow_control(adapter);
 
+		hdd_destroy_acs_timer(adapter);
 		mutex_lock(&hdd_ctx->sap_lock);
 		if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
 			QDF_STATUS status;

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

@@ -517,6 +517,7 @@ struct sap_acs_cfg {
 	uint8_t    ht_sec_ch;
 	uint8_t    vht_seg0_center_ch;
 	uint8_t    vht_seg1_center_ch;
+	uint32_t   band;
 };
 
 /*