Browse Source

qcacld-3.0: Add check for passive channel for SAP

Add a check for passive channels when checking the restricted
bands on SAP. This change blocks SAP from restarting on a passive
channel.

Implement the function to filter out passive channels from the PCL.

Change-Id: I80a4b78c1af77f5bfa68be3163f9e9a78cc6425a
CRs-fixed: 2817589
Lincoln Tran 4 years ago
parent
commit
b18e7854bf

+ 14 - 1
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -76,7 +76,7 @@ typedef const enum policy_mgr_conc_next_action
  * @CSA_REASON_BAND_RESTRICTED: band disabled or re-enabled
  * @CSA_REASON_DCS: DCS
  * @CSA_REASON_CHAN_DISABLED: channel is disabled
- *
+ * @CSA_REASON_CHAN_PASSIVE: channel is passive
  */
 enum sap_csa_reason_code {
 	CSA_REASON_UNKNOWN,
@@ -91,6 +91,7 @@ enum sap_csa_reason_code {
 	CSA_REASON_BAND_RESTRICTED,
 	CSA_REASON_DCS,
 	CSA_REASON_CHAN_DISABLED,
+	CSA_REASON_CHAN_PASSIVE,
 };
 
 /**
@@ -3616,6 +3617,18 @@ bool policy_mgr_dump_channel_list(uint32_t len,
 				  uint32_t *pcl_channels,
 				  uint8_t *pcl_weight);
 
+/**
+ * policy_mgr_filter_passive_ch() -filter out passive channels from the list
+ * @pdev: Pointer to pdev
+ * @ch_freq_list: pointer to channel frequency list
+ * @ch_cnt: number of channels in list
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_filter_passive_ch(struct wlan_objmgr_pdev *pdev,
+					uint32_t *ch_freq_list,
+					uint32_t *ch_cnt);
+
 /**
  * policy_mgr_is_restart_sap_required() - check whether sap need restart
  * @psoc: psoc pointer

+ 22 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c

@@ -2632,3 +2632,25 @@ free:
 
 	return true;
 }
+
+QDF_STATUS policy_mgr_filter_passive_ch(struct wlan_objmgr_pdev *pdev,
+					uint32_t *ch_freq_list,
+					uint32_t *ch_cnt)
+{
+	size_t ch_index;
+	size_t target_ch_cnt = 0;
+
+	if (!pdev || !ch_freq_list || !ch_cnt) {
+		policy_mgr_err("NULL parameters");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	for (ch_index = 0; ch_index < *ch_cnt; ch_index++) {
+		if (!wlan_reg_is_passive_for_freq(pdev, ch_freq_list[ch_index]))
+			ch_freq_list[target_ch_cnt++] = ch_freq_list[ch_index];
+	}
+
+	*ch_cnt = target_ch_cnt;
+
+	return QDF_STATUS_SUCCESS;
+}

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

@@ -1505,6 +1505,19 @@ bool wlansap_is_6ghz_included_in_acs_range(struct sap_context *sap_ctx);
 uint32_t
 wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx);
 
+/**
+ * wlansap_get_safe_channel_from_pcl_for_sap() - Get safe and active channel
+ * for SAP restart
+ * @sap_ctx: sap context
+ *
+ * Get a safe and active channel to restart SAP. PCL already takes into account
+ * the unsafe channels.
+ *
+ * Return: Chan freq num to restart SAP in case of success. In case of any
+ * failure, the channel number returned is zero.
+ */
+uint32_t wlansap_get_safe_channel_from_pcl_for_sap(struct sap_context *sap_ctx);
+
 /**
  * wlansap_get_chan_band_restrict() -  get new chan for band change
  * @sap_ctx: sap context pointer

+ 68 - 1
core/sap/src/sap_module.c

@@ -1285,6 +1285,10 @@ static char *sap_get_csa_reason_str(enum sap_csa_reason_code reason)
 		return "BAND_RESTRICTED";
 	case CSA_REASON_DCS:
 		return "DCS";
+	case CSA_REASON_CHAN_DISABLED:
+		return "DISABLED";
+	case CSA_REASON_CHAN_PASSIVE:
+		return "PASSIVE";
 	default:
 		return "UNKNOWN";
 	}
@@ -2999,13 +3003,14 @@ static uint32_t wlansap_get_2g_first_safe_chan_freq(struct sap_context *sap_ctx)
 		freq = cur_chan_list[i].center_freq;
 		state = wlan_reg_get_channel_state_for_freq(pdev, freq);
 		if (state != CHANNEL_STATE_DISABLE &&
+		    state != CHANNEL_STATE_PASSIVE &&
 		    state != CHANNEL_STATE_INVALID &&
 		    wlan_reg_is_24ghz_ch_freq(freq) &&
 		    policy_mgr_is_safe_channel(psoc, freq) &&
 		    wlansap_is_channel_present_in_acs_list(freq,
 							   acs_freq_list,
 							   acs_list_count)) {
-			sap_debug("find a 2g channel: %d", freq);
+			sap_debug("found a 2g channel: %d", freq);
 			goto err;
 		}
 	}
@@ -3016,6 +3021,63 @@ err:
 	return freq;
 }
 
+uint32_t wlansap_get_safe_channel_from_pcl_for_sap(struct sap_context *sap_ctx)
+{
+	struct wlan_objmgr_pdev *pdev;
+	struct mac_context *mac;
+	struct sir_pcl_list pcl = {0};
+	uint32_t pcl_freqs[NUM_CHANNELS] = {0};
+	QDF_STATUS status;
+	uint32_t pcl_len = 0;
+
+	if (!sap_ctx) {
+		sap_err("NULL parameter");
+		return INVALID_CHANNEL_ID;
+	}
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		sap_err("Invalid MAC context");
+		return INVALID_CHANNEL_ID;
+	}
+
+	pdev = sap_ctx->vdev->vdev_objmgr.wlan_pdev;
+	if (!pdev) {
+		sap_err("NULL pdev");
+	}
+
+	status = policy_mgr_get_pcl_for_vdev_id(mac->psoc, PM_SAP_MODE,
+						pcl_freqs, &pcl_len,
+						pcl.weight_list,
+						QDF_ARRAY_SIZE(pcl.weight_list),
+						sap_ctx->sessionId);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sap_err("Get PCL failed");
+		return INVALID_CHANNEL_ID;
+	}
+
+	if (pcl_len) {
+		status = policy_mgr_filter_passive_ch(pdev, pcl_freqs,
+						      &pcl_len);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			sap_err("failed to filter passive channels");
+			return INVALID_CHANNEL_ID;
+		}
+
+		if (pcl_len) {
+			sap_debug("select %d from valid ch freq list",
+				  pcl_freqs[0]);
+			return pcl_freqs[0];
+		}
+		sap_debug("no active channels found in PCL");
+	} else {
+		sap_debug("pcl length is zero!");
+	}
+
+	return wlansap_get_2g_first_safe_chan_freq(sap_ctx);
+}
+
 qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx,
 					  enum sap_csa_reason_code *csa_reason)
 {
@@ -3081,6 +3143,11 @@ qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx,
 		sap_debug("channel is disabled");
 		*csa_reason = CSA_REASON_CHAN_DISABLED;
 		return wlansap_get_safe_channel_from_pcl_and_acs_range(sap_ctx);
+	} else if (wlan_reg_is_passive_for_freq(mac->pdev,
+						sap_ctx->chan_freq)) {
+		sap_debug("channel is passive");
+		*csa_reason = CSA_REASON_CHAN_PASSIVE;
+		return wlansap_get_safe_channel_from_pcl_for_sap(sap_ctx);
 	} else {
 		sap_debug("No need switch SAP/Go channel");
 		return 0;