Browse Source

qcacld-3.0: Set time quota for 2 MCC vdevs/adapters

If STA + STA connected in MCC, FW should distribute
the duty cycle between primary and secondary connection
in 70:30 ratio.

Quota for the 2nd role is calculated as 100 - quota of
first mode.

Change-Id: I36ab9a9717da1e1f0ff0e0e11a18681c97ed6c58
CRs-Fixed: 2927460
abhinav kumar 4 years ago
parent
commit
7e315ca4af

+ 31 - 0
components/mlme/dispatcher/inc/wlan_mlme_api.h

@@ -280,6 +280,16 @@ QDF_STATUS wlan_mlme_set_band_capability(struct wlan_objmgr_psoc *psoc,
 QDF_STATUS wlan_mlme_set_dual_sta_policy(struct wlan_objmgr_psoc *psoc,
 					 uint8_t dual_sta_config);
 
+/**
+ * wlan_mlme_get_dual_sta_policy() - Get the dual sta policy
+ * @psoc: pointer to psoc object
+ * @dual_sta_config: Value to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_dual_sta_policy(struct wlan_objmgr_psoc *psoc,
+					 uint8_t *dual_sta_config);
+
 /**
  * wlan_mlme_get_prevent_link_down() - Get the prevent link down config
  * @psoc: pointer to psoc object
@@ -1067,6 +1077,27 @@ QDF_STATUS wlan_mlme_set_fils_enabled_info(struct wlan_objmgr_psoc *psoc,
 QDF_STATUS wlan_mlme_set_primary_interface(struct wlan_objmgr_psoc *psoc,
 					   uint8_t value);
 
+/**
+ * wlan_mlme_set_default_primary_iface() - Set the default primary iface id
+ * for driver
+ * @psoc: pointer to psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_set_default_primary_iface(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_mlme_get_mcc_duty_cycle_percentage() - Get primary STA iface duty
+ * cycle percentage
+ * @psoc: pointer to psoc object
+ * @value: value that needs to be set from the caller
+ *
+ * API to get the MCC duty cycle for primary and secondary STA's
+ *
+ * Return: primary iface quota on success
+ */
+int wlan_mlme_get_mcc_duty_cycle_percentage(struct wlan_objmgr_pdev *pdev);
+
 /**
  * wlan_mlme_get_tl_delayed_trgr_frm_int() - Get delay interval(in ms)
  * of UAPSD auto trigger

+ 36 - 0
components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h

@@ -270,6 +270,20 @@ QDF_STATUS ucfg_mlme_set_dual_sta_policy(struct wlan_objmgr_psoc *psoc,
 	return wlan_mlme_set_dual_sta_policy(psoc, dual_sta_config);
 }
 
+/**
+ * ucfg_mlme_get_dual_sta_policy() - Get the Concurrent STA policy value
+ * @psoc: pointer to psoc object
+ * @dual_sta_config: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_dual_sta_policy(struct wlan_objmgr_psoc *psoc,
+					 uint8_t *dual_sta_config)
+{
+	return wlan_mlme_get_dual_sta_policy(psoc, dual_sta_config);
+}
+
 /**
  * ucfg_mlme_get_prevent_link_down() - Get the prevent link down config
  * @psoc: pointer to psoc object
@@ -1980,6 +1994,28 @@ QDF_STATUS ucfg_mlme_set_primary_interface(struct wlan_objmgr_psoc *psoc,
 	return wlan_mlme_set_primary_interface(psoc, value);
 }
 
+/**
+ * ucfg_mlme_get_mcc_duty_cycle_percentage() - Get primary STA iface MCC
+ * duty-cycle
+ *
+ * @psoc: pointer to psoc object
+ * @value: value that needs to be set from the caller
+ *
+ * primary and secondary STA iface MCC duty-cycle value in below format
+ * ******************************************************
+ * |bit 31-24 | bit 23-16 | bits 15-8   |bits 7-0   |
+ * | Unused   | Quota for | chan. # for |chan. # for|
+ * |          | 1st chan  | 1st chan.   |2nd chan.  |
+ * *****************************************************
+ *
+ * Return: primary iface MCC duty-cycle value
+ */
+static inline
+int ucfg_mlme_get_mcc_duty_cycle_percentage(struct wlan_objmgr_pdev *pdev)
+{
+	return wlan_mlme_get_mcc_duty_cycle_percentage(pdev);
+}
+
 /**
  * ucfg_mlme_set_enable_bcast_probe_rsp() - Set enable bcast probe resp info
  * @psoc: pointer to psoc object

+ 116 - 0
components/mlme/dispatcher/src/wlan_mlme_api.c

@@ -30,6 +30,9 @@
 #include "wlan_utility.h"
 #include "wlan_policy_mgr_ucfg.h"
 
+/* quota in milliseconds */
+#define MCC_DUTY_CYCLE 70
+
 QDF_STATUS wlan_mlme_get_cfg_str(uint8_t *dst, struct mlme_cfg_str *cfg_str,
 				 qdf_size_t *len)
 {
@@ -245,6 +248,22 @@ QDF_STATUS wlan_mlme_set_dual_sta_policy(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS wlan_mlme_get_dual_sta_policy(struct wlan_objmgr_psoc *psoc,
+					 uint8_t *dual_sta_config)
+
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return QDF_STATUS_E_FAILURE;
+
+	*dual_sta_config =
+		mlme_obj->cfg.gen.dual_sta_policy.concurrent_sta_policy;
+
+	return QDF_STATUS_SUCCESS;
+}
+
 QDF_STATUS wlan_mlme_get_prevent_link_down(struct wlan_objmgr_psoc *psoc,
 					   bool *prevent_link_down)
 {
@@ -2420,9 +2439,106 @@ QDF_STATUS wlan_mlme_set_primary_interface(struct wlan_objmgr_psoc *psoc,
 		return QDF_STATUS_E_FAILURE;
 
 	mlme_obj->cfg.gen.dual_sta_policy.primary_vdev_id = value;
+	mlme_debug("Set primary iface to :%d", value);
+
 	return QDF_STATUS_SUCCESS;
 }
 
+int wlan_mlme_get_mcc_duty_cycle_percentage(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_objmgr_psoc *psoc = NULL;
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+	uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint32_t i, operating_channel, quota_value = MCC_DUTY_CYCLE;
+	struct dual_sta_policy *dual_sta_policy;
+	uint32_t count, primary_sta_freq = 0, secondary_sta_freq = 0;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return -EINVAL;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return -EINVAL;
+	dual_sta_policy  = &mlme_obj->cfg.gen.dual_sta_policy;
+
+	if (dual_sta_policy->primary_vdev_id == WLAN_INVALID_VDEV_ID ||
+	    (dual_sta_policy->concurrent_sta_policy ==
+	     QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED)) {
+		mlme_debug("Invalid primary vdev id or policy is unbaised :%d",
+			   dual_sta_policy->concurrent_sta_policy);
+		return -EINVAL;
+	}
+
+	count = policy_mgr_get_mode_specific_conn_info(psoc, op_ch_freq_list,
+						       vdev_id_list,
+						       PM_STA_MODE);
+
+	/* Proceed only in case of STA+STA */
+	if (count != 2) {
+		mlme_debug("STA+STA concurrency is not present");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < count; i++) {
+		if (vdev_id_list[i] == dual_sta_policy->primary_vdev_id) {
+			primary_sta_freq = op_ch_freq_list[i];
+			mlme_debug("primary sta vdev:%d at inxex:%d, freq:%d",
+				   i, vdev_id_list[i], op_ch_freq_list[i]);
+		} else {
+			secondary_sta_freq = op_ch_freq_list[i];
+			mlme_debug("secondary sta vdev:%d at inxex:%d, freq:%d",
+				   i, vdev_id_list[i], op_ch_freq_list[i]);
+		}
+	}
+
+	if (!primary_sta_freq || !secondary_sta_freq) {
+		mlme_debug("Invalid primary or secondary sta freq");
+		return -EINVAL;
+	}
+
+	operating_channel = wlan_freq_to_chan(primary_sta_freq);
+
+	/*
+	 * The channel numbers for both adapters and the time
+	 * quota for the 1st adapter, i.e., one specified in cmd
+	 * are formatted as a bit vector
+	 * ******************************************************
+	 * |bit 31-24  | bit 23-16 |  bits 15-8  |bits 7-0   |
+	 * |  Unused   | Quota for | chan. # for |chan. # for|
+	 * |           |  1st chan | 1st chan.   |2nd chan.  |
+	 * ******************************************************
+	 */
+	mlme_debug("First connection channel No.:%d and quota:%dms",
+		   operating_channel, quota_value);
+	/* Move the time quota for first channel to bits 15-8 */
+	quota_value = quota_value << 8;
+	/*
+	 * Store the channel number of 1st channel at bits 7-0
+	 * of the bit vector
+	 */
+	quota_value |= operating_channel;
+		/* Second STA Connection */
+	operating_channel = wlan_freq_to_chan(secondary_sta_freq);
+	if (!operating_channel)
+		mlme_debug("Secondary adapter op channel is invalid");
+	/*
+	 * Now move the time quota and channel number of the
+	 * 1st adapter to bits 23-16 and bits 15-8 of the bit
+	 * vector, respectively.
+	 */
+	quota_value = quota_value << 8;
+	/*
+	 * Set the channel number for 2nd MCC vdev at bits
+	 * 7-0 of set_value
+	 */
+	quota_value |= operating_channel;
+	mlme_debug("quota value:%x", quota_value);
+
+	return quota_value;
+}
+
 QDF_STATUS wlan_mlme_set_enable_bcast_probe_rsp(struct wlan_objmgr_psoc *psoc,
 						bool value)
 {

+ 4 - 4
core/hdd/inc/wlan_hdd_main.h

@@ -4146,15 +4146,15 @@ static inline void hdd_send_peer_status_ind_to_app(
 #endif /* WIFI_POS_CONVERGENCE */
 
 /**
- * wlan_hdd_send_p2p_quota()- Send P2P Quota value to FW
+ * wlan_hdd_send_mcc_vdev_quota()- Send mcc vdev quota value to FW
  * @adapter: Adapter data
- * @sval:    P2P quota value
+ * @sval:    mcc vdev quota value
  *
- * Send P2P quota value to FW
+ * Send mcc vdev quota value value to FW
  *
  * Return: 0 success else failure
  */
-int wlan_hdd_send_p2p_quota(struct hdd_adapter *adapter, int sval);
+int wlan_hdd_send_mcc_vdev_quota(struct hdd_adapter *adapter, int sval);
 
 /**
  * wlan_hdd_send_p2p_quota()- Send MCC latency to FW

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

@@ -8633,7 +8633,9 @@ static int hdd_set_primary_interface(struct hdd_adapter *adapter,
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 	bool is_set_primary_iface;
 	QDF_STATUS status;
-	uint8_t primary_vdev_id;
+	uint8_t primary_vdev_id, dual_sta_policy;
+	int set_value;
+	uint32_t count;
 
 	/* ignore unless in STA mode */
 	if (adapter->device_mode != QDF_STA_MODE)
@@ -8651,6 +8653,41 @@ static int hdd_set_primary_interface(struct hdd_adapter *adapter,
 		return -EINVAL;
 	}
 
+	/*
+	 * send duty cycle percentage to FW only if STA + STA
+	 * concurrency is in MCC.
+	 */
+	count = policy_mgr_mode_specific_connection_count(hdd_ctx->psoc,
+							  PM_STA_MODE, NULL);
+	if (count != 2 &&
+	    !policy_mgr_current_concurrency_is_mcc(hdd_ctx->psoc)) {
+		hdd_debug("STA + STA concurrency is in MCC not present");
+		return -EINVAL;
+	}
+
+	status = ucfg_mlme_get_dual_sta_policy(hdd_ctx->psoc, &dual_sta_policy);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("could not get dual sta policy, %d", status);
+		return -EINVAL;
+	}
+
+	if (is_set_primary_iface && dual_sta_policy ==
+	    QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY) {
+		set_value =
+		   ucfg_mlme_get_mcc_duty_cycle_percentage(hdd_ctx->pdev);
+		if (set_value < 0) {
+			hdd_err("Invalid mcc duty cycle");
+			return -EINVAL;
+		}
+
+		if (QDF_IS_STATUS_ERROR(sme_set_mas(false))) {
+			hdd_err("Failed to disable mcc_adaptive_scheduler");
+				return -EINVAL;
+		}
+
+		wlan_hdd_send_mcc_vdev_quota(adapter, set_value);
+	}
+
 	return 0;
 }
 

+ 2 - 2
core/hdd/src/wlan_hdd_main.c

@@ -18629,13 +18629,13 @@ bool hdd_set_connection_in_progress(bool value)
 	return status;
 }
 
-int wlan_hdd_send_p2p_quota(struct hdd_adapter *adapter, int set_value)
+int wlan_hdd_send_mcc_vdev_quota(struct hdd_adapter *adapter, int set_value)
 {
 	if (!adapter) {
 		hdd_err("Invalid adapter");
 		return -EINVAL;
 	}
-	hdd_info("Send MCC P2P QUOTA to WMA: %d", set_value);
+	hdd_info("send mcc vdev quota to fw: %d", set_value);
 	sme_cli_set_command(adapter->vdev_id,
 			    WMA_VDEV_MCC_SET_TIME_QUOTA,
 			    set_value, VDEV_CMD);

+ 1 - 2
core/hdd/src/wlan_hdd_p2p.c

@@ -1445,8 +1445,7 @@ int wlan_hdd_set_mcc_p2p_quota(struct hdd_adapter *adapter,
 		set_value = set_second_connection_operating_channel(
 			hdd_ctx, set_value, adapter->vdev_id);
 
-
-		ret = wlan_hdd_send_p2p_quota(adapter, set_value);
+		ret = wlan_hdd_send_mcc_vdev_quota(adapter, set_value);
 	} else {
 		hdd_info("MCC is not active. Exit w/o setting latency");
 	}

+ 27 - 2
core/sme/src/csr/csr_api_roam.c

@@ -12689,9 +12689,11 @@ cm_csr_connect_done_ind(struct wlan_objmgr_vdev *vdev,
 {
 	struct mac_context *mac_ctx;
 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
-	int32_t ucast_cipher;
+	int32_t ucast_cipher, count;
 	struct set_context_rsp install_key_rsp;
-	int32_t rsn_cap;
+	int32_t rsn_cap, set_value;
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+	struct dual_sta_policy *dual_sta_policy;
 
 	/*
 	 * This API is to update legacy struct and should be removed once
@@ -12702,6 +12704,10 @@ cm_csr_connect_done_ind(struct wlan_objmgr_vdev *vdev,
 	if (!mac_ctx)
 		return QDF_STATUS_E_INVAL;
 
+	mlme_obj = mlme_get_psoc_ext_obj(mac_ctx->psoc);
+	if (!mlme_obj)
+		return QDF_STATUS_E_INVAL;
+
 	if (QDF_IS_STATUS_ERROR(rsp->connect_status)) {
 		cm_csr_set_idle(vdev_id);
 		sme_qos_update_hand_off(vdev_id, false);
@@ -12712,6 +12718,25 @@ cm_csr_connect_done_ind(struct wlan_objmgr_vdev *vdev,
 		return QDF_STATUS_SUCCESS;
 	}
 
+	dual_sta_policy = &mlme_obj->cfg.gen.dual_sta_policy;
+	count = policy_mgr_mode_specific_connection_count(mac_ctx->psoc,
+							  PM_STA_MODE, NULL);
+	/*
+	 * send duty cycle percentage to FW only if STA + STA
+	 * concurrency is in MCC.
+	 */
+	if (dual_sta_policy->primary_vdev_id != WLAN_UMAC_VDEV_ID_MAX &&
+	    dual_sta_policy->concurrent_sta_policy ==
+	    QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY && count == 2 &&
+	    policy_mgr_current_concurrency_is_mcc(mac_ctx->psoc)) {
+		if (QDF_IS_STATUS_ERROR(sme_set_mas(false)))
+			sme_err("Failed to disable mcc_adaptive_scheduler");
+		set_value =
+			wlan_mlme_get_mcc_duty_cycle_percentage(mac_ctx->pdev);
+		sme_cli_set_command(vdev_id, WMA_VDEV_MCC_SET_TIME_QUOTA,
+				    set_value, VDEV_CMD);
+	}
+
 	/*
 	 * For open mode authentication, send dummy install key response to
 	 * send OBSS scan and QOS event.