Browse Source

qcacmn: Save the unsafe channels in policy manager

Save the list of unsafe channels in policy manager to be used on PCL.

Change-Id: Ibb705830e878d1cc03dfbc76e49c169d2febd75d
CRs-Fixed: 2095290
Tushnim Bhattacharyya 8 years ago
parent
commit
ddfe26635d

+ 4 - 2
umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -304,6 +304,7 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc,
 /**
  * policy_mgr_update_with_safe_channel_list() - provides the safe
  * channel list
+ * @psoc: PSOC object information
  * @pcl_channels: channel list
  * @len: length of the list
  * @weight_list: Weights of the PCL
@@ -314,8 +315,9 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc,
  *
  * Return: None
  */
-void policy_mgr_update_with_safe_channel_list(uint8_t *pcl_channels,
-		uint32_t *len, uint8_t *weight_list, uint32_t weight_len);
+void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc,
+		uint8_t *pcl_channels, uint32_t *len,
+		uint8_t *weight_list, uint32_t weight_len);
 
 /**
  * policy_mgr_get_nondfs_preferred_channel() - to get non-dfs preferred channel

+ 1 - 1
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c

@@ -2106,7 +2106,7 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc,
 			*len, i);
 
 	/* check the channel avoidance list */
-	policy_mgr_update_with_safe_channel_list(pcl_channels, len,
+	policy_mgr_update_with_safe_channel_list(psoc, pcl_channels, len,
 				pcl_weights, weight_len);
 
 	return status;

+ 23 - 0
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h

@@ -224,6 +224,8 @@ extern enum policy_mgr_conc_next_action
  *                            change is in progress
  * @enable_mcc_adaptive_scheduler: Enable MCC adaptive scheduler
  *      value from INI
+ * @unsafe_channel_list: LTE coex channel avoidance list
+ * @unsafe_channel_count: LTE coex channel avoidance list count
  */
 struct policy_mgr_psoc_priv_obj {
 		struct wlan_objmgr_psoc *psoc;
@@ -250,6 +252,8 @@ struct policy_mgr_psoc_priv_obj {
 		struct dual_mac_config dual_mac_cfg;
 		uint32_t hw_mode_change_in_progress;
 		struct policy_mgr_user_cfg user_cfg;
+		uint16_t unsafe_channel_list[QDF_MAX_NUM_CHAN];
+		uint16_t unsafe_channel_count;
 };
 
 /**
@@ -403,4 +407,23 @@ QDF_STATUS policy_mgr_reset_sap_mandatory_channels(
 bool policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc,
 				  uint8_t *channel, uint8_t *vdev_id,
 				  enum policy_mgr_con_mode mode);
+
+/**
+ * policy_mgr_reg_chan_change_callback() - Callback to be
+ * invoked by regulatory module when valid channel list changes
+ * @psoc: PSOC object information
+ * @pdev: PDEV object information
+ * @chan_list: New channel list
+ * @avoid_freq_ind: LTE coex avoid channel list
+ * @arg: Information passed at registration
+ *
+ * Get updated channel list from regulatory module
+ *
+ * Return: None
+ */
+void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc,
+		struct wlan_objmgr_pdev *pdev,
+		struct regulatory_channel *chan_list,
+		struct avoid_freq_ind_data *avoid_freq_ind,
+		void *arg);
 #endif

+ 5 - 0
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c

@@ -101,6 +101,9 @@ static QDF_STATUS policy_mgr_pdev_obj_create_cb(struct wlan_objmgr_pdev *pdev,
 
 	policy_mgr_ctx->pdev = pdev;
 
+	wlan_reg_register_chan_change_callback(psoc,
+		policy_mgr_reg_chan_change_callback, NULL);
+
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -118,6 +121,8 @@ static QDF_STATUS policy_mgr_pdev_obj_destroy_cb(struct wlan_objmgr_pdev *pdev,
 	}
 
 	policy_mgr_ctx->pdev = NULL;
+	wlan_reg_unregister_chan_change_callback(psoc,
+		policy_mgr_reg_chan_change_callback);
 
 	return QDF_STATUS_SUCCESS;
 }

+ 88 - 2
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c

@@ -142,9 +142,95 @@ void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc,
 	return;
 }
 
-void policy_mgr_update_with_safe_channel_list(uint8_t *pcl_channels,
-		uint32_t *len, uint8_t *weight_list, uint32_t weight_len)
+void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc,
+		struct wlan_objmgr_pdev *pdev,
+		struct regulatory_channel *chan_list,
+		struct avoid_freq_ind_data *avoid_freq_ind,
+		void *arg)
 {
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	if (!avoid_freq_ind) {
+		policy_mgr_debug("avoid_freq_ind NULL");
+		return;
+	}
+
+	pm_ctx->unsafe_channel_count = avoid_freq_ind->chan_list.ch_cnt >=
+			QDF_MAX_NUM_CHAN ?
+			QDF_MAX_NUM_CHAN : avoid_freq_ind->chan_list.ch_cnt;
+	if (pm_ctx->unsafe_channel_count)
+		qdf_mem_copy(pm_ctx->unsafe_channel_list,
+			avoid_freq_ind->chan_list.ch_list,
+			pm_ctx->unsafe_channel_count);
+	policy_mgr_debug("Channel list update, recieved %d avoided channels",
+		pm_ctx->unsafe_channel_count);
+}
+
+void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc,
+		uint8_t *pcl_channels, uint32_t *len,
+		uint8_t *weight_list, uint32_t weight_len)
+{
+	uint8_t current_channel_list[QDF_MAX_NUM_CHAN];
+	uint8_t org_weight_list[QDF_MAX_NUM_CHAN];
+	uint8_t is_unsafe = 1;
+	uint8_t i, j;
+	uint32_t safe_channel_count = 0, current_channel_count = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+
+	if (len) {
+		current_channel_count = QDF_MIN(*len, QDF_MAX_NUM_CHAN);
+	} else {
+		policy_mgr_err("invalid number of channel length");
+		return;
+	}
+
+	if (pm_ctx->unsafe_channel_count == 0) {
+		policy_mgr_debug("There are no unsafe channels");
+		return;
+	}
+
+	qdf_mem_copy(current_channel_list, pcl_channels,
+		current_channel_count);
+	qdf_mem_zero(pcl_channels, current_channel_count);
+
+	qdf_mem_copy(org_weight_list, weight_list, QDF_MAX_NUM_CHAN);
+	qdf_mem_zero(weight_list, weight_len);
+
+	for (i = 0; i < current_channel_count; i++) {
+		is_unsafe = 0;
+		for (j = 0; j < pm_ctx->unsafe_channel_count; j++) {
+			if (current_channel_list[i] ==
+				pm_ctx->unsafe_channel_list[j]) {
+				/* Found unsafe channel, update it */
+				is_unsafe = 1;
+				policy_mgr_warn("CH %d is not safe",
+					current_channel_list[i]);
+				break;
+			}
+		}
+		if (!is_unsafe) {
+			pcl_channels[safe_channel_count] =
+				current_channel_list[i];
+			if (safe_channel_count < weight_len)
+				weight_list[safe_channel_count] =
+					org_weight_list[i];
+			safe_channel_count++;
+		}
+	}
+	*len = safe_channel_count;
+
 	return;
 }