Browse Source

qcacld-3.0: Add support for AWGN interference mitigation

Register callback function with dcs component to trigger
channel switch when AWGN interference is detected.

Change-Id: Ifb928b4d2b242eba3bd800207117b7c84a4531d6
CRs-Fixed: 2960240
Yu Wang 3 years ago
parent
commit
3c0cf58dc4
3 changed files with 126 additions and 4 deletions
  1. 123 2
      core/hdd/src/wlan_hdd_dcs.c
  2. 1 1
      core/hdd/src/wlan_hdd_medium_assess.c
  3. 2 1
      core/wma/src/wma_dev_if.c

+ 123 - 2
core/hdd/src/wlan_hdd_dcs.c

@@ -25,6 +25,126 @@
 #include <wlan_hdd_dcs.h>
 #include <wlan_hdd_includes.h>
 #include <wlan_dcs_ucfg_api.h>
+#include <wlan_blm_ucfg_api.h>
+#include <wlan_osif_priv.h>
+#include <wlan_objmgr_vdev_obj.h>
+
+/* Time(in milliseconds) before which the AP doesn't expect a connection */
+#define HDD_DCS_AWGN_BSS_RETRY_DELAY (5 * 60 * 1000)
+
+/**
+ * hdd_dcs_add_bssid_to_reject_list() - add bssid to reject list
+ * @pdev: pdev ptr
+ * @bssid: bssid to be added
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+hdd_dcs_add_bssid_to_reject_list(struct wlan_objmgr_pdev *pdev,
+				 struct qdf_mac_addr *bssid)
+{
+	struct reject_ap_info ap_info;
+
+	qdf_copy_macaddr(&ap_info.bssid, bssid);
+	/* set retry_delay to reject new connect requests */
+	ap_info.rssi_reject_params.retry_delay =
+		HDD_DCS_AWGN_BSS_RETRY_DELAY;
+	ap_info.reject_ap_type = DRIVER_RSSI_REJECT_TYPE;
+	ap_info.reject_reason = REASON_STA_KICKOUT;
+	ap_info.source = ADDED_BY_DRIVER;
+	return ucfg_blm_add_bssid_to_reject_list(pdev, &ap_info);
+}
+
+/**
+ * hdd_dcs_switch_chan_cb() - hdd dcs switch channel callback
+ * @vdev: vdev ptr
+ * @tgt_freq: target channel frequency
+ * @tgt_width: target channel width
+ *
+ * This callback is registered with dcs component to trigger channel switch.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS hdd_dcs_switch_chan_cb(struct wlan_objmgr_vdev *vdev,
+					 qdf_freq_t tgt_freq,
+					 enum phy_ch_width tgt_width)
+{
+	struct vdev_osif_priv *osif_priv;
+	struct hdd_adapter *adapter;
+	mac_handle_t mac_handle;
+	struct qdf_mac_addr *bssid;
+	int ret;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_psoc *psoc;
+
+	osif_priv = wlan_vdev_get_ospriv(vdev);
+	if (!osif_priv) {
+		hdd_err("Invalid osif priv");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	adapter = osif_priv->legacy_osif_priv;
+	if (!adapter) {
+		hdd_err("Invalid adapter");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	switch (adapter->device_mode) {
+	case QDF_STA_MODE:
+		if (!hdd_cm_is_vdev_associated(adapter))
+			return QDF_STATUS_E_INVAL;
+
+		bssid = &adapter->session.station.conn_info.bssid;
+
+		/* disconnect if got invalid freq or width */
+		if (tgt_freq == 0 || tgt_width == CH_WIDTH_INVALID) {
+			pdev = wlan_vdev_get_pdev(vdev);
+			if (!pdev)
+				return QDF_STATUS_E_INVAL;
+
+			hdd_dcs_add_bssid_to_reject_list(pdev, bssid);
+			wlan_hdd_cm_issue_disconnect(adapter,
+						     REASON_UNSPEC_FAILURE,
+						     true);
+			return QDF_STATUS_SUCCESS;
+		}
+
+		mac_handle = hdd_context_get_mac_handle(adapter->hdd_ctx);
+		if (!mac_handle)
+			return QDF_STATUS_E_INVAL;
+
+		status = sme_switch_channel(mac_handle, bssid,
+					    tgt_freq, tgt_width);
+		break;
+	case QDF_SAP_MODE:
+		if (!test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))
+			return QDF_STATUS_E_INVAL;
+
+		/* stop sap if got invalid freq or width */
+		if (tgt_freq == 0 || tgt_width == CH_WIDTH_INVALID) {
+			schedule_work(&adapter->sap_stop_bss_work);
+			return QDF_STATUS_SUCCESS;
+		}
+
+		psoc = wlan_vdev_get_psoc(vdev);
+		if (!psoc)
+			return QDF_STATUS_E_INVAL;
+
+		wlan_hdd_set_sap_csa_reason(psoc, adapter->vdev_id,
+					    CSA_REASON_DCS);
+		ret = hdd_softap_set_channel_change(adapter->dev, tgt_freq,
+						    tgt_width, true);
+		status = qdf_status_from_os_return(ret);
+		break;
+	default:
+		hdd_err("OP mode %d not supported", adapter->device_mode);
+		break;
+	}
+
+	return status;
+}
+
 /**
  * hdd_dcs_cb() - hdd dcs specific callback
  * @psoc: psoc
@@ -48,7 +168,7 @@ static void hdd_dcs_cb(struct wlan_objmgr_psoc *psoc, uint8_t mac_id,
 	/*
 	 * so far CAP_DCS_CWIM interference mitigation is not supported
 	 */
-	if (interference_type == CAP_DCS_CWIM) {
+	if (interference_type == WLAN_HOST_DCS_CWIM) {
 		hdd_debug("CW interference mitigation is not supported");
 		return;
 	}
@@ -85,6 +205,7 @@ static void hdd_dcs_cb(struct wlan_objmgr_psoc *psoc, uint8_t mac_id,
 void hdd_dcs_register_cb(struct hdd_context *hdd_ctx)
 {
 	ucfg_dcs_register_cb(hdd_ctx->psoc, hdd_dcs_cb, hdd_ctx);
+	ucfg_dcs_register_awgn_cb(hdd_ctx->psoc, hdd_dcs_switch_chan_cb);
 }
 
 void hdd_dcs_hostapd_set_chan(struct hdd_context *hdd_ctx,
@@ -233,7 +354,7 @@ void hdd_dcs_clear(struct hdd_adapter *adapter)
 	}
 
 	if (policy_mgr_get_sap_go_count_on_mac(psoc, list, mac_id) <= 1) {
-		ucfg_config_dcs_disable(psoc, mac_id, CAP_DCS_WLANIM);
+		ucfg_config_dcs_disable(psoc, mac_id, WLAN_HOST_DCS_WLANIM);
 		ucfg_wlan_dcs_cmd(psoc, mac_id, true);
 		if (wlansap_dcs_is_wlan_interference_mitigation_enabled(
 					WLAN_HDD_GET_SAP_CTX_PTR(adapter)))

+ 1 - 1
core/hdd/src/wlan_hdd_medium_assess.c

@@ -201,7 +201,7 @@ static int hdd_medium_assess_cca(struct hdd_context *hdd_ctx,
 	}
 
 	dcs_enable = ucfg_get_dcs_enable(hdd_ctx->psoc, mac_id);
-	if (!(dcs_enable & CAP_DCS_WLANIM)) {
+	if (!(dcs_enable & WLAN_HOST_DCS_WLANIM)) {
 		hdd_err_rl("DCS_WLANIM is not enabled");
 		errno = -EINVAL;
 		goto out;

+ 2 - 1
core/wma/src/wma_dev_if.c

@@ -1098,7 +1098,8 @@ static void wma_dcs_wlan_interference_mitigation_enable(
 		ucfg_config_dcs_event_data(mac_ctx->psoc, mac_id, true);
 
 	if (rsp->resp_type == WMI_HOST_VDEV_START_RESP_EVENT) {
-		ucfg_config_dcs_enable(mac_ctx->psoc, mac_id, CAP_DCS_WLANIM);
+		ucfg_config_dcs_enable(mac_ctx->psoc, mac_id,
+				       WLAN_HOST_DCS_WLANIM);
 		ucfg_wlan_dcs_cmd(mac_ctx->psoc, mac_id, true);
 	}
 }