blob: f5db43284b97c462fbc403962c7e117bb17efb75 [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;
34static bool uart_print;
Rajkumar Manoharan8868b122014-11-17 16:44:14 +020035static bool skip_otp;
36
Kalle Valo5e3dd152013-06-12 20:52:10 +030037module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
38module_param(uart_print, bool, 0644);
Rajkumar Manoharan8868b122014-11-17 16:44:14 +020039module_param(skip_otp, bool, 0644);
40
Kalle Valo5e3dd152013-06-12 20:52:10 +030041MODULE_PARM_DESC(debug_mask, "Debugging mask");
42MODULE_PARM_DESC(uart_print, "Uart target debugging");
Rajkumar Manoharan8868b122014-11-17 16:44:14 +020043MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
Kalle Valo5e3dd152013-06-12 20:52:10 +030044
45static const struct ath10k_hw_params ath10k_hw_params_list[] = {
46 {
Kalle Valo5e3dd152013-06-12 20:52:10 +030047 .id = QCA988X_HW_2_0_VERSION,
48 .name = "qca988x hw2.0",
49 .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
Michal Kazior3a8200b2014-12-02 10:55:55 +020050 .uart_pin = 7,
Michal Kazior587f7032015-05-25 14:06:18 +020051 .has_shifted_cc_wraparound = true,
Kalle Valo5e3dd152013-06-12 20:52:10 +030052 .fw = {
53 .dir = QCA988X_HW_2_0_FW_DIR,
54 .fw = QCA988X_HW_2_0_FW_FILE,
55 .otp = QCA988X_HW_2_0_OTP_FILE,
56 .board = QCA988X_HW_2_0_BOARD_DATA_FILE,
Michal Kazior9764a2a2014-12-02 10:55:54 +020057 .board_size = QCA988X_BOARD_DATA_SZ,
58 .board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
Kalle Valo5e3dd152013-06-12 20:52:10 +030059 },
60 },
Michal Kaziord63955b2015-01-24 12:14:49 +020061 {
62 .id = QCA6174_HW_2_1_VERSION,
63 .name = "qca6174 hw2.1",
64 .patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
65 .uart_pin = 6,
66 .fw = {
67 .dir = QCA6174_HW_2_1_FW_DIR,
68 .fw = QCA6174_HW_2_1_FW_FILE,
69 .otp = QCA6174_HW_2_1_OTP_FILE,
70 .board = QCA6174_HW_2_1_BOARD_DATA_FILE,
71 .board_size = QCA6174_BOARD_DATA_SZ,
72 .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
73 },
74 },
75 {
76 .id = QCA6174_HW_3_0_VERSION,
77 .name = "qca6174 hw3.0",
78 .patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
79 .uart_pin = 6,
80 .fw = {
81 .dir = QCA6174_HW_3_0_FW_DIR,
82 .fw = QCA6174_HW_3_0_FW_FILE,
83 .otp = QCA6174_HW_3_0_OTP_FILE,
84 .board = QCA6174_HW_3_0_BOARD_DATA_FILE,
85 .board_size = QCA6174_BOARD_DATA_SZ,
86 .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
87 },
88 },
Michal Kazior608b8f72015-01-29 13:24:33 +010089 {
90 .id = QCA6174_HW_3_2_VERSION,
91 .name = "qca6174 hw3.2",
92 .patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
93 .uart_pin = 6,
94 .fw = {
95 /* uses same binaries as hw3.0 */
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 },
Kalle Valo5e3dd152013-06-12 20:52:10 +0300104};
105
Michal Kaziorb27bc5a2015-06-15 14:46:40 +0300106static const char *const ath10k_core_fw_feature_str[] = {
107 [ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX] = "wmi-mgmt-rx",
108 [ATH10K_FW_FEATURE_WMI_10X] = "wmi-10.x",
109 [ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX] = "has-wmi-mgmt-tx",
110 [ATH10K_FW_FEATURE_NO_P2P] = "no-p2p",
111 [ATH10K_FW_FEATURE_WMI_10_2] = "wmi-10.2",
112 [ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT] = "multi-vif-ps",
113 [ATH10K_FW_FEATURE_WOWLAN_SUPPORT] = "wowlan",
114 [ATH10K_FW_FEATURE_IGNORE_OTP_RESULT] = "ignore-otp",
115 [ATH10K_FW_FEATURE_NO_NWIFI_DECAP_4ADDR_PADDING] = "no-4addr-pad",
116 [ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT] = "skip-clock-init",
117};
118
119static unsigned int ath10k_core_get_fw_feature_str(char *buf,
120 size_t buf_len,
121 enum ath10k_fw_features feat)
122{
123 if (feat >= ARRAY_SIZE(ath10k_core_fw_feature_str) ||
124 WARN_ON(!ath10k_core_fw_feature_str[feat])) {
125 return scnprintf(buf, buf_len, "bit%d", feat);
126 }
127
128 return scnprintf(buf, buf_len, "%s", ath10k_core_fw_feature_str[feat]);
129}
130
131void ath10k_core_get_fw_features_str(struct ath10k *ar,
132 char *buf,
133 size_t buf_len)
134{
135 unsigned int len = 0;
136 int i;
137
138 for (i = 0; i < ATH10K_FW_FEATURE_COUNT; i++) {
139 if (test_bit(i, ar->fw_features)) {
140 if (len > 0)
141 len += scnprintf(buf + len, buf_len - len, ",");
142
143 len += ath10k_core_get_fw_feature_str(buf + len,
144 buf_len - len,
145 i);
146 }
147 }
148}
149
Kalle Valo5e3dd152013-06-12 20:52:10 +0300150static void ath10k_send_suspend_complete(struct ath10k *ar)
151{
Michal Kazior7aa7a722014-08-25 12:09:38 +0200152 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot suspend complete\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300153
Marek Puzyniak9042e172014-02-10 17:14:23 +0100154 complete(&ar->target_suspend);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300155}
156
Kalle Valo5e3dd152013-06-12 20:52:10 +0300157static int ath10k_init_configure_target(struct ath10k *ar)
158{
159 u32 param_host;
160 int ret;
161
162 /* tell target which HTC version it is used*/
163 ret = ath10k_bmi_write32(ar, hi_app_host_interest,
164 HTC_PROTOCOL_VERSION);
165 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200166 ath10k_err(ar, "settings HTC version failed\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300167 return ret;
168 }
169
170 /* set the firmware mode to STA/IBSS/AP */
171 ret = ath10k_bmi_read32(ar, hi_option_flag, &param_host);
172 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200173 ath10k_err(ar, "setting firmware mode (1/2) failed\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300174 return ret;
175 }
176
177 /* TODO following parameters need to be re-visited. */
178 /* num_device */
179 param_host |= (1 << HI_OPTION_NUM_DEV_SHIFT);
180 /* Firmware mode */
181 /* FIXME: Why FW_MODE_AP ??.*/
182 param_host |= (HI_OPTION_FW_MODE_AP << HI_OPTION_FW_MODE_SHIFT);
183 /* mac_addr_method */
184 param_host |= (1 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
185 /* firmware_bridge */
186 param_host |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
187 /* fwsubmode */
188 param_host |= (0 << HI_OPTION_FW_SUBMODE_SHIFT);
189
190 ret = ath10k_bmi_write32(ar, hi_option_flag, param_host);
191 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200192 ath10k_err(ar, "setting firmware mode (2/2) failed\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300193 return ret;
194 }
195
196 /* We do all byte-swapping on the host */
197 ret = ath10k_bmi_write32(ar, hi_be, 0);
198 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200199 ath10k_err(ar, "setting host CPU BE mode failed\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300200 return ret;
201 }
202
203 /* FW descriptor/Data swap flags */
204 ret = ath10k_bmi_write32(ar, hi_fw_swap, 0);
205
206 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200207 ath10k_err(ar, "setting FW data/desc swap flags failed\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300208 return ret;
209 }
210
211 return 0;
212}
213
214static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar,
215 const char *dir,
216 const char *file)
217{
218 char filename[100];
219 const struct firmware *fw;
220 int ret;
221
222 if (file == NULL)
223 return ERR_PTR(-ENOENT);
224
225 if (dir == NULL)
226 dir = ".";
227
228 snprintf(filename, sizeof(filename), "%s/%s", dir, file);
229 ret = request_firmware(&fw, filename, ar->dev);
230 if (ret)
231 return ERR_PTR(ret);
232
233 return fw;
234}
235
Kalle Valoa58227e2014-10-13 09:40:59 +0300236static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data,
237 size_t data_len)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300238{
Michal Kazior9764a2a2014-12-02 10:55:54 +0200239 u32 board_data_size = ar->hw_params.fw.board_size;
240 u32 board_ext_data_size = ar->hw_params.fw.board_ext_size;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300241 u32 board_ext_data_addr;
242 int ret;
243
244 ret = ath10k_bmi_read32(ar, hi_board_ext_data, &board_ext_data_addr);
245 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200246 ath10k_err(ar, "could not read board ext data addr (%d)\n",
247 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300248 return ret;
249 }
250
Michal Kazior7aa7a722014-08-25 12:09:38 +0200251 ath10k_dbg(ar, ATH10K_DBG_BOOT,
Kalle Valoeffea962013-09-08 17:55:44 +0300252 "boot push board extended data addr 0x%x\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300253 board_ext_data_addr);
254
255 if (board_ext_data_addr == 0)
256 return 0;
257
Kalle Valoa58227e2014-10-13 09:40:59 +0300258 if (data_len != (board_data_size + board_ext_data_size)) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200259 ath10k_err(ar, "invalid board (ext) data sizes %zu != %d+%d\n",
Kalle Valoa58227e2014-10-13 09:40:59 +0300260 data_len, board_data_size, board_ext_data_size);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300261 return -EINVAL;
262 }
263
264 ret = ath10k_bmi_write_memory(ar, board_ext_data_addr,
Kalle Valoa58227e2014-10-13 09:40:59 +0300265 data + board_data_size,
Kalle Valo5e3dd152013-06-12 20:52:10 +0300266 board_ext_data_size);
267 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200268 ath10k_err(ar, "could not write board ext data (%d)\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300269 return ret;
270 }
271
272 ret = ath10k_bmi_write32(ar, hi_board_ext_data_config,
273 (board_ext_data_size << 16) | 1);
274 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200275 ath10k_err(ar, "could not write board ext data bit (%d)\n",
276 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300277 return ret;
278 }
279
280 return 0;
281}
282
Kalle Valoa58227e2014-10-13 09:40:59 +0300283static int ath10k_download_board_data(struct ath10k *ar, const void *data,
284 size_t data_len)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300285{
Michal Kazior9764a2a2014-12-02 10:55:54 +0200286 u32 board_data_size = ar->hw_params.fw.board_size;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300287 u32 address;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300288 int ret;
289
Kalle Valoa58227e2014-10-13 09:40:59 +0300290 ret = ath10k_push_board_ext_data(ar, data, data_len);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300291 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200292 ath10k_err(ar, "could not push board ext data (%d)\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300293 goto exit;
294 }
295
296 ret = ath10k_bmi_read32(ar, hi_board_data, &address);
297 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200298 ath10k_err(ar, "could not read board data addr (%d)\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300299 goto exit;
300 }
301
Kalle Valoa58227e2014-10-13 09:40:59 +0300302 ret = ath10k_bmi_write_memory(ar, address, data,
Kalle Valo958df3a2013-09-27 19:55:01 +0300303 min_t(u32, board_data_size,
Kalle Valoa58227e2014-10-13 09:40:59 +0300304 data_len));
Kalle Valo5e3dd152013-06-12 20:52:10 +0300305 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200306 ath10k_err(ar, "could not write board data (%d)\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300307 goto exit;
308 }
309
310 ret = ath10k_bmi_write32(ar, hi_board_data_initialized, 1);
311 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200312 ath10k_err(ar, "could not write board data bit (%d)\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300313 goto exit;
314 }
315
316exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300317 return ret;
318}
319
Kalle Valoa58227e2014-10-13 09:40:59 +0300320static int ath10k_download_cal_file(struct ath10k *ar)
321{
322 int ret;
323
324 if (!ar->cal_file)
325 return -ENOENT;
326
327 if (IS_ERR(ar->cal_file))
328 return PTR_ERR(ar->cal_file);
329
330 ret = ath10k_download_board_data(ar, ar->cal_file->data,
331 ar->cal_file->size);
332 if (ret) {
333 ath10k_err(ar, "failed to download cal_file data: %d\n", ret);
334 return ret;
335 }
336
337 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cal file downloaded\n");
338
339 return 0;
340}
341
Toshi Kikuchi5aabff02014-12-02 10:55:54 +0200342static int ath10k_download_cal_dt(struct ath10k *ar)
343{
344 struct device_node *node;
345 int data_len;
346 void *data;
347 int ret;
348
349 node = ar->dev->of_node;
350 if (!node)
351 /* Device Tree is optional, don't print any warnings if
352 * there's no node for ath10k.
353 */
354 return -ENOENT;
355
356 if (!of_get_property(node, "qcom,ath10k-calibration-data",
357 &data_len)) {
358 /* The calibration data node is optional */
359 return -ENOENT;
360 }
361
362 if (data_len != QCA988X_CAL_DATA_LEN) {
363 ath10k_warn(ar, "invalid calibration data length in DT: %d\n",
364 data_len);
365 ret = -EMSGSIZE;
366 goto out;
367 }
368
369 data = kmalloc(data_len, GFP_KERNEL);
370 if (!data) {
371 ret = -ENOMEM;
372 goto out;
373 }
374
375 ret = of_property_read_u8_array(node, "qcom,ath10k-calibration-data",
376 data, data_len);
377 if (ret) {
378 ath10k_warn(ar, "failed to read calibration data from DT: %d\n",
379 ret);
380 goto out_free;
381 }
382
383 ret = ath10k_download_board_data(ar, data, data_len);
384 if (ret) {
385 ath10k_warn(ar, "failed to download calibration data from Device Tree: %d\n",
386 ret);
387 goto out_free;
388 }
389
390 ret = 0;
391
392out_free:
393 kfree(data);
394
395out:
396 return ret;
397}
398
Kalle Valo5e3dd152013-06-12 20:52:10 +0300399static int ath10k_download_and_run_otp(struct ath10k *ar)
400{
Kalle Valod6d4a582014-03-11 17:33:19 +0200401 u32 result, address = ar->hw_params.patch_load_addr;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300402 int ret;
403
Kalle Valoa58227e2014-10-13 09:40:59 +0300404 ret = ath10k_download_board_data(ar, ar->board_data, ar->board_len);
Kalle Valo83091552014-10-13 09:40:53 +0300405 if (ret) {
406 ath10k_err(ar, "failed to download board data: %d\n", ret);
407 return ret;
408 }
409
Kalle Valo5e3dd152013-06-12 20:52:10 +0300410 /* OTP is optional */
411
Kalle Valo7f06ea12014-03-11 17:33:28 +0200412 if (!ar->otp_data || !ar->otp_len) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200413 ath10k_warn(ar, "Not running otp, calibration will be incorrect (otp-data %p otp_len %zd)!\n",
Ben Greear36a8f412014-03-24 12:20:42 -0700414 ar->otp_data, ar->otp_len);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300415 return 0;
Kalle Valo7f06ea12014-03-11 17:33:28 +0200416 }
417
Michal Kazior7aa7a722014-08-25 12:09:38 +0200418 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n",
Kalle Valo7f06ea12014-03-11 17:33:28 +0200419 address, ar->otp_len);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300420
Kalle Valo958df3a2013-09-27 19:55:01 +0300421 ret = ath10k_bmi_fast_download(ar, address, ar->otp_data, ar->otp_len);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300422 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200423 ath10k_err(ar, "could not write otp (%d)\n", ret);
Kalle Valo7f06ea12014-03-11 17:33:28 +0200424 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300425 }
426
Kalle Valod6d4a582014-03-11 17:33:19 +0200427 ret = ath10k_bmi_execute(ar, address, 0, &result);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300428 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200429 ath10k_err(ar, "could not execute otp (%d)\n", ret);
Kalle Valo7f06ea12014-03-11 17:33:28 +0200430 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300431 }
432
Michal Kazior7aa7a722014-08-25 12:09:38 +0200433 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);
Kalle Valo7f06ea12014-03-11 17:33:28 +0200434
Kalle Valod9153542015-04-28 20:19:30 +0300435 if (!(skip_otp || test_bit(ATH10K_FW_FEATURE_IGNORE_OTP_RESULT,
436 ar->fw_features))
437 && result != 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200438 ath10k_err(ar, "otp calibration failed: %d", result);
Kalle Valo7f06ea12014-03-11 17:33:28 +0200439 return -EINVAL;
440 }
441
442 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300443}
444
Kalle Valo43d2a302014-09-10 18:23:30 +0300445static int ath10k_download_fw(struct ath10k *ar, enum ath10k_firmware_mode mode)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300446{
Kalle Valo43d2a302014-09-10 18:23:30 +0300447 u32 address, data_len;
448 const char *mode_name;
449 const void *data;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300450 int ret;
451
Kalle Valo5e3dd152013-06-12 20:52:10 +0300452 address = ar->hw_params.patch_load_addr;
453
Kalle Valo43d2a302014-09-10 18:23:30 +0300454 switch (mode) {
455 case ATH10K_FIRMWARE_MODE_NORMAL:
456 data = ar->firmware_data;
457 data_len = ar->firmware_len;
458 mode_name = "normal";
459 break;
460 case ATH10K_FIRMWARE_MODE_UTF:
461 data = ar->testmode.utf->data;
462 data_len = ar->testmode.utf->size;
463 mode_name = "utf";
464 break;
465 default:
466 ath10k_err(ar, "unknown firmware mode: %d\n", mode);
467 return -EINVAL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300468 }
469
Kalle Valo43d2a302014-09-10 18:23:30 +0300470 ath10k_dbg(ar, ATH10K_DBG_BOOT,
471 "boot uploading firmware image %p len %d mode %s\n",
472 data, data_len, mode_name);
473
474 ret = ath10k_bmi_fast_download(ar, address, data, data_len);
475 if (ret) {
476 ath10k_err(ar, "failed to download %s firmware: %d\n",
477 mode_name, ret);
478 return ret;
479 }
480
Michal Kazior29385052013-07-16 09:38:58 +0200481 return ret;
482}
483
484static void ath10k_core_free_firmware_files(struct ath10k *ar)
485{
Markus Elfringdb2cf862015-02-04 19:30:23 +0100486 if (!IS_ERR(ar->board))
Kalle Valo36527912013-09-27 19:54:55 +0300487 release_firmware(ar->board);
Michal Kazior29385052013-07-16 09:38:58 +0200488
Markus Elfringdb2cf862015-02-04 19:30:23 +0100489 if (!IS_ERR(ar->otp))
Michal Kazior29385052013-07-16 09:38:58 +0200490 release_firmware(ar->otp);
491
Markus Elfringdb2cf862015-02-04 19:30:23 +0100492 if (!IS_ERR(ar->firmware))
Michal Kazior29385052013-07-16 09:38:58 +0200493 release_firmware(ar->firmware);
494
Markus Elfringdb2cf862015-02-04 19:30:23 +0100495 if (!IS_ERR(ar->cal_file))
Kalle Valoa58227e2014-10-13 09:40:59 +0300496 release_firmware(ar->cal_file);
497
Kalle Valo36527912013-09-27 19:54:55 +0300498 ar->board = NULL;
Kalle Valo958df3a2013-09-27 19:55:01 +0300499 ar->board_data = NULL;
500 ar->board_len = 0;
501
Michal Kazior29385052013-07-16 09:38:58 +0200502 ar->otp = NULL;
Kalle Valo958df3a2013-09-27 19:55:01 +0300503 ar->otp_data = NULL;
504 ar->otp_len = 0;
505
Michal Kazior29385052013-07-16 09:38:58 +0200506 ar->firmware = NULL;
Kalle Valo958df3a2013-09-27 19:55:01 +0300507 ar->firmware_data = NULL;
508 ar->firmware_len = 0;
Kalle Valoa58227e2014-10-13 09:40:59 +0300509
510 ar->cal_file = NULL;
511}
512
513static int ath10k_fetch_cal_file(struct ath10k *ar)
514{
515 char filename[100];
516
517 /* cal-<bus>-<id>.bin */
518 scnprintf(filename, sizeof(filename), "cal-%s-%s.bin",
519 ath10k_bus_str(ar->hif.bus), dev_name(ar->dev));
520
521 ar->cal_file = ath10k_fetch_fw_file(ar, ATH10K_FW_DIR, filename);
522 if (IS_ERR(ar->cal_file))
523 /* calibration file is optional, don't print any warnings */
524 return PTR_ERR(ar->cal_file);
525
526 ath10k_dbg(ar, ATH10K_DBG_BOOT, "found calibration file %s/%s\n",
527 ATH10K_FW_DIR, filename);
528
529 return 0;
Michal Kazior29385052013-07-16 09:38:58 +0200530}
531
Michal Kaziorde57e2c2015-04-17 09:19:17 +0000532static int ath10k_core_fetch_spec_board_file(struct ath10k *ar)
Michal Kazior29385052013-07-16 09:38:58 +0200533{
Michal Kaziorde57e2c2015-04-17 09:19:17 +0000534 char filename[100];
Michal Kazior29385052013-07-16 09:38:58 +0200535
Michal Kaziorde57e2c2015-04-17 09:19:17 +0000536 scnprintf(filename, sizeof(filename), "board-%s-%s.bin",
537 ath10k_bus_str(ar->hif.bus), ar->spec_board_id);
538
539 ar->board = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, filename);
540 if (IS_ERR(ar->board))
541 return PTR_ERR(ar->board);
542
543 ar->board_data = ar->board->data;
544 ar->board_len = ar->board->size;
545 ar->spec_board_loaded = true;
546
547 return 0;
548}
549
550static int ath10k_core_fetch_generic_board_file(struct ath10k *ar)
551{
Michal Kaziord0ed74f2015-04-17 09:19:16 +0000552 if (!ar->hw_params.fw.board) {
553 ath10k_err(ar, "failed to find board file fw entry\n");
Michal Kazior29385052013-07-16 09:38:58 +0200554 return -EINVAL;
555 }
556
Kalle Valo36527912013-09-27 19:54:55 +0300557 ar->board = ath10k_fetch_fw_file(ar,
558 ar->hw_params.fw.dir,
559 ar->hw_params.fw.board);
Michal Kaziorde57e2c2015-04-17 09:19:17 +0000560 if (IS_ERR(ar->board))
561 return PTR_ERR(ar->board);
Michal Kazior29385052013-07-16 09:38:58 +0200562
Kalle Valo958df3a2013-09-27 19:55:01 +0300563 ar->board_data = ar->board->data;
564 ar->board_len = ar->board->size;
Michal Kaziorde57e2c2015-04-17 09:19:17 +0000565 ar->spec_board_loaded = false;
566
567 return 0;
568}
569
570static int ath10k_core_fetch_board_file(struct ath10k *ar)
571{
572 int ret;
573
574 if (strlen(ar->spec_board_id) > 0) {
575 ret = ath10k_core_fetch_spec_board_file(ar);
576 if (ret) {
577 ath10k_info(ar, "failed to load spec board file, falling back to generic: %d\n",
578 ret);
579 goto generic;
580 }
581
582 ath10k_dbg(ar, ATH10K_DBG_BOOT, "found specific board file for %s\n",
583 ar->spec_board_id);
584 return 0;
585 }
586
587generic:
588 ret = ath10k_core_fetch_generic_board_file(ar);
589 if (ret) {
590 ath10k_err(ar, "failed to fetch generic board data: %d\n", ret);
591 return ret;
592 }
Kalle Valo958df3a2013-09-27 19:55:01 +0300593
Michal Kaziord0ed74f2015-04-17 09:19:16 +0000594 return 0;
595}
596
597static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar)
598{
599 int ret = 0;
600
601 if (ar->hw_params.fw.fw == NULL) {
602 ath10k_err(ar, "firmware file not defined\n");
603 return -EINVAL;
604 }
605
Michal Kazior29385052013-07-16 09:38:58 +0200606 ar->firmware = ath10k_fetch_fw_file(ar,
607 ar->hw_params.fw.dir,
608 ar->hw_params.fw.fw);
609 if (IS_ERR(ar->firmware)) {
610 ret = PTR_ERR(ar->firmware);
Michal Kazior7aa7a722014-08-25 12:09:38 +0200611 ath10k_err(ar, "could not fetch firmware (%d)\n", ret);
Michal Kazior29385052013-07-16 09:38:58 +0200612 goto err;
613 }
614
Kalle Valo958df3a2013-09-27 19:55:01 +0300615 ar->firmware_data = ar->firmware->data;
616 ar->firmware_len = ar->firmware->size;
617
Michal Kazior29385052013-07-16 09:38:58 +0200618 /* OTP may be undefined. If so, don't fetch it at all */
619 if (ar->hw_params.fw.otp == NULL)
620 return 0;
621
622 ar->otp = ath10k_fetch_fw_file(ar,
623 ar->hw_params.fw.dir,
624 ar->hw_params.fw.otp);
625 if (IS_ERR(ar->otp)) {
626 ret = PTR_ERR(ar->otp);
Michal Kazior7aa7a722014-08-25 12:09:38 +0200627 ath10k_err(ar, "could not fetch otp (%d)\n", ret);
Michal Kazior29385052013-07-16 09:38:58 +0200628 goto err;
629 }
630
Kalle Valo958df3a2013-09-27 19:55:01 +0300631 ar->otp_data = ar->otp->data;
632 ar->otp_len = ar->otp->size;
633
Michal Kazior29385052013-07-16 09:38:58 +0200634 return 0;
635
636err:
637 ath10k_core_free_firmware_files(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300638 return ret;
639}
640
Kalle Valo1a222432013-09-27 19:55:07 +0300641static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
642{
643 size_t magic_len, len, ie_len;
644 int ie_id, i, index, bit, ret;
645 struct ath10k_fw_ie *hdr;
646 const u8 *data;
Kalle Valo202e86e2014-12-03 10:10:08 +0200647 __le32 *timestamp, *version;
Kalle Valo1a222432013-09-27 19:55:07 +0300648
649 /* first fetch the firmware file (firmware-*.bin) */
650 ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name);
651 if (IS_ERR(ar->firmware)) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200652 ath10k_err(ar, "could not fetch firmware file '%s/%s': %ld\n",
Ben Greear53c02282014-03-24 12:20:41 -0700653 ar->hw_params.fw.dir, name, PTR_ERR(ar->firmware));
Kalle Valo1a222432013-09-27 19:55:07 +0300654 return PTR_ERR(ar->firmware);
655 }
656
657 data = ar->firmware->data;
658 len = ar->firmware->size;
659
660 /* magic also includes the null byte, check that as well */
661 magic_len = strlen(ATH10K_FIRMWARE_MAGIC) + 1;
662
663 if (len < magic_len) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200664 ath10k_err(ar, "firmware file '%s/%s' too small to contain magic: %zu\n",
Ben Greear53c02282014-03-24 12:20:41 -0700665 ar->hw_params.fw.dir, name, len);
Michal Kazior9bab1cc2013-10-04 08:13:20 +0200666 ret = -EINVAL;
667 goto err;
Kalle Valo1a222432013-09-27 19:55:07 +0300668 }
669
670 if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200671 ath10k_err(ar, "invalid firmware magic\n");
Michal Kazior9bab1cc2013-10-04 08:13:20 +0200672 ret = -EINVAL;
673 goto err;
Kalle Valo1a222432013-09-27 19:55:07 +0300674 }
675
676 /* jump over the padding */
677 magic_len = ALIGN(magic_len, 4);
678
679 len -= magic_len;
680 data += magic_len;
681
682 /* loop elements */
683 while (len > sizeof(struct ath10k_fw_ie)) {
684 hdr = (struct ath10k_fw_ie *)data;
685
686 ie_id = le32_to_cpu(hdr->id);
687 ie_len = le32_to_cpu(hdr->len);
688
689 len -= sizeof(*hdr);
690 data += sizeof(*hdr);
691
692 if (len < ie_len) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200693 ath10k_err(ar, "invalid length for FW IE %d (%zu < %zu)\n",
Kalle Valo1a222432013-09-27 19:55:07 +0300694 ie_id, len, ie_len);
Michal Kazior9bab1cc2013-10-04 08:13:20 +0200695 ret = -EINVAL;
696 goto err;
Kalle Valo1a222432013-09-27 19:55:07 +0300697 }
698
699 switch (ie_id) {
700 case ATH10K_FW_IE_FW_VERSION:
701 if (ie_len > sizeof(ar->hw->wiphy->fw_version) - 1)
702 break;
703
704 memcpy(ar->hw->wiphy->fw_version, data, ie_len);
705 ar->hw->wiphy->fw_version[ie_len] = '\0';
706
Michal Kazior7aa7a722014-08-25 12:09:38 +0200707 ath10k_dbg(ar, ATH10K_DBG_BOOT,
Kalle Valo1a222432013-09-27 19:55:07 +0300708 "found fw version %s\n",
709 ar->hw->wiphy->fw_version);
710 break;
711 case ATH10K_FW_IE_TIMESTAMP:
712 if (ie_len != sizeof(u32))
713 break;
714
715 timestamp = (__le32 *)data;
716
Michal Kazior7aa7a722014-08-25 12:09:38 +0200717 ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw timestamp %d\n",
Kalle Valo1a222432013-09-27 19:55:07 +0300718 le32_to_cpup(timestamp));
719 break;
720 case ATH10K_FW_IE_FEATURES:
Michal Kazior7aa7a722014-08-25 12:09:38 +0200721 ath10k_dbg(ar, ATH10K_DBG_BOOT,
Kalle Valo1a222432013-09-27 19:55:07 +0300722 "found firmware features ie (%zd B)\n",
723 ie_len);
724
725 for (i = 0; i < ATH10K_FW_FEATURE_COUNT; i++) {
726 index = i / 8;
727 bit = i % 8;
728
729 if (index == ie_len)
730 break;
731
Ben Greearf591a1a2014-02-04 19:51:38 +0200732 if (data[index] & (1 << bit)) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200733 ath10k_dbg(ar, ATH10K_DBG_BOOT,
Ben Greearf591a1a2014-02-04 19:51:38 +0200734 "Enabling feature bit: %i\n",
735 i);
Kalle Valo1a222432013-09-27 19:55:07 +0300736 __set_bit(i, ar->fw_features);
Ben Greearf591a1a2014-02-04 19:51:38 +0200737 }
Kalle Valo1a222432013-09-27 19:55:07 +0300738 }
739
Michal Kazior7aa7a722014-08-25 12:09:38 +0200740 ath10k_dbg_dump(ar, ATH10K_DBG_BOOT, "features", "",
Kalle Valo1a222432013-09-27 19:55:07 +0300741 ar->fw_features,
742 sizeof(ar->fw_features));
743 break;
744 case ATH10K_FW_IE_FW_IMAGE:
Michal Kazior7aa7a722014-08-25 12:09:38 +0200745 ath10k_dbg(ar, ATH10K_DBG_BOOT,
Kalle Valo1a222432013-09-27 19:55:07 +0300746 "found fw image ie (%zd B)\n",
747 ie_len);
748
749 ar->firmware_data = data;
750 ar->firmware_len = ie_len;
751
752 break;
753 case ATH10K_FW_IE_OTP_IMAGE:
Michal Kazior7aa7a722014-08-25 12:09:38 +0200754 ath10k_dbg(ar, ATH10K_DBG_BOOT,
Kalle Valo1a222432013-09-27 19:55:07 +0300755 "found otp image ie (%zd B)\n",
756 ie_len);
757
758 ar->otp_data = data;
759 ar->otp_len = ie_len;
760
761 break;
Kalle Valo202e86e2014-12-03 10:10:08 +0200762 case ATH10K_FW_IE_WMI_OP_VERSION:
763 if (ie_len != sizeof(u32))
764 break;
765
766 version = (__le32 *)data;
767
768 ar->wmi.op_version = le32_to_cpup(version);
769
770 ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie wmi op version %d\n",
771 ar->wmi.op_version);
772 break;
Rajkumar Manoharan8348db22015-03-25 13:12:27 +0200773 case ATH10K_FW_IE_HTT_OP_VERSION:
774 if (ie_len != sizeof(u32))
775 break;
776
777 version = (__le32 *)data;
778
779 ar->htt.op_version = le32_to_cpup(version);
780
781 ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie htt op version %d\n",
782 ar->htt.op_version);
783 break;
Kalle Valo1a222432013-09-27 19:55:07 +0300784 default:
Michal Kazior7aa7a722014-08-25 12:09:38 +0200785 ath10k_warn(ar, "Unknown FW IE: %u\n",
Kalle Valo1a222432013-09-27 19:55:07 +0300786 le32_to_cpu(hdr->id));
787 break;
788 }
789
790 /* jump over the padding */
791 ie_len = ALIGN(ie_len, 4);
792
793 len -= ie_len;
794 data += ie_len;
Fengguang Wue05634e2013-10-08 21:48:15 +0300795 }
Kalle Valo1a222432013-09-27 19:55:07 +0300796
797 if (!ar->firmware_data || !ar->firmware_len) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200798 ath10k_warn(ar, "No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n",
Ben Greear53c02282014-03-24 12:20:41 -0700799 ar->hw_params.fw.dir, name);
Kalle Valo1a222432013-09-27 19:55:07 +0300800 ret = -ENOMEDIUM;
801 goto err;
802 }
803
Kalle Valo1a222432013-09-27 19:55:07 +0300804 return 0;
805
806err:
807 ath10k_core_free_firmware_files(ar);
808 return ret;
809}
810
811static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
812{
813 int ret;
814
Kalle Valoa58227e2014-10-13 09:40:59 +0300815 /* calibration file is optional, don't check for any errors */
816 ath10k_fetch_cal_file(ar);
817
Michal Kaziord0ed74f2015-04-17 09:19:16 +0000818 ret = ath10k_core_fetch_board_file(ar);
819 if (ret) {
820 ath10k_err(ar, "failed to fetch board file: %d\n", ret);
821 return ret;
822 }
823
Kalle Valo53513c32015-03-25 13:12:42 +0200824 ar->fw_api = 5;
825 ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
826
827 ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API5_FILE);
828 if (ret == 0)
829 goto success;
830
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +0200831 ar->fw_api = 4;
832 ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
833
834 ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API4_FILE);
835 if (ret == 0)
836 goto success;
837
Michal Kazior24c88f72014-07-25 13:32:17 +0200838 ar->fw_api = 3;
Michal Kazior7aa7a722014-08-25 12:09:38 +0200839 ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
Michal Kazior24c88f72014-07-25 13:32:17 +0200840
841 ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API3_FILE);
842 if (ret == 0)
843 goto success;
844
Ben Greear53c02282014-03-24 12:20:41 -0700845 ar->fw_api = 2;
Michal Kazior7aa7a722014-08-25 12:09:38 +0200846 ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
Ben Greear53c02282014-03-24 12:20:41 -0700847
Kalle Valo1a222432013-09-27 19:55:07 +0300848 ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API2_FILE);
Ben Greear53c02282014-03-24 12:20:41 -0700849 if (ret == 0)
850 goto success;
851
852 ar->fw_api = 1;
Michal Kazior7aa7a722014-08-25 12:09:38 +0200853 ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
Kalle Valo1a222432013-09-27 19:55:07 +0300854
855 ret = ath10k_core_fetch_firmware_api_1(ar);
856 if (ret)
857 return ret;
858
Ben Greear53c02282014-03-24 12:20:41 -0700859success:
Michal Kazior7aa7a722014-08-25 12:09:38 +0200860 ath10k_dbg(ar, ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api);
Kalle Valo1a222432013-09-27 19:55:07 +0300861
862 return 0;
863}
864
Kalle Valo83091552014-10-13 09:40:53 +0300865static int ath10k_download_cal_data(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300866{
867 int ret;
868
Kalle Valoa58227e2014-10-13 09:40:59 +0300869 ret = ath10k_download_cal_file(ar);
870 if (ret == 0) {
871 ar->cal_mode = ATH10K_CAL_MODE_FILE;
872 goto done;
873 }
874
875 ath10k_dbg(ar, ATH10K_DBG_BOOT,
Toshi Kikuchi5aabff02014-12-02 10:55:54 +0200876 "boot did not find a calibration file, try DT next: %d\n",
877 ret);
878
879 ret = ath10k_download_cal_dt(ar);
880 if (ret == 0) {
881 ar->cal_mode = ATH10K_CAL_MODE_DT;
882 goto done;
883 }
884
885 ath10k_dbg(ar, ATH10K_DBG_BOOT,
886 "boot did not find DT entry, try OTP next: %d\n",
Kalle Valoa58227e2014-10-13 09:40:59 +0300887 ret);
888
Kalle Valo5e3dd152013-06-12 20:52:10 +0300889 ret = ath10k_download_and_run_otp(ar);
Ben Greear36a8f412014-03-24 12:20:42 -0700890 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200891 ath10k_err(ar, "failed to run otp: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300892 return ret;
Ben Greear36a8f412014-03-24 12:20:42 -0700893 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300894
Kalle Valoa58227e2014-10-13 09:40:59 +0300895 ar->cal_mode = ATH10K_CAL_MODE_OTP;
896
897done:
898 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using calibration mode %s\n",
899 ath10k_cal_mode_str(ar->cal_mode));
900 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300901}
902
903static int ath10k_init_uart(struct ath10k *ar)
904{
905 int ret;
906
907 /*
908 * Explicitly setting UART prints to zero as target turns it on
909 * based on scratch registers.
910 */
911 ret = ath10k_bmi_write32(ar, hi_serial_enable, 0);
912 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200913 ath10k_warn(ar, "could not disable UART prints (%d)\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300914 return ret;
915 }
916
Kalle Valoc8c39af2013-11-20 10:00:41 +0200917 if (!uart_print)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300918 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300919
Michal Kazior3a8200b2014-12-02 10:55:55 +0200920 ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, ar->hw_params.uart_pin);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300921 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200922 ath10k_warn(ar, "could not enable UART prints (%d)\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300923 return ret;
924 }
925
926 ret = ath10k_bmi_write32(ar, hi_serial_enable, 1);
927 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200928 ath10k_warn(ar, "could not enable UART prints (%d)\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300929 return ret;
930 }
931
Bartosz Markowski03fc1372013-09-03 14:24:02 +0200932 /* Set the UART baud rate to 19200. */
933 ret = ath10k_bmi_write32(ar, hi_desired_baud_rate, 19200);
934 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200935 ath10k_warn(ar, "could not set the baud rate (%d)\n", ret);
Bartosz Markowski03fc1372013-09-03 14:24:02 +0200936 return ret;
937 }
938
Michal Kazior7aa7a722014-08-25 12:09:38 +0200939 ath10k_info(ar, "UART prints enabled\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300940 return 0;
941}
942
943static int ath10k_init_hw_params(struct ath10k *ar)
944{
945 const struct ath10k_hw_params *uninitialized_var(hw_params);
946 int i;
947
948 for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) {
949 hw_params = &ath10k_hw_params_list[i];
950
951 if (hw_params->id == ar->target_version)
952 break;
953 }
954
955 if (i == ARRAY_SIZE(ath10k_hw_params_list)) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200956 ath10k_err(ar, "Unsupported hardware version: 0x%x\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300957 ar->target_version);
958 return -EINVAL;
959 }
960
961 ar->hw_params = *hw_params;
962
Michal Kazior7aa7a722014-08-25 12:09:38 +0200963 ath10k_dbg(ar, ATH10K_DBG_BOOT, "Hardware name %s version 0x%x\n",
Kalle Valoc8c39af2013-11-20 10:00:41 +0200964 ar->hw_params.name, ar->target_version);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300965
966 return 0;
967}
968
Michal Kazioraffd3212013-07-16 09:54:35 +0200969static void ath10k_core_restart(struct work_struct *work)
970{
971 struct ath10k *ar = container_of(work, struct ath10k, restart_work);
972
Michal Kazior7962b0d2014-10-28 10:34:38 +0100973 set_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);
974
975 /* Place a barrier to make sure the compiler doesn't reorder
976 * CRASH_FLUSH and calling other functions.
977 */
978 barrier();
979
980 ieee80211_stop_queues(ar->hw);
981 ath10k_drain_tx(ar);
982 complete_all(&ar->scan.started);
983 complete_all(&ar->scan.completed);
984 complete_all(&ar->scan.on_channel);
985 complete_all(&ar->offchan_tx_completed);
986 complete_all(&ar->install_key_done);
987 complete_all(&ar->vdev_setup_done);
Rajkumar Manoharanac2953f2014-12-17 12:22:26 +0200988 complete_all(&ar->thermal.wmi_sync);
Michal Kazior7962b0d2014-10-28 10:34:38 +0100989 wake_up(&ar->htt.empty_tx_wq);
990 wake_up(&ar->wmi.tx_credits_wq);
991 wake_up(&ar->peer_mapping_wq);
992
Michal Kazioraffd3212013-07-16 09:54:35 +0200993 mutex_lock(&ar->conf_mutex);
994
995 switch (ar->state) {
996 case ATH10K_STATE_ON:
Michal Kazioraffd3212013-07-16 09:54:35 +0200997 ar->state = ATH10K_STATE_RESTARTING;
Michal Kazior61e9aab2014-08-22 14:33:18 +0200998 ath10k_hif_stop(ar);
Michal Kazior5c81c7f2014-08-05 14:54:44 +0200999 ath10k_scan_finish(ar);
Michal Kazioraffd3212013-07-16 09:54:35 +02001000 ieee80211_restart_hw(ar->hw);
1001 break;
1002 case ATH10K_STATE_OFF:
Michal Kazior5e90de82013-10-16 16:46:05 +03001003 /* this can happen if driver is being unloaded
1004 * or if the crash happens during FW probing */
Michal Kazior7aa7a722014-08-25 12:09:38 +02001005 ath10k_warn(ar, "cannot restart a device that hasn't been started\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02001006 break;
1007 case ATH10K_STATE_RESTARTING:
Michal Kaziorc5058f52014-05-26 12:46:03 +03001008 /* hw restart might be requested from multiple places */
1009 break;
Michal Kazioraffd3212013-07-16 09:54:35 +02001010 case ATH10K_STATE_RESTARTED:
1011 ar->state = ATH10K_STATE_WEDGED;
1012 /* fall through */
1013 case ATH10K_STATE_WEDGED:
Michal Kazior7aa7a722014-08-25 12:09:38 +02001014 ath10k_warn(ar, "device is wedged, will not restart\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02001015 break;
Kalle Valo43d2a302014-09-10 18:23:30 +03001016 case ATH10K_STATE_UTF:
1017 ath10k_warn(ar, "firmware restart in UTF mode not supported\n");
1018 break;
Michal Kazioraffd3212013-07-16 09:54:35 +02001019 }
1020
1021 mutex_unlock(&ar->conf_mutex);
1022}
1023
Kalle Valo5f2144d2014-12-03 10:09:59 +02001024static int ath10k_core_init_firmware_features(struct ath10k *ar)
Michal Kaziorcfd10612014-11-25 15:16:05 +01001025{
Kalle Valo5f2144d2014-12-03 10:09:59 +02001026 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features) &&
1027 !test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
1028 ath10k_err(ar, "feature bits corrupted: 10.2 feature requires 10.x feature to be set as well");
1029 return -EINVAL;
1030 }
1031
Kalle Valo202e86e2014-12-03 10:10:08 +02001032 if (ar->wmi.op_version >= ATH10K_FW_WMI_OP_VERSION_MAX) {
1033 ath10k_err(ar, "unsupported WMI OP version (max %d): %d\n",
1034 ATH10K_FW_WMI_OP_VERSION_MAX, ar->wmi.op_version);
1035 return -EINVAL;
1036 }
1037
1038 /* Backwards compatibility for firmwares without
1039 * ATH10K_FW_IE_WMI_OP_VERSION.
1040 */
1041 if (ar->wmi.op_version == ATH10K_FW_WMI_OP_VERSION_UNSET) {
1042 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02001043 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2,
1044 ar->fw_features))
Kalle Valo202e86e2014-12-03 10:10:08 +02001045 ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_2;
1046 else
1047 ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_1;
1048 } else {
1049 ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_MAIN;
1050 }
1051 }
1052
1053 switch (ar->wmi.op_version) {
1054 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Michal Kaziorcfd10612014-11-25 15:16:05 +01001055 ar->max_num_peers = TARGET_NUM_PEERS;
1056 ar->max_num_stations = TARGET_NUM_STATIONS;
Kalle Valo30c78162014-12-17 12:20:45 +02001057 ar->max_num_vdevs = TARGET_NUM_VDEVS;
Kalle Valo91ad5f52014-12-03 10:10:17 +02001058 ar->htt.max_num_pending_tx = TARGET_NUM_MSDU_DESC;
Yanbo Li6274cd42015-04-01 22:53:21 +03001059 ar->fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV |
1060 WMI_STAT_PEER;
Kalle Valo202e86e2014-12-03 10:10:08 +02001061 break;
1062 case ATH10K_FW_WMI_OP_VERSION_10_1:
1063 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02001064 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo202e86e2014-12-03 10:10:08 +02001065 ar->max_num_peers = TARGET_10X_NUM_PEERS;
1066 ar->max_num_stations = TARGET_10X_NUM_STATIONS;
Kalle Valo30c78162014-12-17 12:20:45 +02001067 ar->max_num_vdevs = TARGET_10X_NUM_VDEVS;
Kalle Valo91ad5f52014-12-03 10:10:17 +02001068 ar->htt.max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC;
Yanbo Li6274cd42015-04-01 22:53:21 +03001069 ar->fw_stats_req_mask = WMI_STAT_PEER;
Kalle Valo202e86e2014-12-03 10:10:08 +02001070 break;
Michal Kaziorca996ec2014-12-03 10:11:32 +02001071 case ATH10K_FW_WMI_OP_VERSION_TLV:
1072 ar->max_num_peers = TARGET_TLV_NUM_PEERS;
1073 ar->max_num_stations = TARGET_TLV_NUM_STATIONS;
Michal Kazior49274332015-01-08 11:36:56 +01001074 ar->max_num_vdevs = TARGET_TLV_NUM_VDEVS;
Marek Puzyniak8cca3d62015-03-30 09:51:52 +03001075 ar->max_num_tdls_vdevs = TARGET_TLV_NUM_TDLS_VDEVS;
Michal Kaziorca996ec2014-12-03 10:11:32 +02001076 ar->htt.max_num_pending_tx = TARGET_TLV_NUM_MSDU_DESC;
Janusz Dziedzic25c86612015-03-23 17:32:54 +02001077 ar->wow.max_num_patterns = TARGET_TLV_NUM_WOW_PATTERNS;
Yanbo Li6274cd42015-04-01 22:53:21 +03001078 ar->fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV |
1079 WMI_STAT_PEER;
Michal Kaziorca996ec2014-12-03 10:11:32 +02001080 break;
Kalle Valo202e86e2014-12-03 10:10:08 +02001081 case ATH10K_FW_WMI_OP_VERSION_UNSET:
1082 case ATH10K_FW_WMI_OP_VERSION_MAX:
1083 WARN_ON(1);
1084 return -EINVAL;
Michal Kaziorcfd10612014-11-25 15:16:05 +01001085 }
Kalle Valo5f2144d2014-12-03 10:09:59 +02001086
Kalle Valodc3632a2015-03-30 14:14:28 +03001087 /* Backwards compatibility for firmwares without
1088 * ATH10K_FW_IE_HTT_OP_VERSION.
1089 */
1090 if (ar->htt.op_version == ATH10K_FW_HTT_OP_VERSION_UNSET) {
1091 switch (ar->wmi.op_version) {
1092 case ATH10K_FW_WMI_OP_VERSION_MAIN:
1093 ar->htt.op_version = ATH10K_FW_HTT_OP_VERSION_MAIN;
1094 break;
1095 case ATH10K_FW_WMI_OP_VERSION_10_1:
1096 case ATH10K_FW_WMI_OP_VERSION_10_2:
1097 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
1098 ar->htt.op_version = ATH10K_FW_HTT_OP_VERSION_10_1;
1099 break;
1100 case ATH10K_FW_WMI_OP_VERSION_TLV:
1101 ar->htt.op_version = ATH10K_FW_HTT_OP_VERSION_TLV;
1102 break;
1103 case ATH10K_FW_WMI_OP_VERSION_UNSET:
1104 case ATH10K_FW_WMI_OP_VERSION_MAX:
1105 WARN_ON(1);
1106 return -EINVAL;
1107 }
1108 }
1109
Kalle Valo5f2144d2014-12-03 10:09:59 +02001110 return 0;
Michal Kaziorcfd10612014-11-25 15:16:05 +01001111}
1112
Kalle Valo43d2a302014-09-10 18:23:30 +03001113int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001114{
Kalle Valo5e3dd152013-06-12 20:52:10 +03001115 int status;
1116
Kalle Valo60631c52013-10-08 21:45:25 +03001117 lockdep_assert_held(&ar->conf_mutex);
1118
Michal Kazior7962b0d2014-10-28 10:34:38 +01001119 clear_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);
1120
Michal Kazior64d151d2013-07-16 09:38:53 +02001121 ath10k_bmi_start(ar);
1122
Kalle Valo5e3dd152013-06-12 20:52:10 +03001123 if (ath10k_init_configure_target(ar)) {
1124 status = -EINVAL;
1125 goto err;
1126 }
1127
Kalle Valo83091552014-10-13 09:40:53 +03001128 status = ath10k_download_cal_data(ar);
1129 if (status)
1130 goto err;
1131
Rajkumar Manoharan163f5262015-05-29 17:51:53 +03001132 /* Some of of qca988x solutions are having global reset issue
1133 * during target initialization. Bypassing PLL setting before
1134 * downloading firmware and letting the SoC run on REF_CLK is
1135 * fixing the problem. Corresponding firmware change is also needed
1136 * to set the clock source once the target is initialized.
1137 */
1138 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT,
1139 ar->fw_features)) {
1140 status = ath10k_bmi_write32(ar, hi_skip_clock_init, 1);
1141 if (status) {
1142 ath10k_err(ar, "could not write to skip_clock_init: %d\n",
1143 status);
1144 goto err;
1145 }
1146 }
1147
Kalle Valo83091552014-10-13 09:40:53 +03001148 status = ath10k_download_fw(ar, mode);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001149 if (status)
1150 goto err;
1151
1152 status = ath10k_init_uart(ar);
1153 if (status)
1154 goto err;
1155
Michal Kaziorcd003fa2013-07-05 16:15:13 +03001156 ar->htc.htc_ops.target_send_suspend_complete =
1157 ath10k_send_suspend_complete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001158
Michal Kaziorcd003fa2013-07-05 16:15:13 +03001159 status = ath10k_htc_init(ar);
1160 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001161 ath10k_err(ar, "could not init HTC (%d)\n", status);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001162 goto err;
1163 }
1164
1165 status = ath10k_bmi_done(ar);
1166 if (status)
Michal Kaziorcd003fa2013-07-05 16:15:13 +03001167 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001168
1169 status = ath10k_wmi_attach(ar);
1170 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001171 ath10k_err(ar, "WMI attach failed: %d\n", status);
Michal Kaziorcd003fa2013-07-05 16:15:13 +03001172 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001173 }
1174
Michal Kazior95bf21f2014-05-16 17:15:39 +03001175 status = ath10k_htt_init(ar);
1176 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001177 ath10k_err(ar, "failed to init htt: %d\n", status);
Michal Kazior95bf21f2014-05-16 17:15:39 +03001178 goto err_wmi_detach;
1179 }
1180
1181 status = ath10k_htt_tx_alloc(&ar->htt);
1182 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001183 ath10k_err(ar, "failed to alloc htt tx: %d\n", status);
Michal Kazior95bf21f2014-05-16 17:15:39 +03001184 goto err_wmi_detach;
1185 }
1186
1187 status = ath10k_htt_rx_alloc(&ar->htt);
1188 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001189 ath10k_err(ar, "failed to alloc htt rx: %d\n", status);
Michal Kazior95bf21f2014-05-16 17:15:39 +03001190 goto err_htt_tx_detach;
1191 }
1192
Michal Kazior67e3c632013-11-08 08:05:18 +01001193 status = ath10k_hif_start(ar);
1194 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001195 ath10k_err(ar, "could not start HIF: %d\n", status);
Michal Kazior95bf21f2014-05-16 17:15:39 +03001196 goto err_htt_rx_detach;
Michal Kazior67e3c632013-11-08 08:05:18 +01001197 }
1198
1199 status = ath10k_htc_wait_target(&ar->htc);
1200 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001201 ath10k_err(ar, "failed to connect to HTC: %d\n", status);
Michal Kazior67e3c632013-11-08 08:05:18 +01001202 goto err_hif_stop;
1203 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001204
Kalle Valo43d2a302014-09-10 18:23:30 +03001205 if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
1206 status = ath10k_htt_connect(&ar->htt);
1207 if (status) {
1208 ath10k_err(ar, "failed to connect htt (%d)\n", status);
1209 goto err_hif_stop;
1210 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001211 }
1212
Michal Kazior95bf21f2014-05-16 17:15:39 +03001213 status = ath10k_wmi_connect(ar);
1214 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001215 ath10k_err(ar, "could not connect wmi: %d\n", status);
Michal Kazior95bf21f2014-05-16 17:15:39 +03001216 goto err_hif_stop;
1217 }
1218
1219 status = ath10k_htc_start(&ar->htc);
1220 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001221 ath10k_err(ar, "failed to start htc: %d\n", status);
Michal Kazior95bf21f2014-05-16 17:15:39 +03001222 goto err_hif_stop;
1223 }
1224
Kalle Valo43d2a302014-09-10 18:23:30 +03001225 if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
1226 status = ath10k_wmi_wait_for_service_ready(ar);
Nicholas Mc Guire9eea5682015-03-30 15:39:21 +03001227 if (status) {
Kalle Valo43d2a302014-09-10 18:23:30 +03001228 ath10k_warn(ar, "wmi service ready event not received");
Kalle Valo43d2a302014-09-10 18:23:30 +03001229 goto err_hif_stop;
1230 }
Michal Kazior95bf21f2014-05-16 17:15:39 +03001231 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001232
Michal Kazior7aa7a722014-08-25 12:09:38 +02001233 ath10k_dbg(ar, ATH10K_DBG_BOOT, "firmware %s booted\n",
Kalle Valoc8c39af2013-11-20 10:00:41 +02001234 ar->hw->wiphy->fw_version);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001235
Kalle Valo5e3dd152013-06-12 20:52:10 +03001236 status = ath10k_wmi_cmd_init(ar);
1237 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001238 ath10k_err(ar, "could not send WMI init command (%d)\n",
1239 status);
Michal Kaziorb7967dc2014-08-07 11:03:31 +02001240 goto err_hif_stop;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001241 }
1242
1243 status = ath10k_wmi_wait_for_unified_ready(ar);
Nicholas Mc Guire9eea5682015-03-30 15:39:21 +03001244 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001245 ath10k_err(ar, "wmi unified ready event not received\n");
Michal Kaziorb7967dc2014-08-07 11:03:31 +02001246 goto err_hif_stop;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001247 }
1248
Michal Kaziorc5450702015-01-24 12:14:48 +02001249 /* If firmware indicates Full Rx Reorder support it must be used in a
1250 * slightly different manner. Let HTT code know.
1251 */
1252 ar->htt.rx_ring.in_ord_rx = !!(test_bit(WMI_SERVICE_RX_FULL_REORDER,
1253 ar->wmi.svc_map));
1254
1255 status = ath10k_htt_rx_ring_refill(ar);
1256 if (status) {
1257 ath10k_err(ar, "failed to refill htt rx ring: %d\n", status);
1258 goto err_hif_stop;
1259 }
1260
Kalle Valo43d2a302014-09-10 18:23:30 +03001261 /* we don't care about HTT in UTF mode */
1262 if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
1263 status = ath10k_htt_setup(&ar->htt);
1264 if (status) {
1265 ath10k_err(ar, "failed to setup htt: %d\n", status);
1266 goto err_hif_stop;
1267 }
Michal Kazior95bf21f2014-05-16 17:15:39 +03001268 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001269
Kalle Valodb66ea02013-09-03 11:44:03 +03001270 status = ath10k_debug_start(ar);
1271 if (status)
Michal Kaziorb7967dc2014-08-07 11:03:31 +02001272 goto err_hif_stop;
Kalle Valodb66ea02013-09-03 11:44:03 +03001273
Kalle Valo30c78162014-12-17 12:20:45 +02001274 ar->free_vdev_map = (1LL << ar->max_num_vdevs) - 1;
Bartosz Markowskidfa413d2014-06-02 21:19:45 +03001275
Michal Kazior05791192013-10-16 15:44:45 +03001276 INIT_LIST_HEAD(&ar->arvifs);
Michal Kazior1a1b8a82013-07-16 09:38:55 +02001277
Michal Kaziordd30a362013-07-16 09:38:51 +02001278 return 0;
1279
Michal Kazior67e3c632013-11-08 08:05:18 +01001280err_hif_stop:
1281 ath10k_hif_stop(ar);
Michal Kazior95bf21f2014-05-16 17:15:39 +03001282err_htt_rx_detach:
1283 ath10k_htt_rx_free(&ar->htt);
1284err_htt_tx_detach:
1285 ath10k_htt_tx_free(&ar->htt);
Michal Kaziordd30a362013-07-16 09:38:51 +02001286err_wmi_detach:
1287 ath10k_wmi_detach(ar);
1288err:
1289 return status;
1290}
Michal Kazior818bdd12013-07-16 09:38:57 +02001291EXPORT_SYMBOL(ath10k_core_start);
Michal Kaziordd30a362013-07-16 09:38:51 +02001292
Marek Puzyniak00f54822014-02-10 17:14:24 +01001293int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt)
1294{
1295 int ret;
Nicholas Mc Guirea7a42842015-03-30 15:39:21 +03001296 unsigned long time_left;
Marek Puzyniak00f54822014-02-10 17:14:24 +01001297
1298 reinit_completion(&ar->target_suspend);
1299
1300 ret = ath10k_wmi_pdev_suspend_target(ar, suspend_opt);
1301 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001302 ath10k_warn(ar, "could not suspend target (%d)\n", ret);
Marek Puzyniak00f54822014-02-10 17:14:24 +01001303 return ret;
1304 }
1305
Nicholas Mc Guirea7a42842015-03-30 15:39:21 +03001306 time_left = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ);
Marek Puzyniak00f54822014-02-10 17:14:24 +01001307
Nicholas Mc Guirea7a42842015-03-30 15:39:21 +03001308 if (!time_left) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001309 ath10k_warn(ar, "suspend timed out - target pause event never came\n");
Marek Puzyniak00f54822014-02-10 17:14:24 +01001310 return -ETIMEDOUT;
1311 }
1312
1313 return 0;
1314}
1315
Michal Kaziordd30a362013-07-16 09:38:51 +02001316void ath10k_core_stop(struct ath10k *ar)
1317{
Kalle Valo60631c52013-10-08 21:45:25 +03001318 lockdep_assert_held(&ar->conf_mutex);
1319
Marek Puzyniak00f54822014-02-10 17:14:24 +01001320 /* try to suspend target */
Kalle Valo43d2a302014-09-10 18:23:30 +03001321 if (ar->state != ATH10K_STATE_RESTARTING &&
1322 ar->state != ATH10K_STATE_UTF)
Michal Kazior216a1832014-04-23 19:30:04 +03001323 ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
1324
Kalle Valodb66ea02013-09-03 11:44:03 +03001325 ath10k_debug_stop(ar);
Michal Kazior95bf21f2014-05-16 17:15:39 +03001326 ath10k_hif_stop(ar);
1327 ath10k_htt_tx_free(&ar->htt);
1328 ath10k_htt_rx_free(&ar->htt);
Michal Kaziordd30a362013-07-16 09:38:51 +02001329 ath10k_wmi_detach(ar);
1330}
Michal Kazior818bdd12013-07-16 09:38:57 +02001331EXPORT_SYMBOL(ath10k_core_stop);
1332
1333/* mac80211 manages fw/hw initialization through start/stop hooks. However in
1334 * order to know what hw capabilities should be advertised to mac80211 it is
1335 * necessary to load the firmware (and tear it down immediately since start
1336 * hook will try to init it again) before registering */
1337static int ath10k_core_probe_fw(struct ath10k *ar)
1338{
Michal Kazior29385052013-07-16 09:38:58 +02001339 struct bmi_target_info target_info;
1340 int ret = 0;
Michal Kazior818bdd12013-07-16 09:38:57 +02001341
1342 ret = ath10k_hif_power_up(ar);
1343 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001344 ath10k_err(ar, "could not start pci hif (%d)\n", ret);
Michal Kazior818bdd12013-07-16 09:38:57 +02001345 return ret;
1346 }
1347
Michal Kazior29385052013-07-16 09:38:58 +02001348 memset(&target_info, 0, sizeof(target_info));
1349 ret = ath10k_bmi_get_target_info(ar, &target_info);
1350 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001351 ath10k_err(ar, "could not get target info (%d)\n", ret);
Kalle Valoc6ce4922014-12-03 10:09:31 +02001352 goto err_power_down;
Michal Kazior29385052013-07-16 09:38:58 +02001353 }
1354
1355 ar->target_version = target_info.version;
1356 ar->hw->wiphy->hw_version = target_info.version;
1357
1358 ret = ath10k_init_hw_params(ar);
1359 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001360 ath10k_err(ar, "could not get hw params (%d)\n", ret);
Kalle Valoc6ce4922014-12-03 10:09:31 +02001361 goto err_power_down;
Michal Kazior29385052013-07-16 09:38:58 +02001362 }
1363
1364 ret = ath10k_core_fetch_firmware_files(ar);
1365 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001366 ath10k_err(ar, "could not fetch firmware files (%d)\n", ret);
Kalle Valoc6ce4922014-12-03 10:09:31 +02001367 goto err_power_down;
Michal Kazior29385052013-07-16 09:38:58 +02001368 }
1369
Kalle Valo5f2144d2014-12-03 10:09:59 +02001370 ret = ath10k_core_init_firmware_features(ar);
1371 if (ret) {
1372 ath10k_err(ar, "fatal problem with firmware features: %d\n",
1373 ret);
1374 goto err_free_firmware_files;
1375 }
Michal Kaziorcfd10612014-11-25 15:16:05 +01001376
Kalle Valo60631c52013-10-08 21:45:25 +03001377 mutex_lock(&ar->conf_mutex);
1378
Kalle Valo43d2a302014-09-10 18:23:30 +03001379 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
Michal Kazior818bdd12013-07-16 09:38:57 +02001380 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001381 ath10k_err(ar, "could not init core (%d)\n", ret);
Kalle Valoc6ce4922014-12-03 10:09:31 +02001382 goto err_unlock;
Michal Kazior818bdd12013-07-16 09:38:57 +02001383 }
1384
Michal Kazior8079de02014-08-22 14:23:29 +02001385 ath10k_print_driver_info(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02001386 ath10k_core_stop(ar);
Kalle Valo60631c52013-10-08 21:45:25 +03001387
1388 mutex_unlock(&ar->conf_mutex);
1389
Michal Kazior818bdd12013-07-16 09:38:57 +02001390 ath10k_hif_power_down(ar);
1391 return 0;
Kalle Valoc6ce4922014-12-03 10:09:31 +02001392
1393err_unlock:
1394 mutex_unlock(&ar->conf_mutex);
1395
Kalle Valo5f2144d2014-12-03 10:09:59 +02001396err_free_firmware_files:
Kalle Valoc6ce4922014-12-03 10:09:31 +02001397 ath10k_core_free_firmware_files(ar);
1398
1399err_power_down:
1400 ath10k_hif_power_down(ar);
1401
1402 return ret;
Michal Kazior818bdd12013-07-16 09:38:57 +02001403}
Michal Kaziordd30a362013-07-16 09:38:51 +02001404
Michal Kazior6782cb62014-05-23 12:28:47 +02001405static void ath10k_core_register_work(struct work_struct *work)
Michal Kaziordd30a362013-07-16 09:38:51 +02001406{
Michal Kazior6782cb62014-05-23 12:28:47 +02001407 struct ath10k *ar = container_of(work, struct ath10k, register_work);
Michal Kaziordd30a362013-07-16 09:38:51 +02001408 int status;
1409
Michal Kazior818bdd12013-07-16 09:38:57 +02001410 status = ath10k_core_probe_fw(ar);
1411 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001412 ath10k_err(ar, "could not probe fw (%d)\n", status);
Michal Kazior6782cb62014-05-23 12:28:47 +02001413 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02001414 }
Michal Kaziordd30a362013-07-16 09:38:51 +02001415
Kalle Valo5e3dd152013-06-12 20:52:10 +03001416 status = ath10k_mac_register(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02001417 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001418 ath10k_err(ar, "could not register to mac80211 (%d)\n", status);
Michal Kazior29385052013-07-16 09:38:58 +02001419 goto err_release_fw;
Michal Kazior818bdd12013-07-16 09:38:57 +02001420 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001421
Michal Kaziore13cf7a2014-09-04 09:13:08 +02001422 status = ath10k_debug_register(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001423 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001424 ath10k_err(ar, "unable to initialize debugfs\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03001425 goto err_unregister_mac;
1426 }
1427
Simon Wunderlich855aed12014-08-02 09:12:54 +03001428 status = ath10k_spectral_create(ar);
1429 if (status) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001430 ath10k_err(ar, "failed to initialize spectral\n");
Simon Wunderlich855aed12014-08-02 09:12:54 +03001431 goto err_debug_destroy;
1432 }
1433
Rajkumar Manoharanfe6f36d2014-12-17 12:22:07 +02001434 status = ath10k_thermal_register(ar);
1435 if (status) {
1436 ath10k_err(ar, "could not register thermal device: %d\n",
1437 status);
1438 goto err_spectral_destroy;
1439 }
1440
Michal Kazior6782cb62014-05-23 12:28:47 +02001441 set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);
1442 return;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001443
Rajkumar Manoharanfe6f36d2014-12-17 12:22:07 +02001444err_spectral_destroy:
1445 ath10k_spectral_destroy(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03001446err_debug_destroy:
1447 ath10k_debug_destroy(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001448err_unregister_mac:
1449 ath10k_mac_unregister(ar);
Michal Kazior29385052013-07-16 09:38:58 +02001450err_release_fw:
1451 ath10k_core_free_firmware_files(ar);
Michal Kazior6782cb62014-05-23 12:28:47 +02001452err:
Michal Kaziora491a922014-07-14 16:07:29 +03001453 /* TODO: It's probably a good idea to release device from the driver
1454 * but calling device_release_driver() here will cause a deadlock.
1455 */
Michal Kazior6782cb62014-05-23 12:28:47 +02001456 return;
1457}
1458
1459int ath10k_core_register(struct ath10k *ar, u32 chip_id)
1460{
Michal Kazior6782cb62014-05-23 12:28:47 +02001461 ar->chip_id = chip_id;
Michal Kazior6782cb62014-05-23 12:28:47 +02001462 queue_work(ar->workqueue, &ar->register_work);
1463
1464 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001465}
1466EXPORT_SYMBOL(ath10k_core_register);
1467
1468void ath10k_core_unregister(struct ath10k *ar)
1469{
Michal Kazior6782cb62014-05-23 12:28:47 +02001470 cancel_work_sync(&ar->register_work);
1471
1472 if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
1473 return;
1474
Rajkumar Manoharanfe6f36d2014-12-17 12:22:07 +02001475 ath10k_thermal_unregister(ar);
Simon Wunderlich804eef1472014-08-12 17:12:17 +02001476 /* Stop spectral before unregistering from mac80211 to remove the
1477 * relayfs debugfs file cleanly. Otherwise the parent debugfs tree
1478 * would be already be free'd recursively, leading to a double free.
1479 */
1480 ath10k_spectral_destroy(ar);
1481
Kalle Valo5e3dd152013-06-12 20:52:10 +03001482 /* We must unregister from mac80211 before we stop HTC and HIF.
1483 * Otherwise we will fail to submit commands to FW and mac80211 will be
1484 * unhappy about callback failures. */
1485 ath10k_mac_unregister(ar);
Kalle Valodb66ea02013-09-03 11:44:03 +03001486
Kalle Valo43d2a302014-09-10 18:23:30 +03001487 ath10k_testmode_destroy(ar);
1488
Michal Kazior29385052013-07-16 09:38:58 +02001489 ath10k_core_free_firmware_files(ar);
Ben Greear6f1f56e2013-11-04 09:18:16 -08001490
Michal Kaziore13cf7a2014-09-04 09:13:08 +02001491 ath10k_debug_unregister(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001492}
1493EXPORT_SYMBOL(ath10k_core_unregister);
1494
Michal Kaziore7b54192014-08-07 11:03:27 +02001495struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
Kalle Valoe07db352014-10-13 09:40:47 +03001496 enum ath10k_bus bus,
Michal Kaziord63955b2015-01-24 12:14:49 +02001497 enum ath10k_hw_rev hw_rev,
Michal Kazior0d0a6932014-05-23 12:28:45 +02001498 const struct ath10k_hif_ops *hif_ops)
1499{
1500 struct ath10k *ar;
Michal Kaziore13cf7a2014-09-04 09:13:08 +02001501 int ret;
Michal Kazior0d0a6932014-05-23 12:28:45 +02001502
Michal Kaziore7b54192014-08-07 11:03:27 +02001503 ar = ath10k_mac_create(priv_size);
Michal Kazior0d0a6932014-05-23 12:28:45 +02001504 if (!ar)
1505 return NULL;
1506
1507 ar->ath_common.priv = ar;
1508 ar->ath_common.hw = ar->hw;
Michal Kazior0d0a6932014-05-23 12:28:45 +02001509 ar->dev = dev;
Michal Kaziord63955b2015-01-24 12:14:49 +02001510 ar->hw_rev = hw_rev;
Michal Kazior0d0a6932014-05-23 12:28:45 +02001511 ar->hif.ops = hif_ops;
Kalle Valoe07db352014-10-13 09:40:47 +03001512 ar->hif.bus = bus;
Michal Kazior0d0a6932014-05-23 12:28:45 +02001513
Michal Kaziord63955b2015-01-24 12:14:49 +02001514 switch (hw_rev) {
1515 case ATH10K_HW_QCA988X:
1516 ar->regs = &qca988x_regs;
1517 break;
1518 case ATH10K_HW_QCA6174:
1519 ar->regs = &qca6174_regs;
1520 break;
1521 default:
1522 ath10k_err(ar, "unsupported core hardware revision %d\n",
1523 hw_rev);
1524 ret = -ENOTSUPP;
1525 goto err_free_mac;
1526 }
1527
Michal Kazior0d0a6932014-05-23 12:28:45 +02001528 init_completion(&ar->scan.started);
1529 init_completion(&ar->scan.completed);
1530 init_completion(&ar->scan.on_channel);
1531 init_completion(&ar->target_suspend);
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02001532 init_completion(&ar->wow.wakeup_completed);
Michal Kazior0d0a6932014-05-23 12:28:45 +02001533
1534 init_completion(&ar->install_key_done);
1535 init_completion(&ar->vdev_setup_done);
Rajkumar Manoharanac2953f2014-12-17 12:22:26 +02001536 init_completion(&ar->thermal.wmi_sync);
Michal Kazior0d0a6932014-05-23 12:28:45 +02001537
Michal Kazior5c81c7f2014-08-05 14:54:44 +02001538 INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work);
Michal Kazior0d0a6932014-05-23 12:28:45 +02001539
1540 ar->workqueue = create_singlethread_workqueue("ath10k_wq");
1541 if (!ar->workqueue)
Michal Kaziore13cf7a2014-09-04 09:13:08 +02001542 goto err_free_mac;
Michal Kazior0d0a6932014-05-23 12:28:45 +02001543
1544 mutex_init(&ar->conf_mutex);
1545 spin_lock_init(&ar->data_lock);
1546
1547 INIT_LIST_HEAD(&ar->peers);
1548 init_waitqueue_head(&ar->peer_mapping_wq);
Michal Kazior7962b0d2014-10-28 10:34:38 +01001549 init_waitqueue_head(&ar->htt.empty_tx_wq);
1550 init_waitqueue_head(&ar->wmi.tx_credits_wq);
Michal Kazior0d0a6932014-05-23 12:28:45 +02001551
1552 init_completion(&ar->offchan_tx_completed);
1553 INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work);
1554 skb_queue_head_init(&ar->offchan_tx_queue);
1555
1556 INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work);
1557 skb_queue_head_init(&ar->wmi_mgmt_tx_queue);
1558
Michal Kazior6782cb62014-05-23 12:28:47 +02001559 INIT_WORK(&ar->register_work, ath10k_core_register_work);
Michal Kazior0d0a6932014-05-23 12:28:45 +02001560 INIT_WORK(&ar->restart_work, ath10k_core_restart);
1561
Michal Kaziore13cf7a2014-09-04 09:13:08 +02001562 ret = ath10k_debug_create(ar);
1563 if (ret)
1564 goto err_free_wq;
1565
Michal Kazior0d0a6932014-05-23 12:28:45 +02001566 return ar;
1567
Michal Kaziore13cf7a2014-09-04 09:13:08 +02001568err_free_wq:
1569 destroy_workqueue(ar->workqueue);
1570
1571err_free_mac:
Michal Kazior0d0a6932014-05-23 12:28:45 +02001572 ath10k_mac_destroy(ar);
Michal Kaziore13cf7a2014-09-04 09:13:08 +02001573
Michal Kazior0d0a6932014-05-23 12:28:45 +02001574 return NULL;
1575}
1576EXPORT_SYMBOL(ath10k_core_create);
1577
1578void ath10k_core_destroy(struct ath10k *ar)
1579{
1580 flush_workqueue(ar->workqueue);
1581 destroy_workqueue(ar->workqueue);
1582
Michal Kaziore13cf7a2014-09-04 09:13:08 +02001583 ath10k_debug_destroy(ar);
Michal Kazior0d0a6932014-05-23 12:28:45 +02001584 ath10k_mac_destroy(ar);
1585}
1586EXPORT_SYMBOL(ath10k_core_destroy);
1587
Kalle Valo5e3dd152013-06-12 20:52:10 +03001588MODULE_AUTHOR("Qualcomm Atheros");
1589MODULE_DESCRIPTION("Core module for QCA988X PCIe devices.");
1590MODULE_LICENSE("Dual BSD/GPL");