From patchwork Thu May 17 11:32:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ramon Fried X-Patchwork-Id: 136140 Delivered-To: patch@linaro.org Received: by 2002:a2e:9706:0:0:0:0:0 with SMTP id r6-v6csp75046lji; Thu, 17 May 2018 04:33:33 -0700 (PDT) X-Google-Smtp-Source: AB8JxZqcp9FlEViu78MK0+cQ6BkIrb8cx60RZh7EILokIFDVXRHBtDeKI4PTgEM6BzhWi5UVi0rt X-Received: by 2002:a62:d717:: with SMTP id b23-v6mr4800356pfh.5.1526556813273; Thu, 17 May 2018 04:33:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526556813; cv=none; d=google.com; s=arc-20160816; b=vO6Q+CQcUzPrGDIXMNB7E4KErVOm6KX26RcIC2HiROovYScB74IB2HgN9mHNIysXSe 0qAEEkJqcdqSAkNlZBNocipi6tOFFVP6fAFPknGBlTANOBQ82S4mbQxjdHw+mm2d5ZL5 eUJCde5Q12WKtbX9ipFu6r+gXlXP3MeMFzFCLLGqDH1csoyTXV6PWN+e5ckErUFo5AHR uvxMXVJd5tZSR84n88XxNZeUcUmIWtDAnbw37tqKH7yL34BLSphaeLFSkXi+rfQeVyiX /CZTFeLJ+Dk+f+cwwkeIqlMTmIGnBYDxHClciH3mqk7RuoTVheBPsXBe4GYTlilHGi5/ cArw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature :arc-authentication-results; bh=n9ML1TALxawu/1o0UTR5qplJOZQGsjCFFfWkPR3zPT8=; b=Lg1XQ8Bko0/ii/GbW1uCWeSCQMWLXekcxlHfb3amyx6IPjXrNEKkk43NJx8mCxXC4J 5DpPU6lEqJppCpSf7Skn0B3rJMY1tetbPQYZc97VB9etJYryBpR/dRKoRdXKoaItPs/W VxfkeOWiY6yxUAQYnlikQOPDdFruNSOlz+sBKjt6I3PVpljpsDt99CvSQ7MSv4jfDtsv 64eSJYw3t8yNbuiy93H6/+J1/DVgla+U5vDfWlk6uygqYf7deXuzXJakTKW37rSJTVuv X+rgVvvvM3Vk12wEx28G8OdH5BafZq9pcKlQV/dQBvjKHmAT5ymR+Q1pMv1PGG+HkLca VknQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=g/Q70ZXq; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j12-v6si4056379pgf.294.2018.05.17.04.33.32; Thu, 17 May 2018 04:33:33 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=g/Q70ZXq; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752213AbeEQLd1 (ORCPT + 29 others); Thu, 17 May 2018 07:33:27 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:50925 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751097AbeEQLdV (ORCPT ); Thu, 17 May 2018 07:33:21 -0400 Received: by mail-wm0-f66.google.com with SMTP id t11-v6so7878097wmt.0 for ; Thu, 17 May 2018 04:33:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=n9ML1TALxawu/1o0UTR5qplJOZQGsjCFFfWkPR3zPT8=; b=g/Q70ZXqBYyH3VJsW/kIXmhv39gQ+hnAOMv0WaETvSOsWSK0W8oVUlNto5FkRRx++t xTYzlpe1BSVJeHEnJRJDBnNfI05GUBbvzaLePKTOdxxK0jXrdmDAbvIF+rEYqc84fR0z w6qdEle6BTYRz3CdSub3J1pvjrsOukJD0uLYo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=n9ML1TALxawu/1o0UTR5qplJOZQGsjCFFfWkPR3zPT8=; b=II1c+nf1Rk18Cb3Ph+YgWpkLc6nQlQ2YOpaMaQI6IkqjesGdO4hFJ858nDR82gvzvp k/KNbOJGq/erha+B3smYMPsGjh6OEiNQq09v0PZomOjsYRwlSuevKP4JW1qUYIzeb4nM fdJoq7pnjWY7zJY8CLXFGOVcDOr4UdqHctVAKOz+VKYfbaIrE0wS+D+6zskixQriMTXa 2laEz4+wijv7C9tqa6d1pMvk6Cu6YBhFJXiEe764LotFpaAoKXtLmH/LWp82H/+6IGn7 UrDi9xFfX3+DFqY+06pgP7E/fb86y6s/UiuNSzaa4ohk3aEri+LJtazrLXUv/h7Tsbir nf2A== X-Gm-Message-State: ALKqPwcCG4nYi+qpK0JsFMyb5uNaQEZVVsiIoNJF6kjgsxupcbEtUYFr xJKu6/HWDfyUy9cjLeMzzh7AyQ== X-Received: by 2002:a50:c2c1:: with SMTP id u1-v6mr6685730edf.56.1526556799844; Thu, 17 May 2018 04:33:19 -0700 (PDT) Received: from lx-rfried.mea.qualcomm.com ([185.23.60.4]) by smtp.gmail.com with ESMTPSA id g21-v6sm2358575edm.27.2018.05.17.04.33.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 17 May 2018 04:33:19 -0700 (PDT) From: Ramon Fried To: kvalo@codeaurora.org Cc: linux-kernel@vger.kernel.org, wcn36xx@lists.infradead.org, linux-wireless@vger.kernel.org, netdev@vger.kernel.org, Eyal Ilsar , Ramon Fried Subject: [PATCH] wcn36xx: Add support for Factory Test Mode (FTM) Date: Thu, 17 May 2018 14:32:50 +0300 Message-Id: <20180517113250.16517-1-ramon.fried@linaro.org> X-Mailer: git-send-email 2.17.0 MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Eyal Ilsar Introduce infrastructure for supporting Factory Test Mode (FTM) of the wireless LAN subsystem. In order for the user space to access the firmware in test mode the relevant netlink channel needs to be exposed from the kernel driver. The above is achieved as follows: 1) Register wcn36xx driver to testmode callback from netlink 2) Add testmode callback implementation to handle incoming FTM commands 3) Add FTM command packet structure 4) Add handling for GET_BUILD_RELEASE_NUMBER (msgid=0x32A2) 5) Add generic handling for all PTT_MSG packets Signed-off-by: Eyal Ilsar Signed-off-by: Ramon Fried --- drivers/net/wireless/ath/wcn36xx/Makefile | 2 + drivers/net/wireless/ath/wcn36xx/hal.h | 16 ++ drivers/net/wireless/ath/wcn36xx/main.c | 3 + drivers/net/wireless/ath/wcn36xx/smd.c | 74 +++++++++ drivers/net/wireless/ath/wcn36xx/smd.h | 4 + drivers/net/wireless/ath/wcn36xx/testmode.c | 151 ++++++++++++++++++ drivers/net/wireless/ath/wcn36xx/testmode.h | 46 ++++++ drivers/net/wireless/ath/wcn36xx/testmode_i.h | 29 ++++ drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 2 + 9 files changed, 327 insertions(+) create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode.c create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode.h create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode_i.h -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project diff --git a/drivers/net/wireless/ath/wcn36xx/Makefile b/drivers/net/wireless/ath/wcn36xx/Makefile index 3b09435104eb..582049f65735 100644 --- a/drivers/net/wireless/ath/wcn36xx/Makefile +++ b/drivers/net/wireless/ath/wcn36xx/Makefile @@ -6,3 +6,5 @@ wcn36xx-y += main.o \ smd.o \ pmc.o \ debug.o + +wcn36xx-$(CONFIG_NL80211_TESTMODE) += testmode.o diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h index 182963522941..8491b3cb3206 100644 --- a/drivers/net/wireless/ath/wcn36xx/hal.h +++ b/drivers/net/wireless/ath/wcn36xx/hal.h @@ -2230,6 +2230,22 @@ struct wcn36xx_hal_switch_channel_rsp_msg { } __packed; +struct wcn36xx_hal_process_ptt_msg_req_msg { + struct wcn36xx_hal_msg_header header; + + /* Actual FTM Command body */ + u8 ptt_msg[0]; +} __packed; + +struct wcn36xx_hal_process_ptt_msg_rsp_msg { + struct wcn36xx_hal_msg_header header; + + /* FTM Command response status */ + u32 ptt_msg_resp_status; + /* Actual FTM Command body */ + u8 ptt_msg[0]; +} __packed; + struct update_edca_params_req_msg { struct wcn36xx_hal_msg_header header; diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 69d6be59d97f..ea14f87d11ff 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -26,6 +26,7 @@ #include #include #include "wcn36xx.h" +#include "testmode.h" unsigned int wcn36xx_dbg_mask; module_param_named(debug_mask, wcn36xx_dbg_mask, uint, 0644); @@ -1116,6 +1117,8 @@ static const struct ieee80211_ops wcn36xx_ops = { .sta_add = wcn36xx_sta_add, .sta_remove = wcn36xx_sta_remove, .ampdu_action = wcn36xx_ampdu_action, + + CFG80211_TESTMODE_CMD(wcn36xx_tm_cmd) }; static int wcn36xx_init_ieee80211(struct wcn36xx *wcn) diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index 8932af5e4d8d..8eaf192f8bdb 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -292,12 +292,26 @@ static void init_hal_msg(struct wcn36xx_hal_msg_header *hdr, msg_body.header.len = sizeof(msg_body); \ } while (0) \ +#define INIT_HAL_PTT_MSG(p_msg_body, ppt_msg_len) \ + do { \ + memset(p_msg_body, 0, sizeof(*p_msg_body) + ppt_msg_len); \ + p_msg_body->header.msg_type = WCN36XX_HAL_PROCESS_PTT_REQ; \ + p_msg_body->header.msg_version = WCN36XX_HAL_MSG_VERSION0; \ + p_msg_body->header.len = sizeof(*p_msg_body) + ppt_msg_len; \ + } while (0) + #define PREPARE_HAL_BUF(send_buf, msg_body) \ do { \ memset(send_buf, 0, msg_body.header.len); \ memcpy(send_buf, &msg_body, sizeof(msg_body)); \ } while (0) \ +#define PREPARE_HAL_PTT_MSG_BUF(send_buf, p_msg_body) \ + do { \ + memset(send_buf, 0, p_msg_body->header.len); \ + memcpy(send_buf, p_msg_body, p_msg_body->header.len); \ + } while (0) + static int wcn36xx_smd_rsp_status_check(void *buf, size_t len) { struct wcn36xx_fw_msg_status_rsp *rsp; @@ -741,6 +755,64 @@ int wcn36xx_smd_switch_channel(struct wcn36xx *wcn, return ret; } +static int wcn36xx_smd_process_ptt_msg_rsp(void *buf, size_t len, + void **p_ptt_rsp_msg) +{ + struct wcn36xx_hal_process_ptt_msg_rsp_msg *rsp; + int ret = 0; + + ret = wcn36xx_smd_rsp_status_check(buf, len); + if (ret) + return ret; + + rsp = (struct wcn36xx_hal_process_ptt_msg_rsp_msg *)buf; + + wcn36xx_dbg(WCN36XX_DBG_HAL, "process ptt msg responded with length %d\n", + rsp->header.len); + wcn36xx_dbg_dump(WCN36XX_DBG_HAL_DUMP, "HAL_PTT_MSG_RSP:", rsp->ptt_msg, + rsp->header.len - sizeof(rsp->ptt_msg_resp_status)); + + if (rsp->header.len > 0) { + *p_ptt_rsp_msg = kmalloc(rsp->header.len, GFP_ATOMIC); + memcpy(*p_ptt_rsp_msg, rsp->ptt_msg, rsp->header.len); + } + return ret; +} + +int wcn36xx_smd_process_ptt_msg(struct wcn36xx *wcn, + struct ieee80211_vif *vif, void *ptt_msg, size_t len, + void **ptt_rsp_msg) +{ + struct wcn36xx_hal_process_ptt_msg_req_msg *p_msg_body; + int ret = 0; + + mutex_lock(&wcn->hal_mutex); + p_msg_body = kmalloc( + sizeof(struct wcn36xx_hal_process_ptt_msg_req_msg) + len, + GFP_ATOMIC); + INIT_HAL_PTT_MSG(p_msg_body, len); + + memcpy(&p_msg_body->ptt_msg, ptt_msg, len); + + PREPARE_HAL_PTT_MSG_BUF(wcn->hal_buf, p_msg_body); + + ret = wcn36xx_smd_send_and_wait(wcn, p_msg_body->header.len); + if (ret) { + wcn36xx_err("Sending hal_process_ptt_msg failed\n"); + goto out; + } + ret = wcn36xx_smd_process_ptt_msg_rsp(wcn->hal_buf, wcn->hal_rsp_len, + ptt_rsp_msg); + if (ret) { + wcn36xx_err("process_ptt_msg response failed err=%d\n", ret); + goto out; + } +out: + kfree(p_msg_body); + mutex_unlock(&wcn->hal_mutex); + return ret; +} + static int wcn36xx_smd_update_scan_params_rsp(void *buf, size_t len) { struct wcn36xx_hal_update_scan_params_resp *rsp; @@ -2367,6 +2439,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev, case WCN36XX_HAL_JOIN_RSP: case WCN36XX_HAL_UPDATE_SCAN_PARAM_RSP: case WCN36XX_HAL_CH_SWITCH_RSP: + case WCN36XX_HAL_PROCESS_PTT_RSP: case WCN36XX_HAL_FEATURE_CAPS_EXCHANGE_RSP: case WCN36XX_HAL_8023_MULTICAST_LIST_RSP: case WCN36XX_HAL_START_SCAN_OFFLOAD_RSP: @@ -2407,6 +2480,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev, return 0; } + static void wcn36xx_ind_smd_work(struct work_struct *work) { struct wcn36xx *wcn = diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h index 8076edf40ac8..6d83cc99dc25 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.h +++ b/drivers/net/wireless/ath/wcn36xx/smd.h @@ -86,6 +86,10 @@ int wcn36xx_smd_send_beacon(struct wcn36xx *wcn, struct ieee80211_vif *vif, u16 p2p_off); int wcn36xx_smd_switch_channel(struct wcn36xx *wcn, struct ieee80211_vif *vif, int ch); +int wcn36xx_smd_process_ptt_msg(struct wcn36xx *wcn, + struct ieee80211_vif *vif, + void *ptt_msg, size_t len, + void **ptt_rsp_msg); int wcn36xx_smd_update_proberesp_tmpl(struct wcn36xx *wcn, struct ieee80211_vif *vif, struct sk_buff *skb); diff --git a/drivers/net/wireless/ath/wcn36xx/testmode.c b/drivers/net/wireless/ath/wcn36xx/testmode.c new file mode 100644 index 000000000000..07d66b6bb4e8 --- /dev/null +++ b/drivers/net/wireless/ath/wcn36xx/testmode.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2018, 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. + */ + +#include +#include +#include +#include "wcn36xx.h" + +#include "testmode.h" +#include "testmode_i.h" +#include "hal.h" +#include "smd.h" + +static const struct nla_policy wcn36xx_tm_policy[WCN36XX_TM_ATTR_MAX + 1] = { + [WCN36XX_TM_ATTR_CMD] = { .type = NLA_U16 }, + [WCN36XX_TM_ATTR_DATA] = { .type = NLA_BINARY, + .len = WCN36XX_TM_DATA_MAX_LEN }, +}; + +struct build_release_number { + u16 drv_major; + u16 drv_minor; + u16 drv_patch; + u16 drv_build; + u16 ptt_max; + u16 ptt_min; + u16 fw_ver; +} __packed; + +static int wcn36xx_tm_cmd_ptt(struct wcn36xx *wcn, struct ieee80211_vif *vif, + struct nlattr *tb[]) +{ + int ret = 0, buf_len; + void *buf; + struct ftm_rsp_msg *msg, *rsp = NULL; + struct sk_buff *skb; + + if (!tb[WCN36XX_TM_ATTR_DATA]) { + ret = -EINVAL; + goto out; + } + + buf = nla_data(tb[WCN36XX_TM_ATTR_DATA]); + buf_len = nla_len(tb[WCN36XX_TM_ATTR_DATA]); + msg = (struct ftm_rsp_msg *)buf; + + wcn36xx_dbg(WCN36XX_DBG_TESTMODE, + "testmode cmd wmi msg_id 0x%04X msg_len %d buf %pK buf_len %d\n", + msg->msg_id, msg->msg_body_length, + buf, buf_len); + + wcn36xx_dbg_dump(WCN36XX_DBG_TESTMODE_DUMP, "REQ ", buf, buf_len); + + if (msg->msg_id == MSG_GET_BUILD_RELEASE_NUMBER) { + struct build_release_number *body = + (struct build_release_number *) + msg->msg_response; + + body->drv_major = wcn->fw_major; + body->drv_minor = wcn->fw_minor; + body->drv_patch = wcn->fw_version; + body->drv_build = wcn->fw_revision; + body->ptt_max = 10; + body->ptt_min = 0; + + rsp = msg; + rsp->resp_status = 0; + } else { + wcn36xx_dbg(WCN36XX_DBG_TESTMODE, + "PPT Request >> HAL size %d\n", + msg->msg_body_length); + + msg->resp_status = wcn36xx_smd_process_ptt_msg(wcn, vif, msg, + msg->msg_body_length, (void *)(&rsp)); + + wcn36xx_dbg(WCN36XX_DBG_TESTMODE, + "Response status = %d\n", + msg->resp_status); + if (rsp) + wcn36xx_dbg(WCN36XX_DBG_TESTMODE, + "PPT Response << HAL size %d\n", + rsp->msg_body_length); + } + + if (!rsp) { + rsp = msg; + wcn36xx_warn("No response! Echoing request with response status %d\n", + rsp->resp_status); + } + wcn36xx_dbg_dump(WCN36XX_DBG_TESTMODE_DUMP, "RSP ", + rsp, rsp->msg_body_length); + + skb = cfg80211_testmode_alloc_reply_skb(wcn->hw->wiphy, + nla_total_size(msg->msg_body_length)); + if (!skb) { + ret = -ENOMEM; + goto out; + } + + ret = nla_put(skb, WCN36XX_TM_ATTR_DATA, rsp->msg_body_length, rsp); + if (ret) { + kfree_skb(skb); + goto out; + } + + ret = cfg80211_testmode_reply(skb); + +out: + if (rsp != msg) + kfree(rsp); + + return ret; +} + +int wcn36xx_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + void *data, int len) +{ + struct wcn36xx *wcn = hw->priv; + struct nlattr *tb[WCN36XX_TM_ATTR_MAX + 1]; + int ret = 0; + unsigned short attr; + + wcn36xx_dbg_dump(WCN36XX_DBG_TESTMODE_DUMP, "Data:", data, len); + ret = nla_parse(tb, WCN36XX_TM_ATTR_MAX, data, len, + wcn36xx_tm_policy, NULL); + if (ret) + return ret; + + if (!tb[WCN36XX_TM_ATTR_CMD]) + return -EINVAL; + + attr = nla_get_u16(tb[WCN36XX_TM_ATTR_CMD]); + + if (attr != WCN36XX_TM_CMD_PTT) + return -EOPNOTSUPP; + + return wcn36xx_tm_cmd_ptt(wcn, vif, tb); +} diff --git a/drivers/net/wireless/ath/wcn36xx/testmode.h b/drivers/net/wireless/ath/wcn36xx/testmode.h new file mode 100644 index 000000000000..aba014896dfd --- /dev/null +++ b/drivers/net/wireless/ath/wcn36xx/testmode.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018, 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. + */ + +#include "wcn36xx.h" + +struct ftm_rsp_msg { + u16 msg_id; + u16 msg_body_length; + u32 resp_status; + u8 msg_response[0]; +} __packed; + +/* The request buffer of FTM which contains a byte of command and the request */ +struct ftm_payload { + u16 ftm_cmd_type; + struct ftm_rsp_msg ftm_cmd_msg; +} __packed; + +#define MSG_GET_BUILD_RELEASE_NUMBER 0x32A2 + +#ifdef CONFIG_NL80211_TESTMODE +int wcn36xx_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + void *data, int len); + +#else +static inline int wcn36xx_tm_cmd(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + void *data, int len) +{ + return 0; +} + +#endif diff --git a/drivers/net/wireless/ath/wcn36xx/testmode_i.h b/drivers/net/wireless/ath/wcn36xx/testmode_i.h new file mode 100644 index 000000000000..8a1477ffd5a0 --- /dev/null +++ b/drivers/net/wireless/ath/wcn36xx/testmode_i.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018, 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. + */ + +#define WCN36XX_TM_DATA_MAX_LEN 5000 + +enum wcn36xx_tm_attr { + __WCN36XX_TM_ATTR_INVALID = 0, + WCN36XX_TM_ATTR_CMD = 1, + WCN36XX_TM_ATTR_DATA = 2, + + /* keep last */ + __WCN36XX_TM_ATTR_AFTER_LAST, + WCN36XX_TM_ATTR_MAX = __WCN36XX_TM_ATTR_AFTER_LAST - 1, +}; + +#define WCN36XX_TM_CMD_PTT 3 diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h index 5854adf43f3a..547e9a9eb28f 100644 --- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h +++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h @@ -56,6 +56,8 @@ enum wcn36xx_debug_mask { WCN36XX_DBG_BEACON_DUMP = 0x00001000, WCN36XX_DBG_PMC = 0x00002000, WCN36XX_DBG_PMC_DUMP = 0x00004000, + WCN36XX_DBG_TESTMODE = 0x00008000, + WCN36XX_DBG_TESTMODE_DUMP = 0x00010000, WCN36XX_DBG_ANY = 0xffffffff, };