浏览代码

qcacld-3.0: Allow iface pause override for unit test suspend

For testing purposes, expose the ability to override the interface pause
setting sent to firmware during WoW enable. Relatedly, allow userspace
to specify which wakeup trigger firmware should use, instead of assuming
HTC wakeup.

Change-Id: I265ccef7ca5304c94bcb5ff2eb9a3d35cfa74191
CRs-Fixed: 2011131
Dustin Brown 8 年之前
父节点
当前提交
5409643f2e

+ 11 - 3
core/hdd/inc/wlan_hdd_power.h

@@ -325,6 +325,7 @@ void wlan_hdd_inc_suspend_stats(hdd_context_t *hdd_ctx,
 /**
  * wlan_hdd_unit_test_bus_suspend() - suspend the wlan bus
  * @state: state containing the suspend source event
+ * @wow_params: collection of wow enable override parameters
  *
  * This function does the same as wlan_hdd_bus_suspend, but additionally passes
  * the appropriate flags to FW, indicating this is a unit-test suspend and it
@@ -332,7 +333,8 @@ void wlan_hdd_inc_suspend_stats(hdd_context_t *hdd_ctx,
  *
  * Return: 0 for success or error code
  */
-int wlan_hdd_unit_test_bus_suspend(pm_message_t state);
+int wlan_hdd_unit_test_bus_suspend(pm_message_t state,
+				   struct wow_enable_params wow_params);
 
 /**
  * hdd_wlan_fake_apps_resume() - Resume from unit-test triggered suspend
@@ -347,10 +349,14 @@ int hdd_wlan_fake_apps_resume(struct wiphy *wiphy, struct net_device *dev);
  * hdd_wlan_fake_apps_suspend() - Initiate a unit-test triggered suspend
  * @wiphy: the kernel wiphy struct for the device being suspended
  * @dev: the kernel net_device struct for the device being suspended
+ * @pause_setting: interface pause override setting
+ * @resume_setting: resume trigger override setting
  *
  * Return: Zero on success, suspend related non-zero error code on failure
  */
-int hdd_wlan_fake_apps_suspend(struct wiphy *wiphy, struct net_device *dev);
+int hdd_wlan_fake_apps_suspend(struct wiphy *wiphy, struct net_device *dev,
+			       enum wow_interface_pause pause_setting,
+			       enum wow_resume_trigger resume_setting);
 #else
 static inline int
 hdd_wlan_fake_apps_resume(struct wiphy *wiphy, struct net_device *dev)
@@ -359,7 +365,9 @@ hdd_wlan_fake_apps_resume(struct wiphy *wiphy, struct net_device *dev)
 }
 
 static inline int
-hdd_wlan_fake_apps_suspend(struct wiphy *wiphy, struct net_device *dev)
+hdd_wlan_fake_apps_suspend(struct wiphy *wiphy, struct net_device *dev,
+			   enum wow_interface_pause pause_setting,
+			   enum wow_resume_trigger resume_setting)
 {
 	return 0;
 }

+ 10 - 9
core/hdd/src/wlan_hdd_driver_ops.c

@@ -504,7 +504,7 @@ static void wlan_hdd_update_status(uint32_t status)
 /**
  * __wlan_hdd_bus_suspend() - handles platform supsend
  * @state: suspend message from the kernel
- * @wow_flags: bitmap of WMI WOW flags to pass to FW
+ * @wow_params: collection of wow enable override parameters
  *
  * Does precondtion validation. Ensures that a subsystem restart isn't in
  * progress.  Ensures that no load or unload is in progress.
@@ -516,7 +516,8 @@ static void wlan_hdd_update_status(uint32_t status)
  *     -EBUSY or -EAGAIN if another opperation is in progress and
  *     wlan will not be ready to suspend in time.
  */
-static int __wlan_hdd_bus_suspend(pm_message_t state, uint32_t wow_flags)
+static int __wlan_hdd_bus_suspend(pm_message_t state,
+				  struct wow_enable_params wow_params)
 {
 	hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
 	void *hif_ctx;
@@ -524,8 +525,7 @@ static int __wlan_hdd_bus_suspend(pm_message_t state, uint32_t wow_flags)
 	int status;
 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
 
-	hdd_info("starting bus suspend; event:%d, flags:%u",
-		 state.event, wow_flags);
+	hdd_info("starting bus suspend; event:%d", state.event);
 
 	err = wlan_hdd_validate_context(hdd_ctx);
 	if (err) {
@@ -551,7 +551,7 @@ static int __wlan_hdd_bus_suspend(pm_message_t state, uint32_t wow_flags)
 		goto done;
 	}
 
-	err = wma_bus_suspend(wow_flags);
+	err = wma_bus_suspend(wow_params);
 	if (err) {
 		hdd_err("Failed wma bus suspend");
 		goto resume_oltxrx;
@@ -580,22 +580,23 @@ done:
 int wlan_hdd_bus_suspend(pm_message_t state)
 {
 	int ret;
+	struct wow_enable_params default_params = {0};
 
 	cds_ssr_protect(__func__);
-	ret = __wlan_hdd_bus_suspend(state, 0);
+	ret = __wlan_hdd_bus_suspend(state, default_params);
 	cds_ssr_unprotect(__func__);
 
 	return ret;
 }
 
 #ifdef WLAN_SUSPEND_RESUME_TEST
-int wlan_hdd_unit_test_bus_suspend(pm_message_t state)
+int wlan_hdd_unit_test_bus_suspend(pm_message_t state,
+				   struct wow_enable_params wow_params)
 {
 	int ret;
 
 	cds_ssr_protect(__func__);
-	ret = __wlan_hdd_bus_suspend(state, WMI_WOW_FLAG_UNIT_TEST_ENABLE |
-				     WMI_WOW_FLAG_DO_HTC_WAKEUP);
+	ret = __wlan_hdd_bus_suspend(state, wow_params);
 	cds_ssr_unprotect(__func__);
 
 	return ret;

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

@@ -2551,7 +2551,8 @@ static int __iw_softap_set_two_ints_getnone(struct net_device *dev,
 					WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
 					value[1], value[2], DBG_CMD);
 	case QCSAP_SET_WLAN_SUSPEND:
-		ret = hdd_wlan_fake_apps_suspend(hdd_ctx->wiphy, dev);
+		ret = hdd_wlan_fake_apps_suspend(hdd_ctx->wiphy, dev,
+						 value[1], value[2]);
 		break;
 	case QCSAP_SET_WLAN_RESUME:
 		ret = hdd_wlan_fake_apps_resume(hdd_ctx->wiphy, dev);

+ 24 - 2
core/hdd/src/wlan_hdd_power.c

@@ -2262,6 +2262,7 @@ int hdd_set_qpower_config(hdd_context_t *hddctx, hdd_adapter_t *adapter,
 	return 0;
 }
 
+
 #ifdef WLAN_SUSPEND_RESUME_TEST
 /*
  * On iHelium there are 12 CE irqs and #2 is the wake irq. This may not be
@@ -2345,15 +2346,36 @@ static void hdd_wlan_fake_apps_resume_irq_callback(uint32_t val)
 	g_dev = NULL;
 }
 
-int hdd_wlan_fake_apps_suspend(struct wiphy *wiphy, struct net_device *dev)
+int hdd_wlan_fake_apps_suspend(struct wiphy *wiphy, struct net_device *dev,
+			       enum wow_interface_pause pause_setting,
+			       enum wow_resume_trigger resume_setting)
 {
 	qdf_device_t qdf_dev;
 	struct hif_opaque_softc *hif_ctx;
 	pm_message_t state;
 	int i, resume_err, suspend_err;
+	struct wow_enable_params wow_params = {
+		.is_unit_test = true,
+		.interface_pause = pause_setting,
+		.resume_trigger = resume_setting
+	};
 
 	hdd_info("Unit-test suspend WLAN");
 
+	if (pause_setting < WOW_INTERFACE_PAUSE_DEFAULT ||
+	    pause_setting >= WOW_INTERFACE_PAUSE_COUNT) {
+		hdd_err("Invalid interface pause %d (expected range [0, 2])",
+			pause_setting);
+		return -EINVAL;
+	}
+
+	if (resume_setting < WOW_RESUME_TRIGGER_DEFAULT ||
+	    resume_setting >= WOW_RESUME_TRIGGER_COUNT) {
+		hdd_err("Invalid resume trigger %d (expected range [0, 2])",
+			resume_setting);
+		return -EINVAL;
+	}
+
 	qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
 	if (!qdf_dev) {
 		hdd_err("Failed to get QDF device context");
@@ -2376,7 +2398,7 @@ int hdd_wlan_fake_apps_suspend(struct wiphy *wiphy, struct net_device *dev)
 		goto resume_done;
 
 	state.event = PM_EVENT_SUSPEND;
-	suspend_err = wlan_hdd_unit_test_bus_suspend(state);
+	suspend_err = wlan_hdd_unit_test_bus_suspend(state, wow_params);
 	if (suspend_err)
 		goto cfg80211_resume;
 

+ 4 - 2
core/hdd/src/wlan_hdd_wext.c

@@ -12038,9 +12038,11 @@ static int __iw_set_two_ints_getnone(struct net_device *dev,
 	case WE_SET_MON_MODE_CHAN:
 		ret = wlan_hdd_set_mon_chan(pAdapter, value[1], value[2]);
 		break;
-	case WE_SET_WLAN_SUSPEND:
-		ret = hdd_wlan_fake_apps_suspend(hdd_ctx->wiphy, dev);
+	case WE_SET_WLAN_SUSPEND: {
+		ret = hdd_wlan_fake_apps_suspend(hdd_ctx->wiphy, dev,
+						 value[1], value[2]);
 		break;
+	}
 	case WE_SET_WLAN_RESUME:
 		ret = hdd_wlan_fake_apps_resume(hdd_ctx->wiphy, dev);
 		break;

+ 44 - 0
core/mac/inc/sir_api.h

@@ -6827,4 +6827,48 @@ struct scan_chan_info {
 	uint32_t tx_frame_count;
 	uint32_t clock_freq;
 };
+
+/**
+ * enum wow_resume_trigger - resume trigger override setting values
+ * @WOW_RESUME_TRIGGER_DEFAULT: fw to use platform default resume trigger
+ * @WOW_RESUME_TRIGGER_HTC_WAKEUP: force fw to use HTC Wakeup to resume
+ * @WOW_RESUME_TRIGGER_GPIO: force fw to use GPIO to resume
+ * @WOW_RESUME_TRIGGER_COUNT: number of resume trigger options
+ */
+enum wow_resume_trigger {
+	/* always first */
+	WOW_RESUME_TRIGGER_DEFAULT = 0,
+	WOW_RESUME_TRIGGER_HTC_WAKEUP,
+	WOW_RESUME_TRIGGER_GPIO,
+	/* always last */
+	WOW_RESUME_TRIGGER_COUNT
+};
+
+/**
+ * enum wow_interface_pause - interface pause override setting values
+ * @WOW_INTERFACE_PAUSE_DEFAULT: use platform default interface pause setting
+ * @WOW_INTERFACE_PAUSE_ENABLE: force interface pause setting to enabled
+ * @WOW_INTERFACE_PAUSE_DISABLE: force interface pause setting to disabled
+ * @WOW_INTERFACE_PAUSE_COUNT: number of interface pause options
+ */
+enum wow_interface_pause {
+	/* always first */
+	WOW_INTERFACE_PAUSE_DEFAULT = 0,
+	WOW_INTERFACE_PAUSE_ENABLE,
+	WOW_INTERFACE_PAUSE_DISABLE,
+	/* always last */
+	WOW_INTERFACE_PAUSE_COUNT
+};
+
+/**
+ * struct wow_enable_params - A collection of wow enable override parameters
+ * @is_unit_test: true to notify fw this is a unit-test suspend
+ * @interface_pause: used to override the interface pause indication sent to fw
+ * @resume_trigger: used to force fw to use a particular resume method
+ */
+struct wow_enable_params {
+	bool is_unit_test;
+	enum wow_interface_pause interface_pause;
+	enum wow_resume_trigger resume_trigger;
+};
 #endif /* __SIR_API_H */

+ 8 - 4
core/wma/inc/wma_api.h

@@ -134,9 +134,11 @@ QDF_STATUS wma_set_reg_domain(void *clientCtxt, v_REGDOMAIN_t regId);
 QDF_STATUS wma_get_wcnss_software_version(void *p_cds_gctx,
 					  uint8_t *pVersion,
 					  uint32_t versionBufferSize);
-int wma_runtime_suspend(uint32_t wow_flags);
+
+int wma_runtime_suspend(struct wow_enable_params wow_params);
 int wma_runtime_resume(void);
-int wma_bus_suspend(uint32_t wow_flags);
+
+int wma_bus_suspend(struct wow_enable_params wow_params);
 int wma_is_target_wake_up_received(void);
 int wma_clear_target_wake_up(void);
 QDF_STATUS wma_suspend_target(WMA_HANDLE handle, int disable_target_intr);
@@ -147,8 +149,10 @@ QDF_STATUS wma_resume_target(WMA_HANDLE handle);
 QDF_STATUS wma_disable_wow_in_fw(WMA_HANDLE handle);
 QDF_STATUS wma_disable_d0wow_in_fw(WMA_HANDLE handle);
 bool wma_is_wow_mode_selected(WMA_HANDLE handle);
-QDF_STATUS wma_enable_wow_in_fw(WMA_HANDLE handle, uint32_t wow_flags);
-QDF_STATUS wma_enable_d0wow_in_fw(WMA_HANDLE handle, uint32_t wow_flags);
+QDF_STATUS wma_enable_wow_in_fw(WMA_HANDLE handle,
+				struct wow_enable_params wow_params);
+QDF_STATUS wma_enable_d0wow_in_fw(WMA_HANDLE handle,
+				  struct wow_enable_params wow_params);
 bool wma_check_scan_in_progress(WMA_HANDLE handle);
 void wma_set_peer_authorized_cb(void *wma_ctx, wma_peer_authorized_fp auth_cb);
 QDF_STATUS wma_set_peer_param(void *wma_ctx, uint8_t *peer_addr,

+ 49 - 14
core/wma/src/wma_features.c

@@ -3451,11 +3451,12 @@ static inline void wma_set_wow_bus_suspend(tp_wma_handle wma, int val)
 /**
  * wma_enable_wow_in_fw() - wnable wow in fw
  * @wma: wma handle
- * @wow_flags: bitmap of WMI WOW flags to pass to FW
+ * @wow_params: collection of wow enable override parameters
  *
  * Return: QDF status
  */
-QDF_STATUS wma_enable_wow_in_fw(WMA_HANDLE handle, uint32_t wow_flags)
+QDF_STATUS wma_enable_wow_in_fw(WMA_HANDLE handle,
+				struct wow_enable_params wow_params)
 {
 	tp_wma_handle wma = handle;
 	int ret;
@@ -3481,8 +3482,42 @@ QDF_STATUS wma_enable_wow_in_fw(WMA_HANDLE handle, uint32_t wow_flags)
 		 host_credits, wmi_pending_cmds);
 
 	param.enable = true;
-	param.can_suspend_link = htc_can_suspend_link(wma->htc_handle);
-	param.flags = wow_flags;
+	if (wow_params.is_unit_test)
+		param.flags = WMI_WOW_FLAG_UNIT_TEST_ENABLE;
+
+	switch (wow_params.interface_pause) {
+	default:
+		WMA_LOGE("Invalid interface pause setting: %d",
+			 wow_params.interface_pause);
+		/* intentional fall-through to default */
+	case WOW_INTERFACE_PAUSE_DEFAULT:
+		param.can_suspend_link = htc_can_suspend_link(wma->htc_handle);
+		break;
+	case WOW_INTERFACE_PAUSE_ENABLE:
+		param.can_suspend_link = true;
+		break;
+	case WOW_INTERFACE_PAUSE_DISABLE:
+		param.can_suspend_link = false;
+		break;
+	}
+
+	switch (wow_params.resume_trigger) {
+	default:
+		WMA_LOGE("Invalid resume trigger setting: %d",
+			 wow_params.resume_trigger);
+		/* intentional fall-through to default */
+	case WOW_RESUME_TRIGGER_DEFAULT:
+	case WOW_RESUME_TRIGGER_GPIO:
+		/*
+		 * GPIO is currently implicit. This means you can't actually
+		 * force GPIO if a platform's default wake trigger is HTC wakeup
+		 */
+		break;
+	case WOW_RESUME_TRIGGER_HTC_WAKEUP:
+		param.flags |= WMI_WOW_FLAG_DO_HTC_WAKEUP;
+		break;
+	}
+
 	ret = wmi_unified_wow_enable_send(wma->wmi_handle, &param,
 				   WMA_WILDCARD_PDEV_ID);
 	if (ret) {
@@ -5492,14 +5527,15 @@ failure:
 /**
  * __wma_bus_suspend(): handles bus suspend for wma
  * @type: is this suspend part of runtime suspend or system suspend?
- * @wow_flags: bitmap of WMI WOW flags to pass to FW
+ * @wow_params: collection of wow enable override parameters
  *
  * Bails if a scan is in progress.
  * Calls the appropriate handlers based on configuration and event.
  *
  * Return: 0 for success or error code
  */
-static int __wma_bus_suspend(enum qdf_suspend_type type, uint32_t wow_flags)
+static int __wma_bus_suspend(enum qdf_suspend_type type,
+			     struct wow_enable_params wow_params)
 {
 	WMA_HANDLE handle = cds_get_context(QDF_MODULE_ID_WMA);
 	if (NULL == handle) {
@@ -5523,7 +5559,7 @@ static int __wma_bus_suspend(enum qdf_suspend_type type, uint32_t wow_flags)
 				wma_is_wow_mode_selected(handle));
 
 	if (wma_is_wow_mode_selected(handle)) {
-		QDF_STATUS status = wma_enable_wow_in_fw(handle, wow_flags);
+		QDF_STATUS status = wma_enable_wow_in_fw(handle, wow_params);
 		return qdf_status_to_os_return(status);
 	}
 
@@ -5532,7 +5568,7 @@ static int __wma_bus_suspend(enum qdf_suspend_type type, uint32_t wow_flags)
 
 /**
  * wma_runtime_suspend() - handles runtime suspend request from hdd
- * @wow_flags: bitmap of WMI WOW flags to pass to FW
+ * @wow_params: collection of wow enable override parameters
  *
  * Calls the appropriate handler based on configuration and event.
  * Last busy marking should prevent race conditions between processing
@@ -5544,23 +5580,22 @@ static int __wma_bus_suspend(enum qdf_suspend_type type, uint32_t wow_flags)
  *
  * Return: 0 for success or error code
  */
-int wma_runtime_suspend(uint32_t wow_flags)
+int wma_runtime_suspend(struct wow_enable_params wow_params)
 {
-	return __wma_bus_suspend(QDF_RUNTIME_SUSPEND, wow_flags);
+	return __wma_bus_suspend(QDF_RUNTIME_SUSPEND, wow_params);
 }
 
 /**
  * wma_bus_suspend() - handles bus suspend request from hdd
- * @wow_flags: bitmap of WMI WOW flags to pass to FW
+ * @wow_params: collection of wow enable override parameters
  *
  * Calls the appropriate handler based on configuration and event
  *
  * Return: 0 for success or error code
  */
-int wma_bus_suspend(uint32_t wow_flags)
+int wma_bus_suspend(struct wow_enable_params wow_params)
 {
-
-	return __wma_bus_suspend(QDF_SYSTEM_SUSPEND, wow_flags);
+	return __wma_bus_suspend(QDF_SYSTEM_SUSPEND, wow_params);
 }
 
 /**