core.c 50.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * Copyright (c) 2005-2011 Atheros Communications Inc.
 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <linux/module.h>
#include <linux/firmware.h>
20
#include <linux/of.h>
21 22 23 24 25 26 27 28 29

#include "core.h"
#include "mac.h"
#include "htc.h"
#include "hif.h"
#include "wmi.h"
#include "bmi.h"
#include "debug.h"
#include "htt.h"
K
Kalle Valo 已提交
30
#include "testmode.h"
M
Michal Kazior 已提交
31
#include "wmi-ops.h"
32 33

unsigned int ath10k_debug_mask;
34
static unsigned int ath10k_cryptmode_param;
35
static bool uart_print;
36
static bool skip_otp;
B
Bob Copeland 已提交
37
static bool rawmode;
38

39
module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
40
module_param_named(cryptmode, ath10k_cryptmode_param, uint, 0644);
41
module_param(uart_print, bool, 0644);
42
module_param(skip_otp, bool, 0644);
B
Bob Copeland 已提交
43
module_param(rawmode, bool, 0644);
44

45 46
MODULE_PARM_DESC(debug_mask, "Debugging mask");
MODULE_PARM_DESC(uart_print, "Uart target debugging");
47
MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
48
MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software");
B
Bob Copeland 已提交
49
MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath");
50 51 52 53

static const struct ath10k_hw_params ath10k_hw_params_list[] = {
	{
		.id = QCA988X_HW_2_0_VERSION,
54
		.dev_id = QCA988X_2_0_DEVICE_ID,
55 56
		.name = "qca988x hw2.0",
		.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
57
		.uart_pin = 7,
58
		.has_shifted_cc_wraparound = true,
59
		.otp_exe_param = 0,
60
		.channel_counters_freq_hz = 88000,
61
		.max_probe_resp_desc_thres = 0,
62
		.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
63 64 65 66 67
		.fw = {
			.dir = QCA988X_HW_2_0_FW_DIR,
			.fw = QCA988X_HW_2_0_FW_FILE,
			.otp = QCA988X_HW_2_0_OTP_FILE,
			.board = QCA988X_HW_2_0_BOARD_DATA_FILE,
68 69
			.board_size = QCA988X_BOARD_DATA_SZ,
			.board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
70 71
		},
	},
M
Michal Kazior 已提交
72 73
	{
		.id = QCA6174_HW_2_1_VERSION,
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
		.dev_id = QCA6164_2_1_DEVICE_ID,
		.name = "qca6164 hw2.1",
		.patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
		.uart_pin = 6,
		.otp_exe_param = 0,
		.channel_counters_freq_hz = 88000,
		.max_probe_resp_desc_thres = 0,
		.fw = {
			.dir = QCA6174_HW_2_1_FW_DIR,
			.fw = QCA6174_HW_2_1_FW_FILE,
			.otp = QCA6174_HW_2_1_OTP_FILE,
			.board = QCA6174_HW_2_1_BOARD_DATA_FILE,
			.board_size = QCA6174_BOARD_DATA_SZ,
			.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
		},
	},
	{
		.id = QCA6174_HW_2_1_VERSION,
		.dev_id = QCA6174_2_1_DEVICE_ID,
M
Michal Kazior 已提交
93 94 95
		.name = "qca6174 hw2.1",
		.patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
		.uart_pin = 6,
96
		.otp_exe_param = 0,
97
		.channel_counters_freq_hz = 88000,
98
		.max_probe_resp_desc_thres = 0,
99
		.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
M
Michal Kazior 已提交
100 101 102 103 104 105 106 107 108 109 110
		.fw = {
			.dir = QCA6174_HW_2_1_FW_DIR,
			.fw = QCA6174_HW_2_1_FW_FILE,
			.otp = QCA6174_HW_2_1_OTP_FILE,
			.board = QCA6174_HW_2_1_BOARD_DATA_FILE,
			.board_size = QCA6174_BOARD_DATA_SZ,
			.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
		},
	},
	{
		.id = QCA6174_HW_3_0_VERSION,
111
		.dev_id = QCA6174_2_1_DEVICE_ID,
M
Michal Kazior 已提交
112 113 114
		.name = "qca6174 hw3.0",
		.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
		.uart_pin = 6,
115
		.otp_exe_param = 0,
116
		.channel_counters_freq_hz = 88000,
117
		.max_probe_resp_desc_thres = 0,
118
		.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
M
Michal Kazior 已提交
119 120 121 122 123 124 125 126 127
		.fw = {
			.dir = QCA6174_HW_3_0_FW_DIR,
			.fw = QCA6174_HW_3_0_FW_FILE,
			.otp = QCA6174_HW_3_0_OTP_FILE,
			.board = QCA6174_HW_3_0_BOARD_DATA_FILE,
			.board_size = QCA6174_BOARD_DATA_SZ,
			.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
		},
	},
M
Michal Kazior 已提交
128 129
	{
		.id = QCA6174_HW_3_2_VERSION,
130
		.dev_id = QCA6174_2_1_DEVICE_ID,
M
Michal Kazior 已提交
131 132 133
		.name = "qca6174 hw3.2",
		.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
		.uart_pin = 6,
134
		.otp_exe_param = 0,
135
		.channel_counters_freq_hz = 88000,
136
		.max_probe_resp_desc_thres = 0,
137
		.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
M
Michal Kazior 已提交
138 139 140 141 142 143 144 145 146 147
		.fw = {
			/* uses same binaries as hw3.0 */
			.dir = QCA6174_HW_3_0_FW_DIR,
			.fw = QCA6174_HW_3_0_FW_FILE,
			.otp = QCA6174_HW_3_0_OTP_FILE,
			.board = QCA6174_HW_3_0_BOARD_DATA_FILE,
			.board_size = QCA6174_BOARD_DATA_SZ,
			.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
		},
	},
148 149
	{
		.id = QCA99X0_HW_2_0_DEV_VERSION,
150
		.dev_id = QCA99X0_2_0_DEVICE_ID,
151 152 153
		.name = "qca99x0 hw2.0",
		.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
		.uart_pin = 7,
154
		.otp_exe_param = 0x00000700,
155
		.continuous_frag_desc = true,
156
		.channel_counters_freq_hz = 150000,
157
		.max_probe_resp_desc_thres = 24,
158
		.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
159 160 161 162 163 164 165 166 167
		.fw = {
			.dir = QCA99X0_HW_2_0_FW_DIR,
			.fw = QCA99X0_HW_2_0_FW_FILE,
			.otp = QCA99X0_HW_2_0_OTP_FILE,
			.board = QCA99X0_HW_2_0_BOARD_DATA_FILE,
			.board_size = QCA99X0_BOARD_DATA_SZ,
			.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
		},
	},
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
	{
		.id = QCA9377_HW_1_0_DEV_VERSION,
		.dev_id = QCA9377_1_0_DEVICE_ID,
		.name = "qca9377 hw1.0",
		.patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,
		.uart_pin = 6,
		.otp_exe_param = 0,
		.channel_counters_freq_hz = 88000,
		.max_probe_resp_desc_thres = 0,
		.fw = {
			.dir = QCA9377_HW_1_0_FW_DIR,
			.fw = QCA9377_HW_1_0_FW_FILE,
			.otp = QCA9377_HW_1_0_OTP_FILE,
			.board = QCA9377_HW_1_0_BOARD_DATA_FILE,
			.board_size = QCA9377_BOARD_DATA_SZ,
			.board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
		},
	},
186
	{
187
		.id = QCA9377_HW_1_1_DEV_VERSION,
188
		.dev_id = QCA9377_1_0_DEVICE_ID,
189
		.name = "qca9377 hw1.1",
190
		.patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,
191
		.uart_pin = 6,
192
		.otp_exe_param = 0,
193 194
		.channel_counters_freq_hz = 88000,
		.max_probe_resp_desc_thres = 0,
195 196 197 198 199 200 201 202 203
		.fw = {
			.dir = QCA9377_HW_1_0_FW_DIR,
			.fw = QCA9377_HW_1_0_FW_FILE,
			.otp = QCA9377_HW_1_0_OTP_FILE,
			.board = QCA9377_HW_1_0_BOARD_DATA_FILE,
			.board_size = QCA9377_BOARD_DATA_SZ,
			.board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
		},
	},
204 205
};

206 207 208 209 210 211 212 213 214 215 216
static const char *const ath10k_core_fw_feature_str[] = {
	[ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX] = "wmi-mgmt-rx",
	[ATH10K_FW_FEATURE_WMI_10X] = "wmi-10.x",
	[ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX] = "has-wmi-mgmt-tx",
	[ATH10K_FW_FEATURE_NO_P2P] = "no-p2p",
	[ATH10K_FW_FEATURE_WMI_10_2] = "wmi-10.2",
	[ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT] = "multi-vif-ps",
	[ATH10K_FW_FEATURE_WOWLAN_SUPPORT] = "wowlan",
	[ATH10K_FW_FEATURE_IGNORE_OTP_RESULT] = "ignore-otp",
	[ATH10K_FW_FEATURE_NO_NWIFI_DECAP_4ADDR_PADDING] = "no-4addr-pad",
	[ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT] = "skip-clock-init",
217
	[ATH10K_FW_FEATURE_RAW_MODE_SUPPORT] = "raw-mode",
M
Maharaja 已提交
218
	[ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA] = "adaptive-cca",
219
	[ATH10K_FW_FEATURE_MFP_SUPPORT] = "mfp",
220
	[ATH10K_FW_FEATURE_PEER_FLOW_CONTROL] = "peer-flow-ctrl",
221 222 223 224 225 226
};

static unsigned int ath10k_core_get_fw_feature_str(char *buf,
						   size_t buf_len,
						   enum ath10k_fw_features feat)
{
227 228 229 230
	/* make sure that ath10k_core_fw_feature_str[] gets updated */
	BUILD_BUG_ON(ARRAY_SIZE(ath10k_core_fw_feature_str) !=
		     ATH10K_FW_FEATURE_COUNT);

231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
	if (feat >= ARRAY_SIZE(ath10k_core_fw_feature_str) ||
	    WARN_ON(!ath10k_core_fw_feature_str[feat])) {
		return scnprintf(buf, buf_len, "bit%d", feat);
	}

	return scnprintf(buf, buf_len, "%s", ath10k_core_fw_feature_str[feat]);
}

void ath10k_core_get_fw_features_str(struct ath10k *ar,
				     char *buf,
				     size_t buf_len)
{
	unsigned int len = 0;
	int i;

	for (i = 0; i < ATH10K_FW_FEATURE_COUNT; i++) {
		if (test_bit(i, ar->fw_features)) {
			if (len > 0)
				len += scnprintf(buf + len, buf_len - len, ",");

			len += ath10k_core_get_fw_feature_str(buf + len,
							      buf_len - len,
							      i);
		}
	}
}

258 259
static void ath10k_send_suspend_complete(struct ath10k *ar)
{
260
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot suspend complete\n");
261

262
	complete(&ar->target_suspend);
263 264 265 266 267 268 269 270 271 272 273
}

static int ath10k_init_configure_target(struct ath10k *ar)
{
	u32 param_host;
	int ret;

	/* tell target which HTC version it is used*/
	ret = ath10k_bmi_write32(ar, hi_app_host_interest,
				 HTC_PROTOCOL_VERSION);
	if (ret) {
274
		ath10k_err(ar, "settings HTC version failed\n");
275 276 277 278 279 280
		return ret;
	}

	/* set the firmware mode to STA/IBSS/AP */
	ret = ath10k_bmi_read32(ar, hi_option_flag, &param_host);
	if (ret) {
281
		ath10k_err(ar, "setting firmware mode (1/2) failed\n");
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
		return ret;
	}

	/* TODO following parameters need to be re-visited. */
	/* num_device */
	param_host |= (1 << HI_OPTION_NUM_DEV_SHIFT);
	/* Firmware mode */
	/* FIXME: Why FW_MODE_AP ??.*/
	param_host |= (HI_OPTION_FW_MODE_AP << HI_OPTION_FW_MODE_SHIFT);
	/* mac_addr_method */
	param_host |= (1 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
	/* firmware_bridge */
	param_host |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
	/* fwsubmode */
	param_host |= (0 << HI_OPTION_FW_SUBMODE_SHIFT);

	ret = ath10k_bmi_write32(ar, hi_option_flag, param_host);
	if (ret) {
300
		ath10k_err(ar, "setting firmware mode (2/2) failed\n");
301 302 303 304 305 306
		return ret;
	}

	/* We do all byte-swapping on the host */
	ret = ath10k_bmi_write32(ar, hi_be, 0);
	if (ret) {
307
		ath10k_err(ar, "setting host CPU BE mode failed\n");
308 309 310 311 312 313 314
		return ret;
	}

	/* FW descriptor/Data swap flags */
	ret = ath10k_bmi_write32(ar, hi_fw_swap, 0);

	if (ret) {
315
		ath10k_err(ar, "setting FW data/desc swap flags failed\n");
316 317 318
		return ret;
	}

M
Michal Kazior 已提交
319 320 321 322 323 324 325 326 327 328 329
	/* Some devices have a special sanity check that verifies the PCI
	 * Device ID is written to this host interest var. It is known to be
	 * required to boot QCA6164.
	 */
	ret = ath10k_bmi_write32(ar, hi_hci_uart_pwr_mgmt_params_ext,
				 ar->dev_id);
	if (ret) {
		ath10k_err(ar, "failed to set pwr_mgmt_params: %d\n", ret);
		return ret;
	}

330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
	return 0;
}

static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar,
						   const char *dir,
						   const char *file)
{
	char filename[100];
	const struct firmware *fw;
	int ret;

	if (file == NULL)
		return ERR_PTR(-ENOENT);

	if (dir == NULL)
		dir = ".";

	snprintf(filename, sizeof(filename), "%s/%s", dir, file);
	ret = request_firmware(&fw, filename, ar->dev);
	if (ret)
		return ERR_PTR(ret);

	return fw;
}

355 356
static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data,
				      size_t data_len)
357
{
358 359
	u32 board_data_size = ar->hw_params.fw.board_size;
	u32 board_ext_data_size = ar->hw_params.fw.board_ext_size;
360 361 362 363 364
	u32 board_ext_data_addr;
	int ret;

	ret = ath10k_bmi_read32(ar, hi_board_ext_data, &board_ext_data_addr);
	if (ret) {
365 366
		ath10k_err(ar, "could not read board ext data addr (%d)\n",
			   ret);
367 368 369
		return ret;
	}

370
	ath10k_dbg(ar, ATH10K_DBG_BOOT,
371
		   "boot push board extended data addr 0x%x\n",
372 373 374 375 376
		   board_ext_data_addr);

	if (board_ext_data_addr == 0)
		return 0;

377
	if (data_len != (board_data_size + board_ext_data_size)) {
378
		ath10k_err(ar, "invalid board (ext) data sizes %zu != %d+%d\n",
379
			   data_len, board_data_size, board_ext_data_size);
380 381 382 383
		return -EINVAL;
	}

	ret = ath10k_bmi_write_memory(ar, board_ext_data_addr,
384
				      data + board_data_size,
385 386
				      board_ext_data_size);
	if (ret) {
387
		ath10k_err(ar, "could not write board ext data (%d)\n", ret);
388 389 390 391 392 393
		return ret;
	}

	ret = ath10k_bmi_write32(ar, hi_board_ext_data_config,
				 (board_ext_data_size << 16) | 1);
	if (ret) {
394 395
		ath10k_err(ar, "could not write board ext data bit (%d)\n",
			   ret);
396 397 398 399 400 401
		return ret;
	}

	return 0;
}

402 403
static int ath10k_download_board_data(struct ath10k *ar, const void *data,
				      size_t data_len)
404
{
405
	u32 board_data_size = ar->hw_params.fw.board_size;
406 407 408
	u32 address;
	int ret;

409
	ret = ath10k_push_board_ext_data(ar, data, data_len);
410
	if (ret) {
411
		ath10k_err(ar, "could not push board ext data (%d)\n", ret);
412 413 414 415 416
		goto exit;
	}

	ret = ath10k_bmi_read32(ar, hi_board_data, &address);
	if (ret) {
417
		ath10k_err(ar, "could not read board data addr (%d)\n", ret);
418 419 420
		goto exit;
	}

421
	ret = ath10k_bmi_write_memory(ar, address, data,
422
				      min_t(u32, board_data_size,
423
					    data_len));
424
	if (ret) {
425
		ath10k_err(ar, "could not write board data (%d)\n", ret);
426 427 428 429 430
		goto exit;
	}

	ret = ath10k_bmi_write32(ar, hi_board_data_initialized, 1);
	if (ret) {
431
		ath10k_err(ar, "could not write board data bit (%d)\n", ret);
432 433 434 435 436 437 438
		goto exit;
	}

exit:
	return ret;
}

439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460
static int ath10k_download_cal_file(struct ath10k *ar)
{
	int ret;

	if (!ar->cal_file)
		return -ENOENT;

	if (IS_ERR(ar->cal_file))
		return PTR_ERR(ar->cal_file);

	ret = ath10k_download_board_data(ar, ar->cal_file->data,
					 ar->cal_file->size);
	if (ret) {
		ath10k_err(ar, "failed to download cal_file data: %d\n", ret);
		return ret;
	}

	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cal file downloaded\n");

	return 0;
}

461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517
static int ath10k_download_cal_dt(struct ath10k *ar)
{
	struct device_node *node;
	int data_len;
	void *data;
	int ret;

	node = ar->dev->of_node;
	if (!node)
		/* Device Tree is optional, don't print any warnings if
		 * there's no node for ath10k.
		 */
		return -ENOENT;

	if (!of_get_property(node, "qcom,ath10k-calibration-data",
			     &data_len)) {
		/* The calibration data node is optional */
		return -ENOENT;
	}

	if (data_len != QCA988X_CAL_DATA_LEN) {
		ath10k_warn(ar, "invalid calibration data length in DT: %d\n",
			    data_len);
		ret = -EMSGSIZE;
		goto out;
	}

	data = kmalloc(data_len, GFP_KERNEL);
	if (!data) {
		ret = -ENOMEM;
		goto out;
	}

	ret = of_property_read_u8_array(node, "qcom,ath10k-calibration-data",
					data, data_len);
	if (ret) {
		ath10k_warn(ar, "failed to read calibration data from DT: %d\n",
			    ret);
		goto out_free;
	}

	ret = ath10k_download_board_data(ar, data, data_len);
	if (ret) {
		ath10k_warn(ar, "failed to download calibration data from Device Tree: %d\n",
			    ret);
		goto out_free;
	}

	ret = 0;

out_free:
	kfree(data);

out:
	return ret;
}

518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567
static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
{
	u32 result, address;
	u8 board_id, chip_id;
	int ret;

	address = ar->hw_params.patch_load_addr;

	if (!ar->otp_data || !ar->otp_len) {
		ath10k_warn(ar,
			    "failed to retrieve board id because of invalid otp\n");
		return -ENODATA;
	}

	ath10k_dbg(ar, ATH10K_DBG_BOOT,
		   "boot upload otp to 0x%x len %zd for board id\n",
		   address, ar->otp_len);

	ret = ath10k_bmi_fast_download(ar, address, ar->otp_data, ar->otp_len);
	if (ret) {
		ath10k_err(ar, "could not write otp for board id check: %d\n",
			   ret);
		return ret;
	}

	ret = ath10k_bmi_execute(ar, address, BMI_PARAM_GET_EEPROM_BOARD_ID,
				 &result);
	if (ret) {
		ath10k_err(ar, "could not execute otp for board id check: %d\n",
			   ret);
		return ret;
	}

	board_id = MS(result, ATH10K_BMI_BOARD_ID_FROM_OTP);
	chip_id = MS(result, ATH10K_BMI_CHIP_ID_FROM_OTP);

	ath10k_dbg(ar, ATH10K_DBG_BOOT,
		   "boot get otp board id result 0x%08x board_id %d chip_id %d\n",
		   result, board_id, chip_id);

	if ((result & ATH10K_BMI_BOARD_ID_STATUS_MASK) != 0)
		return -EOPNOTSUPP;

	ar->id.bmi_ids_valid = true;
	ar->id.bmi_board_id = board_id;
	ar->id.bmi_chip_id = chip_id;

	return 0;
}

568 569
static int ath10k_download_and_run_otp(struct ath10k *ar)
{
570
	u32 result, address = ar->hw_params.patch_load_addr;
571
	u32 bmi_otp_exe_param = ar->hw_params.otp_exe_param;
572 573
	int ret;

574
	ret = ath10k_download_board_data(ar, ar->board_data, ar->board_len);
575 576 577 578 579
	if (ret) {
		ath10k_err(ar, "failed to download board data: %d\n", ret);
		return ret;
	}

580 581
	/* OTP is optional */

K
Kalle Valo 已提交
582
	if (!ar->otp_data || !ar->otp_len) {
583
		ath10k_warn(ar, "Not running otp, calibration will be incorrect (otp-data %p otp_len %zd)!\n",
584
			    ar->otp_data, ar->otp_len);
585
		return 0;
K
Kalle Valo 已提交
586 587
	}

588
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n",
K
Kalle Valo 已提交
589
		   address, ar->otp_len);
590

591
	ret = ath10k_bmi_fast_download(ar, address, ar->otp_data, ar->otp_len);
592
	if (ret) {
593
		ath10k_err(ar, "could not write otp (%d)\n", ret);
K
Kalle Valo 已提交
594
		return ret;
595 596
	}

597
	ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result);
598
	if (ret) {
599
		ath10k_err(ar, "could not execute otp (%d)\n", ret);
K
Kalle Valo 已提交
600
		return ret;
601 602
	}

603
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);
K
Kalle Valo 已提交
604

605
	if (!(skip_otp || test_bit(ATH10K_FW_FEATURE_IGNORE_OTP_RESULT,
606 607
				   ar->fw_features)) &&
	    result != 0) {
608
		ath10k_err(ar, "otp calibration failed: %d", result);
K
Kalle Valo 已提交
609 610 611 612
		return -EINVAL;
	}

	return 0;
613 614
}

K
Kalle Valo 已提交
615
static int ath10k_download_fw(struct ath10k *ar, enum ath10k_firmware_mode mode)
616
{
K
Kalle Valo 已提交
617 618 619
	u32 address, data_len;
	const char *mode_name;
	const void *data;
620 621 622 623
	int ret;

	address = ar->hw_params.patch_load_addr;

K
Kalle Valo 已提交
624 625 626 627 628
	switch (mode) {
	case ATH10K_FIRMWARE_MODE_NORMAL:
		data = ar->firmware_data;
		data_len = ar->firmware_len;
		mode_name = "normal";
629
		ret = ath10k_swap_code_seg_configure(ar,
K
Kalle Valo 已提交
630
						     ATH10K_SWAP_CODE_SEG_BIN_TYPE_FW);
631 632 633 634 635
		if (ret) {
			ath10k_err(ar, "failed to configure fw code swap: %d\n",
				   ret);
			return ret;
		}
K
Kalle Valo 已提交
636 637
		break;
	case ATH10K_FIRMWARE_MODE_UTF:
A
Alan Liu 已提交
638 639
		data = ar->testmode.utf_firmware_data;
		data_len = ar->testmode.utf_firmware_len;
K
Kalle Valo 已提交
640 641 642 643 644 645 646 647 648 649 650 651
		mode_name = "utf";
		break;
	default:
		ath10k_err(ar, "unknown firmware mode: %d\n", mode);
		return -EINVAL;
	}

	ath10k_dbg(ar, ATH10K_DBG_BOOT,
		   "boot uploading firmware image %p len %d mode %s\n",
		   data, data_len, mode_name);

	ret = ath10k_bmi_fast_download(ar, address, data, data_len);
652
	if (ret) {
K
Kalle Valo 已提交
653 654 655
		ath10k_err(ar, "failed to download %s firmware: %d\n",
			   mode_name, ret);
		return ret;
656 657
	}

658 659 660
	return ret;
}

661
static void ath10k_core_free_board_files(struct ath10k *ar)
662
{
663
	if (!IS_ERR(ar->board))
664
		release_firmware(ar->board);
665

666 667 668 669 670 671 672
	ar->board = NULL;
	ar->board_data = NULL;
	ar->board_len = 0;
}

static void ath10k_core_free_firmware_files(struct ath10k *ar)
{
673
	if (!IS_ERR(ar->otp))
674 675
		release_firmware(ar->otp);

676
	if (!IS_ERR(ar->firmware))
677 678
		release_firmware(ar->firmware);

679
	if (!IS_ERR(ar->cal_file))
680 681
		release_firmware(ar->cal_file);

682 683
	ath10k_swap_code_seg_release(ar);

684
	ar->otp = NULL;
685 686 687
	ar->otp_data = NULL;
	ar->otp_len = 0;

688
	ar->firmware = NULL;
689 690
	ar->firmware_data = NULL;
	ar->firmware_len = 0;
691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711

	ar->cal_file = NULL;
}

static int ath10k_fetch_cal_file(struct ath10k *ar)
{
	char filename[100];

	/* cal-<bus>-<id>.bin */
	scnprintf(filename, sizeof(filename), "cal-%s-%s.bin",
		  ath10k_bus_str(ar->hif.bus), dev_name(ar->dev));

	ar->cal_file = ath10k_fetch_fw_file(ar, ATH10K_FW_DIR, filename);
	if (IS_ERR(ar->cal_file))
		/* calibration file is optional, don't print any warnings */
		return PTR_ERR(ar->cal_file);

	ath10k_dbg(ar, ATH10K_DBG_BOOT, "found calibration file %s/%s\n",
		   ATH10K_FW_DIR, filename);

	return 0;
712 713
}

714
static int ath10k_core_fetch_board_data_api_1(struct ath10k *ar)
715
{
716 717 718 719
	if (!ar->hw_params.fw.board) {
		ath10k_err(ar, "failed to find board file fw entry\n");
		return -EINVAL;
	}
720

721 722 723
	ar->board = ath10k_fetch_fw_file(ar,
					 ar->hw_params.fw.dir,
					 ar->hw_params.fw.board);
724 725 726 727 728
	if (IS_ERR(ar->board))
		return PTR_ERR(ar->board);

	ar->board_data = ar->board->data;
	ar->board_len = ar->board->size;
729

730 731 732
	return 0;
}

733 734 735
static int ath10k_core_parse_bd_ie_board(struct ath10k *ar,
					 const void *buf, size_t buf_len,
					 const char *boardname)
736
{
737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803
	const struct ath10k_fw_ie *hdr;
	bool name_match_found;
	int ret, board_ie_id;
	size_t board_ie_len;
	const void *board_ie_data;

	name_match_found = false;

	/* go through ATH10K_BD_IE_BOARD_ elements */
	while (buf_len > sizeof(struct ath10k_fw_ie)) {
		hdr = buf;
		board_ie_id = le32_to_cpu(hdr->id);
		board_ie_len = le32_to_cpu(hdr->len);
		board_ie_data = hdr->data;

		buf_len -= sizeof(*hdr);
		buf += sizeof(*hdr);

		if (buf_len < ALIGN(board_ie_len, 4)) {
			ath10k_err(ar, "invalid ATH10K_BD_IE_BOARD length: %zu < %zu\n",
				   buf_len, ALIGN(board_ie_len, 4));
			ret = -EINVAL;
			goto out;
		}

		switch (board_ie_id) {
		case ATH10K_BD_IE_BOARD_NAME:
			ath10k_dbg_dump(ar, ATH10K_DBG_BOOT, "board name", "",
					board_ie_data, board_ie_len);

			if (board_ie_len != strlen(boardname))
				break;

			ret = memcmp(board_ie_data, boardname, strlen(boardname));
			if (ret)
				break;

			name_match_found = true;
			ath10k_dbg(ar, ATH10K_DBG_BOOT,
				   "boot found match for name '%s'",
				   boardname);
			break;
		case ATH10K_BD_IE_BOARD_DATA:
			if (!name_match_found)
				/* no match found */
				break;

			ath10k_dbg(ar, ATH10K_DBG_BOOT,
				   "boot found board data for '%s'",
				   boardname);

			ar->board_data = board_ie_data;
			ar->board_len = board_ie_len;

			ret = 0;
			goto out;
		default:
			ath10k_warn(ar, "unknown ATH10K_BD_IE_BOARD found: %d\n",
				    board_ie_id);
			break;
		}

		/* jump over the padding */
		board_ie_len = ALIGN(board_ie_len, 4);

		buf_len -= board_ie_len;
		buf += board_ie_len;
804 805
	}

806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822
	/* no match found */
	ret = -ENOENT;

out:
	return ret;
}

static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
					      const char *boardname,
					      const char *filename)
{
	size_t len, magic_len, ie_len;
	struct ath10k_fw_ie *hdr;
	const u8 *data;
	int ret, ie_id;

	ar->board = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, filename);
823 824
	if (IS_ERR(ar->board))
		return PTR_ERR(ar->board);
825

826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896
	data = ar->board->data;
	len = ar->board->size;

	/* magic has extra null byte padded */
	magic_len = strlen(ATH10K_BOARD_MAGIC) + 1;
	if (len < magic_len) {
		ath10k_err(ar, "failed to find magic value in %s/%s, file too short: %zu\n",
			   ar->hw_params.fw.dir, filename, len);
		ret = -EINVAL;
		goto err;
	}

	if (memcmp(data, ATH10K_BOARD_MAGIC, magic_len)) {
		ath10k_err(ar, "found invalid board magic\n");
		ret = -EINVAL;
		goto err;
	}

	/* magic is padded to 4 bytes */
	magic_len = ALIGN(magic_len, 4);
	if (len < magic_len) {
		ath10k_err(ar, "failed: %s/%s too small to contain board data, len: %zu\n",
			   ar->hw_params.fw.dir, filename, len);
		ret = -EINVAL;
		goto err;
	}

	data += magic_len;
	len -= magic_len;

	while (len > sizeof(struct ath10k_fw_ie)) {
		hdr = (struct ath10k_fw_ie *)data;
		ie_id = le32_to_cpu(hdr->id);
		ie_len = le32_to_cpu(hdr->len);

		len -= sizeof(*hdr);
		data = hdr->data;

		if (len < ALIGN(ie_len, 4)) {
			ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n",
				   ie_id, ie_len, len);
			ret = -EINVAL;
			goto err;
		}

		switch (ie_id) {
		case ATH10K_BD_IE_BOARD:
			ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len,
							    boardname);
			if (ret == -ENOENT)
				/* no match found, continue */
				break;
			else if (ret)
				/* there was an error, bail out */
				goto err;

			/* board data found */
			goto out;
		}

		/* jump over the padding */
		ie_len = ALIGN(ie_len, 4);

		len -= ie_len;
		data += ie_len;
	}

out:
	if (!ar->board_data || !ar->board_len) {
		ath10k_err(ar,
			   "failed to fetch board data for %s from %s/%s\n",
897
			   boardname, ar->hw_params.fw.dir, filename);
898 899 900 901 902 903 904 905 906 907 908 909 910 911
		ret = -ENODATA;
		goto err;
	}

	return 0;

err:
	ath10k_core_free_board_files(ar);
	return ret;
}

static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
					 size_t name_len)
{
912 913 914 915 916 917 918 919 920
	if (ar->id.bmi_ids_valid) {
		scnprintf(name, name_len,
			  "bus=%s,bmi-chip-id=%d,bmi-board-id=%d",
			  ath10k_bus_str(ar->hif.bus),
			  ar->id.bmi_chip_id,
			  ar->id.bmi_board_id);
		goto out;
	}

921 922 923 924 925 926
	scnprintf(name, name_len,
		  "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x",
		  ath10k_bus_str(ar->hif.bus),
		  ar->id.vendor, ar->id.device,
		  ar->id.subsystem_vendor, ar->id.subsystem_device);

927
out:
928
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using board name '%s'\n", name);
929 930 931 932 933 934

	return 0;
}

static int ath10k_core_fetch_board_file(struct ath10k *ar)
{
935
	char boardname[100];
936 937
	int ret;

938 939 940 941
	ret = ath10k_core_create_board_name(ar, boardname, sizeof(boardname));
	if (ret) {
		ath10k_err(ar, "failed to create board name: %d", ret);
		return ret;
942 943
	}

944 945 946 947 948 949 950 951
	ar->bd_api = 2;
	ret = ath10k_core_fetch_board_data_api_n(ar, boardname,
						 ATH10K_BOARD_API2_FILE);
	if (!ret)
		goto success;

	ar->bd_api = 1;
	ret = ath10k_core_fetch_board_data_api_1(ar);
952
	if (ret) {
953
		ath10k_err(ar, "failed to fetch board data\n");
954 955
		return ret;
	}
956

957 958
success:
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "using board api %d\n", ar->bd_api);
959 960 961 962 963 964 965 966 967 968 969 970
	return 0;
}

static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar)
{
	int ret = 0;

	if (ar->hw_params.fw.fw == NULL) {
		ath10k_err(ar, "firmware file not defined\n");
		return -EINVAL;
	}

971 972 973 974 975
	ar->firmware = ath10k_fetch_fw_file(ar,
					    ar->hw_params.fw.dir,
					    ar->hw_params.fw.fw);
	if (IS_ERR(ar->firmware)) {
		ret = PTR_ERR(ar->firmware);
976
		ath10k_err(ar, "could not fetch firmware (%d)\n", ret);
977 978 979
		goto err;
	}

980 981 982
	ar->firmware_data = ar->firmware->data;
	ar->firmware_len = ar->firmware->size;

983 984 985 986 987 988 989 990 991
	/* OTP may be undefined. If so, don't fetch it at all */
	if (ar->hw_params.fw.otp == NULL)
		return 0;

	ar->otp = ath10k_fetch_fw_file(ar,
				       ar->hw_params.fw.dir,
				       ar->hw_params.fw.otp);
	if (IS_ERR(ar->otp)) {
		ret = PTR_ERR(ar->otp);
992
		ath10k_err(ar, "could not fetch otp (%d)\n", ret);
993 994 995
		goto err;
	}

996 997 998
	ar->otp_data = ar->otp->data;
	ar->otp_len = ar->otp->size;

999 1000 1001 1002
	return 0;

err:
	ath10k_core_free_firmware_files(ar);
1003 1004 1005
	return ret;
}

1006 1007 1008 1009 1010 1011
static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
{
	size_t magic_len, len, ie_len;
	int ie_id, i, index, bit, ret;
	struct ath10k_fw_ie *hdr;
	const u8 *data;
1012
	__le32 *timestamp, *version;
1013 1014 1015 1016

	/* first fetch the firmware file (firmware-*.bin) */
	ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name);
	if (IS_ERR(ar->firmware)) {
1017
		ath10k_err(ar, "could not fetch firmware file '%s/%s': %ld\n",
1018
			   ar->hw_params.fw.dir, name, PTR_ERR(ar->firmware));
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028
		return PTR_ERR(ar->firmware);
	}

	data = ar->firmware->data;
	len = ar->firmware->size;

	/* magic also includes the null byte, check that as well */
	magic_len = strlen(ATH10K_FIRMWARE_MAGIC) + 1;

	if (len < magic_len) {
1029
		ath10k_err(ar, "firmware file '%s/%s' too small to contain magic: %zu\n",
1030
			   ar->hw_params.fw.dir, name, len);
1031 1032
		ret = -EINVAL;
		goto err;
1033 1034 1035
	}

	if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) {
1036
		ath10k_err(ar, "invalid firmware magic\n");
1037 1038
		ret = -EINVAL;
		goto err;
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057
	}

	/* jump over the padding */
	magic_len = ALIGN(magic_len, 4);

	len -= magic_len;
	data += magic_len;

	/* loop elements */
	while (len > sizeof(struct ath10k_fw_ie)) {
		hdr = (struct ath10k_fw_ie *)data;

		ie_id = le32_to_cpu(hdr->id);
		ie_len = le32_to_cpu(hdr->len);

		len -= sizeof(*hdr);
		data += sizeof(*hdr);

		if (len < ie_len) {
1058
			ath10k_err(ar, "invalid length for FW IE %d (%zu < %zu)\n",
1059
				   ie_id, len, ie_len);
1060 1061
			ret = -EINVAL;
			goto err;
1062 1063 1064 1065 1066 1067 1068 1069 1070 1071
		}

		switch (ie_id) {
		case ATH10K_FW_IE_FW_VERSION:
			if (ie_len > sizeof(ar->hw->wiphy->fw_version) - 1)
				break;

			memcpy(ar->hw->wiphy->fw_version, data, ie_len);
			ar->hw->wiphy->fw_version[ie_len] = '\0';

1072
			ath10k_dbg(ar, ATH10K_DBG_BOOT,
1073 1074 1075 1076 1077 1078 1079 1080 1081
				   "found fw version %s\n",
				    ar->hw->wiphy->fw_version);
			break;
		case ATH10K_FW_IE_TIMESTAMP:
			if (ie_len != sizeof(u32))
				break;

			timestamp = (__le32 *)data;

1082
			ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw timestamp %d\n",
1083 1084 1085
				   le32_to_cpup(timestamp));
			break;
		case ATH10K_FW_IE_FEATURES:
1086
			ath10k_dbg(ar, ATH10K_DBG_BOOT,
1087 1088 1089 1090 1091 1092 1093 1094 1095 1096
				   "found firmware features ie (%zd B)\n",
				   ie_len);

			for (i = 0; i < ATH10K_FW_FEATURE_COUNT; i++) {
				index = i / 8;
				bit = i % 8;

				if (index == ie_len)
					break;

1097
				if (data[index] & (1 << bit)) {
1098
					ath10k_dbg(ar, ATH10K_DBG_BOOT,
1099 1100
						   "Enabling feature bit: %i\n",
						   i);
1101
					__set_bit(i, ar->fw_features);
1102
				}
1103 1104
			}

1105
			ath10k_dbg_dump(ar, ATH10K_DBG_BOOT, "features", "",
1106 1107 1108 1109
					ar->fw_features,
					sizeof(ar->fw_features));
			break;
		case ATH10K_FW_IE_FW_IMAGE:
1110
			ath10k_dbg(ar, ATH10K_DBG_BOOT,
1111 1112 1113 1114 1115 1116 1117 1118
				   "found fw image ie (%zd B)\n",
				   ie_len);

			ar->firmware_data = data;
			ar->firmware_len = ie_len;

			break;
		case ATH10K_FW_IE_OTP_IMAGE:
1119
			ath10k_dbg(ar, ATH10K_DBG_BOOT,
1120 1121 1122 1123 1124 1125 1126
				   "found otp image ie (%zd B)\n",
				   ie_len);

			ar->otp_data = data;
			ar->otp_len = ie_len;

			break;
1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137
		case ATH10K_FW_IE_WMI_OP_VERSION:
			if (ie_len != sizeof(u32))
				break;

			version = (__le32 *)data;

			ar->wmi.op_version = le32_to_cpup(version);

			ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie wmi op version %d\n",
				   ar->wmi.op_version);
			break;
1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148
		case ATH10K_FW_IE_HTT_OP_VERSION:
			if (ie_len != sizeof(u32))
				break;

			version = (__le32 *)data;

			ar->htt.op_version = le32_to_cpup(version);

			ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie htt op version %d\n",
				   ar->htt.op_version);
			break;
1149 1150 1151 1152 1153 1154 1155
		case ATH10K_FW_IE_FW_CODE_SWAP_IMAGE:
			ath10k_dbg(ar, ATH10K_DBG_BOOT,
				   "found fw code swap image ie (%zd B)\n",
				   ie_len);
			ar->swap.firmware_codeswap_data = data;
			ar->swap.firmware_codeswap_len = ie_len;
			break;
1156
		default:
1157
			ath10k_warn(ar, "Unknown FW IE: %u\n",
1158 1159 1160 1161 1162 1163 1164 1165 1166
				    le32_to_cpu(hdr->id));
			break;
		}

		/* jump over the padding */
		ie_len = ALIGN(ie_len, 4);

		len -= ie_len;
		data += ie_len;
1167
	}
1168 1169

	if (!ar->firmware_data || !ar->firmware_len) {
1170
		ath10k_warn(ar, "No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n",
1171
			    ar->hw_params.fw.dir, name);
1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186
		ret = -ENOMEDIUM;
		goto err;
	}

	return 0;

err:
	ath10k_core_free_firmware_files(ar);
	return ret;
}

static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
{
	int ret;

1187 1188 1189
	/* calibration file is optional, don't check for any errors */
	ath10k_fetch_cal_file(ar);

K
Kalle Valo 已提交
1190 1191 1192 1193 1194 1195 1196
	ar->fw_api = 5;
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);

	ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API5_FILE);
	if (ret == 0)
		goto success;

1197 1198 1199 1200 1201 1202 1203
	ar->fw_api = 4;
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);

	ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API4_FILE);
	if (ret == 0)
		goto success;

1204
	ar->fw_api = 3;
1205
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
1206 1207 1208 1209 1210

	ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API3_FILE);
	if (ret == 0)
		goto success;

1211
	ar->fw_api = 2;
1212
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
1213

1214
	ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API2_FILE);
1215 1216 1217 1218
	if (ret == 0)
		goto success;

	ar->fw_api = 1;
1219
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
1220 1221 1222 1223 1224

	ret = ath10k_core_fetch_firmware_api_1(ar);
	if (ret)
		return ret;

1225
success:
1226
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api);
1227 1228 1229 1230

	return 0;
}

1231
static int ath10k_download_cal_data(struct ath10k *ar)
1232 1233 1234
{
	int ret;

1235 1236 1237 1238 1239 1240 1241
	ret = ath10k_download_cal_file(ar);
	if (ret == 0) {
		ar->cal_mode = ATH10K_CAL_MODE_FILE;
		goto done;
	}

	ath10k_dbg(ar, ATH10K_DBG_BOOT,
1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252
		   "boot did not find a calibration file, try DT next: %d\n",
		   ret);

	ret = ath10k_download_cal_dt(ar);
	if (ret == 0) {
		ar->cal_mode = ATH10K_CAL_MODE_DT;
		goto done;
	}

	ath10k_dbg(ar, ATH10K_DBG_BOOT,
		   "boot did not find DT entry, try OTP next: %d\n",
1253 1254
		   ret);

1255
	ret = ath10k_download_and_run_otp(ar);
1256
	if (ret) {
1257
		ath10k_err(ar, "failed to run otp: %d\n", ret);
1258
		return ret;
1259
	}
1260

1261 1262 1263 1264 1265 1266
	ar->cal_mode = ATH10K_CAL_MODE_OTP;

done:
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using calibration mode %s\n",
		   ath10k_cal_mode_str(ar->cal_mode));
	return 0;
1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278
}

static int ath10k_init_uart(struct ath10k *ar)
{
	int ret;

	/*
	 * Explicitly setting UART prints to zero as target turns it on
	 * based on scratch registers.
	 */
	ret = ath10k_bmi_write32(ar, hi_serial_enable, 0);
	if (ret) {
1279
		ath10k_warn(ar, "could not disable UART prints (%d)\n", ret);
1280 1281 1282
		return ret;
	}

1283
	if (!uart_print)
1284 1285
		return 0;

1286
	ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, ar->hw_params.uart_pin);
1287
	if (ret) {
1288
		ath10k_warn(ar, "could not enable UART prints (%d)\n", ret);
1289 1290 1291 1292 1293
		return ret;
	}

	ret = ath10k_bmi_write32(ar, hi_serial_enable, 1);
	if (ret) {
1294
		ath10k_warn(ar, "could not enable UART prints (%d)\n", ret);
1295 1296 1297
		return ret;
	}

1298 1299 1300
	/* Set the UART baud rate to 19200. */
	ret = ath10k_bmi_write32(ar, hi_desired_baud_rate, 19200);
	if (ret) {
1301
		ath10k_warn(ar, "could not set the baud rate (%d)\n", ret);
1302 1303 1304
		return ret;
	}

1305
	ath10k_info(ar, "UART prints enabled\n");
1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316
	return 0;
}

static int ath10k_init_hw_params(struct ath10k *ar)
{
	const struct ath10k_hw_params *uninitialized_var(hw_params);
	int i;

	for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) {
		hw_params = &ath10k_hw_params_list[i];

1317 1318
		if (hw_params->id == ar->target_version &&
		    hw_params->dev_id == ar->dev_id)
1319 1320 1321 1322
			break;
	}

	if (i == ARRAY_SIZE(ath10k_hw_params_list)) {
1323
		ath10k_err(ar, "Unsupported hardware version: 0x%x\n",
1324 1325 1326 1327 1328 1329
			   ar->target_version);
		return -EINVAL;
	}

	ar->hw_params = *hw_params;

1330
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "Hardware name %s version 0x%x\n",
1331
		   ar->hw_params.name, ar->target_version);
1332 1333 1334 1335

	return 0;
}

1336 1337 1338 1339
static void ath10k_core_restart(struct work_struct *work)
{
	struct ath10k *ar = container_of(work, struct ath10k, restart_work);

M
Michal Kazior 已提交
1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354
	set_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);

	/* Place a barrier to make sure the compiler doesn't reorder
	 * CRASH_FLUSH and calling other functions.
	 */
	barrier();

	ieee80211_stop_queues(ar->hw);
	ath10k_drain_tx(ar);
	complete_all(&ar->scan.started);
	complete_all(&ar->scan.completed);
	complete_all(&ar->scan.on_channel);
	complete_all(&ar->offchan_tx_completed);
	complete_all(&ar->install_key_done);
	complete_all(&ar->vdev_setup_done);
1355
	complete_all(&ar->thermal.wmi_sync);
M
Michal Kazior 已提交
1356 1357 1358 1359
	wake_up(&ar->htt.empty_tx_wq);
	wake_up(&ar->wmi.tx_credits_wq);
	wake_up(&ar->peer_mapping_wq);

1360 1361 1362 1363 1364
	mutex_lock(&ar->conf_mutex);

	switch (ar->state) {
	case ATH10K_STATE_ON:
		ar->state = ATH10K_STATE_RESTARTING;
1365
		ath10k_hif_stop(ar);
1366
		ath10k_scan_finish(ar);
1367 1368 1369
		ieee80211_restart_hw(ar->hw);
		break;
	case ATH10K_STATE_OFF:
1370 1371
		/* this can happen if driver is being unloaded
		 * or if the crash happens during FW probing */
1372
		ath10k_warn(ar, "cannot restart a device that hasn't been started\n");
1373 1374
		break;
	case ATH10K_STATE_RESTARTING:
1375 1376
		/* hw restart might be requested from multiple places */
		break;
1377 1378 1379 1380
	case ATH10K_STATE_RESTARTED:
		ar->state = ATH10K_STATE_WEDGED;
		/* fall through */
	case ATH10K_STATE_WEDGED:
1381
		ath10k_warn(ar, "device is wedged, will not restart\n");
1382
		break;
K
Kalle Valo 已提交
1383 1384 1385
	case ATH10K_STATE_UTF:
		ath10k_warn(ar, "firmware restart in UTF mode not supported\n");
		break;
1386 1387 1388 1389 1390
	}

	mutex_unlock(&ar->conf_mutex);
}

1391
static int ath10k_core_init_firmware_features(struct ath10k *ar)
1392
{
1393 1394 1395 1396 1397 1398
	if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features) &&
	    !test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
		ath10k_err(ar, "feature bits corrupted: 10.2 feature requires 10.x feature to be set as well");
		return -EINVAL;
	}

1399 1400 1401 1402 1403 1404
	if (ar->wmi.op_version >= ATH10K_FW_WMI_OP_VERSION_MAX) {
		ath10k_err(ar, "unsupported WMI OP version (max %d): %d\n",
			   ATH10K_FW_WMI_OP_VERSION_MAX, ar->wmi.op_version);
		return -EINVAL;
	}

1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429
	ar->wmi.rx_decap_mode = ATH10K_HW_TXRX_NATIVE_WIFI;
	switch (ath10k_cryptmode_param) {
	case ATH10K_CRYPT_MODE_HW:
		clear_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);
		clear_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags);
		break;
	case ATH10K_CRYPT_MODE_SW:
		if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT,
			      ar->fw_features)) {
			ath10k_err(ar, "cryptmode > 0 requires raw mode support from firmware");
			return -EINVAL;
		}

		set_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);
		set_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags);
		break;
	default:
		ath10k_info(ar, "invalid cryptmode: %d\n",
			    ath10k_cryptmode_param);
		return -EINVAL;
	}

	ar->htt.max_num_amsdu = ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT;
	ar->htt.max_num_ampdu = ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT;

B
Bob Copeland 已提交
1430 1431 1432 1433 1434 1435 1436 1437 1438
	if (rawmode) {
		if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT,
			      ar->fw_features)) {
			ath10k_err(ar, "rawmode = 1 requires support from firmware");
			return -EINVAL;
		}
		set_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);
	}

1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453
	if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
		ar->wmi.rx_decap_mode = ATH10K_HW_TXRX_RAW;

		/* Workaround:
		 *
		 * Firmware A-MSDU aggregation breaks with RAW Tx encap mode
		 * and causes enormous performance issues (malformed frames,
		 * etc).
		 *
		 * Disabling A-MSDU makes RAW mode stable with heavy traffic
		 * albeit a bit slower compared to regular operation.
		 */
		ar->htt.max_num_amsdu = 1;
	}

1454 1455 1456 1457 1458
	/* Backwards compatibility for firmwares without
	 * ATH10K_FW_IE_WMI_OP_VERSION.
	 */
	if (ar->wmi.op_version == ATH10K_FW_WMI_OP_VERSION_UNSET) {
		if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
1459 1460
			if (test_bit(ATH10K_FW_FEATURE_WMI_10_2,
				     ar->fw_features))
1461 1462 1463 1464 1465 1466 1467 1468 1469 1470
				ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_2;
			else
				ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_1;
		} else {
			ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_MAIN;
		}
	}

	switch (ar->wmi.op_version) {
	case ATH10K_FW_WMI_OP_VERSION_MAIN:
1471 1472
		ar->max_num_peers = TARGET_NUM_PEERS;
		ar->max_num_stations = TARGET_NUM_STATIONS;
1473
		ar->max_num_vdevs = TARGET_NUM_VDEVS;
1474
		ar->htt.max_num_pending_tx = TARGET_NUM_MSDU_DESC;
1475 1476
		ar->fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV |
			WMI_STAT_PEER;
1477
		ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;
1478 1479 1480
		break;
	case ATH10K_FW_WMI_OP_VERSION_10_1:
	case ATH10K_FW_WMI_OP_VERSION_10_2:
1481
	case ATH10K_FW_WMI_OP_VERSION_10_2_4:
1482 1483
		ar->max_num_peers = TARGET_10X_NUM_PEERS;
		ar->max_num_stations = TARGET_10X_NUM_STATIONS;
1484
		ar->max_num_vdevs = TARGET_10X_NUM_VDEVS;
1485
		ar->htt.max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC;
1486
		ar->fw_stats_req_mask = WMI_STAT_PEER;
1487
		ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;
1488
		break;
M
Michal Kazior 已提交
1489 1490 1491
	case ATH10K_FW_WMI_OP_VERSION_TLV:
		ar->max_num_peers = TARGET_TLV_NUM_PEERS;
		ar->max_num_stations = TARGET_TLV_NUM_STATIONS;
1492
		ar->max_num_vdevs = TARGET_TLV_NUM_VDEVS;
1493
		ar->max_num_tdls_vdevs = TARGET_TLV_NUM_TDLS_VDEVS;
M
Michal Kazior 已提交
1494
		ar->htt.max_num_pending_tx = TARGET_TLV_NUM_MSDU_DESC;
1495
		ar->wow.max_num_patterns = TARGET_TLV_NUM_WOW_PATTERNS;
1496 1497
		ar->fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV |
			WMI_STAT_PEER;
1498
		ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;
M
Michal Kazior 已提交
1499
		break;
1500
	case ATH10K_FW_WMI_OP_VERSION_10_4:
1501 1502 1503 1504 1505
		ar->max_num_peers = TARGET_10_4_NUM_PEERS;
		ar->max_num_stations = TARGET_10_4_NUM_STATIONS;
		ar->num_active_peers = TARGET_10_4_ACTIVE_PEERS;
		ar->max_num_vdevs = TARGET_10_4_NUM_VDEVS;
		ar->num_tids = TARGET_10_4_TGT_NUM_TIDS;
1506
		ar->htt.max_num_pending_tx = TARGET_10_4_NUM_MSDU_DESC;
1507
		ar->fw_stats_req_mask = WMI_STAT_PEER;
1508
		ar->max_spatial_stream = WMI_10_4_MAX_SPATIAL_STREAM;
1509
		break;
1510 1511 1512 1513
	case ATH10K_FW_WMI_OP_VERSION_UNSET:
	case ATH10K_FW_WMI_OP_VERSION_MAX:
		WARN_ON(1);
		return -EINVAL;
1514
	}
1515

1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531
	/* Backwards compatibility for firmwares without
	 * ATH10K_FW_IE_HTT_OP_VERSION.
	 */
	if (ar->htt.op_version == ATH10K_FW_HTT_OP_VERSION_UNSET) {
		switch (ar->wmi.op_version) {
		case ATH10K_FW_WMI_OP_VERSION_MAIN:
			ar->htt.op_version = ATH10K_FW_HTT_OP_VERSION_MAIN;
			break;
		case ATH10K_FW_WMI_OP_VERSION_10_1:
		case ATH10K_FW_WMI_OP_VERSION_10_2:
		case ATH10K_FW_WMI_OP_VERSION_10_2_4:
			ar->htt.op_version = ATH10K_FW_HTT_OP_VERSION_10_1;
			break;
		case ATH10K_FW_WMI_OP_VERSION_TLV:
			ar->htt.op_version = ATH10K_FW_HTT_OP_VERSION_TLV;
			break;
1532
		case ATH10K_FW_WMI_OP_VERSION_10_4:
1533 1534 1535 1536 1537 1538 1539
		case ATH10K_FW_WMI_OP_VERSION_UNSET:
		case ATH10K_FW_WMI_OP_VERSION_MAX:
			WARN_ON(1);
			return -EINVAL;
		}
	}

1540
	return 0;
1541 1542
}

K
Kalle Valo 已提交
1543
int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
1544 1545 1546
{
	int status;

1547 1548
	lockdep_assert_held(&ar->conf_mutex);

M
Michal Kazior 已提交
1549 1550
	clear_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);

1551 1552
	ath10k_bmi_start(ar);

1553 1554 1555 1556 1557
	if (ath10k_init_configure_target(ar)) {
		status = -EINVAL;
		goto err;
	}

1558 1559 1560 1561
	status = ath10k_download_cal_data(ar);
	if (status)
		goto err;

1562
	/* Some of of qca988x solutions are having global reset issue
K
Kalle Valo 已提交
1563 1564 1565 1566
	 * during target initialization. Bypassing PLL setting before
	 * downloading firmware and letting the SoC run on REF_CLK is
	 * fixing the problem. Corresponding firmware change is also needed
	 * to set the clock source once the target is initialized.
1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577
	 */
	if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT,
		     ar->fw_features)) {
		status = ath10k_bmi_write32(ar, hi_skip_clock_init, 1);
		if (status) {
			ath10k_err(ar, "could not write to skip_clock_init: %d\n",
				   status);
			goto err;
		}
	}

1578
	status = ath10k_download_fw(ar, mode);
1579 1580 1581 1582 1583 1584 1585
	if (status)
		goto err;

	status = ath10k_init_uart(ar);
	if (status)
		goto err;

1586 1587
	ar->htc.htc_ops.target_send_suspend_complete =
		ath10k_send_suspend_complete;
1588

1589 1590
	status = ath10k_htc_init(ar);
	if (status) {
1591
		ath10k_err(ar, "could not init HTC (%d)\n", status);
1592 1593 1594 1595 1596
		goto err;
	}

	status = ath10k_bmi_done(ar);
	if (status)
1597
		goto err;
1598 1599 1600

	status = ath10k_wmi_attach(ar);
	if (status) {
1601
		ath10k_err(ar, "WMI attach failed: %d\n", status);
1602
		goto err;
1603 1604
	}

M
Michal Kazior 已提交
1605 1606
	status = ath10k_htt_init(ar);
	if (status) {
1607
		ath10k_err(ar, "failed to init htt: %d\n", status);
M
Michal Kazior 已提交
1608 1609 1610 1611 1612
		goto err_wmi_detach;
	}

	status = ath10k_htt_tx_alloc(&ar->htt);
	if (status) {
1613
		ath10k_err(ar, "failed to alloc htt tx: %d\n", status);
M
Michal Kazior 已提交
1614 1615 1616 1617 1618
		goto err_wmi_detach;
	}

	status = ath10k_htt_rx_alloc(&ar->htt);
	if (status) {
1619
		ath10k_err(ar, "failed to alloc htt rx: %d\n", status);
M
Michal Kazior 已提交
1620 1621 1622
		goto err_htt_tx_detach;
	}

M
Michal Kazior 已提交
1623 1624
	status = ath10k_hif_start(ar);
	if (status) {
1625
		ath10k_err(ar, "could not start HIF: %d\n", status);
M
Michal Kazior 已提交
1626
		goto err_htt_rx_detach;
M
Michal Kazior 已提交
1627 1628 1629 1630
	}

	status = ath10k_htc_wait_target(&ar->htc);
	if (status) {
1631
		ath10k_err(ar, "failed to connect to HTC: %d\n", status);
M
Michal Kazior 已提交
1632 1633
		goto err_hif_stop;
	}
1634

K
Kalle Valo 已提交
1635 1636 1637 1638 1639 1640
	if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
		status = ath10k_htt_connect(&ar->htt);
		if (status) {
			ath10k_err(ar, "failed to connect htt (%d)\n", status);
			goto err_hif_stop;
		}
1641 1642
	}

M
Michal Kazior 已提交
1643 1644
	status = ath10k_wmi_connect(ar);
	if (status) {
1645
		ath10k_err(ar, "could not connect wmi: %d\n", status);
M
Michal Kazior 已提交
1646 1647 1648 1649 1650
		goto err_hif_stop;
	}

	status = ath10k_htc_start(&ar->htc);
	if (status) {
1651
		ath10k_err(ar, "failed to start htc: %d\n", status);
M
Michal Kazior 已提交
1652 1653 1654
		goto err_hif_stop;
	}

K
Kalle Valo 已提交
1655 1656
	if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
		status = ath10k_wmi_wait_for_service_ready(ar);
1657
		if (status) {
K
Kalle Valo 已提交
1658 1659 1660
			ath10k_warn(ar, "wmi service ready event not received");
			goto err_hif_stop;
		}
M
Michal Kazior 已提交
1661
	}
1662

1663
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "firmware %s booted\n",
1664
		   ar->hw->wiphy->fw_version);
1665 1666 1667

	status = ath10k_wmi_cmd_init(ar);
	if (status) {
1668 1669
		ath10k_err(ar, "could not send WMI init command (%d)\n",
			   status);
M
Michal Kazior 已提交
1670
		goto err_hif_stop;
1671 1672 1673
	}

	status = ath10k_wmi_wait_for_unified_ready(ar);
1674
	if (status) {
1675
		ath10k_err(ar, "wmi unified ready event not received\n");
M
Michal Kazior 已提交
1676
		goto err_hif_stop;
1677 1678
	}

1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690
	/* If firmware indicates Full Rx Reorder support it must be used in a
	 * slightly different manner. Let HTT code know.
	 */
	ar->htt.rx_ring.in_ord_rx = !!(test_bit(WMI_SERVICE_RX_FULL_REORDER,
						ar->wmi.svc_map));

	status = ath10k_htt_rx_ring_refill(ar);
	if (status) {
		ath10k_err(ar, "failed to refill htt rx ring: %d\n", status);
		goto err_hif_stop;
	}

K
Kalle Valo 已提交
1691 1692 1693 1694 1695 1696 1697
	/* we don't care about HTT in UTF mode */
	if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
		status = ath10k_htt_setup(&ar->htt);
		if (status) {
			ath10k_err(ar, "failed to setup htt: %d\n", status);
			goto err_hif_stop;
		}
M
Michal Kazior 已提交
1698
	}
1699

1700 1701
	status = ath10k_debug_start(ar);
	if (status)
M
Michal Kazior 已提交
1702
		goto err_hif_stop;
1703

1704
	ar->free_vdev_map = (1LL << ar->max_num_vdevs) - 1;
1705

M
Michal Kazior 已提交
1706
	INIT_LIST_HEAD(&ar->arvifs);
1707

1708 1709
	return 0;

M
Michal Kazior 已提交
1710 1711
err_hif_stop:
	ath10k_hif_stop(ar);
M
Michal Kazior 已提交
1712 1713 1714 1715
err_htt_rx_detach:
	ath10k_htt_rx_free(&ar->htt);
err_htt_tx_detach:
	ath10k_htt_tx_free(&ar->htt);
1716 1717 1718 1719 1720
err_wmi_detach:
	ath10k_wmi_detach(ar);
err:
	return status;
}
1721
EXPORT_SYMBOL(ath10k_core_start);
1722

1723 1724 1725
int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt)
{
	int ret;
1726
	unsigned long time_left;
1727 1728 1729 1730 1731

	reinit_completion(&ar->target_suspend);

	ret = ath10k_wmi_pdev_suspend_target(ar, suspend_opt);
	if (ret) {
1732
		ath10k_warn(ar, "could not suspend target (%d)\n", ret);
1733 1734 1735
		return ret;
	}

1736
	time_left = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ);
1737

1738
	if (!time_left) {
1739
		ath10k_warn(ar, "suspend timed out - target pause event never came\n");
1740 1741 1742 1743 1744 1745
		return -ETIMEDOUT;
	}

	return 0;
}

1746 1747
void ath10k_core_stop(struct ath10k *ar)
{
1748
	lockdep_assert_held(&ar->conf_mutex);
1749
	ath10k_debug_stop(ar);
1750

1751
	/* try to suspend target */
K
Kalle Valo 已提交
1752 1753
	if (ar->state != ATH10K_STATE_RESTARTING &&
	    ar->state != ATH10K_STATE_UTF)
1754 1755
		ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);

M
Michal Kazior 已提交
1756 1757 1758
	ath10k_hif_stop(ar);
	ath10k_htt_tx_free(&ar->htt);
	ath10k_htt_rx_free(&ar->htt);
1759 1760
	ath10k_wmi_detach(ar);
}
1761 1762 1763 1764 1765 1766 1767 1768
EXPORT_SYMBOL(ath10k_core_stop);

/* mac80211 manages fw/hw initialization through start/stop hooks. However in
 * order to know what hw capabilities should be advertised to mac80211 it is
 * necessary to load the firmware (and tear it down immediately since start
 * hook will try to init it again) before registering */
static int ath10k_core_probe_fw(struct ath10k *ar)
{
1769 1770
	struct bmi_target_info target_info;
	int ret = 0;
1771 1772 1773

	ret = ath10k_hif_power_up(ar);
	if (ret) {
1774
		ath10k_err(ar, "could not start pci hif (%d)\n", ret);
1775 1776 1777
		return ret;
	}

1778 1779 1780
	memset(&target_info, 0, sizeof(target_info));
	ret = ath10k_bmi_get_target_info(ar, &target_info);
	if (ret) {
1781
		ath10k_err(ar, "could not get target info (%d)\n", ret);
1782
		goto err_power_down;
1783 1784 1785 1786 1787 1788 1789
	}

	ar->target_version = target_info.version;
	ar->hw->wiphy->hw_version = target_info.version;

	ret = ath10k_init_hw_params(ar);
	if (ret) {
1790
		ath10k_err(ar, "could not get hw params (%d)\n", ret);
1791
		goto err_power_down;
1792 1793 1794 1795
	}

	ret = ath10k_core_fetch_firmware_files(ar);
	if (ret) {
1796
		ath10k_err(ar, "could not fetch firmware files (%d)\n", ret);
1797
		goto err_power_down;
1798 1799
	}

1800 1801
	ath10k_debug_print_hwfw_info(ar);

1802 1803
	ret = ath10k_core_get_board_id_from_otp(ar);
	if (ret && ret != -EOPNOTSUPP) {
1804
		ath10k_err(ar, "failed to get board id from otp: %d\n",
1805 1806 1807 1808 1809 1810 1811 1812 1813 1814
			   ret);
		return ret;
	}

	ret = ath10k_core_fetch_board_file(ar);
	if (ret) {
		ath10k_err(ar, "failed to fetch board file: %d\n", ret);
		goto err_free_firmware_files;
	}

1815 1816
	ath10k_debug_print_board_info(ar);

1817 1818 1819 1820 1821 1822
	ret = ath10k_core_init_firmware_features(ar);
	if (ret) {
		ath10k_err(ar, "fatal problem with firmware features: %d\n",
			   ret);
		goto err_free_firmware_files;
	}
1823

1824 1825 1826 1827 1828 1829 1830
	ret = ath10k_swap_code_seg_init(ar);
	if (ret) {
		ath10k_err(ar, "failed to initialize code swap segment: %d\n",
			   ret);
		goto err_free_firmware_files;
	}

1831 1832
	mutex_lock(&ar->conf_mutex);

K
Kalle Valo 已提交
1833
	ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
1834
	if (ret) {
1835
		ath10k_err(ar, "could not init core (%d)\n", ret);
1836
		goto err_unlock;
1837 1838
	}

1839
	ath10k_debug_print_boot_info(ar);
1840
	ath10k_core_stop(ar);
1841 1842 1843

	mutex_unlock(&ar->conf_mutex);

1844 1845
	ath10k_hif_power_down(ar);
	return 0;
1846 1847 1848 1849

err_unlock:
	mutex_unlock(&ar->conf_mutex);

1850
err_free_firmware_files:
1851 1852 1853 1854 1855 1856
	ath10k_core_free_firmware_files(ar);

err_power_down:
	ath10k_hif_power_down(ar);

	return ret;
1857
}
1858

1859
static void ath10k_core_register_work(struct work_struct *work)
1860
{
1861
	struct ath10k *ar = container_of(work, struct ath10k, register_work);
1862 1863
	int status;

1864 1865
	status = ath10k_core_probe_fw(ar);
	if (status) {
1866
		ath10k_err(ar, "could not probe fw (%d)\n", status);
1867
		goto err;
1868
	}
1869

1870
	status = ath10k_mac_register(ar);
1871
	if (status) {
1872
		ath10k_err(ar, "could not register to mac80211 (%d)\n", status);
1873
		goto err_release_fw;
1874
	}
1875

1876
	status = ath10k_debug_register(ar);
1877
	if (status) {
1878
		ath10k_err(ar, "unable to initialize debugfs\n");
1879 1880 1881
		goto err_unregister_mac;
	}

1882 1883
	status = ath10k_spectral_create(ar);
	if (status) {
1884
		ath10k_err(ar, "failed to initialize spectral\n");
1885 1886 1887
		goto err_debug_destroy;
	}

1888 1889 1890 1891 1892 1893 1894
	status = ath10k_thermal_register(ar);
	if (status) {
		ath10k_err(ar, "could not register thermal device: %d\n",
			   status);
		goto err_spectral_destroy;
	}

1895 1896
	set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);
	return;
1897

1898 1899
err_spectral_destroy:
	ath10k_spectral_destroy(ar);
1900 1901
err_debug_destroy:
	ath10k_debug_destroy(ar);
1902 1903
err_unregister_mac:
	ath10k_mac_unregister(ar);
1904 1905
err_release_fw:
	ath10k_core_free_firmware_files(ar);
1906
err:
1907 1908 1909
	/* TODO: It's probably a good idea to release device from the driver
	 * but calling device_release_driver() here will cause a deadlock.
	 */
1910 1911 1912 1913 1914 1915 1916 1917 1918
	return;
}

int ath10k_core_register(struct ath10k *ar, u32 chip_id)
{
	ar->chip_id = chip_id;
	queue_work(ar->workqueue, &ar->register_work);

	return 0;
1919 1920 1921 1922 1923
}
EXPORT_SYMBOL(ath10k_core_register);

void ath10k_core_unregister(struct ath10k *ar)
{
1924 1925 1926 1927 1928
	cancel_work_sync(&ar->register_work);

	if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
		return;

1929
	ath10k_thermal_unregister(ar);
1930 1931 1932 1933 1934 1935
	/* Stop spectral before unregistering from mac80211 to remove the
	 * relayfs debugfs file cleanly. Otherwise the parent debugfs tree
	 * would be already be free'd recursively, leading to a double free.
	 */
	ath10k_spectral_destroy(ar);

1936 1937 1938 1939
	/* We must unregister from mac80211 before we stop HTC and HIF.
	 * Otherwise we will fail to submit commands to FW and mac80211 will be
	 * unhappy about callback failures. */
	ath10k_mac_unregister(ar);
1940

K
Kalle Valo 已提交
1941 1942
	ath10k_testmode_destroy(ar);

1943
	ath10k_core_free_firmware_files(ar);
1944
	ath10k_core_free_board_files(ar);
1945

1946
	ath10k_debug_unregister(ar);
1947 1948 1949
}
EXPORT_SYMBOL(ath10k_core_unregister);

M
Michal Kazior 已提交
1950
struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
K
Kalle Valo 已提交
1951
				  enum ath10k_bus bus,
M
Michal Kazior 已提交
1952
				  enum ath10k_hw_rev hw_rev,
1953 1954 1955
				  const struct ath10k_hif_ops *hif_ops)
{
	struct ath10k *ar;
1956
	int ret;
1957

M
Michal Kazior 已提交
1958
	ar = ath10k_mac_create(priv_size);
1959 1960 1961 1962 1963 1964
	if (!ar)
		return NULL;

	ar->ath_common.priv = ar;
	ar->ath_common.hw = ar->hw;
	ar->dev = dev;
M
Michal Kazior 已提交
1965
	ar->hw_rev = hw_rev;
1966
	ar->hif.ops = hif_ops;
K
Kalle Valo 已提交
1967
	ar->hif.bus = bus;
1968

M
Michal Kazior 已提交
1969 1970 1971
	switch (hw_rev) {
	case ATH10K_HW_QCA988X:
		ar->regs = &qca988x_regs;
1972
		ar->hw_values = &qca988x_values;
M
Michal Kazior 已提交
1973 1974
		break;
	case ATH10K_HW_QCA6174:
1975
	case ATH10K_HW_QCA9377:
M
Michal Kazior 已提交
1976
		ar->regs = &qca6174_regs;
1977
		ar->hw_values = &qca6174_values;
M
Michal Kazior 已提交
1978
		break;
1979 1980 1981 1982
	case ATH10K_HW_QCA99X0:
		ar->regs = &qca99x0_regs;
		ar->hw_values = &qca99x0_values;
		break;
M
Michal Kazior 已提交
1983 1984 1985 1986 1987 1988 1989
	default:
		ath10k_err(ar, "unsupported core hardware revision %d\n",
			   hw_rev);
		ret = -ENOTSUPP;
		goto err_free_mac;
	}

1990 1991 1992 1993
	init_completion(&ar->scan.started);
	init_completion(&ar->scan.completed);
	init_completion(&ar->scan.on_channel);
	init_completion(&ar->target_suspend);
1994
	init_completion(&ar->wow.wakeup_completed);
1995 1996 1997

	init_completion(&ar->install_key_done);
	init_completion(&ar->vdev_setup_done);
1998
	init_completion(&ar->thermal.wmi_sync);
1999

2000
	INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work);
2001 2002 2003

	ar->workqueue = create_singlethread_workqueue("ath10k_wq");
	if (!ar->workqueue)
2004
		goto err_free_mac;
2005

2006 2007 2008 2009
	ar->workqueue_aux = create_singlethread_workqueue("ath10k_aux_wq");
	if (!ar->workqueue_aux)
		goto err_free_wq;

2010 2011 2012 2013 2014
	mutex_init(&ar->conf_mutex);
	spin_lock_init(&ar->data_lock);

	INIT_LIST_HEAD(&ar->peers);
	init_waitqueue_head(&ar->peer_mapping_wq);
M
Michal Kazior 已提交
2015 2016
	init_waitqueue_head(&ar->htt.empty_tx_wq);
	init_waitqueue_head(&ar->wmi.tx_credits_wq);
2017 2018 2019 2020 2021 2022 2023 2024

	init_completion(&ar->offchan_tx_completed);
	INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work);
	skb_queue_head_init(&ar->offchan_tx_queue);

	INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work);
	skb_queue_head_init(&ar->wmi_mgmt_tx_queue);

2025
	INIT_WORK(&ar->register_work, ath10k_core_register_work);
2026 2027
	INIT_WORK(&ar->restart_work, ath10k_core_restart);

2028 2029
	ret = ath10k_debug_create(ar);
	if (ret)
2030
		goto err_free_aux_wq;
2031

2032 2033
	return ar;

2034 2035
err_free_aux_wq:
	destroy_workqueue(ar->workqueue_aux);
2036 2037 2038 2039
err_free_wq:
	destroy_workqueue(ar->workqueue);

err_free_mac:
2040
	ath10k_mac_destroy(ar);
2041

2042 2043 2044 2045 2046 2047 2048 2049 2050
	return NULL;
}
EXPORT_SYMBOL(ath10k_core_create);

void ath10k_core_destroy(struct ath10k *ar)
{
	flush_workqueue(ar->workqueue);
	destroy_workqueue(ar->workqueue);

2051 2052 2053
	flush_workqueue(ar->workqueue_aux);
	destroy_workqueue(ar->workqueue_aux);

2054
	ath10k_debug_destroy(ar);
2055
	ath10k_wmi_free_host_mem(ar);
2056 2057 2058 2059
	ath10k_mac_destroy(ar);
}
EXPORT_SYMBOL(ath10k_core_destroy);

2060 2061 2062
MODULE_AUTHOR("Qualcomm Atheros");
MODULE_DESCRIPTION("Core module for QCA988X PCIe devices.");
MODULE_LICENSE("Dual BSD/GPL");