blob: 13de3617d5abc3e76a5f7dc99eb96f9a500d9b42 [file] [log] [blame]
Kalle Valo5e3dd152013-06-12 20:52:10 +03001/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <linux/module.h>
19#include <linux/firmware.h>
Toshi Kikuchi5aabff02014-12-02 10:55:54 +020020#include <linux/of.h>
Kalle Valo5e3dd152013-06-12 20:52:10 +030021
22#include "core.h"
23#include "mac.h"
24#include "htc.h"
25#include "hif.h"
26#include "wmi.h"
27#include "bmi.h"
28#include "debug.h"
29#include "htt.h"
Kalle Valo43d2a302014-09-10 18:23:30 +030030#include "testmode.h"
Michal Kaziord7579d12014-12-03 10:10:54 +020031#include "wmi-ops.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030032
33unsigned int ath10k_debug_mask;
David Liuccec9032015-07-24 20:25:32 +030034static unsigned int ath10k_cryptmode_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +030035static bool uart_print;
Rajkumar Manoharan8868b122014-11-17 16:44:14 +020036static bool skip_otp;
Bob Copelandb6c7baf2015-09-09 12:47:36 -040037static bool rawmode;
Rajkumar Manoharan8868b122014-11-17 16:44:14 +020038
Kalle Valo5e3dd152013-06-12 20:52:10 +030039module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
David Liuccec9032015-07-24 20:25:32 +030040module_param_named(cryptmode, ath10k_cryptmode_param, uint, 0644);
Kalle Valo5e3dd152013-06-12 20:52:10 +030041module_param(uart_print, bool, 0644);
Rajkumar Manoharan8868b122014-11-17 16:44:14 +020042module_param(skip_otp, bool, 0644);
Bob Copelandb6c7baf2015-09-09 12:47:36 -040043module_param(rawmode, bool, 0644);
Rajkumar Manoharan8868b122014-11-17 16:44:14 +020044
Kalle Valo5e3dd152013-06-12 20:52:10 +030045MODULE_PARM_DESC(debug_mask, "Debugging mask");
46MODULE_PARM_DESC(uart_print, "Uart target debugging");
Rajkumar Manoharan8868b122014-11-17 16:44:14 +020047MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
David Liuccec9032015-07-24 20:25:32 +030048MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software");
Bob Copelandb6c7baf2015-09-09 12:47:36 -040049MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath");
Kalle Valo5e3dd152013-06-12 20:52:10 +030050
51static const struct ath10k_hw_params ath10k_hw_params_list[] = {
52 {
Kalle Valo5e3dd152013-06-12 20:52:10 +030053 .id = QCA988X_HW_2_0_VERSION,
54 .name = "qca988x hw2.0",
55 .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
Michal Kazior3a8200b2014-12-02 10:55:55 +020056 .uart_pin = 7,
Michal Kazior587f7032015-05-25 14:06:18 +020057 .has_shifted_cc_wraparound = true,
Vasanthakumar Thiagarajand7727032015-06-18 12:31:10 +053058 .otp_exe_param = 0,
Vasanthakumar Thiagarajan9c8fb542015-08-12 16:24:05 +053059 .channel_counters_freq_hz = 88000,
Vivek Natarajan7b7da0a2015-08-31 16:34:55 +053060 .max_probe_resp_desc_thres = 0,
Kalle Valo5e3dd152013-06-12 20:52:10 +030061 .fw = {
62 .dir = QCA988X_HW_2_0_FW_DIR,
63 .fw = QCA988X_HW_2_0_FW_FILE,
64 .otp = QCA988X_HW_2_0_OTP_FILE,
65 .board = QCA988X_HW_2_0_BOARD_DATA_FILE,
Michal Kazior9764a2a2014-12-02 10:55:54 +020066 .board_size = QCA988X_BOARD_DATA_SZ,
67 .board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
Kalle Valo5e3dd152013-06-12 20:52:10 +030068 },
69 },
Michal Kaziord63955b2015-01-24 12:14:49 +020070 {
71 .id = QCA6174_HW_2_1_VERSION,
72 .name = "qca6174 hw2.1",
73 .patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
74 .uart_pin = 6,
Vasanthakumar Thiagarajand7727032015-06-18 12:31:10 +053075 .otp_exe_param = 0,
Vasanthakumar Thiagarajan9c8fb542015-08-12 16:24:05 +053076 .channel_counters_freq_hz = 88000,
Vivek Natarajan7b7da0a2015-08-31 16:34:55 +053077 .max_probe_resp_desc_thres = 0,
Michal Kaziord63955b2015-01-24 12:14:49 +020078 .fw = {
79 .dir = QCA6174_HW_2_1_FW_DIR,
80 .fw = QCA6174_HW_2_1_FW_FILE,
81 .otp = QCA6174_HW_2_1_OTP_FILE,
82 .board = QCA6174_HW_2_1_BOARD_DATA_FILE,
83 .board_size = QCA6174_BOARD_DATA_SZ,
84 .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
85 },
86 },
87 {
88 .id = QCA6174_HW_3_0_VERSION,
89 .name = "qca6174 hw3.0",
90 .patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
91 .uart_pin = 6,
Vasanthakumar Thiagarajand7727032015-06-18 12:31:10 +053092 .otp_exe_param = 0,
Vasanthakumar Thiagarajan9c8fb542015-08-12 16:24:05 +053093 .channel_counters_freq_hz = 88000,
Vivek Natarajan7b7da0a2015-08-31 16:34:55 +053094 .max_probe_resp_desc_thres = 0,
Michal Kaziord63955b2015-01-24 12:14:49 +020095 .fw = {
96 .dir = QCA6174_HW_3_0_FW_DIR,
97 .fw = QCA6174_HW_3_0_FW_FILE,
98 .otp = QCA6174_HW_3_0_OTP_FILE,
99 .board = QCA6174_HW_3_0_BOARD_DATA_FILE,
100 .board_size = QCA6174_BOARD_DATA_SZ,
101 .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
102 },
103 },
Michal Kazior608b8f72015-01-29 13:24:33 +0100104 {
105 .id = QCA6174_HW_3_2_VERSION,
106 .name = "qca6174 hw3.2",
107 .patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
108 .uart_pin = 6,
Vasanthakumar Thiagarajand7727032015-06-18 12:31:10 +0530109 .otp_exe_param = 0,
Vasanthakumar Thiagarajan9c8fb542015-08-12 16:24:05 +0530110 .channel_counters_freq_hz = 88000,
Vivek Natarajan7b7da0a2015-08-31 16:34:55 +0530111 .max_probe_resp_desc_thres = 0,
Michal Kazior608b8f72015-01-29 13:24:33 +0100112 .fw = {
113 /* uses same binaries as hw3.0 */
114 .dir = QCA6174_HW_3_0_FW_DIR,
115 .fw = QCA6174_HW_3_0_FW_FILE,
116 .otp = QCA6174_HW_3_0_OTP_FILE,
117 .board = QCA6174_HW_3_0_BOARD_DATA_FILE,
118 .board_size = QCA6174_BOARD_DATA_SZ,
119 .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
120 },
121 },
Vasanthakumar Thiagarajan8bd47022015-06-18 12:31:03 +0530122 {
123 .id = QCA99X0_HW_2_0_DEV_VERSION,
124 .name = "qca99x0 hw2.0",
125 .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
126 .uart_pin = 7,
Vasanthakumar Thiagarajand7727032015-06-18 12:31:10 +0530127 .otp_exe_param = 0x00000700,
Raja Manid9156b52015-06-22 20:22:27 +0530128 .continuous_frag_desc = true,
Vasanthakumar Thiagarajan9c8fb542015-08-12 16:24:05 +0530129 .channel_counters_freq_hz = 150000,
Vivek Natarajan7b7da0a2015-08-31 16:34:55 +0530130 .max_probe_resp_desc_thres = 24,
Vasanthakumar Thiagarajan8bd47022015-06-18 12:31:03 +0530131 .fw = {
132 .dir = QCA99X0_HW_2_0_FW_DIR,
133 .fw = QCA99X0_HW_2_0_FW_FILE,
134 .otp = QCA99X0_HW_2_0_OTP_FILE,
135 .board = QCA99X0_HW_2_0_BOARD_DATA_FILE,
136 .board_size = QCA99X0_BOARD_DATA_SZ,
137 .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
138 },
139 },
Kalle Valo5e3dd152013-06-12 20:52:10 +0300140};
141
Michal Kaziorb27bc5a2015-06-15 14:46:40 +0300142static const char *const ath10k_core_fw_feature_str[] = {
143 [ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX] = "wmi-mgmt-rx",
144 [ATH10K_FW_FEATURE_WMI_10X] = "wmi-10.x",
145 [ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX] = "has-wmi-mgmt-tx",
146 [ATH10K_FW_FEATURE_NO_P2P] = "no-p2p",
147 [ATH10K_FW_FEATURE_WMI_10_2] = "wmi-10.2",
148 [ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT] = "multi-vif-ps",
149 [ATH10K_FW_FEATURE_WOWLAN_SUPPORT] = "wowlan",
150 [ATH10K_FW_FEATURE_IGNORE_OTP_RESULT] = "ignore-otp",
151 [ATH10K_FW_FEATURE_NO_NWIFI_DECAP_4ADDR_PADDING] = "no-4addr-pad",
152 [ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT] = "skip-clock-init",
Kalle Valo5af82fa2015-09-09 11:34:37 +0300153 [ATH10K_FW_FEATURE_RAW_MODE_SUPPORT] = "raw-mode",
Michal Kaziorb27bc5a2015-06-15 14:46:40 +0300154};
155
156static unsigned int ath10k_core_get_fw_feature_str(char *buf,
157 size_t buf_len,
158 enum ath10k_fw_features feat)
159{
Kalle Valo5af82fa2015-09-09 11:34:37 +0300160 /* make sure that ath10k_core_fw_feature_str[] gets updated */
161 BUILD_BUG_ON(ARRAY_SIZE(ath10k_core_fw_feature_str) !=
162 ATH10K_FW_FEATURE_COUNT);
163
Michal Kaziorb27bc5a2015-06-15 14:46:40 +0300164 if (feat >= ARRAY_SIZE(ath10k_core_fw_feature_str) ||
165 WARN_ON(!ath10k_core_fw_feature_str[feat])) {
166 return scnprintf(buf, buf_len, "bit%d", feat);
167 }
168
169 return scnprintf(buf, buf_len, "%s", ath10k_core_fw_feature_str[feat]);
170}
171
172void ath10k_core_get_fw_features_str(struct ath10k *ar,
173 char *buf,
174 size_t buf_len)
175{
176 unsigned int len = 0;
177 int i;
178
179 for (i = 0; i < ATH10K_FW_FEATURE_COUNT; i++) {
180 if (test_bit(i, ar->fw_features)) {
181 if (len > 0)
182 len += scnprintf(buf + len, buf_len - len, ",");
183
184 len += ath10k_core_get_fw_feature_str(buf + len,
185 buf_len - len,
186 i);
187 }
188 }
189}
190
Kalle Valo5e3dd152013-06-12 20:52:10 +0300191static void ath10k_send_suspend_complete(struct ath10k *ar)
192{
Michal Kazior7aa7a722014-08-25 12:09:38 +0200193 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot suspend complete\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300194
Marek Puzyniak9042e172014-02-10 17:14:23 +0100195 complete(&ar->target_suspend);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300196}
197
Kalle Valo5e3dd152013-06-12 20:52:10 +0300198static int ath10k_init_configure_target(struct ath10k *ar)
199{
200 u32 param_host;
201 int ret;
202
203 /* tell target which HTC version it is used*/
204 ret = ath10k_bmi_write32(ar, hi_app_host_interest,
205 HTC_PROTOCOL_VERSION);
206 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200207 ath10k_err(ar, "settings HTC version failed\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300208 return ret;
209 }
210
211 /* set the firmware mode to STA/IBSS/AP */
212 ret = ath10k_bmi_read32(ar, hi_option_flag, &param_host);
213 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200214 ath10k_err(ar, "setting firmware mode (1/2) failed\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300215 return ret;
216 }
217
218 /* TODO following parameters need to be re-visited. */
219 /* num_device */
220 param_host |= (1 << HI_OPTION_NUM_DEV_SHIFT);
221 /* Firmware mode */
222 /* FIXME: Why FW_MODE_AP ??.*/
223 param_host |= (HI_OPTION_FW_MODE_AP << HI_OPTION_FW_MODE_SHIFT);
224 /* mac_addr_method */
225 param_host |= (1 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
226 /* firmware_bridge */
227 param_host |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
228 /* fwsubmode */
229 param_host |= (0 << HI_OPTION_FW_SUBMODE_SHIFT);
230
231 ret = ath10k_bmi_write32(ar, hi_option_flag, param_host);
232 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200233 ath10k_err(ar, "setting firmware mode (2/2) failed\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300234 return ret;
235 }
236
237 /* We do all byte-swapping on the host */
238 ret = ath10k_bmi_write32(ar, hi_be, 0);
239 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200240 ath10k_err(ar, "setting host CPU BE mode failed\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300241 return ret;
242 }
243
244 /* FW descriptor/Data swap flags */
245 ret = ath10k_bmi_write32(ar, hi_fw_swap, 0);
246
247 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200248 ath10k_err(ar, "setting FW data/desc swap flags failed\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300249 return ret;
250 }
251
Michal Kazior36582e52015-08-13 14:32:26 +0200252 /* Some devices have a special sanity check that verifies the PCI
253 * Device ID is written to this host interest var. It is known to be
254 * required to boot QCA6164.
255 */
256 ret = ath10k_bmi_write32(ar, hi_hci_uart_pwr_mgmt_params_ext,
257 ar->dev_id);
258 if (ret) {
259 ath10k_err(ar, "failed to set pwr_mgmt_params: %d\n", ret);
260 return ret;
261 }
262
Kalle Valo5e3dd152013-06-12 20:52:10 +0300263 return 0;
264}
265
266static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar,
267 const char *dir,
268 const char *file)
269{
270 char filename[100];
271 const struct firmware *fw;
272 int ret;
273
274 if (file == NULL)
275 return ERR_PTR(-ENOENT);
276
277 if (dir == NULL)
278 dir = ".";
279
280 snprintf(filename, sizeof(filename), "%s/%s", dir, file);
281 ret = request_firmware(&fw, filename, ar->dev);
282 if (ret)
283 return ERR_PTR(ret);
284
285 return fw;
286}
287
Kalle Valoa58227e2014-10-13 09:40:59 +0300288static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data,
289 size_t data_len)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300290{
Michal Kazior9764a2a2014-12-02 10:55:54 +0200291 u32 board_data_size = ar->hw_params.fw.board_size;
292 u32 board_ext_data_size = ar->hw_params.fw.board_ext_size;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300293 u32 board_ext_data_addr;
294 int ret;
295
296 ret = ath10k_bmi_read32(ar, hi_board_ext_data, &board_ext_data_addr);
297 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200298 ath10k_err(ar, "could not read board ext data addr (%d)\n",
299 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300300 return ret;
301 }
302
Michal Kazior7aa7a722014-08-25 12:09:38 +0200303 ath10k_dbg(ar, ATH10K_DBG_BOOT,
Kalle Valoeffea962013-09-08 17:55:44 +0300304 "boot push board extended data addr 0x%x\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300305 board_ext_data_addr);
306
307 if (board_ext_data_addr == 0)
308 return 0;
309
Kalle Valoa58227e2014-10-13 09:40:59 +0300310 if (data_len != (board_data_size + board_ext_data_size)) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200311 ath10k_err(ar, "invalid board (ext) data sizes %zu != %d+%d\n",
Kalle Valoa58227e2014-10-13 09:40:59 +0300312 data_len, board_data_size, board_ext_data_size);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300313 return -EINVAL;
314 }
315
316 ret = ath10k_bmi_write_memory(ar, board_ext_data_addr,
Kalle Valoa58227e2014-10-13 09:40:59 +0300317 data + board_data_size,
Kalle Valo5e3dd152013-06-12 20:52:10 +0300318 board_ext_data_size);
319 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200320 ath10k_err(ar, "could not write board ext data (%d)\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300321 return ret;
322 }
323
324 ret = ath10k_bmi_write32(ar, hi_board_ext_data_config,
325 (board_ext_data_size << 16) | 1);
326 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200327 ath10k_err(ar, "could not write board ext data bit (%d)\n",
328 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300329 return ret;
330 }
331
332 return 0;
333}
334
Kalle Valoa58227e2014-10-13 09:40:59 +0300335static int ath10k_download_board_data(struct ath10k *ar, const void *data,
336 size_t data_len)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300337{
Michal Kazior9764a2a2014-12-02 10:55:54 +0200338 u32 board_data_size = ar->hw_params.fw.board_size;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300339 u32 address;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300340 int ret;
341
Kalle Valoa58227e2014-10-13 09:40:59 +0300342 ret = ath10k_push_board_ext_data(ar, data, data_len);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300343 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200344 ath10k_err(ar, "could not push board ext data (%d)\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300345 goto exit;
346 }
347
348 ret = ath10k_bmi_read32(ar, hi_board_data, &address);
349 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200350 ath10k_err(ar, "could not read board data addr (%d)\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300351 goto exit;
352 }
353
Kalle Valoa58227e2014-10-13 09:40:59 +0300354 ret = ath10k_bmi_write_memory(ar, address, data,
Kalle Valo958df3a2013-09-27 19:55:01 +0300355 min_t(u32, board_data_size,
Kalle Valoa58227e2014-10-13 09:40:59 +0300356 data_len));
Kalle Valo5e3dd152013-06-12 20:52:10 +0300357 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200358 ath10k_err(ar, "could not write board data (%d)\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300359 goto exit;
360 }
361
362 ret = ath10k_bmi_write32(ar, hi_board_data_initialized, 1);
363 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200364 ath10k_err(ar, "could not write board data bit (%d)\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300365 goto exit;
366 }
367
368exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300369 return ret;
370}
371
Kalle Valoa58227e2014-10-13 09:40:59 +0300372static int ath10k_download_cal_file(struct ath10k *ar)
373{
374 int ret;
375
376 if (!ar->cal_file)
377 return -ENOENT;
378
379 if (IS_ERR(ar->cal_file))
380 return PTR_ERR(ar->cal_file);
381
382 ret = ath10k_download_board_data(ar, ar->cal_file->data,
383 ar->cal_file->size);
384 if (ret) {
385 ath10k_err(ar, "failed to download cal_file data: %d\n", ret);
386 return ret;
387 }
388
389 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cal file downloaded\n");
390
391 return 0;
392}
393
Toshi Kikuchi5aabff02014-12-02 10:55:54 +0200394static int ath10k_download_cal_dt(struct ath10k *ar)
395{
396 struct device_node *node;
397 int data_len;
398 void *data;
399 int ret;
400
401 node = ar->dev->of_node;
402 if (!node)
403 /* Device Tree is optional, don't print any warnings if
404 * there's no node for ath10k.
405 */
406 return -ENOENT;
407
408 if (!of_get_property(node, "qcom,ath10k-calibration-data",
409 &data_len)) {
410 /* The calibration data node is optional */
411 return -ENOENT;
412 }
413
414 if (data_len != QCA988X_CAL_DATA_LEN) {
415 ath10k_warn(ar, "invalid calibration data length in DT: %d\n",
416 data_len);
417 ret = -EMSGSIZE;
418 goto out;
419 }
420
421 data = kmalloc(data_len, GFP_KERNEL);
422 if (!data) {
423 ret = -ENOMEM;
424 goto out;
425 }
426
427 ret = of_property_read_u8_array(node, "qcom,ath10k-calibration-data",
428 data, data_len);
429 if (ret) {
430 ath10k_warn(ar, "failed to read calibration data from DT: %d\n",
431 ret);
432 goto out_free;
433 }
434
435 ret = ath10k_download_board_data(ar, data, data_len);
436 if (ret) {
437 ath10k_warn(ar, "failed to download calibration data from Device Tree: %d\n",
438 ret);
439 goto out_free;
440 }
441
442 ret = 0;
443
444out_free:
445 kfree(data);
446
447out:
448 return ret;
449}
450
Manikanta Pubbisettydb0984e2015-10-09 11:55:59 +0300451static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
452{
453 u32 result, address;
454 u8 board_id, chip_id;
455 int ret;
456
457 address = ar->hw_params.patch_load_addr;
458
459 if (!ar->otp_data || !ar->otp_len) {
460 ath10k_warn(ar,
461 "failed to retrieve board id because of invalid otp\n");
462 return -ENODATA;
463 }
464
465 ath10k_dbg(ar, ATH10K_DBG_BOOT,
466 "boot upload otp to 0x%x len %zd for board id\n",
467 address, ar->otp_len);
468
469 ret = ath10k_bmi_fast_download(ar, address, ar->otp_data, ar->otp_len);
470 if (ret) {
471 ath10k_err(ar, "could not write otp for board id check: %d\n",
472 ret);
473 return ret;
474 }
475
476 ret = ath10k_bmi_execute(ar, address, BMI_PARAM_GET_EEPROM_BOARD_ID,
477 &result);
478 if (ret) {
479 ath10k_err(ar, "could not execute otp for board id check: %d\n",
480 ret);
481 return ret;
482 }
483
484 board_id = MS(result, ATH10K_BMI_BOARD_ID_FROM_OTP);
485 chip_id = MS(result, ATH10K_BMI_CHIP_ID_FROM_OTP);
486
487 ath10k_dbg(ar, ATH10K_DBG_BOOT,
488 "boot get otp board id result 0x%08x board_id %d chip_id %d\n",
489 result, board_id, chip_id);
490
491 if ((result & ATH10K_BMI_BOARD_ID_STATUS_MASK) != 0)
492 return -EOPNOTSUPP;
493
494 ar->id.bmi_ids_valid = true;
495 ar->id.bmi_board_id = board_id;
496 ar->id.bmi_chip_id = chip_id;
497
498 return 0;
499}
500
Kalle Valo5e3dd152013-06-12 20:52:10 +0300501static int ath10k_download_and_run_otp(struct ath10k *ar)
502{
Kalle Valod6d4a582014-03-11 17:33:19 +0200503 u32 result, address = ar->hw_params.patch_load_addr;
Vasanthakumar Thiagarajand7727032015-06-18 12:31:10 +0530504 u32 bmi_otp_exe_param = ar->hw_params.otp_exe_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300505 int ret;
506
Kalle Valoa58227e2014-10-13 09:40:59 +0300507 ret = ath10k_download_board_data(ar, ar->board_data, ar->board_len);
Kalle Valo83091552014-10-13 09:40:53 +0300508 if (ret) {
509 ath10k_err(ar, "failed to download board data: %d\n", ret);
510 return ret;
511 }
512
Kalle Valo5e3dd152013-06-12 20:52:10 +0300513 /* OTP is optional */
514
Kalle Valo7f06ea12014-03-11 17:33:28 +0200515 if (!ar->otp_data || !ar->otp_len) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200516 ath10k_warn(ar, "Not running otp, calibration will be incorrect (otp-data %p otp_len %zd)!\n",
Ben Greear36a8f412014-03-24 12:20:42 -0700517 ar->otp_data, ar->otp_len);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300518 return 0;
Kalle Valo7f06ea12014-03-11 17:33:28 +0200519 }
520
Michal Kazior7aa7a722014-08-25 12:09:38 +0200521 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n",
Kalle Valo7f06ea12014-03-11 17:33:28 +0200522 address, ar->otp_len);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300523
Kalle Valo958df3a2013-09-27 19:55:01 +0300524 ret = ath10k_bmi_fast_download(ar, address, ar->otp_data, ar->otp_len);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300525 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200526 ath10k_err(ar, "could not write otp (%d)\n", ret);
Kalle Valo7f06ea12014-03-11 17:33:28 +0200527 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300528 }
529
Vasanthakumar Thiagarajand7727032015-06-18 12:31:10 +0530530 ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300531 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200532 ath10k_err(ar, "could not execute otp (%d)\n", ret);
Kalle Valo7f06ea12014-03-11 17:33:28 +0200533 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300534 }
535
Michal Kazior7aa7a722014-08-25 12:09:38 +0200536 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);
Kalle Valo7f06ea12014-03-11 17:33:28 +0200537
Kalle Valod9153542015-04-28 20:19:30 +0300538 if (!(skip_otp || test_bit(ATH10K_FW_FEATURE_IGNORE_OTP_RESULT,
Kalle Valobe62e922015-10-05 17:56:34 +0300539 ar->fw_features)) &&
540 result != 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200541 ath10k_err(ar, "otp calibration failed: %d", result);
Kalle Valo7f06ea12014-03-11 17:33:28 +0200542 return -EINVAL;
543 }
544
545 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300546}
547
Kalle Valo43d2a302014-09-10 18:23:30 +0300548static int ath10k_download_fw(struct ath10k *ar, enum ath10k_firmware_mode mode)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300549{
Kalle Valo43d2a302014-09-10 18:23:30 +0300550 u32 address, data_len;
551 const char *mode_name;
552 const void *data;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300553 int ret;
554
Kalle Valo5e3dd152013-06-12 20:52:10 +0300555 address = ar->hw_params.patch_load_addr;
556
Kalle Valo43d2a302014-09-10 18:23:30 +0300557 switch (mode) {
558 case ATH10K_FIRMWARE_MODE_NORMAL:
559 data = ar->firmware_data;
560 data_len = ar->firmware_len;
561 mode_name = "normal";
Vasanthakumar Thiagarajandcb02db2015-06-18 12:31:09 +0530562 ret = ath10k_swap_code_seg_configure(ar,
Kalle Valo617b0f42015-10-05 17:56:35 +0300563 ATH10K_SWAP_CODE_SEG_BIN_TYPE_FW);
Vasanthakumar Thiagarajandcb02db2015-06-18 12:31:09 +0530564 if (ret) {
565 ath10k_err(ar, "failed to configure fw code swap: %d\n",
566 ret);
567 return ret;
568 }
Kalle Valo43d2a302014-09-10 18:23:30 +0300569 break;
570 case ATH10K_FIRMWARE_MODE_UTF:
571 data = ar->testmode.utf->data;
572 data_len = ar->testmode.utf->size;
573 mode_name = "utf";
574 break;
575 default:
576 ath10k_err(ar, "unknown firmware mode: %d\n", mode);
577 return -EINVAL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300578 }
579
Kalle Valo43d2a302014-09-10 18:23:30 +0300580 ath10k_dbg(ar, ATH10K_DBG_BOOT,
581 "boot uploading firmware image %p len %d mode %s\n",
582 data, data_len, mode_name);
583
584 ret = ath10k_bmi_fast_download(ar, address, data, data_len);
585 if (ret) {
586 ath10k_err(ar, "failed to download %s firmware: %d\n",
587 mode_name, ret);
588 return ret;
589 }
590
Michal Kazior29385052013-07-16 09:38:58 +0200591 return ret;
592}
593
Manikanta Pubbisetty0a51b342015-10-09 11:55:58 +0300594static void ath10k_core_free_board_files(struct ath10k *ar)
Michal Kazior29385052013-07-16 09:38:58 +0200595{
Markus Elfringdb2cf862015-02-04 19:30:23 +0100596 if (!IS_ERR(ar->board))
Kalle Valo36527912013-09-27 19:54:55 +0300597 release_firmware(ar->board);
Michal Kazior29385052013-07-16 09:38:58 +0200598
Manikanta Pubbisetty0a51b342015-10-09 11:55:58 +0300599 ar->board = NULL;
600 ar->board_data = NULL;
601 ar->board_len = 0;
602}
603
604static void ath10k_core_free_firmware_files(struct ath10k *ar)
605{
Markus Elfringdb2cf862015-02-04 19:30:23 +0100606 if (!IS_ERR(ar->otp))
Michal Kazior29385052013-07-16 09:38:58 +0200607 release_firmware(ar->otp);
608
Markus Elfringdb2cf862015-02-04 19:30:23 +0100609 if (!IS_ERR(ar->firmware))
Michal Kazior29385052013-07-16 09:38:58 +0200610 release_firmware(ar->firmware);
611
Markus Elfringdb2cf862015-02-04 19:30:23 +0100612 if (!IS_ERR(ar->cal_file))
Kalle Valoa58227e2014-10-13 09:40:59 +0300613 release_firmware(ar->cal_file);
614
Vasanthakumar Thiagarajandcb02db2015-06-18 12:31:09 +0530615 ath10k_swap_code_seg_release(ar);
616
Michal Kazior29385052013-07-16 09:38:58 +0200617 ar->otp = NULL;
Kalle Valo958df3a2013-09-27 19:55:01 +0300618 ar->otp_data = NULL;
619 ar->otp_len = 0;
620
Michal Kazior29385052013-07-16 09:38:58 +0200621 ar->firmware = NULL;
Kalle Valo958df3a2013-09-27 19:55:01 +0300622 ar->firmware_data = NULL;
623 ar->firmware_len = 0;
Kalle Valoa58227e2014-10-13 09:40:59 +0300624
625 ar->cal_file = NULL;
626}
627
628static int ath10k_fetch_cal_file(struct ath10k *ar)
629{
630 char filename[100];
631
632 /* cal-<bus>-<id>.bin */
633 scnprintf(filename, sizeof(filename), "cal-%s-%s.bin",
634 ath10k_bus_str(ar->hif.bus), dev_name(ar->dev));
635
636 ar->cal_file = ath10k_fetch_fw_file(ar, ATH10K_FW_DIR, filename);
637 if (IS_ERR(ar->cal_file))
638 /* calibration file is optional, don't print any warnings */
639 return PTR_ERR(ar->cal_file);
640
641 ath10k_dbg(ar, ATH10K_DBG_BOOT, "found calibration file %s/%s\n",
642 ATH10K_FW_DIR, filename);
643
644 return 0;
Michal Kazior29385052013-07-16 09:38:58 +0200645}
646
Manikanta Pubbisetty0a51b342015-10-09 11:55:58 +0300647static int ath10k_core_fetch_board_data_api_1(struct ath10k *ar)
Michal Kaziorde57e2c2015-04-17 09:19:17 +0000648{
Michal Kaziord0ed74f2015-04-17 09:19:16 +0000649 if (!ar->hw_params.fw.board) {
650 ath10k_err(ar, "failed to find board file fw entry\n");
Michal Kazior29385052013-07-16 09:38:58 +0200651 return -EINVAL;
652 }
653
Kalle Valo36527912013-09-27 19:54:55 +0300654 ar->board = ath10k_fetch_fw_file(ar,
655 ar->hw_params.fw.dir,
656 ar->hw_params.fw.board);
Michal Kaziorde57e2c2015-04-17 09:19:17 +0000657 if (IS_ERR(ar->board))
658 return PTR_ERR(ar->board);
Michal Kazior29385052013-07-16 09:38:58 +0200659
Kalle Valo958df3a2013-09-27 19:55:01 +0300660 ar->board_data = ar->board->data;
661 ar->board_len = ar->board->size;
Manikanta Pubbisetty0a51b342015-10-09 11:55:58 +0300662
663 return 0;
664}
665
666static int ath10k_core_parse_bd_ie_board(struct ath10k *ar,
667 const void *buf, size_t buf_len,
668 const char *boardname)
669{
670 const struct ath10k_fw_ie *hdr;
671 bool name_match_found;
672 int ret, board_ie_id;
673 size_t board_ie_len;
674 const void *board_ie_data;
675
676 name_match_found = false;
677
678 /* go through ATH10K_BD_IE_BOARD_ elements */
679 while (buf_len > sizeof(struct ath10k_fw_ie)) {
680 hdr = buf;
681 board_ie_id = le32_to_cpu(hdr->id);
682 board_ie_len = le32_to_cpu(hdr->len);
683 board_ie_data = hdr->data;
684
685 buf_len -= sizeof(*hdr);
686 buf += sizeof(*hdr);
687
688 if (buf_len < ALIGN(board_ie_len, 4)) {
689 ath10k_err(ar, "invalid ATH10K_BD_IE_BOARD length: %zu < %zu\n",
690 buf_len, ALIGN(board_ie_len, 4));
691 ret = -EINVAL;
692 goto out;
693 }
694
695 switch (board_ie_id) {
696 case ATH10K_BD_IE_BOARD_NAME:
697 ath10k_dbg_dump(ar, ATH10K_DBG_BOOT, "board name", "",
698 board_ie_data, board_ie_len);
699
700 if (board_ie_len != strlen(boardname))
701 break;
702
703 ret = memcmp(board_ie_data, boardname, strlen(boardname));
704 if (ret)
705 break;
706
707 name_match_found = true;
708 ath10k_dbg(ar, ATH10K_DBG_BOOT,
709 "boot found match for name '%s'",
710 boardname);
711 break;
712 case ATH10K_BD_IE_BOARD_DATA:
713 if (!name_match_found)
714 /* no match found */
715 break;
716
717 ath10k_dbg(ar, ATH10K_DBG_BOOT,
718 "boot found board data for '%s'",
719 boardname);
720
721 ar->board_data = board_ie_data;
722 ar->board_len = board_ie_len;
723
724 ret = 0;
725 goto out;
726 default:
727 ath10k_warn(ar, "unknown ATH10K_BD_IE_BOARD found: %d\n",
728 board_ie_id);
729 break;
730 }
731
732 /* jump over the padding */
733 board_ie_len = ALIGN(board_ie_len, 4);
734
735 buf_len -= board_ie_len;
736 buf += board_ie_len;
737 }
738
739 /* no match found */
740 ret = -ENOENT;
741
742out:
743 return ret;
744}
745
746static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
747 const char *boardname,
748 const char *filename)
749{
750 size_t len, magic_len, ie_len;
751 struct ath10k_fw_ie *hdr;
752 const u8 *data;
753 int ret, ie_id;
754
755 ar->board = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, filename);
756 if (IS_ERR(ar->board))
757 return PTR_ERR(ar->board);
758
759 data = ar->board->data;
760 len = ar->board->size;
761
762 /* magic has extra null byte padded */
763 magic_len = strlen(ATH10K_BOARD_MAGIC) + 1;
764 if (len < magic_len) {
765 ath10k_err(ar, "failed to find magic value in %s/%s, file too short: %zu\n",
766 ar->hw_params.fw.dir, filename, len);
767 ret = -EINVAL;
768 goto err;
769 }
770
771 if (memcmp(data, ATH10K_BOARD_MAGIC, magic_len)) {
772 ath10k_err(ar, "found invalid board magic\n");
773 ret = -EINVAL;
774 goto err;
775 }
776
777 /* magic is padded to 4 bytes */
778 magic_len = ALIGN(magic_len, 4);
779 if (len < magic_len) {
780 ath10k_err(ar, "failed: %s/%s too small to contain board data, len: %zu\n",
781 ar->hw_params.fw.dir, filename, len);
782 ret = -EINVAL;
783 goto err;
784 }
785
786 data += magic_len;
787 len -= magic_len;
788
789 while (len > sizeof(struct ath10k_fw_ie)) {
790 hdr = (struct ath10k_fw_ie *)data;
791 ie_id = le32_to_cpu(hdr->id);
792 ie_len = le32_to_cpu(hdr->len);
793
794 len -= sizeof(*hdr);
795 data = hdr->data;
796
797 if (len < ALIGN(ie_len, 4)) {
798 ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n",
799 ie_id, ie_len, len);
800 ret = -EINVAL;
801 goto err;
802 }
803
804 switch (ie_id) {
805 case ATH10K_BD_IE_BOARD:
806 ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len,
807 boardname);
808 if (ret == -ENOENT)
809 /* no match found, continue */
810 break;
811 else if (ret)
812 /* there was an error, bail out */
813 goto err;
814
815 /* board data found */
816 goto out;
817 }
818
819 /* jump over the padding */
820 ie_len = ALIGN(ie_len, 4);
821
822 len -= ie_len;
823 data += ie_len;
824 }
825
826out:
827 if (!ar->board_data || !ar->board_len) {
828 ath10k_err(ar,
829 "failed to fetch board data for %s from %s/%s\n",
830 ar->hw_params.fw.dir, boardname, filename);
831 ret = -ENODATA;
832 goto err;
833 }
834
835 return 0;
836
837err:
838 ath10k_core_free_board_files(ar);
839 return ret;
840}
841
842static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
843 size_t name_len)
844{
Manikanta Pubbisettydb0984e2015-10-09 11:55:59 +0300845 if (ar->id.bmi_ids_valid) {
846 scnprintf(name, name_len,
847 "bus=%s,bmi-chip-id=%d,bmi-board-id=%d",
848 ath10k_bus_str(ar->hif.bus),
849 ar->id.bmi_chip_id,
850 ar->id.bmi_board_id);
851 goto out;
852 }
853
Manikanta Pubbisetty0a51b342015-10-09 11:55:58 +0300854 scnprintf(name, name_len,
855 "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x",
856 ath10k_bus_str(ar->hif.bus),
857 ar->id.vendor, ar->id.device,
858 ar->id.subsystem_vendor, ar->id.subsystem_device);
859
Manikanta Pubbisettydb0984e2015-10-09 11:55:59 +0300860out:
Manikanta Pubbisetty0a51b342015-10-09 11:55:58 +0300861 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using board name '%s'\n", name);
Michal Kaziorde57e2c2015-04-17 09:19:17 +0000862
863 return 0;
864}
865
866static int ath10k_core_fetch_board_file(struct ath10k *ar)
867{
Manikanta Pubbisetty0a51b342015-10-09 11:55:58 +0300868 char boardname[100];
Michal Kaziorde57e2c2015-04-17 09:19:17 +0000869 int ret;
870
Manikanta Pubbisetty0a51b342015-10-09 11:55:58 +0300871 ret = ath10k_core_create_board_name(ar, boardname, sizeof(boardname));
Michal Kaziorde57e2c2015-04-17 09:19:17 +0000872 if (ret) {
Manikanta Pubbisetty0a51b342015-10-09 11:55:58 +0300873 ath10k_err(ar, "failed to create board name: %d", ret);
Michal Kaziorde57e2c2015-04-17 09:19:17 +0000874 return ret;
875 }
Kalle Valo958df3a2013-09-27 19:55:01 +0300876
Manikanta Pubbisetty0a51b342015-10-09 11:55:58 +0300877 ar->bd_api = 2;
878 ret = ath10k_core_fetch_board_data_api_n(ar, boardname,
879 ATH10K_BOARD_API2_FILE);
880 if (!ret)
881 goto success;
882
883 ar->bd_api = 1;
884 ret = ath10k_core_fetch_board_data_api_1(ar);
885 if (ret) {
886 ath10k_err(ar, "failed to fetch board data\n");
887 return ret;
888 }
889
890success:
891 ath10k_dbg(ar, ATH10K_DBG_BOOT, "using board api %d\n", ar->bd_api);
Michal Kaziord0ed74f2015-04-17 09:19:16 +0000892 return 0;
893}
894
895static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar)
896{
897 int ret = 0;
898
899 if (ar->hw_params.fw.fw == NULL) {
900 ath10k_err(ar, "firmware file not defined\n");
901 return -EINVAL;
902 }
903
Michal Kazior29385052013-07-16 09:38:58 +0200904 ar->firmware = ath10k_fetch_fw_file(ar,
905 ar->hw_params.fw.dir,
906 ar->hw_params.fw.fw);
907 if (IS_ERR(ar->firmware)) {
908 ret = PTR_ERR(ar->firmware);
Michal Kazior7aa7a722014-08-25 12:09:38 +0200909 ath10k_err(ar, "could not fetch firmware (%d)\n", ret);
Michal Kazior29385052013-07-16 09:38:58 +0200910 goto err;
911 }
912
Kalle Valo958df3a2013-09-27 19:55:01 +0300913 ar->firmware_data = ar->firmware->data;
914 ar->firmware_len = ar->firmware->size;
915
Michal Kazior29385052013-07-16 09:38:58 +0200916 /* OTP may be undefined. If so, don't fetch it at all */
917 if (ar->hw_params.fw.otp == NULL)
918 return 0;
919
920 ar->otp = ath10k_fetch_fw_file(ar,
921 ar->hw_params.fw.dir,
922 ar->hw_params.fw.otp);
923 if (IS_ERR(ar->otp)) {
924 ret = PTR_ERR(ar->otp);
Michal Kazior7aa7a722014-08-25 12:09:38 +0200925 ath10k_err(ar, "could not fetch otp (%d)\n", ret);
Michal Kazior29385052013-07-16 09:38:58 +0200926 goto err;
927 }
928
Kalle Valo958df3a2013-09-27 19:55:01 +0300929 ar->otp_data = ar->otp->data;
930 ar->otp_len = ar->otp->size;
931
Michal Kazior29385052013-07-16 09:38:58 +0200932 return 0;
933
934err:
935 ath10k_core_free_firmware_files(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300936 return ret;
937}
938
Kalle Valo1a222432013-09-27 19:55:07 +0300939static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
940{
941 size_t magic_len, len, ie_len;
942 int ie_id, i, index, bit, ret;
943 struct ath10k_fw_ie *hdr;
944 const u8 *data;
Kalle Valo202e86e2014-12-03 10:10:08 +0200945 __le32 *timestamp, *version;
Kalle Valo1a222432013-09-27 19:55:07 +0300946
947 /* first fetch the firmware file (firmware-*.bin) */
948 ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name);
949 if (IS_ERR(ar->firmware)) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200950 ath10k_err(ar, "could not fetch firmware file '%s/%s': %ld\n",
Ben Greear53c02282014-03-24 12:20:41 -0700951 ar->hw_params.fw.dir, name, PTR_ERR(ar->firmware));
Kalle Valo1a222432013-09-27 19:55:07 +0300952 return PTR_ERR(ar->firmware);
953 }
954
955 data = ar->firmware->data;
956 len = ar->firmware->size;
957
958 /* magic also includes the null byte, check that as well */
959 magic_len = strlen(ATH10K_FIRMWARE_MAGIC) + 1;
960
961 if (len < magic_len) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200962 ath10k_err(ar, "firmware file '%s/%s' too small to contain magic: %zu\n",
Ben Greear53c02282014-03-24 12:20:41 -0700963 ar->hw_params.fw.dir, name, len);
Michal Kazior9bab1cc2013-10-04 08:13:20 +0200964 ret = -EINVAL;
965 goto err;
Kalle Valo1a222432013-09-27 19:55:07 +0300966 }
967
968 if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200969 ath10k_err(ar, "invalid firmware magic\n");
Michal Kazior9bab1cc2013-10-04 08:13:20 +0200970 ret = -EINVAL;
971 goto err;
Kalle Valo1a222432013-09-27 19:55:07 +0300972 }
973
974 /* jump over the padding */
975 magic_len = ALIGN(magic_len, 4);
976
977 len -= magic_len;
978 data += magic_len;
979
980 /* loop elements */
981 while (len > sizeof(struct ath10k_fw_ie)) {
982 hdr = (struct ath10k_fw_ie *)data;
983
984 ie_id = le32_to_cpu(hdr->id);
985 ie_len = le32_to_cpu(hdr->len);
986
987 len -= sizeof(*hdr);
988 data += sizeof(*hdr);
989
990 if (len < ie_len) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200991 ath10k_err(ar, "invalid length for FW IE %d (%zu < %zu)\n",
Kalle Valo1a222432013-09-27 19:55:07 +0300992 ie_id, len, ie_len);
Michal Kazior9bab1cc2013-10-04 08:13:20 +0200993 ret = -EINVAL;
994 goto err;
Kalle Valo1a222432013-09-27 19:55:07 +0300995 }
996
997 switch (ie_id) {
998 case ATH10K_FW_IE_FW_VERSION:
999 if (ie_len > sizeof(ar->hw->wiphy->fw_version) - 1)
1000 break;
1001
1002 memcpy(ar->hw->wiphy->fw_version, data, ie_len);
1003 ar->hw->wiphy->fw_version[ie_len] = '\0';
1004
Michal Kazior7aa7a722014-08-25 12:09:38 +02001005 ath10k_dbg(ar, ATH10K_DBG_BOOT,
Kalle Valo1a222432013-09-27 19:55:07 +03001006 "found fw version %s\n",
1007 ar->hw->wiphy->fw_version);
1008 break;
1009 case ATH10K_FW_IE_TIMESTAMP:
1010 if (ie_len != sizeof(u32))
1011 break;
1012
1013 timestamp = (__le32 *)data;
1014
Michal Kazior7aa7a722014-08-25 12:09:38 +02001015 ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw timestamp %d\n",
Kalle Valo1a222432013-09-27 19:55:07 +03001016 le32_to_cpup(timestamp));
1017 break;
1018 case ATH10K_FW_IE_FEATURES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02001019 ath10k_dbg(ar, ATH10K_DBG_BOOT,
Kalle Valo1a222432013-09-27 19:55:07 +03001020 "found firmware features ie (%zd B)\n",
1021 ie_len);
1022
1023 for (i = 0; i < ATH10K_FW_FEATURE_COUNT; i++) {
1024 index = i / 8;
1025 bit = i % 8;
1026
1027 if (index == ie_len)
1028 break;
1029
Ben Greearf591a1a2014-02-04 19:51:38 +02001030 if (data[index] & (1 << bit)) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001031 ath10k_dbg(ar, ATH10K_DBG_BOOT,
Ben Greearf591a1a2014-02-04 19:51:38 +02001032 "Enabling feature bit: %i\n",
1033 i);
Kalle Valo1a222432013-09-27 19:55:07 +03001034 __set_bit(i, ar->fw_features);
Ben Greearf591a1a2014-02-04 19:51:38 +02001035 }
Kalle Valo1a222432013-09-27 19:55:07 +03001036 }
1037
Michal Kazior7aa7a722014-08-25 12:09:38 +02001038 ath10k_dbg_dump(ar, ATH10K_DBG_BOOT, "features", "",
Kalle Valo1a222432013-09-27 19:55:07 +03001039 ar->fw_features,
1040 sizeof(ar->fw_features));
1041 break;
1042 case ATH10K_FW_IE_FW_IMAGE:
Michal Kazior7aa7a722014-08-25 12:09:38 +02001043 ath10k_dbg(ar, ATH10K_DBG_BOOT,
Kalle Valo1a222432013-09-27 19:55:07 +03001044 "found fw image ie (%zd B)\n",
1045 ie_len);
1046
1047 ar->firmware_data = data;
1048 ar->firmware_len = ie_len;
1049
1050 break;
1051 case ATH10K_FW_IE_OTP_IMAGE:
Michal Kazior7aa7a722014-08-25 12:09:38 +02001052 ath10k_dbg(ar, ATH10K_DBG_BOOT,
Kalle Valo1a222432013-09-27 19:55:07 +03001053 "found otp image ie (%zd B)\n",
1054 ie_len);
1055
1056 ar->otp_data = data;
1057 ar->otp_len = ie_len;
1058
1059 break;
Kalle Valo202e86e2014-12-03 10:10:08 +02001060 case ATH10K_FW_IE_WMI_OP_VERSION:
1061 if (ie_len != sizeof(u32))
1062 break;
1063
1064 version = (__le32 *)data;
1065
1066 ar->wmi.op_version = le32_to_cpup(version);
1067
1068 ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie wmi op version %d\n",
1069 ar->wmi.op_version);
1070 break;
Rajkumar Manoharan8348db22015-03-25 13:12:27 +02001071 case ATH10K_FW_IE_HTT_OP_VERSION:
1072 if (ie_len != sizeof(u32))
1073 break;
1074
1075 version = (__le32 *)data;
1076
1077 ar->htt.op_version = le32_to_cpup(version);
1078
1079 ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie htt op version %d\n",
1080 ar->htt.op_version);
1081 break;
Vasanthakumar Thiagarajandcb02db2015-06-18 12:31:09 +05301082 case ATH10K_FW_IE_FW_CODE_SWAP_IMAGE:
1083 ath10k_dbg(ar, ATH10K_DBG_BOOT,
1084 "found fw code swap image ie (%zd B)\n",
1085 ie_len);
1086 ar->swap.firmware_codeswap_data = data;
1087 ar->swap.firmware_codeswap_len = ie_len;
1088 break;
Kalle Valo1a222432013-09-27 19:55:07 +03001089 default:
Michal Kazior7aa7a722014-08-25 12:09:38 +02001090 ath10k_warn(ar, "Unknown FW IE: %u\n",
Kalle Valo1a222432013-09-27 19:55:07 +03001091 le32_to_cpu(hdr->id));
1092 break;
1093 }
1094
1095 /* jump over the padding */
1096 ie_len = ALIGN(ie_len, 4);
1097
1098 len -= ie_len;
1099 data += ie_len;
Fengguang Wue05634e2013-10-08 21:48:15 +03001100 }
Kalle Valo1a222432013-09-27 19:55:07 +03001101
1102 if (!ar->firmware_data || !ar->firmware_len) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001103 ath10k_warn(ar, "No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n",
Ben Greear53c02282014-03-24 12:20:41 -07001104 ar->hw_params.fw.dir, name);
Kalle Valo1a222432013-09-27 19:55:07 +03001105 ret = -ENOMEDIUM;
1106 goto err;
1107 }
1108
Kalle Valo1a222432013-09-27 19:55:07 +03001109 return 0;
1110
1111err:
1112 ath10k_core_free_firmware_files(ar);
1113 return ret;
1114}
1115
1116static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
1117{
1118 int ret;
1119
Kalle Valoa58227e2014-10-13 09:40:59 +03001120 /* calibration file is optional, don't check for any errors */
1121 ath10k_fetch_cal_file(ar);
1122
Kalle Valo53513c32015-03-25 13:12:42 +02001123 ar->fw_api = 5;
1124 ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
1125
1126 ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API5_FILE);
1127 if (ret == 0)
1128 goto success;
1129
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02001130 ar->fw_api = 4;
1131 ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
1132
1133 ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API4_FILE);
1134 if (ret == 0)
1135 goto success;
1136
Michal Kazior24c88f72014-07-25 13:32:17 +02001137 ar->fw_api = 3;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001138 ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
Michal Kazior24c88f72014-07-25 13:32:17 +02001139
1140 ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API3_FILE);
1141 if (ret == 0)
1142 goto success;
1143
Ben Greear53c02282014-03-24 12:20:41 -07001144 ar->fw_api = 2;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001145 ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
Ben Greear53c02282014-03-24 12:20:41 -07001146
Kalle Valo1a222432013-09-27 19:55:07 +03001147 ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API2_FILE);
Ben Greear53c02282014-03-24 12:20:41 -07001148 if (ret == 0)
1149 goto success;
1150
1151 ar->fw_api = 1;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001152 ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
Kalle Valo1a222432013-09-27 19:55:07 +03001153
1154 ret = ath10k_core_fetch_firmware_api_1(ar);
1155 if (ret)
1156 return ret;
1157
Ben Greear53c02282014-03-24 12:20:41 -07001158success:
Michal Kazior7aa7a722014-08-25 12:09:38 +02001159 ath10k_dbg(ar, ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api);
Kalle Valo1a222432013-09-27 19:55:07 +03001160
1161 return 0;
1162}
1163
Kalle Valo83091552014-10-13 09:40:53 +03001164static int ath10k_download_cal_data(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001165{
1166 int ret;
1167
Kalle Valoa58227e2014-10-13 09:40:59 +03001168 ret = ath10k_download_cal_file(ar);
1169 if (ret == 0) {
1170 ar->cal_mode = ATH10K_CAL_MODE_FILE;
1171 goto done;
1172 }
1173
1174 ath10k_dbg(ar, ATH10K_DBG_BOOT,
Toshi Kikuchi5aabff02014-12-02 10:55:54 +02001175 "boot did not find a calibration file, try DT next: %d\n",
1176 ret);
1177
1178 ret = ath10k_download_cal_dt(ar);
1179 if (ret == 0) {
1180 ar->cal_mode = ATH10K_CAL_MODE_DT;
1181 goto done;
1182 }
1183
1184 ath10k_dbg(ar, ATH10K_DBG_BOOT,
1185 "boot did not find DT entry, try OTP next: %d\n",
Kalle Valoa58227e2014-10-13 09:40:59 +03001186 ret);
1187
Kalle Valo5e3dd152013-06-12 20:52:10 +03001188 ret = ath10k_download_and_run_otp(ar);
Ben Greear36a8f412014-03-24 12:20:42 -07001189 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001190 ath10k_err(ar, "failed to run otp: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001191 return ret;
Ben Greear36a8f412014-03-24 12:20:42 -07001192 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001193
Kalle Valoa58227e2014-10-13 09:40:59 +03001194 ar->cal_mode = ATH10K_CAL_MODE_OTP;
1195
1196done:
1197 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using calibration mode %s\n",
1198 ath10k_cal_mode_str(ar->cal_mode));
1199 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001200}
1201
1202static int ath10k_init_uart(struct ath10k *ar)
1203{
1204 int ret;
1205
1206 /*
1207 * Explicitly setting UART prints to zero as target turns it on
1208 * based on scratch registers.
1209 */
1210 ret = ath10k_bmi_write32(ar, hi_serial_enable, 0);
1211 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001212 ath10k_warn(ar, "could not disable UART prints (%d)\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001213 return ret;
1214 }
1215
Kalle Valoc8c39af2013-11-20 10:00:41 +02001216 if (!uart_print)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001217 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001218
Michal Kazior3a8200b2014-12-02 10:55:55 +02001219 ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, ar->hw_params.uart_pin);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001220 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001221 ath10k_warn(ar, "could not enable UART prints (%d)\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001222 return ret;
1223 }
1224
1225 ret = ath10k_bmi_write32(ar, hi_serial_enable, 1);
1226 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001227 ath10k_warn(ar, "could not enable UART prints (%d)\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001228 return ret;
1229 }
1230
Bartosz Markowski03fc1372013-09-03 14:24:02 +02001231 /* Set the UART baud rate to 19200. */
1232 ret = ath10k_bmi_write32(ar, hi_desired_baud_rate, 19200);
1233 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001234 ath10k_warn(ar, "could not set the baud rate (%d)\n", ret);
Bartosz Markowski03fc1372013-09-03 14:24:02 +02001235 return ret;
1236 }
1237
Michal Kazior7aa7a722014-08-25 12:09:38 +02001238 ath10k_info(ar, "UART prints enabled\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03001239 return 0;
1240}
1241
1242static int ath10k_init_hw_params(struct ath10k *ar)
1243{
1244 const struct ath10k_hw_params *uninitialized_var(hw_params);
1245 int i;
1246
1247 for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) {
1248 hw_params = &ath10k_hw_params_list[i];
1249
1250 if (hw_params->id == ar->target_version)
1251 break;
1252 }
1253
1254 if (i == ARRAY_SIZE(ath10k_hw_params_list)) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001255 ath10k_err(ar, "Unsupported hardware version: 0x%x\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001256 ar->target_version);
1257 return -EINVAL;
1258 }
1259
1260 ar->hw_params = *hw_params;
1261
Michal Kazior7aa7a722014-08-25 12:09:38 +02001262 ath10k_dbg(ar, ATH10K_DBG_BOOT, "Hardware name %s version 0x%x\n",
Kalle Valoc8c39af2013-11-20 10:00:41 +02001263 ar->hw_params.name, ar->target_version);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001264
1265 return 0;
1266}
1267
Michal Kazioraffd3212013-07-16 09:54:35 +02001268static void ath10k_core_restart(struct work_struct *work)
1269{
1270 struct ath10k *ar = container_of(work, struct ath10k, restart_work);
1271
Michal Kazior7962b0d2014-10-28 10:34:38 +01001272 set_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);
1273
1274 /* Place a barrier to make sure the compiler doesn't reorder
1275 * CRASH_FLUSH and calling other functions.
1276 */
1277 barrier();
1278
1279 ieee80211_stop_queues(ar->hw);
1280 ath10k_drain_tx(ar);
1281 complete_all(&ar->scan.started);
1282 complete_all(&ar->scan.completed);
1283 complete_all(&ar->scan.on_channel);
1284 complete_all(&ar->offchan_tx_completed);
1285 complete_all(&ar->install_key_done);
1286 complete_all(&ar->vdev_setup_done);
Rajkumar Manoharanac2953f2014-12-17 12:22:26 +02001287 complete_all(&ar->thermal.wmi_sync);
Michal Kazior7962b0d2014-10-28 10:34:38 +01001288 wake_up(&ar->htt.empty_tx_wq);
1289 wake_up(&ar->wmi.tx_credits_wq);
1290 wake_up(&ar->peer_mapping_wq);
1291
Michal Kazioraffd3212013-07-16 09:54:35 +02001292 mutex_lock(&ar->conf_mutex);
1293
1294 switch (ar->state) {
1295 case ATH10K_STATE_ON:
Michal Kazioraffd3212013-07-16 09:54:35 +02001296 ar->state = ATH10K_STATE_RESTARTING;
Michal Kazior61e9aab2014-08-22 14:33:18 +02001297 ath10k_hif_stop(ar);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02001298 ath10k_scan_finish(ar);
Michal Kazioraffd3212013-07-16 09:54:35 +02001299 ieee80211_restart_hw(ar->hw);
1300 break;
1301 case ATH10K_STATE_OFF:
Michal Kazior5e90de82013-10-16 16:46:05 +03001302 /* this can happen if driver is being unloaded
1303 * or if the crash happens during FW probing */
Michal Kazior7aa7a722014-08-25 12:09:38 +02001304 ath10k_warn(ar, "cannot restart a device that hasn't been started\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02001305 break;
1306 case ATH10K_STATE_RESTARTING:
Michal Kaziorc5058f52014-05-26 12:46:03 +03001307 /* hw restart might be requested from multiple places */
1308 break;
Michal Kazioraffd3212013-07-16 09:54:35 +02001309 case ATH10K_STATE_RESTARTED:
1310 ar->state = ATH10K_STATE_WEDGED;
1311 /* fall through */
1312 case ATH10K_STATE_WEDGED:
Michal Kazior7aa7a722014-08-25 12:09:38 +02001313 ath10k_warn(ar, "device is wedged, will not restart\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02001314 break;
Kalle Valo43d2a302014-09-10 18:23:30 +03001315 case ATH10K_STATE_UTF:
1316 ath10k_warn(ar, "firmware restart in UTF mode not supported\n");
1317 break;
Michal Kazioraffd3212013-07-16 09:54:35 +02001318 }
1319
1320 mutex_unlock(&ar->conf_mutex);
1321}
1322
Kalle Valo5f2144d2014-12-03 10:09:59 +02001323static int ath10k_core_init_firmware_features(struct ath10k *ar)
Michal Kaziorcfd10612014-11-25 15:16:05 +01001324{
Kalle Valo5f2144d2014-12-03 10:09:59 +02001325 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features) &&
1326 !test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
1327 ath10k_err(ar, "feature bits corrupted: 10.2 feature requires 10.x feature to be set as well");
1328 return -EINVAL;
1329 }
1330
Kalle Valo202e86e2014-12-03 10:10:08 +02001331 if (ar->wmi.op_version >= ATH10K_FW_WMI_OP_VERSION_MAX) {
1332 ath10k_err(ar, "unsupported WMI OP version (max %d): %d\n",
1333 ATH10K_FW_WMI_OP_VERSION_MAX, ar->wmi.op_version);
1334 return -EINVAL;
1335 }
1336
David Liuccec9032015-07-24 20:25:32 +03001337 ar->wmi.rx_decap_mode = ATH10K_HW_TXRX_NATIVE_WIFI;
1338 switch (ath10k_cryptmode_param) {
1339 case ATH10K_CRYPT_MODE_HW:
1340 clear_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);
1341 clear_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags);
1342 break;
1343 case ATH10K_CRYPT_MODE_SW:
1344 if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT,
1345 ar->fw_features)) {
1346 ath10k_err(ar, "cryptmode > 0 requires raw mode support from firmware");
1347 return -EINVAL;
1348 }
1349
1350 set_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);
1351 set_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags);
1352 break;
1353 default:
1354 ath10k_info(ar, "invalid cryptmode: %d\n",
1355 ath10k_cryptmode_param);
1356 return -EINVAL;
1357 }
1358
1359 ar->htt.max_num_amsdu = ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT;
1360 ar->htt.max_num_ampdu = ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT;
1361
Bob Copelandb6c7baf2015-09-09 12:47:36 -04001362 if (rawmode) {
1363 if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT,
1364 ar->fw_features)) {
1365 ath10k_err(ar, "rawmode = 1 requires support from firmware");
1366 return -EINVAL;
1367 }
1368 set_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);
1369 }
1370
David Liuccec9032015-07-24 20:25:32 +03001371 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
1372 ar->wmi.rx_decap_mode = ATH10K_HW_TXRX_RAW;
1373
1374 /* Workaround:
1375 *
1376 * Firmware A-MSDU aggregation breaks with RAW Tx encap mode
1377 * and causes enormous performance issues (malformed frames,
1378 * etc).
1379 *
1380 * Disabling A-MSDU makes RAW mode stable with heavy traffic
1381 * albeit a bit slower compared to regular operation.
1382 */
1383 ar->htt.max_num_amsdu = 1;
1384 }
1385
Kalle Valo202e86e2014-12-03 10:10:08 +02001386 /* Backwards compatibility for firmwares without
1387 * ATH10K_FW_IE_WMI_OP_VERSION.
1388 */
1389 if (ar->wmi.op_version == ATH10K_FW_WMI_OP_VERSION_UNSET) {
1390 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02001391 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2,
1392 ar->fw_features))
Kalle Valo202e86e2014-12-03 10:10:08 +02001393 ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_2;
1394 else
1395 ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_1;
1396 } else {
1397 ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_MAIN;
1398 }
1399 }
1400
1401 switch (ar->wmi.op_version) {
1402 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Michal Kaziorcfd10612014-11-25 15:16:05 +01001403 ar->max_num_peers = TARGET_NUM_PEERS;
1404 ar->max_num_stations = TARGET_NUM_STATIONS;
Kalle Valo30c78162014-12-17 12:20:45 +02001405 ar->max_num_vdevs = TARGET_NUM_VDEVS;
Kalle Valo91ad5f52014-12-03 10:10:17 +02001406 ar->htt.max_num_pending_tx = TARGET_NUM_MSDU_DESC;
Yanbo Li6274cd42015-04-01 22:53:21 +03001407 ar->fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV |
1408 WMI_STAT_PEER;
Raja Mani5c8726e2015-06-22 20:22:26 +05301409 ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;
Kalle Valo202e86e2014-12-03 10:10:08 +02001410 break;
1411 case ATH10K_FW_WMI_OP_VERSION_10_1:
1412 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02001413 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo202e86e2014-12-03 10:10:08 +02001414 ar->max_num_peers = TARGET_10X_NUM_PEERS;
1415 ar->max_num_stations = TARGET_10X_NUM_STATIONS;
Kalle Valo30c78162014-12-17 12:20:45 +02001416 ar->max_num_vdevs = TARGET_10X_NUM_VDEVS;
Kalle Valo91ad5f52014-12-03 10:10:17 +02001417 ar->htt.max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC;
Yanbo Li6274cd42015-04-01 22:53:21 +03001418 ar->fw_stats_req_mask = WMI_STAT_PEER;
Raja Mani5c8726e2015-06-22 20:22:26 +05301419 ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;
Kalle Valo202e86e2014-12-03 10:10:08 +02001420 break;
Michal Kaziorca996ec2014-12-03 10:11:32 +02001421 case ATH10K_FW_WMI_OP_VERSION_TLV:
1422 ar->max_num_peers = TARGET_TLV_NUM_PEERS;
1423 ar->max_num_stations = TARGET_TLV_NUM_STATIONS;
Michal Kazior49274332015-01-08 11:36:56 +01001424 ar->max_num_vdevs = TARGET_TLV_NUM_VDEVS;
Marek Puzyniak8cca3d62015-03-30 09:51:52 +03001425 ar->max_num_tdls_vdevs = TARGET_TLV_NUM_TDLS_VDEVS;
Michal Kaziorca996ec2014-12-03 10:11:32 +02001426 ar->htt.max_num_pending_tx = TARGET_TLV_NUM_MSDU_DESC;
Janusz Dziedzic25c86612015-03-23 17:32:54 +02001427 ar->wow.max_num_patterns = TARGET_TLV_NUM_WOW_PATTERNS;
Yanbo Li6274cd42015-04-01 22:53:21 +03001428 ar->fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV |
1429 WMI_STAT_PEER;
Raja Mani5c8726e2015-06-22 20:22:26 +05301430 ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;
Michal Kaziorca996ec2014-12-03 10:11:32 +02001431 break;
Raja Mani9bd21322015-06-22 20:10:09 +05301432 case ATH10K_FW_WMI_OP_VERSION_10_4:
Raja Manid1e52a82015-06-22 20:10:15 +05301433 ar->max_num_peers = TARGET_10_4_NUM_PEERS;
1434 ar->max_num_stations = TARGET_10_4_NUM_STATIONS;
1435 ar->num_active_peers = TARGET_10_4_ACTIVE_PEERS;
1436 ar->max_num_vdevs = TARGET_10_4_NUM_VDEVS;
1437 ar->num_tids = TARGET_10_4_TGT_NUM_TIDS;
Raja Mani721ad3c2015-06-22 20:22:24 +05301438 ar->htt.max_num_pending_tx = TARGET_10_4_NUM_MSDU_DESC;
Raja Manid1e52a82015-06-22 20:10:15 +05301439 ar->fw_stats_req_mask = WMI_STAT_PEER;
Raja Mani5c8726e2015-06-22 20:22:26 +05301440 ar->max_spatial_stream = WMI_10_4_MAX_SPATIAL_STREAM;
Raja Manid1e52a82015-06-22 20:10:15 +05301441 break;
Kalle Valo202e86e2014-12-03 10:10:08 +02001442 case ATH10K_FW_WMI_OP_VERSION_UNSET:
1443 case ATH10K_FW_WMI_OP_VERSION_MAX:
1444 WARN_ON(1);
1445 return -EINVAL;
Michal Kaziorcfd10612014-11-25 15:16:05 +01001446 }
Kalle Valo5f2144d2014-12-03 10:09:59 +02001447
Kalle Valodc3632a2015-03-30 14:14:28 +03001448 /* Backwards compatibility for firmwares without
1449 * ATH10K_FW_IE_HTT_OP_VERSION.
1450 */
1451 if (ar->htt.op_version == ATH10K_FW_HTT_OP_VERSION_UNSET) {
1452 switch (ar->wmi.op_version) {
1453 case ATH10K_FW_WMI_OP_VERSION_MAIN:
1454 ar->htt.op_version = ATH10K_FW_HTT_OP_VERSION_MAIN;
1455 break;
1456 case ATH10K_FW_WMI_OP_VERSION_10_1:
1457 case ATH10K_FW_WMI_OP_VERSION_10_2:
1458 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
1459 ar->htt.op_version = ATH10K_FW_HTT_OP_VERSION_10_1;
1460 break;
1461 case ATH10K_FW_WMI_OP_VERSION_TLV:
1462 ar->htt.op_version = ATH10K_FW_HTT_OP_VERSION_TLV;
1463 break;
Raja Mani9bd21322015-06-22 20:10:09 +05301464 case ATH10K_FW_WMI_OP_VERSION_10_4:
Kalle Valodc3632a2015-03-30 14:14:28 +03001465 case ATH10K_FW_WMI_OP_VERSION_UNSET:
1466 case ATH10K_FW_WMI_OP_VERSION_MAX:
1467 WARN_ON(1);
1468 return -EINVAL;
1469 }
1470 }
1471
Kalle Valo5f2144d2014-12-03 10:09:59 +02001472 return 0;
Michal Kaziorcfd10612014-11-25 15:16:05 +01001473}
1474
Kalle Valo43d2a302014-09-10 18:23:30 +03001475int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001476{
Kalle Valo5e3dd152013-06-12 20:52:10 +03001477 int status;
1478
Kalle Valo60631c52013-10-08 21:45:25 +03001479 lockdep_assert_held(&ar->conf_mutex);
1480
Michal Kazior7962b0d2014-10-28 10:34:38 +01001481 clear_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);
1482
Michal Kazior64d151d2013-07-16 09:38:53 +02001483 ath10k_bmi_start(ar);
1484
Kalle Valo5e3dd152013-06-12 20:52:10 +03001485 if (ath10k_init_configure_target(ar)) {
1486 status = -EINVAL;
1487 goto err;
1488 }
1489
Kalle Valo83091552014-10-13 09:40:53 +03001490 status = ath10k_download_cal_data(ar);
1491 if (status)
1492 goto err;
1493
Rajkumar Manoharan163f5262015-05-29 17:51:53 +03001494 /* Some of of qca988x solutions are having global reset issue
Kalle Valo617b0f42015-10-05 17:56:35 +03001495 * during target initialization. Bypassing PLL setting before
1496 * downloading firmware and letting the SoC run on REF_CLK is
1497 * fixing the problem. Corresponding firmware change is also needed
1498 * to set the clock source once the target is initialized.
Rajkumar Manoharan163f5262015-05-29 17:51:53 +03001499 */
1500 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT,
1501 ar->fw_features)) {
1502 status = ath10k_bmi_write32(ar, hi_skip_clock_init, 1);
1503 if (status) {
1504 ath10k_err(ar, "could not write to skip_clock_init: %d\n",
1505 status);
1506 goto err;
1507 }
1508 }
1509
Kalle Valo83091552014-10-13 09:40:53 +03001510 status = ath10k_download_fw(ar, mode);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001511 if (status)
1512 goto err;
1513
1514 status = ath10k_init_uart(ar);
1515 if (status)
1516 goto err;
1517
Michal Kaziorcd003fa2013-07-05 16:15:13 +03001518 ar->htc.htc_ops.target_send_suspend_complete =
1519 ath10k_send_suspend_complete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001520
Michal Kaziorcd003fa2013-07-05 16:15:13 +03001521 status = ath10k_htc_init(ar);
1522 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001523 ath10k_err(ar, "could not init HTC (%d)\n", status);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001524 goto err;
1525 }
1526
1527 status = ath10k_bmi_done(ar);
1528 if (status)
Michal Kaziorcd003fa2013-07-05 16:15:13 +03001529 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001530
1531 status = ath10k_wmi_attach(ar);
1532 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001533 ath10k_err(ar, "WMI attach failed: %d\n", status);
Michal Kaziorcd003fa2013-07-05 16:15:13 +03001534 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001535 }
1536
Michal Kazior95bf21f2014-05-16 17:15:39 +03001537 status = ath10k_htt_init(ar);
1538 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001539 ath10k_err(ar, "failed to init htt: %d\n", status);
Michal Kazior95bf21f2014-05-16 17:15:39 +03001540 goto err_wmi_detach;
1541 }
1542
1543 status = ath10k_htt_tx_alloc(&ar->htt);
1544 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001545 ath10k_err(ar, "failed to alloc htt tx: %d\n", status);
Michal Kazior95bf21f2014-05-16 17:15:39 +03001546 goto err_wmi_detach;
1547 }
1548
1549 status = ath10k_htt_rx_alloc(&ar->htt);
1550 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001551 ath10k_err(ar, "failed to alloc htt rx: %d\n", status);
Michal Kazior95bf21f2014-05-16 17:15:39 +03001552 goto err_htt_tx_detach;
1553 }
1554
Michal Kazior67e3c632013-11-08 08:05:18 +01001555 status = ath10k_hif_start(ar);
1556 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001557 ath10k_err(ar, "could not start HIF: %d\n", status);
Michal Kazior95bf21f2014-05-16 17:15:39 +03001558 goto err_htt_rx_detach;
Michal Kazior67e3c632013-11-08 08:05:18 +01001559 }
1560
1561 status = ath10k_htc_wait_target(&ar->htc);
1562 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001563 ath10k_err(ar, "failed to connect to HTC: %d\n", status);
Michal Kazior67e3c632013-11-08 08:05:18 +01001564 goto err_hif_stop;
1565 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001566
Kalle Valo43d2a302014-09-10 18:23:30 +03001567 if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
1568 status = ath10k_htt_connect(&ar->htt);
1569 if (status) {
1570 ath10k_err(ar, "failed to connect htt (%d)\n", status);
1571 goto err_hif_stop;
1572 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001573 }
1574
Michal Kazior95bf21f2014-05-16 17:15:39 +03001575 status = ath10k_wmi_connect(ar);
1576 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001577 ath10k_err(ar, "could not connect wmi: %d\n", status);
Michal Kazior95bf21f2014-05-16 17:15:39 +03001578 goto err_hif_stop;
1579 }
1580
1581 status = ath10k_htc_start(&ar->htc);
1582 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001583 ath10k_err(ar, "failed to start htc: %d\n", status);
Michal Kazior95bf21f2014-05-16 17:15:39 +03001584 goto err_hif_stop;
1585 }
1586
Kalle Valo43d2a302014-09-10 18:23:30 +03001587 if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
1588 status = ath10k_wmi_wait_for_service_ready(ar);
Nicholas Mc Guire9eea5682015-03-30 15:39:21 +03001589 if (status) {
Kalle Valo43d2a302014-09-10 18:23:30 +03001590 ath10k_warn(ar, "wmi service ready event not received");
Kalle Valo43d2a302014-09-10 18:23:30 +03001591 goto err_hif_stop;
1592 }
Michal Kazior95bf21f2014-05-16 17:15:39 +03001593 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001594
Michal Kazior7aa7a722014-08-25 12:09:38 +02001595 ath10k_dbg(ar, ATH10K_DBG_BOOT, "firmware %s booted\n",
Kalle Valoc8c39af2013-11-20 10:00:41 +02001596 ar->hw->wiphy->fw_version);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001597
Kalle Valo5e3dd152013-06-12 20:52:10 +03001598 status = ath10k_wmi_cmd_init(ar);
1599 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001600 ath10k_err(ar, "could not send WMI init command (%d)\n",
1601 status);
Michal Kaziorb7967dc2014-08-07 11:03:31 +02001602 goto err_hif_stop;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001603 }
1604
1605 status = ath10k_wmi_wait_for_unified_ready(ar);
Nicholas Mc Guire9eea5682015-03-30 15:39:21 +03001606 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001607 ath10k_err(ar, "wmi unified ready event not received\n");
Michal Kaziorb7967dc2014-08-07 11:03:31 +02001608 goto err_hif_stop;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001609 }
1610
Michal Kaziorc5450702015-01-24 12:14:48 +02001611 /* If firmware indicates Full Rx Reorder support it must be used in a
1612 * slightly different manner. Let HTT code know.
1613 */
1614 ar->htt.rx_ring.in_ord_rx = !!(test_bit(WMI_SERVICE_RX_FULL_REORDER,
1615 ar->wmi.svc_map));
1616
1617 status = ath10k_htt_rx_ring_refill(ar);
1618 if (status) {
1619 ath10k_err(ar, "failed to refill htt rx ring: %d\n", status);
1620 goto err_hif_stop;
1621 }
1622
Kalle Valo43d2a302014-09-10 18:23:30 +03001623 /* we don't care about HTT in UTF mode */
1624 if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
1625 status = ath10k_htt_setup(&ar->htt);
1626 if (status) {
1627 ath10k_err(ar, "failed to setup htt: %d\n", status);
1628 goto err_hif_stop;
1629 }
Michal Kazior95bf21f2014-05-16 17:15:39 +03001630 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001631
Kalle Valodb66ea02013-09-03 11:44:03 +03001632 status = ath10k_debug_start(ar);
1633 if (status)
Michal Kaziorb7967dc2014-08-07 11:03:31 +02001634 goto err_hif_stop;
Kalle Valodb66ea02013-09-03 11:44:03 +03001635
Kalle Valo30c78162014-12-17 12:20:45 +02001636 ar->free_vdev_map = (1LL << ar->max_num_vdevs) - 1;
Bartosz Markowskidfa413d2014-06-02 21:19:45 +03001637
Michal Kazior05791192013-10-16 15:44:45 +03001638 INIT_LIST_HEAD(&ar->arvifs);
Michal Kazior1a1b8a82013-07-16 09:38:55 +02001639
Michal Kaziordd30a362013-07-16 09:38:51 +02001640 return 0;
1641
Michal Kazior67e3c632013-11-08 08:05:18 +01001642err_hif_stop:
1643 ath10k_hif_stop(ar);
Michal Kazior95bf21f2014-05-16 17:15:39 +03001644err_htt_rx_detach:
1645 ath10k_htt_rx_free(&ar->htt);
1646err_htt_tx_detach:
1647 ath10k_htt_tx_free(&ar->htt);
Michal Kaziordd30a362013-07-16 09:38:51 +02001648err_wmi_detach:
1649 ath10k_wmi_detach(ar);
1650err:
1651 return status;
1652}
Michal Kazior818bdd12013-07-16 09:38:57 +02001653EXPORT_SYMBOL(ath10k_core_start);
Michal Kaziordd30a362013-07-16 09:38:51 +02001654
Marek Puzyniak00f54822014-02-10 17:14:24 +01001655int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt)
1656{
1657 int ret;
Nicholas Mc Guirea7a42842015-03-30 15:39:21 +03001658 unsigned long time_left;
Marek Puzyniak00f54822014-02-10 17:14:24 +01001659
1660 reinit_completion(&ar->target_suspend);
1661
1662 ret = ath10k_wmi_pdev_suspend_target(ar, suspend_opt);
1663 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001664 ath10k_warn(ar, "could not suspend target (%d)\n", ret);
Marek Puzyniak00f54822014-02-10 17:14:24 +01001665 return ret;
1666 }
1667
Nicholas Mc Guirea7a42842015-03-30 15:39:21 +03001668 time_left = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ);
Marek Puzyniak00f54822014-02-10 17:14:24 +01001669
Nicholas Mc Guirea7a42842015-03-30 15:39:21 +03001670 if (!time_left) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001671 ath10k_warn(ar, "suspend timed out - target pause event never came\n");
Marek Puzyniak00f54822014-02-10 17:14:24 +01001672 return -ETIMEDOUT;
1673 }
1674
1675 return 0;
1676}
1677
Michal Kaziordd30a362013-07-16 09:38:51 +02001678void ath10k_core_stop(struct ath10k *ar)
1679{
Kalle Valo60631c52013-10-08 21:45:25 +03001680 lockdep_assert_held(&ar->conf_mutex);
Raja Manif1ee2682015-07-09 14:19:42 +05301681 ath10k_debug_stop(ar);
Kalle Valo60631c52013-10-08 21:45:25 +03001682
Marek Puzyniak00f54822014-02-10 17:14:24 +01001683 /* try to suspend target */
Kalle Valo43d2a302014-09-10 18:23:30 +03001684 if (ar->state != ATH10K_STATE_RESTARTING &&
1685 ar->state != ATH10K_STATE_UTF)
Michal Kazior216a1832014-04-23 19:30:04 +03001686 ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
1687
Michal Kazior95bf21f2014-05-16 17:15:39 +03001688 ath10k_hif_stop(ar);
1689 ath10k_htt_tx_free(&ar->htt);
1690 ath10k_htt_rx_free(&ar->htt);
Michal Kaziordd30a362013-07-16 09:38:51 +02001691 ath10k_wmi_detach(ar);
1692}
Michal Kazior818bdd12013-07-16 09:38:57 +02001693EXPORT_SYMBOL(ath10k_core_stop);
1694
1695/* mac80211 manages fw/hw initialization through start/stop hooks. However in
1696 * order to know what hw capabilities should be advertised to mac80211 it is
1697 * necessary to load the firmware (and tear it down immediately since start
1698 * hook will try to init it again) before registering */
1699static int ath10k_core_probe_fw(struct ath10k *ar)
1700{
Michal Kazior29385052013-07-16 09:38:58 +02001701 struct bmi_target_info target_info;
1702 int ret = 0;
Michal Kazior818bdd12013-07-16 09:38:57 +02001703
1704 ret = ath10k_hif_power_up(ar);
1705 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001706 ath10k_err(ar, "could not start pci hif (%d)\n", ret);
Michal Kazior818bdd12013-07-16 09:38:57 +02001707 return ret;
1708 }
1709
Michal Kazior29385052013-07-16 09:38:58 +02001710 memset(&target_info, 0, sizeof(target_info));
1711 ret = ath10k_bmi_get_target_info(ar, &target_info);
1712 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001713 ath10k_err(ar, "could not get target info (%d)\n", ret);
Kalle Valoc6ce4922014-12-03 10:09:31 +02001714 goto err_power_down;
Michal Kazior29385052013-07-16 09:38:58 +02001715 }
1716
1717 ar->target_version = target_info.version;
1718 ar->hw->wiphy->hw_version = target_info.version;
1719
1720 ret = ath10k_init_hw_params(ar);
1721 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001722 ath10k_err(ar, "could not get hw params (%d)\n", ret);
Kalle Valoc6ce4922014-12-03 10:09:31 +02001723 goto err_power_down;
Michal Kazior29385052013-07-16 09:38:58 +02001724 }
1725
1726 ret = ath10k_core_fetch_firmware_files(ar);
1727 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001728 ath10k_err(ar, "could not fetch firmware files (%d)\n", ret);
Kalle Valoc6ce4922014-12-03 10:09:31 +02001729 goto err_power_down;
Michal Kazior29385052013-07-16 09:38:58 +02001730 }
1731
Manikanta Pubbisettydb0984e2015-10-09 11:55:59 +03001732 ret = ath10k_core_get_board_id_from_otp(ar);
1733 if (ret && ret != -EOPNOTSUPP) {
1734 ath10k_err(ar, "failed to get board id from otp for qca99x0: %d\n",
1735 ret);
1736 return ret;
1737 }
1738
1739 ret = ath10k_core_fetch_board_file(ar);
1740 if (ret) {
1741 ath10k_err(ar, "failed to fetch board file: %d\n", ret);
1742 goto err_free_firmware_files;
1743 }
1744
Kalle Valo5f2144d2014-12-03 10:09:59 +02001745 ret = ath10k_core_init_firmware_features(ar);
1746 if (ret) {
1747 ath10k_err(ar, "fatal problem with firmware features: %d\n",
1748 ret);
1749 goto err_free_firmware_files;
1750 }
Michal Kaziorcfd10612014-11-25 15:16:05 +01001751
Vasanthakumar Thiagarajandcb02db2015-06-18 12:31:09 +05301752 ret = ath10k_swap_code_seg_init(ar);
1753 if (ret) {
1754 ath10k_err(ar, "failed to initialize code swap segment: %d\n",
1755 ret);
1756 goto err_free_firmware_files;
1757 }
1758
Kalle Valo60631c52013-10-08 21:45:25 +03001759 mutex_lock(&ar->conf_mutex);
1760
Kalle Valo43d2a302014-09-10 18:23:30 +03001761 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
Michal Kazior818bdd12013-07-16 09:38:57 +02001762 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001763 ath10k_err(ar, "could not init core (%d)\n", ret);
Kalle Valoc6ce4922014-12-03 10:09:31 +02001764 goto err_unlock;
Michal Kazior818bdd12013-07-16 09:38:57 +02001765 }
1766
Michal Kazior8079de02014-08-22 14:23:29 +02001767 ath10k_print_driver_info(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02001768 ath10k_core_stop(ar);
Kalle Valo60631c52013-10-08 21:45:25 +03001769
1770 mutex_unlock(&ar->conf_mutex);
1771
Michal Kazior818bdd12013-07-16 09:38:57 +02001772 ath10k_hif_power_down(ar);
1773 return 0;
Kalle Valoc6ce4922014-12-03 10:09:31 +02001774
1775err_unlock:
1776 mutex_unlock(&ar->conf_mutex);
1777
Kalle Valo5f2144d2014-12-03 10:09:59 +02001778err_free_firmware_files:
Kalle Valoc6ce4922014-12-03 10:09:31 +02001779 ath10k_core_free_firmware_files(ar);
1780
1781err_power_down:
1782 ath10k_hif_power_down(ar);
1783
1784 return ret;
Michal Kazior818bdd12013-07-16 09:38:57 +02001785}
Michal Kaziordd30a362013-07-16 09:38:51 +02001786
Michal Kazior6782cb62014-05-23 12:28:47 +02001787static void ath10k_core_register_work(struct work_struct *work)
Michal Kaziordd30a362013-07-16 09:38:51 +02001788{
Michal Kazior6782cb62014-05-23 12:28:47 +02001789 struct ath10k *ar = container_of(work, struct ath10k, register_work);
Michal Kaziordd30a362013-07-16 09:38:51 +02001790 int status;
1791
Michal Kazior818bdd12013-07-16 09:38:57 +02001792 status = ath10k_core_probe_fw(ar);
1793 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001794 ath10k_err(ar, "could not probe fw (%d)\n", status);
Michal Kazior6782cb62014-05-23 12:28:47 +02001795 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02001796 }
Michal Kaziordd30a362013-07-16 09:38:51 +02001797
Kalle Valo5e3dd152013-06-12 20:52:10 +03001798 status = ath10k_mac_register(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02001799 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001800 ath10k_err(ar, "could not register to mac80211 (%d)\n", status);
Michal Kazior29385052013-07-16 09:38:58 +02001801 goto err_release_fw;
Michal Kazior818bdd12013-07-16 09:38:57 +02001802 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001803
Michal Kaziore13cf7a2014-09-04 09:13:08 +02001804 status = ath10k_debug_register(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001805 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001806 ath10k_err(ar, "unable to initialize debugfs\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03001807 goto err_unregister_mac;
1808 }
1809
Simon Wunderlich855aed12014-08-02 09:12:54 +03001810 status = ath10k_spectral_create(ar);
1811 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001812 ath10k_err(ar, "failed to initialize spectral\n");
Simon Wunderlich855aed12014-08-02 09:12:54 +03001813 goto err_debug_destroy;
1814 }
1815
Rajkumar Manoharanfe6f36d2014-12-17 12:22:07 +02001816 status = ath10k_thermal_register(ar);
1817 if (status) {
1818 ath10k_err(ar, "could not register thermal device: %d\n",
1819 status);
1820 goto err_spectral_destroy;
1821 }
1822
Michal Kazior6782cb62014-05-23 12:28:47 +02001823 set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);
1824 return;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001825
Rajkumar Manoharanfe6f36d2014-12-17 12:22:07 +02001826err_spectral_destroy:
1827 ath10k_spectral_destroy(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03001828err_debug_destroy:
1829 ath10k_debug_destroy(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001830err_unregister_mac:
1831 ath10k_mac_unregister(ar);
Michal Kazior29385052013-07-16 09:38:58 +02001832err_release_fw:
1833 ath10k_core_free_firmware_files(ar);
Michal Kazior6782cb62014-05-23 12:28:47 +02001834err:
Michal Kaziora491a922014-07-14 16:07:29 +03001835 /* TODO: It's probably a good idea to release device from the driver
1836 * but calling device_release_driver() here will cause a deadlock.
1837 */
Michal Kazior6782cb62014-05-23 12:28:47 +02001838 return;
1839}
1840
1841int ath10k_core_register(struct ath10k *ar, u32 chip_id)
1842{
Michal Kazior6782cb62014-05-23 12:28:47 +02001843 ar->chip_id = chip_id;
Michal Kazior6782cb62014-05-23 12:28:47 +02001844 queue_work(ar->workqueue, &ar->register_work);
1845
1846 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001847}
1848EXPORT_SYMBOL(ath10k_core_register);
1849
1850void ath10k_core_unregister(struct ath10k *ar)
1851{
Michal Kazior6782cb62014-05-23 12:28:47 +02001852 cancel_work_sync(&ar->register_work);
1853
1854 if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
1855 return;
1856
Rajkumar Manoharanfe6f36d2014-12-17 12:22:07 +02001857 ath10k_thermal_unregister(ar);
Simon Wunderlich804eef1472014-08-12 17:12:17 +02001858 /* Stop spectral before unregistering from mac80211 to remove the
1859 * relayfs debugfs file cleanly. Otherwise the parent debugfs tree
1860 * would be already be free'd recursively, leading to a double free.
1861 */
1862 ath10k_spectral_destroy(ar);
1863
Kalle Valo5e3dd152013-06-12 20:52:10 +03001864 /* We must unregister from mac80211 before we stop HTC and HIF.
1865 * Otherwise we will fail to submit commands to FW and mac80211 will be
1866 * unhappy about callback failures. */
1867 ath10k_mac_unregister(ar);
Kalle Valodb66ea02013-09-03 11:44:03 +03001868
Kalle Valo43d2a302014-09-10 18:23:30 +03001869 ath10k_testmode_destroy(ar);
1870
Michal Kazior29385052013-07-16 09:38:58 +02001871 ath10k_core_free_firmware_files(ar);
Manikanta Pubbisetty0a51b342015-10-09 11:55:58 +03001872 ath10k_core_free_board_files(ar);
Ben Greear6f1f56e2013-11-04 09:18:16 -08001873
Michal Kaziore13cf7a2014-09-04 09:13:08 +02001874 ath10k_debug_unregister(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001875}
1876EXPORT_SYMBOL(ath10k_core_unregister);
1877
Michal Kaziore7b54192014-08-07 11:03:27 +02001878struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
Kalle Valoe07db352014-10-13 09:40:47 +03001879 enum ath10k_bus bus,
Michal Kaziord63955b2015-01-24 12:14:49 +02001880 enum ath10k_hw_rev hw_rev,
Michal Kazior0d0a6932014-05-23 12:28:45 +02001881 const struct ath10k_hif_ops *hif_ops)
1882{
1883 struct ath10k *ar;
Michal Kaziore13cf7a2014-09-04 09:13:08 +02001884 int ret;
Michal Kazior0d0a6932014-05-23 12:28:45 +02001885
Michal Kaziore7b54192014-08-07 11:03:27 +02001886 ar = ath10k_mac_create(priv_size);
Michal Kazior0d0a6932014-05-23 12:28:45 +02001887 if (!ar)
1888 return NULL;
1889
1890 ar->ath_common.priv = ar;
1891 ar->ath_common.hw = ar->hw;
Michal Kazior0d0a6932014-05-23 12:28:45 +02001892 ar->dev = dev;
Michal Kaziord63955b2015-01-24 12:14:49 +02001893 ar->hw_rev = hw_rev;
Michal Kazior0d0a6932014-05-23 12:28:45 +02001894 ar->hif.ops = hif_ops;
Kalle Valoe07db352014-10-13 09:40:47 +03001895 ar->hif.bus = bus;
Michal Kazior0d0a6932014-05-23 12:28:45 +02001896
Michal Kaziord63955b2015-01-24 12:14:49 +02001897 switch (hw_rev) {
1898 case ATH10K_HW_QCA988X:
1899 ar->regs = &qca988x_regs;
Vasanthakumar Thiagarajan2f2cfc42015-06-18 12:31:01 +05301900 ar->hw_values = &qca988x_values;
Michal Kaziord63955b2015-01-24 12:14:49 +02001901 break;
1902 case ATH10K_HW_QCA6174:
1903 ar->regs = &qca6174_regs;
Vasanthakumar Thiagarajan2f2cfc42015-06-18 12:31:01 +05301904 ar->hw_values = &qca6174_values;
Michal Kaziord63955b2015-01-24 12:14:49 +02001905 break;
Vasanthakumar Thiagarajan8bd47022015-06-18 12:31:03 +05301906 case ATH10K_HW_QCA99X0:
1907 ar->regs = &qca99x0_regs;
1908 ar->hw_values = &qca99x0_values;
1909 break;
Michal Kaziord63955b2015-01-24 12:14:49 +02001910 default:
1911 ath10k_err(ar, "unsupported core hardware revision %d\n",
1912 hw_rev);
1913 ret = -ENOTSUPP;
1914 goto err_free_mac;
1915 }
1916
Michal Kazior0d0a6932014-05-23 12:28:45 +02001917 init_completion(&ar->scan.started);
1918 init_completion(&ar->scan.completed);
1919 init_completion(&ar->scan.on_channel);
1920 init_completion(&ar->target_suspend);
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02001921 init_completion(&ar->wow.wakeup_completed);
Michal Kazior0d0a6932014-05-23 12:28:45 +02001922
1923 init_completion(&ar->install_key_done);
1924 init_completion(&ar->vdev_setup_done);
Rajkumar Manoharanac2953f2014-12-17 12:22:26 +02001925 init_completion(&ar->thermal.wmi_sync);
Michal Kazior0d0a6932014-05-23 12:28:45 +02001926
Michal Kazior5c81c7f2014-08-05 14:54:44 +02001927 INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work);
Michal Kazior0d0a6932014-05-23 12:28:45 +02001928
1929 ar->workqueue = create_singlethread_workqueue("ath10k_wq");
1930 if (!ar->workqueue)
Michal Kaziore13cf7a2014-09-04 09:13:08 +02001931 goto err_free_mac;
Michal Kazior0d0a6932014-05-23 12:28:45 +02001932
Raja Manic8ecfc12015-07-29 11:40:38 +03001933 ar->workqueue_aux = create_singlethread_workqueue("ath10k_aux_wq");
1934 if (!ar->workqueue_aux)
1935 goto err_free_wq;
1936
Michal Kazior0d0a6932014-05-23 12:28:45 +02001937 mutex_init(&ar->conf_mutex);
1938 spin_lock_init(&ar->data_lock);
1939
1940 INIT_LIST_HEAD(&ar->peers);
1941 init_waitqueue_head(&ar->peer_mapping_wq);
Michal Kazior7962b0d2014-10-28 10:34:38 +01001942 init_waitqueue_head(&ar->htt.empty_tx_wq);
1943 init_waitqueue_head(&ar->wmi.tx_credits_wq);
Michal Kazior0d0a6932014-05-23 12:28:45 +02001944
1945 init_completion(&ar->offchan_tx_completed);
1946 INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work);
1947 skb_queue_head_init(&ar->offchan_tx_queue);
1948
1949 INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work);
1950 skb_queue_head_init(&ar->wmi_mgmt_tx_queue);
1951
Michal Kazior6782cb62014-05-23 12:28:47 +02001952 INIT_WORK(&ar->register_work, ath10k_core_register_work);
Michal Kazior0d0a6932014-05-23 12:28:45 +02001953 INIT_WORK(&ar->restart_work, ath10k_core_restart);
1954
Michal Kaziore13cf7a2014-09-04 09:13:08 +02001955 ret = ath10k_debug_create(ar);
1956 if (ret)
Raja Manic8ecfc12015-07-29 11:40:38 +03001957 goto err_free_aux_wq;
Michal Kaziore13cf7a2014-09-04 09:13:08 +02001958
Michal Kazior0d0a6932014-05-23 12:28:45 +02001959 return ar;
1960
Raja Manic8ecfc12015-07-29 11:40:38 +03001961err_free_aux_wq:
1962 destroy_workqueue(ar->workqueue_aux);
Michal Kaziore13cf7a2014-09-04 09:13:08 +02001963err_free_wq:
1964 destroy_workqueue(ar->workqueue);
1965
1966err_free_mac:
Michal Kazior0d0a6932014-05-23 12:28:45 +02001967 ath10k_mac_destroy(ar);
Michal Kaziore13cf7a2014-09-04 09:13:08 +02001968
Michal Kazior0d0a6932014-05-23 12:28:45 +02001969 return NULL;
1970}
1971EXPORT_SYMBOL(ath10k_core_create);
1972
1973void ath10k_core_destroy(struct ath10k *ar)
1974{
1975 flush_workqueue(ar->workqueue);
1976 destroy_workqueue(ar->workqueue);
1977
Raja Manic8ecfc12015-07-29 11:40:38 +03001978 flush_workqueue(ar->workqueue_aux);
1979 destroy_workqueue(ar->workqueue_aux);
1980
Michal Kaziore13cf7a2014-09-04 09:13:08 +02001981 ath10k_debug_destroy(ar);
Vasanthakumar Thiagarajana925a372015-08-28 17:21:34 +05301982 ath10k_wmi_free_host_mem(ar);
Michal Kazior0d0a6932014-05-23 12:28:45 +02001983 ath10k_mac_destroy(ar);
1984}
1985EXPORT_SYMBOL(ath10k_core_destroy);
1986
Kalle Valo5e3dd152013-06-12 20:52:10 +03001987MODULE_AUTHOR("Qualcomm Atheros");
1988MODULE_DESCRIPTION("Core module for QCA988X PCIe devices.");
1989MODULE_LICENSE("Dual BSD/GPL");