summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlok Kumar <alokkuma@codeaurora.org>2019-04-21 17:28:42 +0530
committernshrivas <nshrivas@codeaurora.org>2019-05-17 18:27:33 -0700
commitbda10db5eed360d9322e9d851a791838e058ea38 (patch)
tree608e433a3a87ab034a6dd89a2517d751044d2a08
parentbf240dc3a2e5d5268dbd6232e89658a96b2111ab (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.h3
-rw-r--r--core/wma/inc/wma_internal.h6
-rw-r--r--core/wma/src/wma_main.c23
-rw-r--r--core/wma/src/wma_mgmt.c105
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