Эх сурвалжийг харах

qcacld-3.0: Combine LTE Coex & DNBS avoid freqs

Avoid frequency list can be generated due to LTE Coex and
Do_Not_Break_Stream.
Combine LTE Coex & DNBS avoid frequencies before sending the list to
application.

Change-Id: Ibafac2fcc160d029fc5643847a5647edf10db29d
CRs-Fixed: 2045120
Ajit Pal Singh 8 жил өмнө
parent
commit
2c7aecd2ed

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

@@ -1614,6 +1614,12 @@ struct hdd_context_s {
 	unsigned long last_scan_reject_timestamp;
 	bool dfs_cac_offload;
 	bool reg_offload;
+#ifdef FEATURE_WLAN_CH_AVOID
+	tHddAvoidFreqList coex_avoid_freq_list;
+	tHddAvoidFreqList dnbs_avoid_freq_list;
+	/* Lock to control access to dnbs and coex avoid freq list */
+	struct mutex avoid_freq_lock;
+#endif
 };
 
 /**

+ 45 - 1
core/hdd/src/wlan_hdd_cfg80211.c

@@ -761,6 +761,27 @@ wlan_hdd_cfg80211_get_tdls_capabilities(struct wiphy *wiphy,
 static void wlan_hdd_cfg80211_start_pending_acs(struct work_struct *work);
 #endif
 
+int wlan_hdd_merge_avoid_freqs(tHddAvoidFreqList *destFreqList,
+		tHddAvoidFreqList *srcFreqList)
+{
+	int i;
+	tHddAvoidFreqRange *avoidRange =
+	&destFreqList->avoidFreqRange[destFreqList->avoidFreqRangeCount];
+
+	destFreqList->avoidFreqRangeCount += srcFreqList->avoidFreqRangeCount;
+	if (destFreqList->avoidFreqRangeCount > HDD_MAX_AVOID_FREQ_RANGES) {
+		hdd_err("avoid freq overflow");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < srcFreqList->avoidFreqRangeCount; i++) {
+		avoidRange->startFreq =
+			srcFreqList->avoidFreqRange[i].startFreq;
+		avoidRange->endFreq = srcFreqList->avoidFreqRange[i].endFreq;
+		avoidRange++;
+	}
+	return 0;
+}
 /*
  * FUNCTION: wlan_hdd_send_avoid_freq_event
  * This is called when wlan driver needs to send vendor specific
@@ -862,6 +883,16 @@ int wlan_hdd_send_avoid_freq_for_dnbs(hdd_context_t *pHddCtx, uint8_t op_chan)
 	 * If channel passed is zero, clear the avoid_freq list in application.
 	 */
 	if (!op_chan) {
+#ifdef FEATURE_WLAN_CH_AVOID
+		mutex_lock(&pHddCtx->avoid_freq_lock);
+		qdf_mem_zero(&pHddCtx->dnbs_avoid_freq_list,
+				sizeof(tHddAvoidFreqList));
+		if (pHddCtx->coex_avoid_freq_list.avoidFreqRangeCount)
+			memcpy(&p2p_avoid_freq_list,
+			       &pHddCtx->coex_avoid_freq_list,
+			       sizeof(tHddAvoidFreqList));
+		mutex_unlock(&pHddCtx->avoid_freq_lock);
+#endif
 		ret = wlan_hdd_send_avoid_freq_event(pHddCtx,
 						     &p2p_avoid_freq_list);
 		if (ret)
@@ -925,7 +956,20 @@ int wlan_hdd_send_avoid_freq_for_dnbs(hdd_context_t *pHddCtx, uint8_t op_chan)
 		p2p_avoid_freq_list.avoidFreqRange[0].endFreq =
 			wlan_chan_to_freq(chan);
 	}
-
+#ifdef FEATURE_WLAN_CH_AVOID
+	mutex_lock(&pHddCtx->avoid_freq_lock);
+	pHddCtx->dnbs_avoid_freq_list = p2p_avoid_freq_list;
+	if (pHddCtx->coex_avoid_freq_list.avoidFreqRangeCount) {
+		ret = wlan_hdd_merge_avoid_freqs(&p2p_avoid_freq_list,
+				&pHddCtx->coex_avoid_freq_list);
+		if (ret) {
+			mutex_unlock(&pHddCtx->avoid_freq_lock);
+			hdd_err("avoid freq merge failed");
+			return ret;
+		}
+	}
+	mutex_unlock(&pHddCtx->avoid_freq_lock);
+#endif
 	ret = wlan_hdd_send_avoid_freq_event(pHddCtx, &p2p_avoid_freq_list);
 	if (ret)
 		hdd_err("wlan_hdd_send_avoid_freq_event error:%d", ret);

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

@@ -528,4 +528,14 @@ void hdd_update_cca_info_cb(void *context, uint32_t congestion,
  */
 int wlan_hdd_get_adjacent_chan(uint8_t chan, bool upper);
 
+/**
+ * wlan_hdd_merge_avoid_freqs(): Merge two tHddAvoidFreqList
+ * @destFreqList: Destination list in which merged frequency
+ * list will be available.
+ * @srcFreqList: Source frequency list.
+ *
+ * Merges two avoid_frequency lists
+ */
+int wlan_hdd_merge_avoid_freqs(tHddAvoidFreqList *destFreqList,
+		tHddAvoidFreqList *srcFreqList);
 #endif

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

@@ -5527,6 +5527,9 @@ static void hdd_wlan_exit(hdd_context_t *hdd_ctx)
 
 	hdd_exit_netlink_services(hdd_ctx);
 	mutex_destroy(&hdd_ctx->iface_change_lock);
+#ifdef FEATURE_WLAN_CH_AVOID
+	mutex_destroy(&hdd_ctx->avoid_freq_lock);
+#endif
 
 	driver_status = hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
 	if (driver_status)
@@ -6840,6 +6843,7 @@ next_adapater:
 		adapter_node = next;
 	}
 }
+
 /**
  * hdd_ch_avoid_cb() - Avoid notified channels from FW handler
  * @adapter:	HDD adapter pointer
@@ -6889,6 +6893,10 @@ void hdd_ch_avoid_cb(void *hdd_context, void *indi_param)
 	hdd_avoid_freq_list.avoidFreqRangeCount =
 		ch_avoid_indi->avoid_range_count;
 
+	mutex_lock(&hdd_ctxt->avoid_freq_lock);
+	hdd_ctxt->coex_avoid_freq_list = hdd_avoid_freq_list;
+	mutex_unlock(&hdd_ctxt->avoid_freq_lock);
+
 	/* clear existing unsafe channel cache */
 	hdd_ctxt->unsafe_channel_count = 0;
 	qdf_mem_zero(hdd_ctxt->unsafe_channel_list,
@@ -6979,6 +6987,15 @@ void hdd_ch_avoid_cb(void *hdd_context, void *indi_param)
 		       hdd_ctxt->unsafe_channel_list[channel_loop]);
 	}
 
+	mutex_lock(&hdd_ctxt->avoid_freq_lock);
+	if (hdd_ctxt->dnbs_avoid_freq_list.avoidFreqRangeCount)
+		if (wlan_hdd_merge_avoid_freqs(&hdd_avoid_freq_list,
+					&hdd_ctxt->dnbs_avoid_freq_list)) {
+			mutex_unlock(&hdd_ctxt->avoid_freq_lock);
+			hdd_debug("unable to merge avoid freqs");
+			return;
+	}
+	mutex_unlock(&hdd_ctxt->avoid_freq_lock);
 	/*
 	 * first update the unsafe channel list to the platform driver and
 	 * send the avoid freq event to the application
@@ -9201,6 +9218,9 @@ int hdd_wlan_startup(struct device *dev)
 			  hdd_iface_change_callback, (void *)hdd_ctx);
 
 	mutex_init(&hdd_ctx->iface_change_lock);
+#ifdef FEATURE_WLAN_CH_AVOID
+	mutex_init(&hdd_ctx->avoid_freq_lock);
+#endif
 
 	ret = hdd_init_netlink_services(hdd_ctx);
 	if (ret)