Kaynağa Gözat

qcacmn: Add support to force power save the active MLO links

Add MLO manager and target interface support to force power
save on all the active MLO links for a defined number of
beacon periods. Force power save allows the firmware to
suspend STA links for X beacon periods and remain asleep
even if the AP advertises TIM as opposed to regular power
save mode where STA links wake up if the AP indicates that
it has buffered data to send.

Change-Id: Idb3ea42cfc2333a4b177780d09ddec6904ea0c16
CRs-Fixed: 3514468
Gururaj Pandurangi 2 yıl önce
ebeveyn
işleme
2d67497cfb

+ 10 - 0
target_if/mlo_mgr/inc/target_if_mlo_mgr.h

@@ -93,6 +93,16 @@ QDF_STATUS target_if_mlo_send_link_removal_cmd(
 		struct wlan_objmgr_psoc *psoc,
 		const struct mlo_link_removal_cmd_params *param);
 
+/**
+ * target_if_mlo_send_vdev_pause() - Send WMI command for MLO vdev pause
+ * @psoc: psoc pointer
+ * @info: MLO vdev pause information
+ *
+ * Return: QDF_STATUS of operation
+ */
+QDF_STATUS target_if_mlo_send_vdev_pause(struct wlan_objmgr_psoc *psoc,
+					 struct mlo_vdev_pause *info);
+
 /**
  * target_if_extract_mlo_link_removal_info_mgmt_rx() - Extract MLO link removal
  * information from MGMT Rx event

+ 21 - 0
target_if/mlo_mgr/src/target_if_mlo_mgr.c

@@ -631,6 +631,25 @@ QDF_STATUS target_if_mlo_send_link_removal_cmd(
 	return wmi_send_mlo_link_removal_cmd(wmi_handle, param);
 }
 
+QDF_STATUS target_if_mlo_send_vdev_pause(struct wlan_objmgr_psoc *psoc,
+					 struct mlo_vdev_pause *info)
+{
+	struct wmi_unified *wmi_handle;
+
+	if (!psoc) {
+		target_if_err("null psoc");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("null handle");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wmi_send_mlo_vdev_pause(wmi_handle, info);
+}
+
 /**
  * target_if_mlo_register_tx_ops() - lmac handler to register mlo tx ops
  *  callback functions
@@ -664,6 +683,8 @@ target_if_mlo_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
 	mlo_tx_ops->send_link_removal_cmd = target_if_mlo_send_link_removal_cmd;
 	mlo_tx_ops->request_link_state_info_cmd =
 		target_if_request_ml_link_state_info;
+	mlo_tx_ops->send_vdev_pause = target_if_mlo_send_vdev_pause;
+
 	return QDF_STATUS_SUCCESS;
 }
 

+ 10 - 0
umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h

@@ -894,6 +894,16 @@ struct mlo_bcast_t2lm_info {
 	uint8_t vdev_id[MAX_AP_MLDS_PER_LINK];
 	uint32_t expected_duration[MAX_AP_MLDS_PER_LINK];
 };
+
+/**
+ * struct mlo_vdev_pause - ML vdev pause info
+ * @vdev_id: vdev id of vdev to be paused
+ * @vdev_pause_duration: vdev pause duration
+ */
+struct mlo_vdev_pause {
+	uint16_t vdev_id;
+	uint32_t vdev_pause_duration;
+};
 #endif
 
 /**

+ 3 - 0
umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h

@@ -1511,6 +1511,7 @@ struct wlan_lmac_if_son_rx_ops {
  * @shmem_local_ops: operations specific to WLAN_MLO_GLOBAL_SHMEM_SUPPORT
  * @send_tid_to_link_mapping: function to send T2LM command to FW
  * @send_link_removal_cmd: function to send MLO link removal command to FW
+ * @send_vdev_pause: function to send MLO vdev pause to FW
  */
 struct wlan_lmac_if_mlo_tx_ops {
 	QDF_STATUS (*register_events)(struct wlan_objmgr_psoc *psoc);
@@ -1529,6 +1530,8 @@ struct wlan_lmac_if_mlo_tx_ops {
 	QDF_STATUS (*send_link_removal_cmd)(
 		struct wlan_objmgr_psoc *psoc,
 		const struct mlo_link_removal_cmd_params *param);
+	QDF_STATUS (*send_vdev_pause)(struct wlan_objmgr_psoc *psoc,
+				      struct mlo_vdev_pause *info);
 };
 
 /**

+ 22 - 0
umac/mlo_mgr/inc/wlan_mlo_mgr_sta.h

@@ -703,6 +703,21 @@ void mlo_process_ml_reconfig_ie(struct wlan_objmgr_vdev *vdev,
 				struct scan_cache_entry *scan_entry,
 				uint8_t *ml_ie, qdf_size_t ml_ie_len,
 				struct mlo_partner_info *partner_info);
+
+/**
+ * wlan_mlo_send_vdev_pause() - send MLO vdev pause to FW
+ * @psoc: pointer to psoc
+ * @vdev: vdev pointer
+ * @session_id: session ID
+ * @vdev_pause_dur: vdev pause duration
+ *
+ * Return: None
+ */
+void wlan_mlo_send_vdev_pause(struct wlan_objmgr_psoc *psoc,
+			      struct wlan_objmgr_vdev *vdev,
+			      uint16_t session_id,
+			      uint16_t vdev_pause_dur);
+
 /**
  * mlo_allocate_and_copy_ies() - allocate and copy ies
  * @target: target connect req pointer
@@ -924,5 +939,12 @@ mlo_get_link_state_context(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_SUCCESS;
 }
 #endif
+
+static inline
+void wlan_mlo_send_vdev_pause(struct wlan_objmgr_psoc *psoc,
+			      struct wlan_objmgr_vdev *vdev,
+			      uint16_t session_id,
+			      uint16_t vdev_pause_dur)
+{}
 #endif
 #endif

+ 27 - 0
umac/mlo_mgr/src/wlan_mlo_mgr_sta.c

@@ -2503,4 +2503,31 @@ mlo_get_link_state_context(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_SUCCESS;
 }
 
+void
+wlan_mlo_send_vdev_pause(struct wlan_objmgr_psoc *psoc,
+			 struct wlan_objmgr_vdev *vdev,
+			 uint16_t session_id,
+			 uint16_t vdev_pause_dur)
+{
+	struct wlan_lmac_if_mlo_tx_ops *mlo_tx_ops;
+	struct mlo_vdev_pause vdev_pause_info;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	mlo_tx_ops = &psoc->soc_cb.tx_ops->mlo_ops;
+	if (!mlo_tx_ops) {
+		mlo_err("tx_ops is null!");
+		return;
+	}
+
+	if (!mlo_tx_ops->send_vdev_pause) {
+		mlo_err("send_vdev_pause is null");
+		return;
+	}
+
+	vdev_pause_info.vdev_id = session_id;
+	vdev_pause_info.vdev_pause_duration = vdev_pause_dur;
+	status = mlo_tx_ops->send_vdev_pause(psoc, &vdev_pause_info);
+	if (QDF_IS_STATUS_ERROR(status))
+		mlo_err("Failed to send vdev pause to FW");
+}
 #endif