summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrishna Kumaar Natarajan <kknatara@codeaurora.org>2016-07-02 17:44:25 -0700
committerNandini Suresh <snandini@codeaurora.org>2016-07-19 13:17:51 -0700
commit36e5aa00be78baa5c4294ef23a46c9ea2135655a (patch)
tree07a268751fca1e25d5c01429fce40450b391ea15
parente5aa26be8b7790fd0dc2c93a4f1aa68c11d697cb (diff)
qcacld-3.0: Update handling of WOW packet buffer
Update handling of WOW packet buffer. Change-Id: If3ba082bb862a7c9d81e9b9f619f805420c83860 CRs-Fixed: 1042616
-rw-r--r--core/wma/src/wma_features.c288
-rw-r--r--core/wma/src/wma_scan_roam.c101
2 files changed, 208 insertions, 181 deletions
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index 8b92c7826877..c0bb0ff209c9 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -2732,6 +2732,138 @@ static void wma_wow_wake_up_stats(tp_wma_handle wma, uint8_t *data,
return;
}
+#ifdef FEATURE_WLAN_EXTSCAN
+/**
+ * wma_extscan_get_eventid_from_tlvtag() - map tlv tag to corresponding event id
+ * @tag: WMI TLV tag
+ *
+ * Return:
+ * 0 if TLV tag is invalid
+ * else return corresponding WMI event id
+ */
+static int wma_extscan_get_eventid_from_tlvtag(uint32_t tag)
+{
+ uint32_t event_id;
+
+ switch (tag) {
+ case WMITLV_TAG_STRUC_wmi_extscan_start_stop_event_fixed_param:
+ event_id = WMI_EXTSCAN_START_STOP_EVENTID;
+ break;
+
+ case WMITLV_TAG_STRUC_wmi_extscan_operation_event_fixed_param:
+ event_id = WMI_EXTSCAN_OPERATION_EVENTID;
+ break;
+
+ case WMITLV_TAG_STRUC_wmi_extscan_table_usage_event_fixed_param:
+ event_id = WMI_EXTSCAN_TABLE_USAGE_EVENTID;
+ break;
+
+ case WMITLV_TAG_STRUC_wmi_extscan_cached_results_event_fixed_param:
+ event_id = WMI_EXTSCAN_CACHED_RESULTS_EVENTID;
+ break;
+
+ case WMITLV_TAG_STRUC_wmi_extscan_wlan_change_results_event_fixed_param:
+ event_id = WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID;
+ break;
+
+ case WMITLV_TAG_STRUC_wmi_extscan_hotlist_match_event_fixed_param:
+ event_id = WMI_EXTSCAN_HOTLIST_MATCH_EVENTID;
+ break;
+
+ case WMITLV_TAG_STRUC_wmi_extscan_capabilities_event_fixed_param:
+ event_id = WMI_EXTSCAN_CAPABILITIES_EVENTID;
+ break;
+
+ case WMITLV_TAG_STRUC_wmi_extscan_hotlist_ssid_match_event_fixed_param:
+ event_id = WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID;
+ break;
+
+ default:
+ event_id = 0;
+ WMA_LOGE("%s: Unknown tag: %d", __func__, tag);
+ break;
+ }
+
+ WMA_LOGI("%s: For tag %d WMI event 0x%x", __func__, tag, event_id);
+ return event_id;
+}
+#else
+static int wma_extscan_get_eventid_from_tlvtag(uint32_t tag)
+{
+ return 0;
+}
+#endif
+
+/**
+ * wow_get_wmi_eventid() - map reason or tlv tag to corresponding event id
+ * @tag: WMI TLV tag
+ * @reason: WOW reason
+ *
+ * WOW reason type is primarily used to find the ID. If there could be
+ * multiple events that can be sent as a WOW event with same reason
+ * then tlv tag is used to identify the corresponding event.
+ *
+ * Return:
+ * 0 if TLV tag/reason is invalid
+ * else return corresponding WMI event id
+ */
+static int wow_get_wmi_eventid(int32_t reason, uint32_t tag)
+{
+ uint32_t event_id;
+
+ switch (reason) {
+ case WOW_REASON_NLO_SCAN_COMPLETE:
+ event_id = WMI_NLO_SCAN_COMPLETE_EVENTID;
+ break;
+ case WOW_REASON_CSA_EVENT:
+ event_id = WMI_CSA_HANDLING_EVENTID;
+ break;
+ case WOW_REASON_LOW_RSSI:
+ event_id = WMI_ROAM_EVENTID;
+ break;
+ case WOW_REASON_CLIENT_KICKOUT_EVENT:
+ event_id = WMI_PEER_STA_KICKOUT_EVENTID;
+ break;
+ case WOW_REASON_EXTSCAN:
+ event_id = wma_extscan_get_eventid_from_tlvtag(tag);
+ break;
+ case WOW_REASON_RSSI_BREACH_EVENT:
+ event_id = WMI_RSSI_BREACH_EVENTID;
+ break;
+ case WOW_REASON_NAN_EVENT:
+ event_id = WMI_NAN_EVENTID;
+ break;
+ default:
+ WMA_LOGD(FL("Unexpected WOW reason : %s(%d)"),
+ wma_wow_wake_reason_str(reason), reason);
+ event_id = 0;
+ break;
+ }
+
+ return event_id;
+}
+
+/**
+ * tlv_check_required() - tells whether to check the wow packet buffer
+ * for proper TLV structure.
+ * @reason: WOW reason
+ *
+ * In most cases, wow wake up event carries the actual event buffer in
+ * wow_packet_buffer with some exceptions. This function is used to
+ * determine when to check for the TLVs in wow_packet_buffer.
+ *
+ * Return: true if check is required and false otherwise.
+ */
+static bool tlv_check_required(int32_t reason)
+{
+ switch (reason) {
+ case WOW_REASON_PATTERN_MATCH_FOUND:
+ return false;
+ default:
+ return true;
+ }
+}
+
/**
* wma_wow_wakeup_host_event() - wakeup host event handler
* @handle: wma handle
@@ -2753,7 +2885,9 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
struct wma_txrx_node *node;
#endif /* FEATURE_WLAN_SCAN_PNO */
uint32_t wake_lock_duration = 0;
- uint32_t wow_buf_pkt_len = 0;
+ void *wmi_cmd_struct_ptr = NULL;
+ uint32_t tlv_hdr, tag, wow_buf_pkt_len = 0, event_id = 0;
+ int tlv_ok_status;
param_buf = (WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *) event;
if (!param_buf) {
@@ -2769,6 +2903,35 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
qdf_event_set(&wma->wma_resume_event);
+ if (param_buf->wow_packet_buffer &&
+ tlv_check_required(wake_info->wake_reason)) {
+ /*
+ * In case of wow_packet_buffer, first 4 bytes is the length.
+ * Following the length is the actual buffer.
+ */
+ wow_buf_pkt_len = *(uint32_t *)param_buf->wow_packet_buffer;
+ tlv_hdr = WMITLV_GET_HDR(
+ (uint8_t *)param_buf->wow_packet_buffer + 4);
+
+ tag = WMITLV_GET_TLVTAG(tlv_hdr);
+ event_id = wow_get_wmi_eventid(wake_info->wake_reason, tag);
+ if (!event_id) {
+ WMA_LOGE(FL("Unable to find matching ID"));
+ return -EINVAL;
+ }
+
+ tlv_ok_status = wmitlv_check_and_pad_event_tlvs(
+ handle, param_buf->wow_packet_buffer + 4,
+ wow_buf_pkt_len, event_id,
+ &wmi_cmd_struct_ptr);
+
+ if (tlv_ok_status != 0) {
+ WMA_LOGE(FL("Invalid TLVs, Length:%d event_id:%d status: %d"),
+ wow_buf_pkt_len, event_id, tlv_ok_status);
+ return -EINVAL;
+ }
+ }
+
switch (wake_info->wake_reason) {
case WOW_REASON_AUTH_REQ_RECV:
wake_lock_duration = WMA_AUTH_REQ_RECV_WAKE_LOCK_TIMEOUT;
@@ -2819,34 +2982,19 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
break;
case WOW_REASON_NLO_SCAN_COMPLETE:
- {
- WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs param;
-
- WMA_LOGD("Host woken up due to pno scan complete reason");
-
- /* First 4-bytes of wow_packet_buffer is the length */
- if (param_buf->wow_packet_buffer) {
- param.fixed_param = (wmi_nlo_event *)
- (param_buf->wow_packet_buffer + 4);
- wma_nlo_scan_cmp_evt_handler(handle,
- (u_int8_t *)&param, sizeof(param));
- } else
- WMA_LOGD("No wow_packet_buffer present");
- }
+ WMA_LOGD("Host woken up due to pno scan complete reason");
+ if (param_buf->wow_packet_buffer)
+ wma_nlo_scan_cmp_evt_handler(handle,
+ wmi_cmd_struct_ptr, wow_buf_pkt_len);
+ else
+ WMA_LOGD("No wow_packet_buffer present");
break;
#endif /* FEATURE_WLAN_SCAN_PNO */
case WOW_REASON_CSA_EVENT:
- {
- WMI_CSA_HANDLING_EVENTID_param_tlvs param;
WMA_LOGD("Host woken up because of CSA IE");
- param.fixed_param = (wmi_csa_event_fixed_param *)
- (((uint8_t *) wake_info)
- + sizeof(WOW_EVENT_INFO_fixed_param)
- + WOW_CSA_EVENT_OFFSET);
- wma_csa_offload_handler(handle, (uint8_t *) &param,
- sizeof(param));
- }
+ wma_csa_offload_handler(handle, wmi_cmd_struct_ptr,
+ wow_buf_pkt_len);
break;
#ifdef FEATURE_WLAN_LPHB
@@ -2878,115 +3026,69 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
break;
case WOW_REASON_LOW_RSSI:
- {
/* WOW_REASON_LOW_RSSI is used for all roaming events.
* WMI_ROAM_REASON_BETTER_AP, WMI_ROAM_REASON_BMISS,
* WMI_ROAM_REASON_SUITABLE_AP will be handled by
* wma_roam_event_callback().
*/
- WMI_ROAM_EVENTID_param_tlvs param;
wma_wow_wake_up_stats(wma, NULL, 0, WOW_REASON_LOW_RSSI);
+ WMA_LOGD("Host woken up because of roam event");
if (param_buf->wow_packet_buffer) {
/* Roam event is embedded in wow_packet_buffer */
- WMA_LOGD("Host woken up because of roam event");
- qdf_mem_copy((uint8_t *) &wow_buf_pkt_len,
- param_buf->wow_packet_buffer, 4);
WMA_LOGD("wow_packet_buffer dump");
qdf_trace_hex_dump(QDF_MODULE_ID_WMA,
QDF_TRACE_LEVEL_DEBUG,
param_buf->wow_packet_buffer,
wow_buf_pkt_len);
- if (wow_buf_pkt_len >= sizeof(param)) {
- param.fixed_param =
- (wmi_roam_event_fixed_param *)
- (param_buf->wow_packet_buffer + 4);
- wma_roam_event_callback(handle,
- (uint8_t *) &
- param,
- sizeof(param));
- } else {
- WMA_LOGE("Wrong length for roam event = %d bytes",
- wow_buf_pkt_len);
- }
+ wma_roam_event_callback(handle, wmi_cmd_struct_ptr,
+ wow_buf_pkt_len);
} else {
- /* No wow_packet_buffer means a better AP beacon
+ /*
+ * No wow_packet_buffer means a better AP beacon
* will follow in a later event.
*/
WMA_LOGD("Host woken up because of better AP beacon");
}
break;
- }
case WOW_REASON_CLIENT_KICKOUT_EVENT:
- {
- WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs param;
+ WMA_LOGD("Host woken up because of sta_kickout event");
if (param_buf->wow_packet_buffer) {
- /* station kickout event embedded in wow_packet_buffer */
- WMA_LOGD("Host woken up because of sta_kickout event");
- qdf_mem_copy((u_int8_t *) &wow_buf_pkt_len,
- param_buf->wow_packet_buffer, 4);
- WMA_LOGD("wow_packet_buffer dump");
- qdf_trace_hex_dump(QDF_MODULE_ID_WMA,
+ WMA_LOGD("wow_packet_buffer dump");
+ qdf_trace_hex_dump(QDF_MODULE_ID_WMA,
QDF_TRACE_LEVEL_DEBUG,
param_buf->wow_packet_buffer, wow_buf_pkt_len);
- if (wow_buf_pkt_len >= sizeof(param)) {
- param.fixed_param = (wmi_peer_sta_kickout_event_fixed_param *)
- (param_buf->wow_packet_buffer + 4);
wma_peer_sta_kickout_event_handler(handle,
- (u_int8_t *)&param, sizeof(param));
- } else {
- WMA_LOGE("Wrong length for sta_kickout event = %d bytes",
- wow_buf_pkt_len);
- }
+ wmi_cmd_struct_ptr, wow_buf_pkt_len);
} else {
WMA_LOGD("No wow_packet_buffer present");
}
break;
- }
#ifdef FEATURE_WLAN_EXTSCAN
case WOW_REASON_EXTSCAN:
WMA_LOGD("Host woken up because of extscan reason");
wma_wow_wake_up_stats(wma, NULL, 0, WOW_REASON_EXTSCAN);
- if (param_buf->wow_packet_buffer) {
- wow_buf_pkt_len =
- *(uint32_t *)param_buf->wow_packet_buffer;
+ if (param_buf->wow_packet_buffer)
wma_extscan_wow_event_callback(handle,
- (u_int8_t *)(param_buf->wow_packet_buffer + 4),
- wow_buf_pkt_len);
- } else
+ wmi_cmd_struct_ptr, wow_buf_pkt_len);
+ else
WMA_LOGE("wow_packet_buffer is empty");
break;
#endif
case WOW_REASON_RSSI_BREACH_EVENT:
- {
- WMI_RSSI_BREACH_EVENTID_param_tlvs param;
-
- wma_wow_wake_up_stats(wma, NULL, 0,
+ wma_wow_wake_up_stats(wma, NULL, 0,
WOW_REASON_RSSI_BREACH_EVENT);
- WMA_LOGD("Host woken up because of rssi breach reason");
- /* rssi breach event is embedded in wow_packet_buffer */
- if (param_buf->wow_packet_buffer) {
- qdf_mem_copy((u_int8_t *) &wow_buf_pkt_len,
- param_buf->wow_packet_buffer, 4);
- if (wow_buf_pkt_len >= sizeof(param)) {
- param.fixed_param =
- (wmi_rssi_breach_event_fixed_param *)
- (param_buf->wow_packet_buffer + 4);
- wma_rssi_breached_event_handler(handle,
- (u_int8_t *)&param,
- sizeof(param));
- } else {
- WMA_LOGE("%s: Wrong length: %d bytes",
- __func__, wow_buf_pkt_len);
- }
- } else
- WMA_LOGD("No wow_packet_buffer present");
- }
+ WMA_LOGD("Host woken up because of rssi breach reason");
+ /* rssi breach event is embedded in wow_packet_buffer */
+ if (param_buf->wow_packet_buffer)
+ wma_rssi_breached_event_handler(handle,
+ wmi_cmd_struct_ptr, wow_buf_pkt_len);
+ else
+ WMA_LOGD("No wow_packet_buffer present");
break;
case WOW_REASON_NAN_EVENT:
WMA_LOGA("Host woken up due to NAN event reason");
wma_nan_rsp_event_handler(handle,
- (uint8_t *)param_buf->wow_packet_buffer,
- sizeof(WMI_NAN_EVENTID_param_tlvs));
+ wmi_cmd_struct_ptr, wow_buf_pkt_len);
break;
case WOW_REASON_NAN_DATA:
WMA_LOGD(FL("Host woken up for NAN data path event from FW"));
@@ -3006,6 +3108,9 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
}
break;
default:
+ WMA_LOGE(FL("WOW reason %s(%d)- not handled"),
+ wma_wow_wake_reason_str(wake_info->wake_reason),
+ wake_info->wake_reason);
break;
}
@@ -3016,6 +3121,7 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
WMA_LOGA("Holding %d msec wake_lock", wake_lock_duration);
}
+ wmitlv_free_allocated_event_tlvs(event_id, &wmi_cmd_struct_ptr);
return 0;
}
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index f9ec557416a0..0bd344a38af6 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -3260,61 +3260,6 @@ void wma_scan_cache_updated_ind(tp_wma_handle wma, uint8_t sessionId)
#ifdef FEATURE_WLAN_EXTSCAN
/**
- * wma_extscan_get_eventid_from_tlvtag() - map tlv tag to corresponding event id
- * @tag: WMI TLV tag
- *
- * Return:
- * 0 if TLV tag is invalid
- * else return corresponding WMI event id
- */
-static int wma_extscan_get_eventid_from_tlvtag(uint32_t tag)
-{
- uint32_t event_id;
-
- switch (tag) {
- case WMITLV_TAG_STRUC_wmi_extscan_start_stop_event_fixed_param:
- event_id = WMI_EXTSCAN_START_STOP_EVENTID;
- break;
-
- case WMITLV_TAG_STRUC_wmi_extscan_operation_event_fixed_param:
- event_id = WMI_EXTSCAN_OPERATION_EVENTID;
- break;
-
- case WMITLV_TAG_STRUC_wmi_extscan_table_usage_event_fixed_param:
- event_id = WMI_EXTSCAN_TABLE_USAGE_EVENTID;
- break;
-
- case WMITLV_TAG_STRUC_wmi_extscan_cached_results_event_fixed_param:
- event_id = WMI_EXTSCAN_CACHED_RESULTS_EVENTID;
- break;
-
- case WMITLV_TAG_STRUC_wmi_extscan_wlan_change_results_event_fixed_param:
- event_id = WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID;
- break;
-
- case WMITLV_TAG_STRUC_wmi_extscan_hotlist_match_event_fixed_param:
- event_id = WMI_EXTSCAN_HOTLIST_MATCH_EVENTID;
- break;
-
- case WMITLV_TAG_STRUC_wmi_extscan_capabilities_event_fixed_param:
- event_id = WMI_EXTSCAN_CAPABILITIES_EVENTID;
- break;
-
- case WMITLV_TAG_STRUC_wmi_extscan_hotlist_ssid_match_event_fixed_param:
- event_id = WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID;
- break;
-
- default:
- event_id = 0;
- WMA_LOGE("%s: Unknown tag: %d", __func__, tag);
- break;
- }
-
- WMA_LOGI("%s: For tag %d WMI event 0x%x", __func__, tag, event_id);
- return event_id;
-}
-
-/**
* wma_extscan_wow_event_callback() - extscan wow event callback
* @handle: WMA handle
* @event: event buffer
@@ -3326,77 +3271,53 @@ static int wma_extscan_get_eventid_from_tlvtag(uint32_t tag)
* of event buffer is common tlv header, which is a combination
* of tag (higher 2 bytes) and length (lower 2 bytes). The tag is used to
* identify the event which triggered wow event.
+ * Payload is extracted and converted into generic tlv structure before
+ * being passed to this function.
*
* @Return: none
*/
void wma_extscan_wow_event_callback(void *handle, void *event, uint32_t len)
{
- uint32_t id;
- int tlv_ok_status = 0;
- void *wmi_cmd_struct_ptr = NULL;
uint32_t tag = WMITLV_GET_TLVTAG(WMITLV_GET_HDR(event));
- id = wma_extscan_get_eventid_from_tlvtag(tag);
- if (!id) {
- WMA_LOGE("%s: Invalid Tag: %d", __func__, tag);
- return;
- }
-
- tlv_ok_status = wmitlv_check_and_pad_event_tlvs(
- handle, event, len, id,
- &wmi_cmd_struct_ptr);
- if (tlv_ok_status != 0) {
- WMA_LOGE("%s: Invalid Tag: %d could not check and pad tlvs",
- __func__, tag);
- return;
- }
-
switch (tag) {
case WMITLV_TAG_STRUC_wmi_extscan_start_stop_event_fixed_param:
- wma_extscan_start_stop_event_handler(handle,
- wmi_cmd_struct_ptr, len);
+ wma_extscan_start_stop_event_handler(handle, event, len);
break;
case WMITLV_TAG_STRUC_wmi_extscan_operation_event_fixed_param:
- wma_extscan_operations_event_handler(handle,
- wmi_cmd_struct_ptr, len);
+ wma_extscan_operations_event_handler(handle, event, len);
break;
case WMITLV_TAG_STRUC_wmi_extscan_table_usage_event_fixed_param:
- wma_extscan_table_usage_event_handler(handle,
- wmi_cmd_struct_ptr, len);
+ wma_extscan_table_usage_event_handler(handle, event, len);
break;
case WMITLV_TAG_STRUC_wmi_extscan_cached_results_event_fixed_param:
- wma_extscan_cached_results_event_handler(handle,
- wmi_cmd_struct_ptr, len);
+ wma_extscan_cached_results_event_handler(handle, event, len);
break;
case WMITLV_TAG_STRUC_wmi_extscan_wlan_change_results_event_fixed_param:
- wma_extscan_change_results_event_handler(handle,
- wmi_cmd_struct_ptr, len);
+ wma_extscan_change_results_event_handler(handle, event, len);
break;
case WMITLV_TAG_STRUC_wmi_extscan_hotlist_match_event_fixed_param:
- wma_extscan_hotlist_match_event_handler(handle,
- wmi_cmd_struct_ptr, len);
+ wma_extscan_hotlist_match_event_handler(handle, event, len);
break;
case WMITLV_TAG_STRUC_wmi_extscan_capabilities_event_fixed_param:
- wma_extscan_capabilities_event_handler(handle,
- wmi_cmd_struct_ptr, len);
+ wma_extscan_capabilities_event_handler(handle, event, len);
break;
case WMITLV_TAG_STRUC_wmi_extscan_hotlist_ssid_match_event_fixed_param:
wma_extscan_hotlist_ssid_match_event_handler(handle,
- wmi_cmd_struct_ptr, len);
+ event, len);
break;
default:
- WMA_LOGE("%s: Unknown tag: %d", __func__, tag);
+ WMA_LOGE(FL("Unknown tag: %d"), tag);
break;
}
- wmitlv_free_allocated_event_tlvs(id, &wmi_cmd_struct_ptr);
return;
}