|
@@ -0,0 +1,668 @@
|
|
|
+/*
|
|
|
+ * Copyright (c) 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
|
|
|
+ * above copyright notice and this permission notice appear in all
|
|
|
+ * copies.
|
|
|
+ *
|
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
|
|
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
|
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
|
|
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
|
|
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
|
|
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
|
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
|
+ * PERFORMANCE OF THIS SOFTWARE.
|
|
|
+ */
|
|
|
+
|
|
|
+/**
|
|
|
+ * DOC: wlan_hdd_debugfs_coex.c
|
|
|
+ *
|
|
|
+ * This file currently supports the following debugfs:
|
|
|
+ * Get the following information coex information
|
|
|
+ * COEX STATE
|
|
|
+ * COEX DPWB STATE
|
|
|
+ * COEX TDM STATE
|
|
|
+ * COEX IDRX STATE
|
|
|
+ * COEX ANTENNA SHARING STATE
|
|
|
+ *
|
|
|
+ * Example to read the COEX STATE logging:
|
|
|
+ * sm6150:/ # cat /sys/kernel/debug/wlan/mws_coex_state
|
|
|
+ */
|
|
|
+
|
|
|
+#include <wlan_hdd_includes.h>
|
|
|
+#include <wlan_osif_request_manager.h>
|
|
|
+#include <wlan_hdd_debugfs_coex.h>
|
|
|
+#include "wmi_unified.h"
|
|
|
+#include "wmi_unified_param.h"
|
|
|
+#include "osif_sync.h"
|
|
|
+
|
|
|
+#define MWS_DEBUGFS_PERMS (QDF_FILE_USR_READ | \
|
|
|
+ QDF_FILE_GRP_READ | \
|
|
|
+ QDF_FILE_OTH_READ)
|
|
|
+
|
|
|
+/* wait time for mws coex info in milliseconds */
|
|
|
+#define WLAN_WAIT_TIME_MWS_COEX_INFO 800
|
|
|
+
|
|
|
+struct mws_coex_state_priv {
|
|
|
+ struct mws_coex_state coex_state;
|
|
|
+};
|
|
|
+
|
|
|
+struct mws_coex_dpwb_state_priv {
|
|
|
+ struct mws_coex_dpwb_state dpwb_state;
|
|
|
+};
|
|
|
+
|
|
|
+struct mws_coex_tdm_state_priv {
|
|
|
+ struct mws_coex_tdm_state tdm_state;
|
|
|
+};
|
|
|
+
|
|
|
+struct mws_coex_idrx_state_priv {
|
|
|
+ struct mws_coex_idrx_state idrx_state;
|
|
|
+};
|
|
|
+
|
|
|
+struct mws_antenna_sharing_info_priv {
|
|
|
+ struct mws_antenna_sharing_info antenna_sharing;
|
|
|
+};
|
|
|
+
|
|
|
+static void hdd_debugfs_mws_coex_info_cb(void *coex_info_data, void *context,
|
|
|
+ wmi_mws_coex_cmd_id cmd_id)
|
|
|
+{
|
|
|
+ struct osif_request *request = NULL;
|
|
|
+ struct mws_coex_state_priv *coex_priv;
|
|
|
+ struct mws_coex_dpwb_state_priv *dpwb_priv;
|
|
|
+ struct mws_coex_tdm_state_priv *tdm_priv;
|
|
|
+ struct mws_coex_idrx_state_priv *idrx_priv;
|
|
|
+ struct mws_antenna_sharing_info_priv *antenna_priv;
|
|
|
+
|
|
|
+ if (!coex_info_data) {
|
|
|
+ hdd_err("data is null");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ request = osif_request_get(context);
|
|
|
+ if (!request) {
|
|
|
+ hdd_err("obselete request");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (cmd_id) {
|
|
|
+ case WMI_MWS_COEX_STATE:
|
|
|
+ coex_priv = osif_request_priv(request);
|
|
|
+ qdf_mem_copy(&coex_priv->coex_state, coex_info_data,
|
|
|
+ sizeof(struct mws_coex_state));
|
|
|
+ break;
|
|
|
+ case WMI_MWS_COEX_DPWB_STATE:
|
|
|
+ dpwb_priv = osif_request_priv(request);
|
|
|
+ qdf_mem_copy(&dpwb_priv->dpwb_state, coex_info_data,
|
|
|
+ sizeof(struct mws_coex_dpwb_state));
|
|
|
+ break;
|
|
|
+ case WMI_MWS_COEX_TDM_STATE:
|
|
|
+ tdm_priv = osif_request_priv(request);
|
|
|
+ qdf_mem_copy(&tdm_priv->tdm_state, coex_info_data,
|
|
|
+ sizeof(struct mws_coex_tdm_state));
|
|
|
+ break;
|
|
|
+ case WMI_MWS_COEX_IDRX_STATE:
|
|
|
+ idrx_priv = osif_request_priv(request);
|
|
|
+ qdf_mem_copy(&idrx_priv->idrx_state, coex_info_data,
|
|
|
+ sizeof(struct mws_coex_idrx_state));
|
|
|
+ break;
|
|
|
+ case WMI_MWS_COEX_ANTENNA_SHARING_STATE:
|
|
|
+ antenna_priv = osif_request_priv(request);
|
|
|
+ qdf_mem_copy(&antenna_priv->antenna_sharing, coex_info_data,
|
|
|
+ sizeof(struct mws_antenna_sharing_info));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ osif_request_complete(request);
|
|
|
+ osif_request_put(request);
|
|
|
+}
|
|
|
+
|
|
|
+static QDF_STATUS __hdd_debugfs_mws_coex_state_read(struct hdd_context *hdd_ctx,
|
|
|
+ qdf_debugfs_file_t file)
|
|
|
+{
|
|
|
+ struct hdd_adapter *adapter;
|
|
|
+ QDF_STATUS status;
|
|
|
+ int rc;
|
|
|
+ struct osif_request *request;
|
|
|
+ struct mws_coex_state *coex_state;
|
|
|
+ struct mws_coex_state_priv *priv;
|
|
|
+ static const struct osif_request_params params = {
|
|
|
+ .priv_size = sizeof(*priv),
|
|
|
+ .timeout_ms = WLAN_WAIT_TIME_MWS_COEX_INFO,
|
|
|
+ };
|
|
|
+ void *cookie;
|
|
|
+
|
|
|
+ adapter = hdd_get_first_valid_adapter(hdd_ctx);
|
|
|
+ if (!adapter) {
|
|
|
+ hdd_err("Failed to get adapter");
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
|
|
|
+ hdd_err("Interface is not enabled");
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (file->index > 0)
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+
|
|
|
+ request = osif_request_alloc(¶ms);
|
|
|
+ if (!request) {
|
|
|
+ hdd_err("Request allocation failure");
|
|
|
+ return QDF_STATUS_E_NOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ cookie = osif_request_cookie(request);
|
|
|
+
|
|
|
+ status = sme_get_mws_coex_info(hdd_ctx->mac_handle,
|
|
|
+ adapter->vdev_id, WMI_MWS_COEX_STATE,
|
|
|
+ hdd_debugfs_mws_coex_info_cb, cookie);
|
|
|
+
|
|
|
+ if (QDF_IS_STATUS_ERROR(status)) {
|
|
|
+ rc = qdf_status_to_os_return(status);
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = osif_request_wait_for_response(request);
|
|
|
+ if (rc) {
|
|
|
+ qdf_debugfs_printf(file, "Timedout while retrieving MWS coex state");
|
|
|
+ rc = -ETIMEDOUT;
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ priv = osif_request_priv(request);
|
|
|
+ coex_state = &priv->coex_state;
|
|
|
+
|
|
|
+ qdf_debugfs_printf(file, "vdev_id = %u\n"
|
|
|
+ "coex_scheme_bitmap = %u\n"
|
|
|
+ "active_conflict_count = %u\n"
|
|
|
+ "potential_conflict_count = %u\n"
|
|
|
+ "chavd_group0_bitmap = %u\n"
|
|
|
+ "chavd_group1_bitmap = %u\n"
|
|
|
+ "chavd_group2_bitmap = %u\n"
|
|
|
+ "chavd_group3_bitmap = %u\n",
|
|
|
+ coex_state->vdev_id,
|
|
|
+ coex_state->coex_scheme_bitmap,
|
|
|
+ coex_state->active_conflict_count,
|
|
|
+ coex_state->potential_conflict_count,
|
|
|
+ coex_state->chavd_group0_bitmap,
|
|
|
+ coex_state->chavd_group1_bitmap,
|
|
|
+ coex_state->chavd_group2_bitmap,
|
|
|
+ coex_state->chavd_group3_bitmap);
|
|
|
+
|
|
|
+exit:
|
|
|
+ osif_request_put(request);
|
|
|
+ return qdf_status_from_os_return(rc);
|
|
|
+ }
|
|
|
+
|
|
|
+static QDF_STATUS hdd_debugfs_mws_coex_state_read(qdf_debugfs_file_t file,
|
|
|
+ void *arg)
|
|
|
+{
|
|
|
+ struct osif_psoc_sync *psoc_sync;
|
|
|
+ struct hdd_context *hdd_ctx = arg;
|
|
|
+ int ret;
|
|
|
+ QDF_STATUS status;
|
|
|
+
|
|
|
+ ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync);
|
|
|
+ if (ret)
|
|
|
+ return qdf_status_from_os_return(ret);
|
|
|
+
|
|
|
+ status = __hdd_debugfs_mws_coex_state_read(hdd_ctx, file);
|
|
|
+
|
|
|
+ osif_psoc_sync_op_stop(psoc_sync);
|
|
|
+ return qdf_status_from_os_return(ret);
|
|
|
+}
|
|
|
+
|
|
|
+static QDF_STATUS __hdd_debugfs_mws_coex_dpwb_read(struct hdd_context *hdd_ctx,
|
|
|
+ qdf_debugfs_file_t file)
|
|
|
+ {
|
|
|
+ struct hdd_adapter *adapter;
|
|
|
+ QDF_STATUS status;
|
|
|
+ int rc;
|
|
|
+ struct osif_request *request;
|
|
|
+ struct mws_coex_dpwb_state *dpwb_state;
|
|
|
+ struct mws_coex_dpwb_state_priv *dpwb_priv;
|
|
|
+ static const struct osif_request_params params = {
|
|
|
+ .priv_size = sizeof(*dpwb_priv),
|
|
|
+ .timeout_ms = WLAN_WAIT_TIME_MWS_COEX_INFO,
|
|
|
+ };
|
|
|
+ void *cookie;
|
|
|
+
|
|
|
+ adapter = hdd_get_first_valid_adapter(hdd_ctx);
|
|
|
+ if (!adapter) {
|
|
|
+ hdd_err("Failed to get adapter");
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
|
|
|
+ hdd_err("Interface is not enabled");
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (file->index > 0)
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+
|
|
|
+ request = osif_request_alloc(¶ms);
|
|
|
+ if (!request) {
|
|
|
+ hdd_err("Request allocation failure");
|
|
|
+ return QDF_STATUS_E_NOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ cookie = osif_request_cookie(request);
|
|
|
+
|
|
|
+ status = sme_get_mws_coex_info(hdd_ctx->mac_handle,
|
|
|
+ adapter->vdev_id,
|
|
|
+ WMI_MWS_COEX_DPWB_STATE,
|
|
|
+ hdd_debugfs_mws_coex_info_cb, cookie);
|
|
|
+
|
|
|
+ if (QDF_IS_STATUS_ERROR(status)) {
|
|
|
+ rc = qdf_status_to_os_return(status);
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = osif_request_wait_for_response(request);
|
|
|
+ if (rc) {
|
|
|
+ qdf_debugfs_printf(file, "Timedout while retrieving MWS coex dpwb state");
|
|
|
+ rc = -ETIMEDOUT;
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ dpwb_priv = osif_request_priv(request);
|
|
|
+ dpwb_state = &dpwb_priv->dpwb_state;
|
|
|
+ qdf_debugfs_printf(file, "vdev_id = %u\n"
|
|
|
+ "current_dpwb_state = %d\n"
|
|
|
+ "pnp1_value = %d\n"
|
|
|
+ "lte_dutycycle = %d\n"
|
|
|
+ "sinr_wlan_on = %d\n"
|
|
|
+ "bler_count = %u\n"
|
|
|
+ "block_count = %u\n"
|
|
|
+ "wlan_rssi_level = %u\n"
|
|
|
+ "wlan_rssi = %d\n"
|
|
|
+ "is_tdm_running = %u\n",
|
|
|
+ dpwb_state->vdev_id,
|
|
|
+ dpwb_state->current_dpwb_state,
|
|
|
+ dpwb_state->pnp1_value,
|
|
|
+ dpwb_state->lte_dutycycle,
|
|
|
+ dpwb_state->sinr_wlan_on,
|
|
|
+ dpwb_state->sinr_wlan_off,
|
|
|
+ dpwb_state->bler_count,
|
|
|
+ dpwb_state->block_count,
|
|
|
+ dpwb_state->wlan_rssi_level,
|
|
|
+ dpwb_state->wlan_rssi,
|
|
|
+ dpwb_state->is_tdm_running);
|
|
|
+
|
|
|
+exit:
|
|
|
+ osif_request_put(request);
|
|
|
+ return qdf_status_from_os_return(rc);
|
|
|
+}
|
|
|
+
|
|
|
+static QDF_STATUS hdd_debugfs_mws_coex_dpwb_read(qdf_debugfs_file_t file,
|
|
|
+ void *arg)
|
|
|
+{
|
|
|
+ struct osif_psoc_sync *psoc_sync;
|
|
|
+ struct hdd_context *hdd_ctx = arg;
|
|
|
+ int ret;
|
|
|
+ QDF_STATUS status;
|
|
|
+
|
|
|
+ ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync);
|
|
|
+ if (ret)
|
|
|
+ return qdf_status_from_os_return(ret);
|
|
|
+
|
|
|
+ status = __hdd_debugfs_mws_coex_dpwb_read(hdd_ctx, file);
|
|
|
+
|
|
|
+ osif_psoc_sync_op_stop(psoc_sync);
|
|
|
+ return qdf_status_from_os_return(ret);
|
|
|
+}
|
|
|
+
|
|
|
+static QDF_STATUS __hdd_debugfs_mws_tdm_state_read(struct hdd_context *hdd_ctx,
|
|
|
+ qdf_debugfs_file_t file)
|
|
|
+{
|
|
|
+ struct hdd_adapter *adapter;
|
|
|
+ QDF_STATUS status;
|
|
|
+ int rc;
|
|
|
+ struct mws_coex_tdm_state *tdm_state;
|
|
|
+ struct mws_coex_tdm_state_priv *tdm_priv;
|
|
|
+ struct osif_request *request;
|
|
|
+ static const struct osif_request_params params = {
|
|
|
+ .priv_size = sizeof(*tdm_priv),
|
|
|
+ .timeout_ms = WLAN_WAIT_TIME_MWS_COEX_INFO,
|
|
|
+ };
|
|
|
+ void *cookie;
|
|
|
+
|
|
|
+ adapter = hdd_get_first_valid_adapter(hdd_ctx);
|
|
|
+ if (!adapter) {
|
|
|
+ hdd_err("Failed to get adapter");
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
|
|
|
+ hdd_err("Interface is not enabled");
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (file->index > 0)
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+
|
|
|
+ request = osif_request_alloc(¶ms);
|
|
|
+ if (!request) {
|
|
|
+ hdd_err("Request allocation failure");
|
|
|
+ return QDF_STATUS_E_NOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ cookie = osif_request_cookie(request);
|
|
|
+
|
|
|
+ status = sme_get_mws_coex_info(hdd_ctx->mac_handle,
|
|
|
+ adapter->vdev_id, WMI_MWS_COEX_TDM_STATE,
|
|
|
+ hdd_debugfs_mws_coex_info_cb, cookie);
|
|
|
+
|
|
|
+ if (QDF_IS_STATUS_ERROR(status)) {
|
|
|
+ rc = qdf_status_to_os_return(status);
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = osif_request_wait_for_response(request);
|
|
|
+ if (rc) {
|
|
|
+ qdf_debugfs_printf(file, "Timedout while retrieving MWS coex tdm state");
|
|
|
+ rc = -ETIMEDOUT;
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ tdm_priv = osif_request_priv(request);
|
|
|
+ tdm_state = &tdm_priv->tdm_state;
|
|
|
+
|
|
|
+ qdf_debugfs_printf(file, "vdev_id = %u\n"
|
|
|
+ "tdm_policy_bitmap = %u\n"
|
|
|
+ "tdm_sf_bitmap = %u\n",
|
|
|
+ tdm_state->vdev_id,
|
|
|
+ tdm_state->tdm_policy_bitmap,
|
|
|
+ tdm_state->tdm_sf_bitmap);
|
|
|
+
|
|
|
+exit:
|
|
|
+ osif_request_put(request);
|
|
|
+ return qdf_status_from_os_return(rc);
|
|
|
+}
|
|
|
+
|
|
|
+static QDF_STATUS hdd_debugfs_mws_tdm_state_read(qdf_debugfs_file_t file,
|
|
|
+ void *arg)
|
|
|
+{
|
|
|
+ struct osif_psoc_sync *psoc_sync;
|
|
|
+ struct hdd_context *hdd_ctx = arg;
|
|
|
+ int ret;
|
|
|
+ QDF_STATUS status;
|
|
|
+
|
|
|
+ ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync);
|
|
|
+ if (ret)
|
|
|
+ return qdf_status_from_os_return(ret);
|
|
|
+
|
|
|
+ status = __hdd_debugfs_mws_tdm_state_read(hdd_ctx, file);
|
|
|
+
|
|
|
+ osif_psoc_sync_op_stop(psoc_sync);
|
|
|
+ return qdf_status_from_os_return(ret);
|
|
|
+}
|
|
|
+
|
|
|
+static QDF_STATUS __hdd_debugfs_mws_coex_idrx_read(struct hdd_context *hdd_ctx,
|
|
|
+ qdf_debugfs_file_t file)
|
|
|
+{
|
|
|
+ struct hdd_adapter *adapter;
|
|
|
+ QDF_STATUS status;
|
|
|
+ int rc;
|
|
|
+ struct osif_request *request;
|
|
|
+ struct mws_coex_idrx_state_priv *idrx_priv;
|
|
|
+ struct mws_coex_idrx_state *idrx_state;
|
|
|
+ static const struct osif_request_params params = {
|
|
|
+ .priv_size = sizeof(*idrx_priv),
|
|
|
+ .timeout_ms = WLAN_WAIT_TIME_MWS_COEX_INFO,
|
|
|
+ };
|
|
|
+ void *cookie;
|
|
|
+
|
|
|
+ adapter = hdd_get_first_valid_adapter(hdd_ctx);
|
|
|
+ if (!adapter) {
|
|
|
+ hdd_err("Failed to get adapter");
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
|
|
|
+ hdd_err("Interface is not enabled");
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (file->index > 0)
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+
|
|
|
+ request = osif_request_alloc(¶ms);
|
|
|
+ if (!request) {
|
|
|
+ hdd_err("Request allocation failure");
|
|
|
+ return QDF_STATUS_E_NOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ cookie = osif_request_cookie(request);
|
|
|
+
|
|
|
+ status = sme_get_mws_coex_info(hdd_ctx->mac_handle,
|
|
|
+ adapter->vdev_id,
|
|
|
+ WMI_MWS_COEX_IDRX_STATE,
|
|
|
+ hdd_debugfs_mws_coex_info_cb, cookie);
|
|
|
+
|
|
|
+ if (QDF_IS_STATUS_ERROR(status)) {
|
|
|
+ rc = qdf_status_to_os_return(status);
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = osif_request_wait_for_response(request);
|
|
|
+ if (rc) {
|
|
|
+ qdf_debugfs_printf(file, "Timedout while retrieving MWS coex idrx state");
|
|
|
+ rc = -ETIMEDOUT;
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ idrx_priv = osif_request_priv(request);
|
|
|
+ idrx_state = &idrx_priv->idrx_state;
|
|
|
+ qdf_debugfs_printf(file, "vdev_id = %u\n"
|
|
|
+ "sub0_techid = %u\n"
|
|
|
+ "sub0_policy = %u\n"
|
|
|
+ "sub0_is_link_critical = %u\n"
|
|
|
+ "sub0_static_power = %u\n"
|
|
|
+ "sub0_rssi = %d\n"
|
|
|
+ "sub0_techid = %d\n"
|
|
|
+ "sub0_policy = %d\n"
|
|
|
+ "sub0_is_link_critical = %d\n"
|
|
|
+ "sub0_static_power = %u\n"
|
|
|
+ "sub0_rssi = %d\n",
|
|
|
+ idrx_state->vdev_id,
|
|
|
+ idrx_state->sub0_techid,
|
|
|
+ idrx_state->sub0_policy,
|
|
|
+ idrx_state->sub0_is_link_critical,
|
|
|
+ idrx_state->sub0_static_power,
|
|
|
+ idrx_state->sub0_rssi,
|
|
|
+ idrx_state->sub1_techid,
|
|
|
+ idrx_state->sub1_policy,
|
|
|
+ idrx_state->sub1_is_link_critical,
|
|
|
+ idrx_state->sub1_static_power,
|
|
|
+ idrx_state->sub1_rssi);
|
|
|
+
|
|
|
+exit:
|
|
|
+ osif_request_put(request);
|
|
|
+ return qdf_status_from_os_return(rc);
|
|
|
+}
|
|
|
+
|
|
|
+static QDF_STATUS hdd_debugfs_mws_coex_idrx_read(qdf_debugfs_file_t file,
|
|
|
+ void *arg)
|
|
|
+{
|
|
|
+ struct osif_psoc_sync *psoc_sync;
|
|
|
+ struct hdd_context *hdd_ctx = arg;
|
|
|
+ int ret;
|
|
|
+ QDF_STATUS status;
|
|
|
+
|
|
|
+ ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync);
|
|
|
+ if (ret)
|
|
|
+ return qdf_status_from_os_return(ret);
|
|
|
+
|
|
|
+ status = __hdd_debugfs_mws_coex_idrx_read(hdd_ctx, file);
|
|
|
+
|
|
|
+ osif_psoc_sync_op_stop(psoc_sync);
|
|
|
+ return qdf_status_from_os_return(ret);
|
|
|
+}
|
|
|
+
|
|
|
+static QDF_STATUS __hdd_debugfs_mws_antenna_sharing_read(struct hdd_context
|
|
|
+ *hdd_ctx,
|
|
|
+ qdf_debugfs_file_t
|
|
|
+ file)
|
|
|
+{
|
|
|
+ struct hdd_adapter *adapter;
|
|
|
+ QDF_STATUS status;
|
|
|
+ int rc;
|
|
|
+ struct mws_antenna_sharing_info *antenna_sharing;
|
|
|
+ struct mws_antenna_sharing_info_priv *antenna_priv;
|
|
|
+ struct osif_request *request;
|
|
|
+ static const struct osif_request_params params = {
|
|
|
+ .priv_size = sizeof(*antenna_priv),
|
|
|
+ .timeout_ms = WLAN_WAIT_TIME_MWS_COEX_INFO,
|
|
|
+ };
|
|
|
+ void *cookie;
|
|
|
+
|
|
|
+ adapter = hdd_get_first_valid_adapter(hdd_ctx);
|
|
|
+ if (!adapter) {
|
|
|
+ hdd_err("Failed to get adapter");
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
|
|
|
+ hdd_err("Interface is not enabled");
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (file->index > 0)
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+
|
|
|
+ request = osif_request_alloc(¶ms);
|
|
|
+ if (!request) {
|
|
|
+ hdd_err("Request allocation failure");
|
|
|
+ return QDF_STATUS_E_NOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ cookie = osif_request_cookie(request);
|
|
|
+
|
|
|
+ status = sme_get_mws_coex_info(hdd_ctx->mac_handle,
|
|
|
+ adapter->vdev_id,
|
|
|
+ WMI_MWS_COEX_ANTENNA_SHARING_STATE,
|
|
|
+ hdd_debugfs_mws_coex_info_cb, cookie);
|
|
|
+
|
|
|
+ if (QDF_IS_STATUS_ERROR(status)) {
|
|
|
+ rc = qdf_status_to_os_return(status);
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = osif_request_wait_for_response(request);
|
|
|
+ if (rc) {
|
|
|
+ qdf_debugfs_printf(file, "Timedout while retrieving MWS coex antenna sharing state");
|
|
|
+ rc = -ETIMEDOUT;
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ antenna_priv = osif_request_priv(request);
|
|
|
+ antenna_sharing = &antenna_priv->antenna_sharing;
|
|
|
+ qdf_debugfs_printf(file, "vdev_id = %u\n"
|
|
|
+ "coex_flags = %u\n"
|
|
|
+ "coex_config = %u\n"
|
|
|
+ "tx_chain_mask = %u\n"
|
|
|
+ "rx_chain_mask = %u\n"
|
|
|
+ "rx_nss = %u\n"
|
|
|
+ "force_mrc = %u\n"
|
|
|
+ "rssi_type = %u\n"
|
|
|
+ "chain0_rssi = %d\n"
|
|
|
+ "chain1_rssi = %d\n"
|
|
|
+ "combined_rssi = %d\n"
|
|
|
+ "imbalance = %u\n"
|
|
|
+ "mrc_threshold = %d\n"
|
|
|
+ "grant_duration = %u\n",
|
|
|
+ antenna_sharing->vdev_id,
|
|
|
+ antenna_sharing->coex_flags,
|
|
|
+ antenna_sharing->coex_config,
|
|
|
+ antenna_sharing->tx_chain_mask,
|
|
|
+ antenna_sharing->rx_chain_mask,
|
|
|
+ antenna_sharing->rx_nss,
|
|
|
+ antenna_sharing->force_mrc,
|
|
|
+ antenna_sharing->rssi_type,
|
|
|
+ antenna_sharing->chain0_rssi,
|
|
|
+ antenna_sharing->chain1_rssi,
|
|
|
+ antenna_sharing->combined_rssi,
|
|
|
+ antenna_sharing->imbalance,
|
|
|
+ antenna_sharing->mrc_threshold,
|
|
|
+ antenna_sharing->grant_duration);
|
|
|
+
|
|
|
+exit:
|
|
|
+ osif_request_put(request);
|
|
|
+ return qdf_status_from_os_return(rc);
|
|
|
+}
|
|
|
+
|
|
|
+static QDF_STATUS hdd_debugfs_mws_antenna_sharing_read(qdf_debugfs_file_t file,
|
|
|
+ void *arg)
|
|
|
+{
|
|
|
+ struct osif_psoc_sync *psoc_sync;
|
|
|
+ struct hdd_context *hdd_ctx = arg;
|
|
|
+ int ret;
|
|
|
+ QDF_STATUS status;
|
|
|
+
|
|
|
+ ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync);
|
|
|
+ if (ret)
|
|
|
+ return qdf_status_from_os_return(ret);
|
|
|
+
|
|
|
+ status = __hdd_debugfs_mws_antenna_sharing_read(hdd_ctx, file);
|
|
|
+
|
|
|
+ osif_psoc_sync_op_stop(psoc_sync);
|
|
|
+ return qdf_status_from_os_return(ret);
|
|
|
+}
|
|
|
+
|
|
|
+static struct qdf_debugfs_fops hdd_mws_debugfs_coex_state_fops = {
|
|
|
+ .show = hdd_debugfs_mws_coex_state_read,
|
|
|
+};
|
|
|
+
|
|
|
+static struct qdf_debugfs_fops hdd_mws_debugfs_fops_coex_dpwb_fops = {
|
|
|
+ .show = hdd_debugfs_mws_coex_dpwb_read,
|
|
|
+};
|
|
|
+
|
|
|
+static struct qdf_debugfs_fops hdd_mws_debugfs_tdm_state_fpos = {
|
|
|
+ .show = hdd_debugfs_mws_tdm_state_read,
|
|
|
+};
|
|
|
+
|
|
|
+static struct qdf_debugfs_fops hdd_mws_debugfs_idrx_state_fpos = {
|
|
|
+ .show = hdd_debugfs_mws_coex_idrx_read,
|
|
|
+};
|
|
|
+
|
|
|
+static struct qdf_debugfs_fops hdd_mws_debugfs_antenna_sharing_fpos = {
|
|
|
+ .show = hdd_debugfs_mws_antenna_sharing_read,
|
|
|
+};
|
|
|
+
|
|
|
+void hdd_debugfs_mws_coex_info_init(struct hdd_context *hdd_ctx)
|
|
|
+{
|
|
|
+ hdd_mws_debugfs_coex_state_fops.priv = hdd_ctx;
|
|
|
+ hdd_mws_debugfs_fops_coex_dpwb_fops.priv = hdd_ctx;
|
|
|
+ hdd_mws_debugfs_tdm_state_fpos.priv = hdd_ctx;
|
|
|
+ hdd_mws_debugfs_idrx_state_fpos.priv = hdd_ctx;
|
|
|
+ hdd_mws_debugfs_antenna_sharing_fpos.priv = hdd_ctx;
|
|
|
+ if (!qdf_debugfs_create_file("mws_coex_state", MWS_DEBUGFS_PERMS,
|
|
|
+ NULL, &hdd_mws_debugfs_coex_state_fops))
|
|
|
+ hdd_err("Failed to create the mws coex state file");
|
|
|
+ if (!qdf_debugfs_create_file("mws_coex_dpwb_state", MWS_DEBUGFS_PERMS,
|
|
|
+ NULL,
|
|
|
+ &hdd_mws_debugfs_fops_coex_dpwb_fops))
|
|
|
+ hdd_err("Failed to create the mws coex dpwb file");
|
|
|
+ if (!qdf_debugfs_create_file("mws_coex_tdm_state", MWS_DEBUGFS_PERMS,
|
|
|
+ NULL, &hdd_mws_debugfs_tdm_state_fpos))
|
|
|
+ hdd_err("Failed to create the mws coex tdm file");
|
|
|
+ if (!qdf_debugfs_create_file("mws_coex_idrx", MWS_DEBUGFS_PERMS,
|
|
|
+ NULL, &hdd_mws_debugfs_idrx_state_fpos))
|
|
|
+ hdd_err("Failed to create the mws coex idrx file");
|
|
|
+ if (!qdf_debugfs_create_file("mws_coex_antenna_sharing",
|
|
|
+ MWS_DEBUGFS_PERMS,
|
|
|
+ NULL,
|
|
|
+ &hdd_mws_debugfs_antenna_sharing_fpos))
|
|
|
+ hdd_err("Failed to create the mws coex antenna sharing file");
|
|
|
+}
|
|
|
+
|
|
|
+void hdd_debugfs_mws_coex_info_deinit(struct hdd_context *hdd_ctx)
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * Coex info dosent have a directory it is removed as part of qdf remove
|
|
|
+ */
|
|
|
+}
|