|
@@ -94,6 +94,132 @@ QDF_STATUS target_if_register_green_ap_tx_ops(
|
|
|
return QDF_STATUS_SUCCESS;
|
|
|
}
|
|
|
|
|
|
+#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
|
|
|
+/**
|
|
|
+ * target_if_green_ap_ll_ps_event() - Green AP low latency
|
|
|
+ * Power save event handler
|
|
|
+ * @scn: pointer to scn handle
|
|
|
+ * @evt_buf: pointer to event buffer
|
|
|
+ * @data_len: data len of the event buffer
|
|
|
+ *
|
|
|
+ * Return: 0 for success, otherwise appropriate error code
|
|
|
+ */
|
|
|
+static int target_if_green_ap_ll_ps_event(ol_scn_t scn, uint8_t *evt_buf,
|
|
|
+ uint32_t data_len)
|
|
|
+{
|
|
|
+ QDF_STATUS status;
|
|
|
+ int err = 0;
|
|
|
+ struct wlan_objmgr_pdev *pdev;
|
|
|
+ struct wlan_green_ap_ll_ps_event_param *ll_ps_param;
|
|
|
+ void *wmi_hdl;
|
|
|
+ struct wlan_objmgr_psoc *psoc;
|
|
|
+ struct wlan_pdev_green_ap_ctx *green_ap_ctx;
|
|
|
+
|
|
|
+ psoc = target_if_get_psoc_from_scn_hdl(scn);
|
|
|
+ if (!psoc) {
|
|
|
+ green_ap_err("psoc is null");
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ pdev = target_if_get_pdev_from_scn_hdl(scn);
|
|
|
+ if (!pdev) {
|
|
|
+ green_ap_err("pdev is null");
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
|
|
|
+ pdev, WLAN_UMAC_COMP_GREEN_AP);
|
|
|
+ if (!green_ap_ctx) {
|
|
|
+ green_ap_err("green_ap_ctx not found");
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ ll_ps_param = qdf_mem_malloc(sizeof(*ll_ps_param));
|
|
|
+ if (!ll_ps_param) {
|
|
|
+ green_ap_err("Unable to allocate memory");
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ qdf_mem_zero(ll_ps_param, sizeof(*ll_ps_param));
|
|
|
+
|
|
|
+ wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev);
|
|
|
+ if (!wmi_hdl) {
|
|
|
+ green_ap_err("null wmi_hdl");
|
|
|
+ err = -EINVAL;
|
|
|
+ goto free_event_param;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (wmi_unified_extract_green_ap_ll_ps_param(wmi_hdl,
|
|
|
+ evt_buf,
|
|
|
+ ll_ps_param)) {
|
|
|
+ green_ap_err("unable to extract green ap ll ps event params");
|
|
|
+ err = -EINVAL;
|
|
|
+ goto free_event_param;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((ll_ps_param->dialog_token % 2))
|
|
|
+ ll_ps_param->bcn_mult = green_ap_ctx->bcn_mult;
|
|
|
+ else
|
|
|
+ ll_ps_param->bcn_mult = 1;
|
|
|
+
|
|
|
+ green_ap_debug("Next TSF: %llu Dialog Token: %llu bcn_mult: %u",
|
|
|
+ ll_ps_param->next_tsf,
|
|
|
+ ll_ps_param->dialog_token,
|
|
|
+ ll_ps_param->bcn_mult);
|
|
|
+
|
|
|
+ status = wlan_green_ap_send_ll_ps_event_params(pdev,
|
|
|
+ ll_ps_param);
|
|
|
+ if (status != QDF_STATUS_SUCCESS) {
|
|
|
+ wmi_err("wlan_green_ap_send_ll_ps_event failed");
|
|
|
+ err = -EINVAL;
|
|
|
+ goto free_event_param;
|
|
|
+ }
|
|
|
+
|
|
|
+free_event_param:
|
|
|
+ qdf_mem_free(ll_ps_param);
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
+QDF_STATUS target_if_green_ap_register_ll_ps_event_handler(
|
|
|
+ struct wlan_objmgr_pdev *pdev)
|
|
|
+{
|
|
|
+ struct wlan_pdev_green_ap_ctx *green_ap_ctx;
|
|
|
+ QDF_STATUS ret;
|
|
|
+ wmi_unified_t wmi_hdl;
|
|
|
+
|
|
|
+ if (!pdev) {
|
|
|
+ green_ap_err("pdev is null");
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev);
|
|
|
+ if (!wmi_hdl) {
|
|
|
+ green_ap_err("null wmi_hdl");
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
|
|
|
+ pdev, WLAN_UMAC_COMP_GREEN_AP);
|
|
|
+ if (!green_ap_ctx) {
|
|
|
+ green_ap_err("green ap context obtained is NULL");
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = wmi_unified_register_event_handler(
|
|
|
+ wmi_hdl,
|
|
|
+ wmi_xgap_enable_complete_eventid,
|
|
|
+ target_if_green_ap_ll_ps_event,
|
|
|
+ WMI_RX_UMAC_CTX);
|
|
|
+
|
|
|
+ if (QDF_IS_STATUS_ERROR(ret))
|
|
|
+ green_ap_err("Failed to register Enhance Green AP event");
|
|
|
+ else
|
|
|
+ green_ap_debug("Set the Enhance Green AP event handler");
|
|
|
+
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
/**
|
|
|
* target_if_green_ap_egap_status_info_event() - egap status info event
|
|
|
* @scn: pointer to scn handle
|