Browse Source

qcacld-3.0: Make XGAP wakable

XGAP power save event need host actions and notifying
the userspace.

Register for XGAP events to wake up host.

Change-Id: Ic58837580a35bd27ac5e87fc5debbd4f4d5b9b6b
CRs-Fixed: 3272421
Vijay Raj 2 years ago
parent
commit
724b68644c

+ 2 - 0
components/pmo/core/src/wlan_pmo_wow.c

@@ -462,6 +462,8 @@ void pmo_set_sap_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmap_size)
 				 bitmask);
 	pmo_set_wow_event_bitmap(WOW_RTT_11AZ_EVENT,
 				 wow_bitmap_size, bitmask);
+	pmo_set_wow_event_bitmap(WOW_XGAP_EVENT,
+				 wow_bitmap_size, bitmask);
 }
 
 uint8_t pmo_get_num_wow_filters(struct wlan_objmgr_psoc *psoc)

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

@@ -1858,6 +1858,7 @@ static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
 		.subcmd = QCA_NL80211_VENDOR_SUBCMD_SR,
 	},
 #endif
+	FEATURE_GREEN_AP_LOW_LATENCY_PWR_SAVE_EVENT
 };
 
 /**

+ 91 - 0
core/hdd/src/wlan_hdd_green_ap.c

@@ -31,6 +31,8 @@
 #include <wlan_green_ap_ucfg_api.h>
 #include "wlan_mlme_ucfg_api.h"
 #include <osif_vdev_sync.h>
+#include "wlan_osif_priv.h"
+#include "wlan_lmac_if_def.h"
 
 /**
  * hdd_green_ap_check_enable() - to check whether to enable green ap or not
@@ -275,4 +277,93 @@ wlan_hdd_enter_sap_low_pwr_mode(struct wiphy *wiphy,
 
 	return 0;
 }
+
+QDF_STATUS wlan_hdd_send_green_ap_ll_ps_event(
+					struct wlan_objmgr_vdev *vdev,
+					struct wlan_green_ap_ll_ps_event_param
+					*ll_ps_param)
+{
+	int index = QCA_NL80211_VENDOR_SUBCMD_DOZED_AP_INDEX;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t len;
+	struct vdev_osif_priv *osif_priv;
+	struct sk_buff *skb;
+
+	osif_priv = wlan_vdev_get_ospriv(vdev);
+	if (!osif_priv) {
+		hdd_err("OSIF priv is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	hdd_enter_dev(osif_priv->wdev->netdev);
+
+	len = NLMSG_HDRLEN;
+	/*QCA_WLAN_VENDOR_ATTR_DOZED_AP_NEXT_TSF*/
+	len += nla_total_size(sizeof(u64));
+	/*QCA_WLAN_VENDOR_ATTR_DOZED_AP_COOKIE*/
+	len += nla_total_size(sizeof(u64));
+	/*QCA_WLAN_VENDOR_ATTR_DOZED_AP_BI_MULTIPLIER*/
+	len += nla_total_size(sizeof(u16));
+
+	skb = wlan_cfg80211_vendor_event_alloc(osif_priv->wdev->wiphy,
+					       osif_priv->wdev, len,
+					       index, qdf_mem_malloc_flags());
+	if (!skb) {
+		hdd_err("skb allocation failed");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	if (wlan_cfg80211_nla_put_u64(skb, QCA_WLAN_VENDOR_ATTR_DOZED_AP_COOKIE,
+				      ll_ps_param->dialog_token)) {
+		hdd_err("nla_put failed");
+		status = QDF_STATUS_E_FAILURE;
+		goto nla_put_failure;
+	}
+
+	if (wlan_cfg80211_nla_put_u64(skb, QCA_WLAN_VENDOR_ATTR_DOZED_AP_NEXT_TSF,
+				      ll_ps_param->next_tsf)) {
+		hdd_err("nla_put failed for next tsf");
+		status = QDF_STATUS_E_FAILURE;
+		goto nla_put_failure;
+	}
+
+	if (nla_put_u16(skb, QCA_WLAN_VENDOR_ATTR_DOZED_AP_BI_MULTIPLIER,
+			ll_ps_param->bcn_mult)) {
+		hdd_err("nla_put for BI multiplier failed");
+		status = QDF_STATUS_E_FAILURE;
+		goto nla_put_failure;
+	}
+
+	hdd_debug("next_tsf : %llu, cookie: %llu beacon multiplier: %u",
+		  ll_ps_param->next_tsf, ll_ps_param->dialog_token,
+		  ll_ps_param->bcn_mult);
+
+	wlan_cfg80211_vendor_event(skb, qdf_mem_malloc_flags());
+
+	hdd_exit();
+
+	return status;
+
+nla_put_failure:
+	wlan_cfg80211_vendor_free_skb(skb);
+	return status;
+}
+
+QDF_STATUS green_ap_register_hdd_callback(struct wlan_objmgr_pdev *pdev,
+					  struct green_ap_hdd_callback *hdd_cback)
+{
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+
+	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+			pdev, WLAN_UMAC_COMP_GREEN_AP);
+
+	if (!green_ap_ctx) {
+		hdd_err("green ap context obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	green_ap_ctx->hdd_cback = *hdd_cback;
+
+	return QDF_STATUS_SUCCESS;
+}
 #endif

+ 20 - 0
core/hdd/src/wlan_hdd_green_ap.h

@@ -23,6 +23,10 @@
 #include "qdf_types.h"
 #include "qca_vendor.h"
 #include <net/netlink.h>
+#include <osif_vdev_sync.h>
+#include "wlan_lmac_if_def.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "wlan_green_ap_api.h"
 
 struct hdd_context;
 
@@ -114,12 +118,28 @@ wlan_hdd_sap_low_pwr_mode[QCA_WLAN_VENDOR_ATTR_DOZED_AP_MAX + 1];
 			      QCA_WLAN_VENDOR_ATTR_MAX)			\
 },
 
+#define FEATURE_GREEN_AP_LOW_LATENCY_PWR_SAVE_EVENT			\
+[QCA_NL80211_VENDOR_SUBCMD_DOZED_AP_INDEX] = {				\
+	.vendor_id = QCA_NL80211_VENDOR_ID,				\
+	.subcmd = QCA_NL80211_VENDOR_SUBCMD_DOZED_AP,			\
+},
+
 int
 wlan_hdd_enter_sap_low_pwr_mode(struct wiphy *wiphy,
 				struct wireless_dev *wdev,
 				const void *data, int data_len);
+
+QDF_STATUS wlan_hdd_send_green_ap_ll_ps_event(
+		struct wlan_objmgr_vdev *vdev,
+		struct wlan_green_ap_ll_ps_event_param *ll_ps_event_param);
+
+QDF_STATUS green_ap_register_hdd_callback(struct wlan_objmgr_pdev *pdev,
+					  struct green_ap_hdd_callback *hdd_cback);
+
 #else
 #define FEATURE_GREEN_AP_LOW_LATENCY_PWR_SAVE_COMMANDS
+
+#define FEATURE_GREEN_AP_LOW_LATENCY_PWR_SAVE_EVENT
 #endif
 
 #endif /* !defined(WLAN_HDD_GREEN_AP_H) */

+ 21 - 0
core/hdd/src/wlan_hdd_main.c

@@ -3640,6 +3640,25 @@ static void hdd_register_policy_manager_callback(
 }
 #endif
 
+#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
+static void hdd_register_green_ap_callback(struct wlan_objmgr_pdev *pdev)
+{
+	struct green_ap_hdd_callback hdd_cback;
+	qdf_mem_zero(&hdd_cback, sizeof(hdd_cback));
+
+	hdd_cback.send_event = wlan_hdd_send_green_ap_ll_ps_event;
+
+	if (QDF_STATUS_SUCCESS !=
+			green_ap_register_hdd_callback(pdev, &hdd_cback)) {
+		hdd_err("HDD callback registration for Green AP failed");
+	}
+}
+#else
+static inline void hdd_register_green_ap_callback(struct wlan_objmgr_pdev *pdev)
+{
+}
+#endif
+
 #ifdef WLAN_FEATURE_NAN
 #ifdef WLAN_FEATURE_SR
 static void hdd_register_sr_concurrency_cb(struct nan_callbacks *cb_obj)
@@ -14841,6 +14860,8 @@ int hdd_configure_cds(struct hdd_context *hdd_ctx)
 	if (hdd_green_ap_enable_egap(hdd_ctx))
 		hdd_debug("enhance green ap is not enabled");
 
+	hdd_register_green_ap_callback(hdd_ctx->pdev);
+
 	if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true))
 		hdd_debug("Failed to set wow pulse");
 

+ 4 - 0
core/wma/src/wma_features.c

@@ -1821,6 +1821,10 @@ static const uint8_t *wma_wow_wake_reason_str(A_INT32 wake_reason)
 		return "DELAYED_WAKEUP_TIMER_ELAPSED";
 	case WOW_REASON_DELAYED_WAKEUP_DATA_STORE_LIST_FULL:
 		return "DELAYED_WAKEUP_DATA_STORE_LIST_FULL";
+#ifndef WLAN_SUPPORT_GAP_LL_PS_MODE
+	case WOW_REASON_XGAP:
+		return "XGAP";
+#endif
 	default:
 		return "unknown";
 	}

+ 3 - 1
core/wma/src/wma_main.c

@@ -5756,9 +5756,11 @@ static void wma_green_ap_register_handlers(tp_wma_handle wma_handle)
 		target_if_green_ap_register_egap_event_handler(
 					wma_handle->pdev);
 
+	target_if_green_ap_register_ll_ps_event_handler(wma_handle->pdev);
+
 }
 #else
-static void wma_green_ap_register_handlers(tp_wma_handle wma_handle)
+static inline void wma_green_ap_register_handlers(tp_wma_handle wma_handle)
 {
 }
 #endif