diff options
| author | Alok Kumar <alokkuma@codeaurora.org> | 2019-04-21 17:28:42 +0530 |
|---|---|---|
| committer | nshrivas <nshrivas@codeaurora.org> | 2019-05-17 18:27:33 -0700 |
| commit | bda10db5eed360d9322e9d851a791838e058ea38 (patch) | |
| tree | 608e433a3a87ab034a6dd89a2517d751044d2a08 | |
| parent | bf240dc3a2e5d5268dbd6232e89658a96b2111ab (diff) | |
qcacld-3.0: Add WMI EVENT handler for offloaded mgmt data
Register event handler for WMI_VDEV_MGMT_OFFLOAD_DATA_EVENTID
to handle offloaded management data.
Change-Id: Ie05748c0408730fc032f91f2965cc3fff3a853e9
CRs-Fixed: 2448510
| -rw-r--r-- | core/wma/inc/wma.h | 3 | ||||
| -rw-r--r-- | core/wma/inc/wma_internal.h | 6 | ||||
| -rw-r--r-- | core/wma/src/wma_main.c | 23 | ||||
| -rw-r--r-- | core/wma/src/wma_mgmt.c | 105 |
4 files changed, 132 insertions, 5 deletions
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 03c7a5c91456..252de47335ca 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -1762,6 +1762,7 @@ typedef struct { #ifdef FEATURE_WLAN_D0WOW atomic_t in_d0wow; #endif + bool is_pktcapture_enabled; } t_wma_handle, *tp_wma_handle; /** diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index 23c60673ed19..a7c5b78380ea 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -715,6 +715,10 @@ void wma_process_update_userpos(tp_wma_handle wma_handle, void wma_hidden_ssid_vdev_restart(tp_wma_handle wma_handle, tHalHiddenSsidVdevRestart *pReq); +int +wma_mgmt_offload_data_event_handler(void *handle, uint8_t *data, + uint32_t data_len); + /* * wma_power.c functions declarations */ diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index d9d06e49fb08..693c1b531ea8 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -5263,6 +5263,28 @@ int wma_rx_service_ready_event(void *handle, uint8_t *cmd_param_info, } } + if (cds_get_pktcap_mode_enable() && + WMI_SERVICE_EXT_IS_ENABLED( + wma_handle->wmi_service_bitmap, + wma_handle->wmi_service_ext_bitmap, + WMI_SERVICE_PACKET_CAPTURE_SUPPORT)) { + uint8_t status; + + status = wmi_unified_register_event_handler( + wma_handle->wmi_handle, + WMI_VDEV_MGMT_OFFLOAD_EVENTID, + wma_mgmt_offload_data_event_handler, + WMA_RX_SERIALIZER_CTX); + if (status) { + WMA_LOGE("Failed to register MGMT offload handler"); + return -EINVAL; + } + WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( + wma_handle->wlan_resource_config.flag1, 1); + + wma_handle->is_pktcapture_enabled = true; + } + if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap, WMI_SERVICE_MGMT_TX_WMI)) { WMA_LOGD("Firmware supports management TX over WMI,use WMI interface instead of HTT for management Tx"); @@ -5298,6 +5320,7 @@ int wma_rx_service_ready_event(void *handle, uint8_t *cmd_param_info, } else { WMA_LOGE("FW doesnot support WMI_SERVICE_MGMT_TX_WMI, Use HTT interface for Management Tx"); } + #ifdef WLAN_FEATURE_GTK_OFFLOAD if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap, WMI_SERVICE_GTK_OFFLOAD)) { diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index e4e26371c7ab..5631f1b30328 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -2771,6 +2771,9 @@ static const char *wma_get_status_str(uint32_t status) } } +#define RATE_LIMIT 16 +#define RESERVE_BYTES 100 + /** * wma_process_mon_mgmt_tx_data(): process management tx packets * for pkt capture mode @@ -2825,9 +2828,6 @@ wma_process_mon_mgmt_tx_data(wmi_mgmt_hdr *hdr, return ol_txrx_mon_mgmt_process(&txrx_status, nbuf, status); } -#define RATE_LIMIT 16 -#define RESERVE_BYTES 100 - static int wma_process_mon_mgmt_tx_completion(tp_wma_handle wma_handle, uint32_t desc_id, uint32_t status, @@ -3780,6 +3780,105 @@ end: } /** + * wma_mgmt_offload_data_event_handler() - process management offload frame. + * @handle: wma handle + * @data: mgmt data + * @data_len: data length + * + * Return: 0 for success or error code + */ +int +wma_mgmt_offload_data_event_handler(void *handle, uint8_t *data, + uint32_t data_len) +{ + tp_wma_handle wma_handle = (tp_wma_handle)handle; + WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs = NULL; + wmi_mgmt_hdr *hdr = NULL; + static uint8_t limit_prints_invalid_len = RATE_LIMIT - 1; + static uint8_t limit_prints_load_unload = RATE_LIMIT - 1; + static uint8_t limit_prints_recovery = RATE_LIMIT - 1; + uint8_t status; + qdf_nbuf_t wbuf; + + if (!wma_handle) { + WMA_LOGE("%s: Failed to get WMA context", __func__); + return -EINVAL; + } + + param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)data; + if (!param_tlvs) { + WMA_LOGE("Get NULL point message from FW"); + return -EINVAL; + } + + hdr = param_tlvs->fixed_param; + if (!hdr) { + WMA_LOGE("Offload data event is NULL"); + return -EINVAL; + } + + if (hdr->buf_len > param_tlvs->num_bufp) { + WMA_LOGE( + "Invalid frame len hdr->buf_len:%u, param_tlvs->num_bufp:%u", + hdr->buf_len, param_tlvs->num_bufp); + return -EINVAL; + } + if (hdr->buf_len < sizeof(struct ieee80211_frame) || + hdr->buf_len > data_len) { + limit_prints_invalid_len++; + if (limit_prints_invalid_len == RATE_LIMIT) { + WMA_LOGD( + "Invalid mgmt packet, data_len %u, hdr->buf_len %u", + data_len, hdr->buf_len); + limit_prints_invalid_len = 0; + } + return -EINVAL; + } + + if (cds_is_load_or_unload_in_progress()) { + limit_prints_load_unload++; + if (limit_prints_load_unload == RATE_LIMIT) { + WMA_LOGD(FL("Load/Unload in progress")); + limit_prints_load_unload = 0; + } + return -EINVAL; + } + + if (cds_is_driver_recovering()) { + limit_prints_recovery++; + if (limit_prints_recovery == RATE_LIMIT) { + WMA_LOGD(FL("Recovery in progress")); + limit_prints_recovery = 0; + } + return -EINVAL; + } + + if (cds_is_driver_in_bad_state()) { + WMA_LOGW(FL("Driver in bad state")); + return -EINVAL; + } + + wbuf = qdf_nbuf_alloc(NULL, + roundup(hdr->buf_len + RESERVE_BYTES, 4), + RESERVE_BYTES, 4, false); + if (!wbuf) { + WMA_LOGE("%s: Failed to allocate wbuf for mgmt pkt len(%u)", + __func__, hdr->buf_len); + return -ENOMEM; + } + + qdf_nbuf_put_tail(wbuf, hdr->buf_len); + qdf_nbuf_set_protocol(wbuf, ETH_P_CONTROL); + qdf_mem_copy(qdf_nbuf_data(wbuf), param_tlvs->bufp, hdr->buf_len); + + status = hdr->tx_status; + if (!wma_process_mon_mgmt_tx_data(hdr, wbuf, status)) + qdf_nbuf_free(wbuf); + + return 0; +} + +/** * wma_mgmt_rx_process() - process management rx frame. * @handle: wma handle * @data: rx data |
