Browse Source

qcacld-3.0: Don't reject SR command if threshold not provided

As per current implementation, SR(Spatial Reuse) commands are
rejected if STA is not connected or connected to AP that doesn't
support SR which causes issue because SR Enable/Disable command
shouldn't reject if STA is not connected instead of rejection
same configuration should be applied when SR AP connects to STA.

Fix is to not to reject SR command if PD threshold is not provided
along with enable command, so that enable command can be accepted and
applied when AP that supports SR connects to station.

Change-Id: Ie4a973053b79d0d5931bcc2520da42f9aab93089
CRs-Fixed: 3350451
Sheenam Monga 2 years ago
parent
commit
188ac8c5b7

+ 5 - 2
components/spatial_reuse/dispatcher/src/spatial_reuse_ucfg_api.c

@@ -138,12 +138,16 @@ QDF_STATUS ucfg_spatial_reuse_operation_allowed(struct wlan_objmgr_psoc *psoc,
 {
 	uint32_t conc_vdev_id;
 	uint8_t vdev_id, mac_id;
-	QDF_STATUS status;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
 	if (!vdev || !psoc)
 		return QDF_STATUS_E_NULL_VALUE;
 
 	vdev_id = wlan_vdev_get_id(vdev);
+	if (!policy_mgr_get_connection_count(psoc)) {
+		mlme_debug("No active vdev");
+		return status;
+	}
 	status = policy_mgr_get_mac_id_by_session_id(psoc, vdev_id, &mac_id);
 	if (QDF_IS_STATUS_ERROR(status))
 		return status;
@@ -152,6 +156,5 @@ QDF_STATUS ucfg_spatial_reuse_operation_allowed(struct wlan_objmgr_psoc *psoc,
 	if (conc_vdev_id != WLAN_INVALID_VDEV_ID &&
 	    !policy_mgr_sr_same_mac_conc_enabled(psoc))
 		return QDF_STATUS_E_NOSUPPORT;
-
 	return status;
 }

+ 144 - 72
core/hdd/src/wlan_hdd_he.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -34,6 +34,7 @@
 #include "cdp_txrx_host_stats.h"
 #include "wlan_policy_mgr_i.h"
 #include "wlan_objmgr_vdev_obj.h"
+#include "wlan_hdd_object_manager.h"
 
 const struct nla_policy
 wlan_hdd_sr_policy[QCA_WLAN_VENDOR_ATTR_SR_MAX + 1] = {
@@ -649,6 +650,27 @@ static int hdd_clear_sr_stats(struct hdd_context *hdd_ctx, uint8_t mac_id)
 	return 0;
 }
 
+/**
+ * hdd_check_mode_support_for_sr: Check if SR allowed or not
+ * @adapter: hdd adapter
+ * @sr_ctrl: sr ctrl ie
+ *
+ * Return: true if provided mode supports SR else flase
+ */
+static bool hdd_check_mode_support_for_sr(struct hdd_adapter *adapter,
+					  uint8_t sr_ctrl)
+{
+	if ((adapter->device_mode == QDF_STA_MODE) &&
+	    (!hdd_cm_is_vdev_connected(adapter) ||
+	    !sr_ctrl ||
+	    ((sr_ctrl & NON_SRG_PD_SR_DISALLOWED) &&
+	    !(sr_ctrl & SRG_INFO_PRESENT)))) {
+		hdd_err("mode %d doesn't supports SR", adapter->device_mode);
+		return false;
+	}
+	return true;
+}
+
 /**
  * __wlan_hdd_cfg80211_sr_operations: To handle SR operation
  *
@@ -673,9 +695,9 @@ static int __wlan_hdd_cfg80211_sr_operations(struct wiphy *wiphy,
 	uint8_t srg_min_pd_offset = 0, srg_max_pd_offset = 0;
 	uint32_t nl_buf_len;
 	int ret;
-	uint32_t conc_vdev_id;
 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev);
+	struct wlan_objmgr_vdev *vdev;
 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SR_MAX + 1];
 	struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_SR_PARAMS_MAX + 1] = {0};
 	enum qca_wlan_sr_operation sr_oper;
@@ -684,33 +706,26 @@ static int __wlan_hdd_cfg80211_sr_operations(struct wiphy *wiphy,
 	struct sk_buff *skb;
 	struct cdp_pdev_obss_pd_stats_tlv stats;
 	uint8_t sr_device_modes;
+	bool is_pd_threshold_present = false;
 
 	hdd_enter_dev(wdev->netdev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam() ||
 	    QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM or Monitor mode");
 		return -EPERM;
 	}
 
-	sr_ctrl = wlan_vdev_mlme_get_sr_ctrl(adapter->vdev);
-	if ((adapter->device_mode == QDF_STA_MODE) &&
-	    (!ucfg_cm_is_vdev_connected(adapter->vdev) ||
-	     !sr_ctrl ||
-	    ((sr_ctrl & NON_SRG_PD_SR_DISALLOWED) &&
-	    !(sr_ctrl & SRG_INFO_PRESENT)))) {
-		hdd_err("station is not connected to AP that supports SR");
-		return -EPERM;
-	}
-	policy_mgr_get_mac_id_by_session_id(hdd_ctx->psoc, adapter->vdev_id,
-					    &mac_id);
-	conc_vdev_id = policy_mgr_get_conc_vdev_on_same_mac(hdd_ctx->psoc,
-							    adapter->vdev_id,
-							    mac_id);
-	if (conc_vdev_id != WLAN_INVALID_VDEV_ID &&
-	    !policy_mgr_sr_same_mac_conc_enabled(hdd_ctx->psoc)) {
-		hdd_err("don't allow SR in SCC/MCC");
-		return -EPERM;
+	vdev = hdd_objmgr_get_vdev_by_user(adapter, WLAN_HDD_ID_OBJ_MGR);
+	if (!vdev) {
+		hdd_err("Null VDEV");
+		return -EINVAL;
 	}
+	sr_ctrl = wlan_vdev_mlme_get_sr_ctrl(vdev);
 	/**
 	 * Reject command if SR concurrency is not allowed and
 	 * only STA mode is set in ini to enable SR.
@@ -719,64 +734,77 @@ static int __wlan_hdd_cfg80211_sr_operations(struct wiphy *wiphy,
 	if (!(sr_device_modes & (1 << adapter->device_mode))) {
 		hdd_debug("SR operation not allowed for mode %d",
 			  adapter->device_mode);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto exit;
 	}
 
-	ret = wlan_hdd_validate_context(hdd_ctx);
-	if (0 != ret)
-		return ret;
 	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
 		hdd_err("Driver Modules are closed");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto exit;
 	}
 	if (!sme_is_feature_supported_by_fw(DOT11AX)) {
 		hdd_err("11AX is not supported");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto exit;
 	}
-	status = ucfg_spatial_reuse_operation_allowed(hdd_ctx->psoc,
-						      adapter->vdev);
+	status = ucfg_spatial_reuse_operation_allowed(hdd_ctx->psoc, vdev);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		hdd_err("SR operations not allowed status: %u", status);
+		hdd_objmgr_put_vdev_by_user(vdev, WLAN_HDD_ID_OBJ_MGR);
 		return qdf_status_to_os_return(status);
 	}
 	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SR_MAX, data,
 				    data_len, wlan_hdd_sr_policy)) {
 		hdd_err("invalid attr");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto exit;
 	}
+
 	id = QCA_WLAN_VENDOR_ATTR_SR_OPERATION;
 	sr_oper_attr = tb[id];
-
 	if (!sr_oper_attr) {
 		hdd_err("SR operation not specified");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto exit;
 	}
 
 	sr_oper = nla_get_u8(sr_oper_attr);
 	hdd_debug("SR Operation 0x%x", sr_oper);
 
-	ucfg_spatial_reuse_get_sr_config(adapter->vdev, &sr_ctrl,
-					 &non_srg_max_pd_offset, &is_sr_enable);
-
+	ucfg_spatial_reuse_get_sr_config(vdev, &sr_ctrl, &non_srg_max_pd_offset,
+					 &is_sr_enable);
 	if (sr_oper != QCA_WLAN_SR_OPERATION_SR_ENABLE && !is_sr_enable) {
 		hdd_err("SR operation not allowed");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto exit;
 	}
 
 	id = QCA_WLAN_VENDOR_ATTR_SR_PARAMS;
 	sr_param_attr = tb[id];
-	if (sr_param_attr)
+	if (sr_param_attr) {
 		ret = wlan_cfg80211_nla_parse_nested(
 				tb2, QCA_WLAN_VENDOR_ATTR_SR_PARAMS_MAX,
 				sr_param_attr,
 				qca_wlan_vendor_srp_param_policy);
+		if (ret) {
+			hdd_err("sr_param_attr parse failed");
+			goto exit;
+		}
+	}
 	switch (sr_oper) {
 	case QCA_WLAN_SR_OPERATION_SR_ENABLE:
 	case QCA_WLAN_SR_OPERATION_SR_DISABLE:
-		if (sr_oper == QCA_WLAN_SR_OPERATION_SR_ENABLE)
-			is_sr_enable = 1;
-		else
-			is_sr_enable = 0;
+		if (sr_oper == QCA_WLAN_SR_OPERATION_SR_ENABLE) {
+			is_sr_enable = true;
+		} else {
+			is_sr_enable = false;
+			if (!wlan_vdev_mlme_get_he_spr_enabled(vdev)) {
+				hdd_debug("SR not enabled, reject disable command");
+				ret = -EINVAL;
+				goto exit;
+			}
+		}
 		/**
 		 * As per currenct implementation from userspace same
 		 * PD threshold value is configured for both SRG and
@@ -788,8 +816,9 @@ static int __wlan_hdd_cfg80211_sr_operations(struct wiphy *wiphy,
 			srg_pd_threshold =
 			nla_get_s32(
 			tb2[QCA_WLAN_VENDOR_ATTR_SR_PARAMS_SRG_PD_THRESHOLD]);
-			wlan_vdev_mlme_set_pd_threshold_present(adapter->vdev,
-								true);
+			is_pd_threshold_present = true;
+			wlan_vdev_mlme_set_pd_threshold_present(
+						vdev, is_pd_threshold_present);
 		}
 
 		if (is_sr_enable &&
@@ -798,102 +827,144 @@ static int __wlan_hdd_cfg80211_sr_operations(struct wiphy *wiphy,
 			nla_get_s32(
 			tb2[QCA_WLAN_VENDOR_ATTR_SR_PARAMS_NON_SRG_PD_THRESHOLD]
 			);
-			wlan_vdev_mlme_set_pd_threshold_present(adapter->vdev,
-								true);
+			is_pd_threshold_present = true;
+			wlan_vdev_mlme_set_pd_threshold_present(
+						vdev, is_pd_threshold_present);
+		}
+		if (is_pd_threshold_present) {
+			if (!hdd_check_mode_support_for_sr(adapter, sr_ctrl)) {
+				ret = -EINVAL;
+				goto exit;
+			}
 		}
 		hdd_debug("setting sr enable %d with pd threshold srg: %d non srg: %d",
 			  is_sr_enable, srg_pd_threshold, non_srg_pd_threshold);
 		/* Set the variables */
-		ucfg_spatial_reuse_set_sr_enable(adapter->vdev, is_sr_enable);
-		status = ucfg_spatial_reuse_setup_req(
-				adapter->vdev, hdd_ctx->pdev, is_sr_enable,
+		ucfg_spatial_reuse_set_sr_enable(vdev, is_sr_enable);
+		if (hdd_check_mode_support_for_sr(adapter, sr_ctrl)) {
+			status = ucfg_spatial_reuse_setup_req(
+				vdev, hdd_ctx->pdev, is_sr_enable,
 				srg_pd_threshold, non_srg_pd_threshold);
-		if (status != QDF_STATUS_SUCCESS) {
-			hdd_err("failed to enable Spatial Reuse feature");
-			return -EINVAL;
+			if (status != QDF_STATUS_SUCCESS) {
+				hdd_err("failed to enable Spatial Reuse feature");
+				ret = -EINVAL;
+				goto exit;
+			}
 		}
 
 		break;
 	case QCA_WLAN_SR_OPERATION_GET_STATS:
+		if (!hdd_check_mode_support_for_sr(adapter, sr_ctrl)) {
+			ret = -EINVAL;
+			goto exit;
+		}
 		status = policy_mgr_get_mac_id_by_session_id(hdd_ctx->psoc,
 							     adapter->vdev_id,
 							     &mac_id);
 		if (QDF_IS_STATUS_ERROR(status)) {
 			hdd_err("Failed to get mac_id for vdev_id: %u",
-				adapter->vdev_id);
-			return -EAGAIN;
+				adapter->vdev_id); {
+				ret = -EAGAIN;
+				goto exit;
+			}
+		}
+		if (hdd_get_sr_stats(hdd_ctx, mac_id, &stats)) {
+			ret = -EINVAL;
+			goto exit;
 		}
-		if (hdd_get_sr_stats(hdd_ctx, mac_id, &stats))
-			return -EINVAL;
 		nl_buf_len = hdd_get_srp_stats_len();
 		skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
 							       nl_buf_len);
 		if (!skb) {
 			hdd_err("wlan_cfg80211_vendor_cmd_alloc_reply_skb failed");
-			return -ENOMEM;
+			ret = -ENOMEM;
+			goto exit;
 		}
 		if (hdd_add_stats_info(skb, &stats)) {
 			wlan_cfg80211_vendor_free_skb(skb);
-			return -EINVAL;
+			ret = -EINVAL;
+			goto exit;
 		}
 
 		ret = wlan_cfg80211_vendor_cmd_reply(skb);
 		break;
 	case QCA_WLAN_SR_OPERATION_CLEAR_STATS:
+		if (!hdd_check_mode_support_for_sr(adapter, sr_ctrl)) {
+			ret = -EINVAL;
+			goto exit;
+		}
 		status = policy_mgr_get_mac_id_by_session_id(hdd_ctx->psoc,
 							     adapter->vdev_id,
 							     &mac_id);
 		if (QDF_IS_STATUS_ERROR(status)) {
 			hdd_err("Failed to get mac_id for vdev_id: %u",
 				adapter->vdev_id);
-			return -EAGAIN;
+			ret = -EAGAIN;
+			goto exit;
+		}
+		if (hdd_clear_sr_stats(hdd_ctx, mac_id)) {
+			ret = -EAGAIN;
+			goto exit;
 		}
-		if (hdd_clear_sr_stats(hdd_ctx, mac_id))
-			return -EAGAIN;
 		break;
 	case QCA_WLAN_SR_OPERATION_PSR_AND_NON_SRG_OBSS_PD_PROHIBIT:
+		if (!hdd_check_mode_support_for_sr(adapter, sr_ctrl)) {
+			ret = -EINVAL;
+			goto exit;
+		}
 		if (tb2[QCA_WLAN_VENDOR_ATTR_SR_PARAMS_HESIGA_VAL15_ENABLE])
 			sr_he_siga_val15_allowed = nla_get_u8(
 			tb2[QCA_WLAN_VENDOR_ATTR_SR_PARAMS_HESIGA_VAL15_ENABLE]
 			);
 		if (!sr_he_siga_val15_allowed) {
 			hdd_err("invalid sr_he_siga_val15_enable param");
-			return -EINVAL;
+			ret = -EINVAL;
+			goto exit;
 		}
 		if (!QDF_IS_STATUS_SUCCESS(ucfg_spatial_reuse_send_sr_prohibit(
-					  adapter->vdev,
-					  sr_he_siga_val15_allowed))) {
+					   vdev, sr_he_siga_val15_allowed))) {
 			hdd_debug("Prohibit command can not be sent");
-			return -EINVAL;
+			ret = -EINVAL;
+			goto exit;
 		}
 		break;
 	case QCA_WLAN_SR_OPERATION_PSR_AND_NON_SRG_OBSS_PD_ALLOW:
+		if (!hdd_check_mode_support_for_sr(adapter, sr_ctrl)) {
+			ret = -EINVAL;
+			goto exit;
+		}
 		if (!QDF_IS_STATUS_SUCCESS(ucfg_spatial_reuse_send_sr_prohibit(
-					   adapter->vdev, false))) {
+					   vdev, false))) {
 			hdd_debug("Prohibit command can not be sent");
-			return -EINVAL;
+			ret = -EINVAL;
+			goto exit;
 		}
 		break;
 	case QCA_WLAN_SR_OPERATION_GET_PARAMS:
-		wlan_vdev_mlme_get_srg_pd_offset(adapter->vdev,
-						 &srg_max_pd_offset,
+		if (!hdd_check_mode_support_for_sr(adapter, sr_ctrl)) {
+			ret = -EINVAL;
+			goto exit;
+		}
+		wlan_vdev_mlme_get_srg_pd_offset(vdev, &srg_max_pd_offset,
 						 &srg_min_pd_offset);
 		non_srg_max_pd_offset =
-			wlan_vdev_mlme_get_non_srg_pd_offset(adapter->vdev);
-		sr_ctrl = wlan_vdev_mlme_get_sr_ctrl(adapter->vdev);
+			wlan_vdev_mlme_get_non_srg_pd_offset(vdev);
+		sr_ctrl = wlan_vdev_mlme_get_sr_ctrl(vdev);
 		nl_buf_len = hdd_get_srp_param_len();
 		skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
 							       nl_buf_len);
 		if (!skb) {
 			hdd_err("wlan_cfg80211_vendor_cmd_alloc_reply_skb failed");
-			return -ENOMEM;
+			ret = -ENOMEM;
+			goto exit;
 		}
 		if (hdd_add_param_info(skb, srg_max_pd_offset,
 				       srg_min_pd_offset, non_srg_max_pd_offset,
 				       sr_ctrl,
 				       QCA_WLAN_VENDOR_ATTR_SR_PARAMS)) {
 			wlan_cfg80211_vendor_free_skb(skb);
-			return -EINVAL;
+			ret = -EINVAL;
+			goto exit;
 		}
 
 		ret = wlan_cfg80211_vendor_cmd_reply(skb);
@@ -905,7 +976,8 @@ static int __wlan_hdd_cfg80211_sr_operations(struct wiphy *wiphy,
 	}
 
 	hdd_exit();
-
+exit:
+	hdd_objmgr_put_vdev_by_user(vdev, WLAN_HDD_ID_OBJ_MGR);
 	return ret;
 }
 

+ 2 - 2
core/mac/src/pe/lim/lim_api.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -4106,7 +4106,7 @@ void lim_update_vdev_sr_elements(struct pe_session *session_entry,
 				   srp_ie->srg_info.info.srg_color);
 	lim_store_array_to_bit_map(&srg_partial_bssid_bit_map,
 				   srp_ie->srg_info.info.srg_partial_bssid);
-	pe_debug("Spatial Reuse Control field: %x Non-SRG Max PD Offset: %x SRG range %d - %d srg_color_bit_map:%lu srg_partial_bssid_bit_map: %lu",
+	pe_debug("Spatial Reuse Control field: %x Non-SRG Max PD Offset: %x SRG range %d - %d srg_color_bit_map:%llu srg_partial_bssid_bit_map: %llu",
 		 sr_ctrl, non_srg_max_pd_offset, srg_min_pd_offset,
 		 srg_max_pd_offset, srg_color_bit_map,
 		 srg_partial_bssid_bit_map);