blob: b806ba18a737ec7fc1a3452471581eaa0d874515 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Ryan Hsuc8b27a42018-01-02 13:57:56 -08002 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * DOC: wlan_hdd_ftm.c
30 *
31 * This file contains the WLAN factory test mode implementation
32 */
33
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080034#include "cds_sched.h"
35#include <cds_api.h>
36#include "sir_types.h"
Anurag Chouhan6d760662016-02-20 16:05:43 +053037#include "qdf_types.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080038#include "sir_api.h"
39#include "sir_mac_prot_def.h"
40#include "sme_api.h"
41#include "mac_init_api.h"
42#include "wlan_qct_sys.h"
43#include "wlan_hdd_misc.h"
44#include "i_cds_packet.h"
45#include "cds_reg_service.h"
46#include "wlan_hdd_main.h"
Jeff Johnson9078bdc2016-09-23 17:18:11 -070047#include "wlan_hdd_lpass.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080048#include "qwlan_version.h"
49#include "wma_types.h"
50#include "cfg_api.h"
51
Ryan Hsu6fdc60f2018-01-05 16:51:09 -080052#ifdef QCA_WIFI_FTM
53
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080054#include "wlan_hdd_cfg80211.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080055#include "hif.h"
Ryan Hsuc8b27a42018-01-02 13:57:56 -080056#include <wlan_ioctl_ftm.h>
Arif Hussain55aaaad2018-02-14 12:23:26 -080057#include <wlan_cfg80211_ftm.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080058
Jeff Johnsone0e77452017-08-21 14:59:12 -070059struct qcmbr_data {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080060 unsigned int cmd;
61 unsigned int length;
Arif Hussain55aaaad2018-02-14 12:23:26 -080062 unsigned char buf[WLAN_FTM_DATA_MAX_LEN + 4];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080063 unsigned int copy_to_user;
Jeff Johnsone0e77452017-08-21 14:59:12 -070064};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080065
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080066/**
Arun Khandavallic811dcc2016-06-26 07:37:21 +053067 * hdd_update_cds_config_ftm() - API to update cds configuration parameters
68 * for FTM mode.
69 * @hdd_ctx: HDD Context
70 *
71 * Return: 0 on success; errno on failure
72 */
73
Jeff Johnson2b59af62017-08-28 12:01:18 -070074int hdd_update_cds_config_ftm(struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +053075{
76 struct cds_config_info *cds_cfg;
77
Jeff Johnson9078bdc2016-09-23 17:18:11 -070078 cds_cfg = qdf_mem_malloc(sizeof(*cds_cfg));
Arun Khandavallic811dcc2016-06-26 07:37:21 +053079 if (!cds_cfg) {
80 hdd_err("failed to allocate cds config");
81 return -ENOMEM;
82 }
Arun Khandavallic811dcc2016-06-26 07:37:21 +053083
Srinivas Girigowda35b00312017-06-27 21:52:03 -070084 cds_cfg->driver_type = QDF_DRIVER_TYPE_MFG;
Arun Khandavallic811dcc2016-06-26 07:37:21 +053085 cds_cfg->powersave_offload_enabled =
86 hdd_ctx->config->enablePowersaveOffload;
Jeff Johnson9078bdc2016-09-23 17:18:11 -070087 hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
Naveen Rawat64e477e2016-05-20 10:34:56 -070088 cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
Arun Khandavallic811dcc2016-06-26 07:37:21 +053089 cds_init_ini_config(cds_cfg);
90
91 return 0;
92}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080093
Ryan Hsu6fdc60f2018-01-05 16:51:09 -080094#ifdef LINUX_QCMBR
Lin Bai06cfea02018-02-01 18:08:37 +080095
96/**
97 * wlan_hdd_qcmbr_command() - QCMBR command handler
98 * @adapter: adapter upon which the command was received
99 * @pqcmbr_data: QCMBR command
100 *
101 * Return: 0 on success, non-zero on error
102 */
103static int wlan_hdd_qcmbr_command(struct hdd_adapter *adapter,
104 struct qcmbr_data *pqcmbr_data)
105{
106 int ret = 0;
107 struct hdd_context *hdd_ctx;
108
109 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
110 ret = wlan_hdd_validate_context(hdd_ctx);
111 if (ret)
112 return ret;
113
114 ret = wlan_ioctl_ftm_testmode_cmd(hdd_ctx->hdd_pdev,
115 pqcmbr_data->cmd,
116 pqcmbr_data->buf,
117 pqcmbr_data->length);
118
119 return ret;
120}
121
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800122#ifdef CONFIG_COMPAT
Ryan Hsu6fdc60f2018-01-05 16:51:09 -0800123
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800124/**
125 * wlan_hdd_qcmbr_ioctl() - Compatability-mode QCMBR ioctl handler
126 * @adapter: adapter upon which the ioctl was received
127 * @ifr: the ioctl request
128 *
129 * Return: 0 on success, non-zero on error
130 */
Jeff Johnsona5dc3f42017-08-29 14:34:33 -0700131static int wlan_hdd_qcmbr_compat_ioctl(struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800132 struct ifreq *ifr)
133{
Jeff Johnsone0e77452017-08-21 14:59:12 -0700134 struct qcmbr_data *qcmbr_data;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800135 int ret = 0;
136
Jeff Johnsone0e77452017-08-21 14:59:12 -0700137 qcmbr_data = qdf_mem_malloc(sizeof(*qcmbr_data));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800138 if (qcmbr_data == NULL)
139 return -ENOMEM;
140
141 if (copy_from_user(qcmbr_data, ifr->ifr_data, sizeof(*qcmbr_data))) {
142 ret = -EFAULT;
143 goto exit;
144 }
145
146 ret = wlan_hdd_qcmbr_command(adapter, qcmbr_data);
Arif Hussain55aaaad2018-02-14 12:23:26 -0800147 if ((ret == 0) && (qcmbr_data->cmd == 0x1001)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800148 ret = copy_to_user(ifr->ifr_data, qcmbr_data->buf,
Arif Hussain55aaaad2018-02-14 12:23:26 -0800149 (WLAN_FTM_DATA_MAX_LEN + 4));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800150 }
151
152exit:
Mahesh Kumar Kalikot Veetil9c656182016-11-02 10:28:03 -0700153 qdf_mem_free(qcmbr_data);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800154 return ret;
155}
156#else /* CONFIG_COMPAT */
Jeff Johnsona5dc3f42017-08-29 14:34:33 -0700157static int wlan_hdd_qcmbr_compat_ioctl(struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800158 struct ifreq *ifr)
159{
160 return 0;
161}
162#endif /* CONFIG_COMPAT */
163
164/**
165 * wlan_hdd_qcmbr_ioctl() - Standard QCMBR ioctl handler
166 * @adapter: adapter upon which the ioctl was received
167 * @ifr: the ioctl request
168 *
169 * Return: 0 on success, non-zero on error
170 */
Jeff Johnsona5dc3f42017-08-29 14:34:33 -0700171static int wlan_hdd_qcmbr_ioctl(struct hdd_adapter *adapter, struct ifreq *ifr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800172{
Jeff Johnsone0e77452017-08-21 14:59:12 -0700173 struct qcmbr_data *qcmbr_data;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800174 int ret = 0;
175
Jeff Johnsone0e77452017-08-21 14:59:12 -0700176 qcmbr_data = qdf_mem_malloc(sizeof(*qcmbr_data));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800177 if (qcmbr_data == NULL)
178 return -ENOMEM;
179
180 if (copy_from_user(qcmbr_data, ifr->ifr_data, sizeof(*qcmbr_data))) {
181 ret = -EFAULT;
182 goto exit;
183 }
184
185 ret = wlan_hdd_qcmbr_command(adapter, qcmbr_data);
Arif Hussain55aaaad2018-02-14 12:23:26 -0800186 if ((ret == 0) && (qcmbr_data->cmd == 0x1001)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800187 ret = copy_to_user(ifr->ifr_data, qcmbr_data->buf,
Arif Hussain55aaaad2018-02-14 12:23:26 -0800188 (WLAN_FTM_DATA_MAX_LEN + 4));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800189 }
190
191exit:
Mahesh Kumar Kalikot Veetil9c656182016-11-02 10:28:03 -0700192 qdf_mem_free(qcmbr_data);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800193 return ret;
194}
195
196/**
197 * wlan_hdd_qcmbr_unified_ioctl() - Unified QCMBR ioctl handler
198 * @adapter: adapter upon which the ioctl was received
199 * @ifr: the ioctl request
200 *
201 * Return: 0 on success, non-zero on error
202 */
Jeff Johnsonaf007ea2017-10-03 11:16:51 -0700203int wlan_hdd_qcmbr_unified_ioctl(struct hdd_adapter *adapter,
204 struct ifreq *ifr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800205{
206 int ret = 0;
207
Srinivas Girigowda576b2352017-08-25 14:44:26 -0700208 if (is_compat_task())
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800209 ret = wlan_hdd_qcmbr_compat_ioctl(adapter, ifr);
Srinivas Girigowda576b2352017-08-25 14:44:26 -0700210 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800211 ret = wlan_hdd_qcmbr_ioctl(adapter, ifr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800212
213 return ret;
214}
215
Ryan Hsu6fdc60f2018-01-05 16:51:09 -0800216#endif /* LINUX_QCMBR */
217#endif /* QCA_WIFI_FTM */