summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYingying Tang <yintang@codeaurora.org>2016-10-20 15:16:15 +0800
committerqcabuildsw <qcabuildsw@localhost>2016-12-07 03:08:51 -0800
commitecf1b7e3387c971c846c9868d5aa75015baa2340 (patch)
treef23d3a9f35173418eb2c46e45150224d1f5812f6
parent855d8cf434c9265333bbb048847e5b061b543337 (diff)
qcacld-3.0: Add support to set wakeup pulse for WoW
Propagate from qcacld-2.0 to qcacld-3.0 Host send WoW pulse setting information to firmware and allow firmware to use this pulse to wake host Change-Id: I632b3e85a8e113b8b8d4c927e822dce53f1b6727 CRs-Fixed: 924672
-rw-r--r--core/hdd/inc/wlan_hdd_cfg.h47
-rw-r--r--core/hdd/src/wlan_hdd_cfg.c31
-rw-r--r--core/hdd/src/wlan_hdd_main.c58
-rw-r--r--core/mac/inc/sir_api.h18
-rw-r--r--core/mac/src/include/sir_params.h2
-rw-r--r--core/sme/inc/sme_api.h7
-rw-r--r--core/sme/src/common/sme_api.c46
-rw-r--r--core/wma/inc/wma_types.h9
-rw-r--r--core/wma/src/wma_main.c77
9 files changed, 294 insertions, 1 deletions
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index 1b8508e29db8..2e05d10eced9 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -3589,6 +3589,47 @@ enum dot11p_mode {
*/
#define CFG_RPS_RX_QUEUE_CPU_MAP_LIST_LEN 30
+#ifdef WLAN_FEATURE_WOW_PULSE
+/*
+ * Enable/Disable WOW PULSE feature
+ * Set the wakeup pulse which FW use to wake up HOST
+ * Default : Disable
+ */
+#define CFG_WOW_PULSE_SUPPORT_NAME "gwow_pulse_support"
+#define CFG_WOW_PULSE_SUPPORT_MIN (0)
+#define CFG_WOW_PULSE_SUPPORT_MAX (1)
+#define CFG_WOW_PULSE_SUPPORT_DEFAULT (CFG_WOW_PULSE_SUPPORT_MIN)
+
+/*
+ * GPIO PIN for Pulse
+ * Which PIN to send the Pulse
+ */
+#define CFG_WOW_PULSE_PIN_NAME "gwow_pulse_pin"
+#define CFG_WOW_PULSE_PIN_MIN (CFG_SET_TSF_GPIO_PIN_MIN)
+#define CFG_WOW_PULSE_PIN_MAX (CFG_SET_TSF_GPIO_PIN_MAX)
+#define CFG_WOW_PULSE_PIN_DEFAULT (35)
+
+/*
+ * Pulse interval low
+ * The interval of low level in the pulse
+ * The value which defined by customer should between 160 and 480
+ */
+#define CFG_WOW_PULSE_INTERVAL_LOW_NAME "gwow_pulse_interval_low"
+#define CFG_WOW_PULSE_INTERVAL_LOW_MIN (160)
+#define CFG_WOW_PULSE_INTERVAL_LOW_MAX (480)
+#define CFG_WOW_PULSE_INTERVAL_LOW_DEFAULT (180)
+
+/*
+ * Pulse interval high
+ * The interval of high level in the pulse
+ * The value which defined by customer should between 20 and 40
+ */
+#define CFG_WOW_PULSE_INTERVAL_HIGH_NAME "gwow_pulse_interval_high"
+#define CFG_WOW_PULSE_INTERVAL_HIGH_MIN (20)
+#define CFG_WOW_PULSE_INTERVAL_HIGH_MAX (40)
+#define CFG_WOW_PULSE_INTERVAL_HIGH_DEFAULT (20)
+#endif
+
/*
* Support to start sap in indoor channel
* Customer can config this item to enable/disable sap in indoor channel
@@ -4342,6 +4383,12 @@ struct hdd_config {
uint8_t sap_max_inactivity_override;
bool fw_timeout_crash;
uint32_t rx_wakelock_timeout;
+#ifdef WLAN_FEATURE_WOW_PULSE
+ bool wow_pulse_support;
+ uint8_t wow_pulse_pin;
+ uint16_t wow_pulse_interval_high;
+ uint16_t wow_pulse_interval_low;
+#endif
};
#define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index 222e272f7a08..f70c76ba0537 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -3566,6 +3566,37 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_EXTSCAN_ACTIVE_MIN_CHANNEL_TIME_MAX),
#endif
+#ifdef WLAN_FEATURE_WOW_PULSE
+ REG_VARIABLE(CFG_WOW_PULSE_SUPPORT_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, wow_pulse_support,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_WOW_PULSE_SUPPORT_DEFAULT,
+ CFG_WOW_PULSE_SUPPORT_MIN,
+ CFG_WOW_PULSE_SUPPORT_MAX),
+
+ REG_VARIABLE(CFG_WOW_PULSE_PIN_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, wow_pulse_pin,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_WOW_PULSE_PIN_DEFAULT,
+ CFG_WOW_PULSE_PIN_MIN,
+ CFG_WOW_PULSE_PIN_MAX),
+
+ REG_VARIABLE(CFG_WOW_PULSE_INTERVAL_LOW_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, wow_pulse_interval_low,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_WOW_PULSE_INTERVAL_LOW_DEFAULT,
+ CFG_WOW_PULSE_INTERVAL_LOW_MIN,
+ CFG_WOW_PULSE_INTERVAL_LOW_MAX),
+
+ REG_VARIABLE(CFG_WOW_PULSE_INTERVAL_HIGH_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, wow_pulse_interval_high,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_WOW_PULSE_INTERVAL_HIGH_DEFAULT,
+ CFG_WOW_PULSE_INTERVAL_HIGH_MIN,
+ CFG_WOW_PULSE_INTERVAL_HIGH_MAX),
+#endif
+
+
REG_VARIABLE(CFG_CE_CLASSIFY_ENABLE_NAME, WLAN_PARAM_Integer,
struct hdd_config, ce_classify_enabled,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index 46bef0eb319b..71458d9ba2e0 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -5792,6 +5792,61 @@ static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
}
#endif
+#ifdef WLAN_FEATURE_WOW_PULSE
+/**
+ * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse
+ * @phddctx: hdd_context_t structure pointer
+ * @enable: enable or disable this behaviour
+ *
+ * Return: int
+ */
+static int wlan_hdd_set_wow_pulse(hdd_context_t *phddctx, bool enable)
+{
+ struct hdd_config *pcfg_ini = phddctx->config;
+ struct wow_pulse_mode wow_pulse_set_info;
+ QDF_STATUS status;
+
+ hdd_notice("wow pulse enable flag is %d", enable);
+
+ if (false == phddctx->config->wow_pulse_support)
+ return 0;
+
+ /* prepare the request to send to SME */
+ if (enable == true) {
+ wow_pulse_set_info.wow_pulse_enable = true;
+ wow_pulse_set_info.wow_pulse_pin =
+ pcfg_ini->wow_pulse_pin;
+ wow_pulse_set_info.wow_pulse_interval_low =
+ pcfg_ini->wow_pulse_interval_low;
+ wow_pulse_set_info.wow_pulse_interval_high =
+ pcfg_ini->wow_pulse_interval_high;
+ } else {
+ wow_pulse_set_info.wow_pulse_enable = false;
+ wow_pulse_set_info.wow_pulse_pin = 0;
+ wow_pulse_set_info.wow_pulse_interval_low = 0;
+ wow_pulse_set_info.wow_pulse_interval_high = 0;
+ }
+ hdd_notice("enable %d pin %d low %d high %d",
+ wow_pulse_set_info.wow_pulse_enable,
+ wow_pulse_set_info.wow_pulse_pin,
+ wow_pulse_set_info.wow_pulse_interval_low,
+ wow_pulse_set_info.wow_pulse_interval_high);
+
+ status = sme_set_wow_pulse(&wow_pulse_set_info);
+ if (QDF_STATUS_E_FAILURE == status) {
+ hdd_notice("sme_set_wow_pulse failure!");
+ return -EIO;
+ }
+ hdd_notice("sme_set_wow_pulse success!");
+ return 0;
+}
+#else
+static inline int wlan_hdd_set_wow_pulse(hdd_context_t *phddctx, bool enable)
+{
+ return 0;
+}
+#endif
+
#ifdef WLAN_FEATURE_FASTPATH
/**
* hdd_enable_fastpath() - Enable fastpath if enabled in config INI
@@ -8058,6 +8113,9 @@ int hdd_wlan_startup(struct device *dev)
wlan_hdd_update_wiphy(hdd_ctx);
+ if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true))
+ hdd_notice("Failed to set wow pulse");
+
hdd_ctx->hHal = cds_get_context(QDF_MODULE_ID_SME);
if (NULL == hdd_ctx->hHal) {
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index b38d08ed4ff2..54b84c0534b4 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -6704,4 +6704,22 @@ struct sme_sta_inactivity_timeout {
uint8_t session_id;
uint32_t sta_inactivity_timeout;
};
+
+/*
+ * struct wow_pulse_mode - WoW Pulse set cmd struct
+ * @wow_pulse_enable: enable or disable this feature
+ * @wow_pulse_pin: GPIO PIN for Pulse
+ * @wow_pulse_interval_low: Pulse interval low
+ * @wow_pulse_interval_high: Pulse interval high
+ *
+ * SME uses this structure to configure wow pulse info
+ * and send it to WMA
+ */
+struct wow_pulse_mode {
+ bool wow_pulse_enable;
+ uint8_t wow_pulse_pin;
+ uint16_t wow_pulse_interval_high;
+ uint16_t wow_pulse_interval_low;
+};
+
#endif /* __SIR_API_H */
diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h
index e91e6ca08b29..a8d27ec200d8 100644
--- a/core/mac/src/include/sir_params.h
+++ b/core/mac/src/include/sir_params.h
@@ -642,6 +642,8 @@ typedef struct sSirMbMsgP2p {
#define SIR_HAL_UPDATE_TX_FAIL_CNT_TH (SIR_HAL_ITC_MSG_TYPES_BEGIN + 367)
#define SIR_HAL_POWER_DEBUG_STATS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 368)
+#define SIR_HAL_SET_WOW_PULSE_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 369)
+
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
/* CFG message types */
diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h
index b7effcea939b..9ae1047ca1d7 100644
--- a/core/sme/inc/sme_api.h
+++ b/core/sme/inc/sme_api.h
@@ -1355,6 +1355,7 @@ QDF_STATUS sme_update_sta_inactivity_timeout(tHalHandle hal_handle,
*/
QDF_STATUS sme_set_lost_link_info_cb(tHalHandle hal,
void (*cb)(void *, struct sir_lost_link_info *));
+
#ifdef WLAN_POWER_DEBUGFS
QDF_STATUS sme_power_debug_stats_req(tHalHandle hal, void (*callback_fn)
(struct power_stats_response *response,
@@ -1362,4 +1363,10 @@ QDF_STATUS sme_power_debug_stats_req(tHalHandle hal, void (*callback_fn)
#endif
void sme_set_cc_src(tHalHandle hal_handle, enum country_src);
+
+
+#ifdef WLAN_FEATURE_WOW_PULSE
+QDF_STATUS sme_set_wow_pulse(struct wow_pulse_mode *wow_pulse_set_info);
+#endif
+
#endif /* #if !defined( __SME_API_H ) */
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index a7bde02e23a5..b40a7010f275 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -17008,6 +17008,7 @@ QDF_STATUS sme_set_cts2self_for_p2p_go(tHalHandle hal_handle)
}
return QDF_STATUS_SUCCESS;
}
+
/**
* sme_update_tx_fail_cnt_threshold() - update tx fail count Threshold
* @hal: Handle returned by mac_open
@@ -17072,3 +17073,48 @@ QDF_STATUS sme_set_lost_link_info_cb(tHalHandle hal,
}
return status;
}
+
+
+#ifdef WLAN_FEATURE_WOW_PULSE
+/**
+ * sme_set_wow_pulse() - set wow pulse info
+ * @wow_pulse_set_info: wow_pulse_mode structure pointer
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_wow_pulse(struct wow_pulse_mode *wow_pulse_set_info)
+{
+ cds_msg_t message;
+ QDF_STATUS status;
+ struct wow_pulse_mode *wow_pulse_set_cmd;
+
+ if (!wow_pulse_set_info) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ "%s: invalid wow_pulse_set_info pointer", __func__);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ wow_pulse_set_cmd = qdf_mem_malloc(sizeof(*wow_pulse_set_cmd));
+ if (NULL == wow_pulse_set_cmd) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ "%s: fail to alloc wow_pulse_set_cmd", __func__);
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ *wow_pulse_set_cmd = *wow_pulse_set_info;
+
+ message.type = WMA_SET_WOW_PULSE_CMD;
+ message.bodyptr = wow_pulse_set_cmd;
+ status = cds_mq_post_message(QDF_MODULE_ID_WMA,
+ &message);
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ "%s: Not able to post msg to WDA!",
+ __func__);
+ qdf_mem_free(wow_pulse_set_cmd);
+ status = QDF_STATUS_E_FAILURE;
+ }
+
+ return status;
+}
+#endif
diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h
index af7d2a13c1bd..5ca393b9e403 100644
--- a/core/wma/inc/wma_types.h
+++ b/core/wma/inc/wma_types.h
@@ -132,6 +132,13 @@
#define WMA_GET_RX_RSSI_RAW(pRxMeta) \
(((t_packetmeta *)pRxMeta)->rssi_raw)
+/*
+ * the repeat_cnt is reserved by FW team, the current value
+ * is always 0xffffffff
+ */
+#define WMI_WOW_PULSE_REPEAT_CNT 0xffffffff
+
+
/* WMA Messages */
#define WMA_MSG_TYPES_BEGIN SIR_HAL_MSG_TYPES_BEGIN
#define WMA_ITC_MSG_TYPES_BEGIN SIR_HAL_ITC_MSG_TYPES_BEGIN
@@ -479,6 +486,8 @@
#define WMA_ENCRYPT_DECRYPT_MSG SIR_HAL_ENCRYPT_DECRYPT_MSG
#define WMA_POWER_DEBUG_STATS_REQ SIR_HAL_POWER_DEBUG_STATS_REQ
+#define WMA_SET_WOW_PULSE_CMD SIR_HAL_SET_WOW_PULSE_CMD
+
/* Bit 6 will be used to control BD rate for Management frames */
#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index e8fce4d15b07..601f000032e3 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -5956,7 +5956,6 @@ static QDF_STATUS wma_update_wep_default_key(tp_wma_handle wma,
return QDF_STATUS_SUCCESS;
}
-
/**
* wma_update_tx_fail_cnt_th() - Set threshold for TX pkt fail
* @wma_handle: WMA handle
@@ -6121,6 +6120,77 @@ void wma_update_sta_inactivity_timeout(tp_wma_handle wma,
max_unresponsive_time);
}
+#ifdef WLAN_FEATURE_WOW_PULSE
+
+
+#define WMI_WOW_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM \
+WMI_WOW_HOSTWAKEUP_GPIO_PIN_PATTERN_CONFIG_CMD_fixed_param
+
+
+#define WMITLV_TAG_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM \
+WMITLV_TAG_STRUC_wmi_wow_hostwakeup_gpio_pin_pattern_config_cmd_fixed_param
+
+/**
+* wma_send_wow_pulse_cmd() - send wmi cmd of wow pulse cmd
+* infomation to fw.
+* @wma_handle: wma handler
+* @udp_response: wow_pulse_mode pointer
+*
+* Return: Return QDF_STATUS
+*/
+static QDF_STATUS wma_send_wow_pulse_cmd(tp_wma_handle wma_handle,
+ struct wow_pulse_mode *wow_pulse_cmd)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ wmi_buf_t buf;
+ WMI_WOW_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM *cmd;
+ u_int16_t len;
+
+ len = sizeof(*cmd);
+ buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+ if (!buf) {
+ WMA_LOGE("wmi_buf_alloc failed");
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ cmd = (WMI_WOW_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM *)wmi_buf_data(buf);
+ qdf_mem_zero(cmd, len);
+
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM,
+ WMITLV_GET_STRUCT_TLVLEN(
+ WMI_WOW_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM));
+
+ cmd->enable = wow_pulse_cmd->wow_pulse_enable;
+ cmd->pin = wow_pulse_cmd->wow_pulse_pin;
+ cmd->interval_low = wow_pulse_cmd->wow_pulse_interval_low;
+ cmd->interval_high = wow_pulse_cmd->wow_pulse_interval_high;
+ cmd->repeat_cnt = WMI_WOW_PULSE_REPEAT_CNT;
+
+ if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+ WMI_WOW_HOSTWAKEUP_GPIO_PIN_PATTERN_CONFIG_CMDID)) {
+ WMA_LOGE("Failed to send send wow pulse");
+ wmi_buf_free(buf);
+ status = QDF_STATUS_E_FAILURE;
+ }
+
+ WMA_LOGD("%s: Exit", __func__);
+ return status;
+}
+
+#undef WMI_WOW_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM
+#undef WMITLV_TAG_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM
+#undef WMI_WOW_PULSE_REPEAT_CNT
+
+#else
+static inline QDF_STATUS wma_send_wow_pulse_cmd(tp_wma_handle wma_handle,
+ struct wow_pulse_mode *wow_pulse_cmd)
+{
+ return QDF_STATUS_E_FAILURE;
+}
+#endif
+
+
/**
* wma_process_power_debug_stats_req() - Process the Chip Power stats collect
* request and pass the Power stats request to Fw
@@ -7008,6 +7078,11 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg)
case SIR_HAL_POWER_DEBUG_STATS_REQ:
wma_process_power_debug_stats_req(wma_handle);
break;
+ case WMA_SET_WOW_PULSE_CMD:
+ wma_send_wow_pulse_cmd(wma_handle,
+ (struct wow_pulse_mode *)msg->bodyptr);
+ qdf_mem_free(msg->bodyptr);
+ break;
default:
WMA_LOGD("unknown msg type %x", msg->type);
/* Do Nothing? MSG Body should be freed at here */