Browse Source

qcacld-3.0: Clear coex unsafe channel list for user space event

This change is to clear coex unsafe channels list if vendor command
QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_EXT sends start and end
frequencies as '0'.

Change-Id: I8cea94f743de02c036ce1c6bed352857fec2d44d
CRs-Fixed: 3127863
Balaji Pothunoori 3 years ago
parent
commit
6a71939a15

+ 20 - 1
core/hdd/inc/wlan_hdd_main.h

@@ -4098,6 +4098,8 @@ int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx,
  * @hdd_ctx: hdd context pointer
  * @local_unsafe_list: unsafe chan list to be compared with hdd_ctx's list
  * @local_unsafe_list_count: channel number in local_unsafe_list
+ * @restriction_mask: restriction mask is to differentiate current channel
+ * list different from previous channel list
  *
  * The function checked the input channel is same as current unsafe chan
  * list in hdd_ctx.
@@ -4105,12 +4107,29 @@ int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx,
  * Return: true if input channel list is same as the list in hdd_ctx
  */
 bool hdd_local_unsafe_channel_updated(struct hdd_context *hdd_ctx,
-	uint16_t *local_unsafe_list, uint16_t local_unsafe_list_count);
+	uint16_t *local_unsafe_list, uint16_t local_unsafe_list_count,
+	uint32_t restriction_mask);
 
 int hdd_enable_disable_ca_event(struct hdd_context *hddctx,
 				uint8_t set_value);
 void wlan_hdd_undo_acs(struct hdd_adapter *adapter);
 
+/**
+ * wlan_hdd_set_restriction_mask() - set restriction mask for hdd context
+ * @hdd_ctx: hdd context pointer
+ *
+ * Return: None
+ */
+void wlan_hdd_set_restriction_mask(struct hdd_context *hdd_ctx);
+
+/**
+ * wlan_hdd_get_restriction_mask() - get restriction mask from hdd context
+ * @hdd_ctx: hdd context pointer
+ *
+ * Return: restriction_mask
+ */
+uint32_t wlan_hdd_get_restriction_mask(struct hdd_context *hdd_ctx);
+
 #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)

+ 24 - 18
core/hdd/src/wlan_hdd_avoid_freq_ext.c

@@ -72,14 +72,14 @@ __wlan_hdd_cfg80211_avoid_freq_ext(struct wiphy *wiphy,
 	hdd_enter_dev(wdev->netdev);
 
 	if (!ucfg_mlme_get_coex_unsafe_chan_nb_user_prefer(hdd_ctx->psoc)) {
-		hdd_debug("Coex unsafe chan nb user prefer is not set");
+		hdd_debug_rl("Coex unsafe chan nb user prefer is not set");
 		return -EOPNOTSUPP;
 	}
 
 	curr_mode = hdd_get_conparam();
 	if (curr_mode == QDF_GLOBAL_FTM_MODE ||
 	    curr_mode == QDF_GLOBAL_MONITOR_MODE) {
-		hdd_debug("Command not allowed in FTM/MONITOR mode");
+		hdd_debug_rl("Command not allowed in FTM/MONITOR mode");
 		return -EINVAL;
 	}
 
@@ -88,7 +88,7 @@ __wlan_hdd_cfg80211_avoid_freq_ext(struct wiphy *wiphy,
 		return ret;
 
 	if (hdd_is_connection_in_progress(NULL, NULL)) {
-		hdd_debug("Update chan list refused: conn in progress");
+		hdd_debug_rl("Update chan list refused: conn in progress");
 		ret = -EPERM;
 		goto out;
 	}
@@ -96,7 +96,7 @@ __wlan_hdd_cfg80211_avoid_freq_ext(struct wiphy *wiphy,
 	qdf_mem_zero(&avoid_freq_list, sizeof(struct ch_avoid_ind_type));
 
 	if (!data && data_len == 0) {
-		hdd_debug("Clear extended avoid frequency list");
+		hdd_debug_rl("Clear extended avoid frequency list");
 		goto process_avoid_channel_ext;
 	}
 
@@ -106,7 +106,7 @@ __wlan_hdd_cfg80211_avoid_freq_ext(struct wiphy *wiphy,
 				      data_len,
 				      avoid_freq_ext_policy);
 	if (ret) {
-		hdd_err("Invalid avoid freq ext ATTR");
+		hdd_err_rl("Invalid avoid freq ext ATTR");
 		ret = -EINVAL;
 		goto out;
 	}
@@ -114,7 +114,7 @@ __wlan_hdd_cfg80211_avoid_freq_ext(struct wiphy *wiphy,
 	id = QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE;
 
 	if (!tb[id]) {
-		hdd_err("Attr avoid frequency ext range failed");
+		hdd_err_rl("Attr avoid frequency ext range failed");
 		ret = -EINVAL;
 		goto out;
 	}
@@ -130,7 +130,7 @@ __wlan_hdd_cfg80211_avoid_freq_ext(struct wiphy *wiphy,
 
 	nla_for_each_nested(freq_ext, tb[id], rem) {
 		if (i == CH_AVOID_MAX_RANGE) {
-			hdd_warn("Ignoring excess range number");
+			hdd_warn_rl("Ignoring excess range number");
 			break;
 		}
 
@@ -138,7 +138,7 @@ __wlan_hdd_cfg80211_avoid_freq_ext(struct wiphy *wiphy,
 					    nla_data(freq_ext),
 					    nla_len(freq_ext),
 					    avoid_freq_ext_policy)) {
-			hdd_err("nla_parse failed");
+			hdd_err_rl("nla_parse failed");
 			ret = -EINVAL;
 			goto out;
 		}
@@ -161,9 +161,15 @@ __wlan_hdd_cfg80211_avoid_freq_ext(struct wiphy *wiphy,
 		}
 		avoid_freq_range->end_freq = nla_get_u32(tb2[sub_id]);
 
-		if (!wlan_reg_is_same_band_freqs(avoid_freq_range->start_freq,
-						 avoid_freq_range->end_freq)) {
-			hdd_debug("Not in same band");
+		if (!avoid_freq_range->start_freq &&
+		    !avoid_freq_range->end_freq && (i < 1)) {
+			hdd_debug_rl("Clear unsafe channel list");
+		} else if (!wlan_reg_is_same_band_freqs(
+			   avoid_freq_range->start_freq,
+			   avoid_freq_range->end_freq)) {
+			hdd_debug_rl("start freq %d end freq %d not in same band",
+				     avoid_freq_range->start_freq,
+				     avoid_freq_range->end_freq);
 			ret = -EINVAL;
 			goto out;
 		}
@@ -182,17 +188,17 @@ __wlan_hdd_cfg80211_avoid_freq_ext(struct wiphy *wiphy,
 			avoid_freq_range->is_valid_txpower = true;
 		}
 
-		hdd_debug("ext avoid freq start: %u end: %u txpower %d mask %d",
-			  avoid_freq_range->start_freq,
-			  avoid_freq_range->end_freq,
-			  avoid_freq_range->txpower,
-			  avoid_freq_list.restriction_mask);
+		hdd_debug_rl("ext avoid freq start: %u end: %u txpower %d mask %d",
+			     avoid_freq_range->start_freq,
+			     avoid_freq_range->end_freq,
+			     avoid_freq_range->txpower,
+			     avoid_freq_list.restriction_mask);
 		i++;
 	}
 
 	if (i < CH_AVOID_MAX_RANGE) {
-		hdd_warn("Number of freq range %u less than expected %u",
-			 i, CH_AVOID_MAX_RANGE);
+		hdd_warn_rl("Number of freq range %u less than expected %u",
+			    i, CH_AVOID_MAX_RANGE);
 		avoid_freq_list.ch_avoid_range_cnt = i;
 	}
 

+ 37 - 3
core/hdd/src/wlan_hdd_main.c

@@ -11995,6 +11995,28 @@ int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason)
 	return status;
 }
 
+#ifdef FEATURE_WLAN_CH_AVOID_EXT
+uint32_t wlan_hdd_get_restriction_mask(struct hdd_context *hdd_ctx)
+{
+	return hdd_ctx->restriction_mask;
+}
+
+void wlan_hdd_set_restriction_mask(struct hdd_context *hdd_ctx)
+{
+	hdd_ctx->restriction_mask =
+		hdd_ctx->coex_avoid_freq_list.restriction_mask;
+}
+#else
+uint32_t wlan_hdd_get_restriction_mask(struct hdd_context *hdd_ctx)
+{
+	return -EINVAL;
+}
+
+void wlan_hdd_set_restriction_mask(struct hdd_context *hdd_ctx)
+{
+}
+#endif
+
 #if defined(FEATURE_WLAN_CH_AVOID)
 /**
  * hdd_store_sap_restart_channel() - store sap restart channel
@@ -12294,8 +12316,9 @@ int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx,
 	return 0;
 }
 
-bool hdd_local_unsafe_channel_updated(struct hdd_context *hdd_ctx,
-	uint16_t *local_unsafe_list, uint16_t local_unsafe_list_count)
+bool hdd_local_unsafe_channel_updated(
+	struct hdd_context *hdd_ctx, uint16_t *local_unsafe_list,
+	uint16_t local_unsafe_list_count, uint32_t restriction_mask)
 {
 	int i, j;
 
@@ -12311,7 +12334,18 @@ bool hdd_local_unsafe_channel_updated(struct hdd_context *hdd_ctx,
 		if (j >= local_unsafe_list_count)
 			break;
 	}
-	if (i >= local_unsafe_list_count) {
+
+	if (ucfg_mlme_get_coex_unsafe_chan_nb_user_prefer(hdd_ctx->psoc)) {
+		/* Return false if current channel list is same as previous
+		 * and restriction mask is not altered
+		 */
+		if (i >= local_unsafe_list_count &&
+		    (restriction_mask ==
+		     wlan_hdd_get_restriction_mask(hdd_ctx))) {
+			hdd_info("unsafe chan list same");
+			return false;
+		}
+	} else if (i >= local_unsafe_list_count) {
 		hdd_info("unsafe chan list same");
 		return false;
 	}

+ 6 - 1
core/hdd/src/wlan_hdd_regulatory.c

@@ -1244,6 +1244,7 @@ void hdd_ch_avoid_ind(struct hdd_context *hdd_ctxt,
 {
 	uint16_t *local_unsafe_list;
 	uint16_t local_unsafe_list_count;
+	uint32_t restriction_mask;
 	uint8_t i;
 
 	/* Basic sanity */
@@ -1257,6 +1258,7 @@ void hdd_ch_avoid_ind(struct hdd_context *hdd_ctxt,
 			sizeof(struct ch_avoid_ind_type));
 	mutex_unlock(&hdd_ctxt->avoid_freq_lock);
 
+	restriction_mask = wlan_hdd_get_restriction_mask(hdd_ctxt);
 	if (hdd_clone_local_unsafe_chan(hdd_ctxt,
 					&local_unsafe_list,
 					&local_unsafe_list_count) != 0) {
@@ -1271,6 +1273,8 @@ void hdd_ch_avoid_ind(struct hdd_context *hdd_ctxt,
 
 	hdd_ctxt->unsafe_channel_count = unsafe_chan_list->chan_cnt;
 
+	wlan_hdd_set_restriction_mask(hdd_ctxt);
+
 	for (i = 0; i < unsafe_chan_list->chan_cnt; i++) {
 		hdd_ctxt->unsafe_channel_list[i] =
 				unsafe_chan_list->chan_freq_list[i];
@@ -1314,7 +1318,8 @@ void hdd_ch_avoid_ind(struct hdd_context *hdd_ctxt,
 	}
 	if (hdd_local_unsafe_channel_updated(hdd_ctxt,
 					    local_unsafe_list,
-					    local_unsafe_list_count))
+					    local_unsafe_list_count,
+					    restriction_mask))
 		hdd_unsafe_channel_restart_sap(hdd_ctxt);
 	qdf_mem_free(local_unsafe_list);