Lines Matching +full:x +full:- +full:rc
1 // SPDX-License-Identifier: ISC
3 * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
4 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
25 wil_err_fw(wil, "bad %s: 0x%08x\n", msg, le32_to_cpu(val)); in wil_fw_addr_check()
32 * wil_fw_verify - verify firmware file validity
49 return -EINVAL; in wil_fw_verify()
54 return -EINVAL; in wil_fw_verify()
58 if (le16_to_cpu(hdr->type) != wil_fw_type_file_header) { in wil_fw_verify()
60 return -EINVAL; in wil_fw_verify()
65 dlen = le32_to_cpu(fh_->data_len); in wil_fw_verify()
68 return -EINVAL; in wil_fw_verify()
73 return -EINVAL; in wil_fw_verify()
77 return -EINVAL; in wil_fw_verify()
81 if (le32_to_cpu(fh_->signature) != WIL_FW_SIGNATURE) { in wil_fw_verify()
82 wil_err_fw(wil, "bad header signature: 0x%08x\n", in wil_fw_verify()
83 le32_to_cpu(fh_->signature)); in wil_fw_verify()
84 return -EINVAL; in wil_fw_verify()
88 if (le32_to_cpu(fh_->version) > WIL_FW_FMT_VERSION) { in wil_fw_verify()
90 le32_to_cpu(fh_->version)); in wil_fw_verify()
91 return -EINVAL; in wil_fw_verify()
101 dlen - sizeof(*hdr) - sizeof(fh)); in wil_fw_verify()
104 if (crc != le32_to_cpu(fh_->crc)) { in wil_fw_verify()
106 " calculated for %lu bytes 0x%08x != 0x%08x\n", in wil_fw_verify()
107 (ulong)dlen, crc, le32_to_cpu(fh_->crc)); in wil_fw_verify()
108 return -EINVAL; in wil_fw_verify()
133 capa_size = size - offsetof(struct wil_fw_record_capabilities, in fw_handle_capabilities()
135 bitmap_zero(wil->fw_capabilities, WMI_FW_CAPABILITY_MAX); in fw_handle_capabilities()
136 memcpy(wil->fw_capabilities, rec->capabilities, in fw_handle_capabilities()
137 min_t(size_t, sizeof(wil->fw_capabilities), capa_size)); in fw_handle_capabilities()
139 rec->capabilities, capa_size, false); in fw_handle_capabilities()
152 return -EINVAL; in fw_handle_brd_file()
155 ent_size = size - offsetof(struct wil_fw_record_brd_file, brd_info); in fw_handle_brd_file()
160 return -EINVAL; in fw_handle_brd_file()
163 wil->brd_info = kcalloc(max_num_ent, sizeof(struct wil_brd_info), in fw_handle_brd_file()
165 if (!wil->brd_info) in fw_handle_brd_file()
166 return -ENOMEM; in fw_handle_brd_file()
169 wil->brd_info[i].file_addr = in fw_handle_brd_file()
170 le32_to_cpu(rec->brd_info[i].base_addr); in fw_handle_brd_file()
171 wil->brd_info[i].file_max_size = in fw_handle_brd_file()
172 le32_to_cpu(rec->brd_info[i].max_size_bytes); in fw_handle_brd_file()
174 if (!wil->brd_info[i].file_addr) in fw_handle_brd_file()
178 "brd info %d: file_addr 0x%x, file_max_size %d\n", in fw_handle_brd_file()
179 i, wil->brd_info[i].file_addr, in fw_handle_brd_file()
180 wil->brd_info[i].file_max_size); in fw_handle_brd_file()
183 wil->num_of_brd_entries = i; in fw_handle_brd_file()
184 if (wil->num_of_brd_entries == 0) { in fw_handle_brd_file()
185 kfree(wil->brd_info); in fw_handle_brd_file()
186 wil->brd_info = NULL; in fw_handle_brd_file()
192 wil->num_of_brd_entries); in fw_handle_brd_file()
214 n_combos = le16_to_cpu(rec->n_combos); in fw_handle_concurrency()
215 remain = size - offsetof(struct wil_fw_record_concurrency, combos); in fw_handle_concurrency()
216 combo = rec->combos; in fw_handle_concurrency()
220 remain -= sizeof(*combo); in fw_handle_concurrency()
221 limit = combo->limits; in fw_handle_concurrency()
222 lsize = combo->n_limits * sizeof(*limit); in fw_handle_concurrency()
225 remain -= lsize; in fw_handle_concurrency()
226 limit += combo->n_limits; in fw_handle_concurrency()
242 int rc = 0; in fw_handle_comment() local
247 magic = le32_to_cpu(hdr->magic); in fw_handle_comment()
252 rc = fw_handle_capabilities(wil, data, size); in fw_handle_comment()
256 rc = fw_handle_brd_file(wil, data, size); in fw_handle_comment()
260 rc = fw_handle_concurrency(wil, data, size); in fw_handle_comment()
267 return rc; in fw_handle_comment()
275 size_t s = size - sizeof(*d); in __fw_handle_data()
279 return -EINVAL; in __fw_handle_data()
283 return -EINVAL; in __fw_handle_data()
284 wil_dbg_fw(wil, "write [0x%08x] <== %zu bytes\n", le32_to_cpu(addr), s); in __fw_handle_data()
285 wil_memcpy_toio_32(dst, d->data, s); in __fw_handle_data()
296 return __fw_handle_data(wil, data, size, d->addr); in fw_handle_data()
305 size_t s = (size_t)le32_to_cpu(d->size); in fw_handle_fill()
309 return -EINVAL; in fw_handle_fill()
314 return -EINVAL; in fw_handle_fill()
319 return -EINVAL; in fw_handle_fill()
322 if (!wil_fw_addr_check(wil, &dst, d->addr, s, "address")) in fw_handle_fill()
323 return -EINVAL; in fw_handle_fill()
325 v = le32_to_cpu(d->value); in fw_handle_fill()
326 wil_dbg_fw(wil, "fill [0x%08x] <== 0x%08x, %zu bytes\n", in fw_handle_fill()
327 le32_to_cpu(d->addr), v, s); in fw_handle_fill()
341 return -EINVAL; in fw_handle_file_header()
345 d->version, d->data_len); in fw_handle_file_header()
346 wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, d->comment, in fw_handle_file_header()
347 sizeof(d->comment), true); in fw_handle_file_header()
349 if (!memcmp(d->comment, WIL_FW_VERSION_PREFIX, in fw_handle_file_header()
351 memcpy(wil->fw_version, in fw_handle_file_header()
352 d->comment + WIL_FW_VERSION_PREFIX_LEN, in fw_handle_file_header()
353 min(sizeof(d->comment) - WIL_FW_VERSION_PREFIX_LEN, in fw_handle_file_header()
354 sizeof(wil->fw_version) - 1)); in fw_handle_file_header()
363 const struct wil_fw_data_dwrite *block = d->data; in fw_handle_direct_write()
369 return -EINVAL; in fw_handle_direct_write()
377 u32 x, y; in fw_handle_direct_write() local
380 return -EINVAL; in fw_handle_direct_write()
382 x = readl(dst); in fw_handle_direct_write()
383 y = (x & m) | (v & ~m); in fw_handle_direct_write()
384 wil_dbg_fw(wil, "write [0x%08x] <== 0x%08x " in fw_handle_direct_write()
385 "(old 0x%08x val 0x%08x mask 0x%08x)\n", in fw_handle_direct_write()
386 le32_to_cpu(block[i].addr), y, x, v, m); in fw_handle_direct_write()
409 return -EINVAL; in gw_write()
420 const struct wil_fw_data_gw *block = d->data; in fw_handle_gateway_data()
430 return -EINVAL; in fw_handle_gateway_data()
433 if ((size - sizeof(*d)) % sizeof(*block)) { in fw_handle_gateway_data()
436 sizeof(*block), size - sizeof(*d)); in fw_handle_gateway_data()
437 return -EINVAL; in fw_handle_gateway_data()
439 n = (size - sizeof(*d)) / sizeof(*block); in fw_handle_gateway_data()
441 gw_cmd = le32_to_cpu(d->command); in fw_handle_gateway_data()
443 wil_dbg_fw(wil, "gw write record [%3d] blocks, cmd 0x%08x\n", in fw_handle_gateway_data()
446 if (!wil_fw_addr_check(wil, &gwa_addr, d->gateway_addr_addr, 0, in fw_handle_gateway_data()
448 !wil_fw_addr_check(wil, &gwa_val, d->gateway_value_addr, 0, in fw_handle_gateway_data()
450 !wil_fw_addr_check(wil, &gwa_cmd, d->gateway_cmd_addr, 0, in fw_handle_gateway_data()
452 !wil_fw_addr_check(wil, &gwa_ctl, d->gateway_ctrl_address, 0, in fw_handle_gateway_data()
454 return -EINVAL; in fw_handle_gateway_data()
456 wil_dbg_fw(wil, "gw addresses: addr 0x%08x val 0x%08x" in fw_handle_gateway_data()
457 " cmd 0x%08x ctl 0x%08x\n", in fw_handle_gateway_data()
458 le32_to_cpu(d->gateway_addr_addr), in fw_handle_gateway_data()
459 le32_to_cpu(d->gateway_value_addr), in fw_handle_gateway_data()
460 le32_to_cpu(d->gateway_cmd_addr), in fw_handle_gateway_data()
461 le32_to_cpu(d->gateway_ctrl_address)); in fw_handle_gateway_data()
464 int rc; in fw_handle_gateway_data() local
468 wil_dbg_fw(wil, " gw write[%3d] [0x%08x] <== 0x%08x\n", in fw_handle_gateway_data()
472 rc = gw_write(wil, gwa_addr, gwa_cmd, gwa_ctl, gw_cmd, a); in fw_handle_gateway_data()
473 if (rc) in fw_handle_gateway_data()
474 return rc; in fw_handle_gateway_data()
484 const struct wil_fw_data_gw4 *block = d->data; in fw_handle_gateway_data4()
486 void __iomem *gwa_val[ARRAY_SIZE(block->value)]; in fw_handle_gateway_data4()
494 return -EINVAL; in fw_handle_gateway_data4()
497 if ((size - sizeof(*d)) % sizeof(*block)) { in fw_handle_gateway_data4()
500 sizeof(*block), size - sizeof(*d)); in fw_handle_gateway_data4()
501 return -EINVAL; in fw_handle_gateway_data4()
503 n = (size - sizeof(*d)) / sizeof(*block); in fw_handle_gateway_data4()
505 gw_cmd = le32_to_cpu(d->command); in fw_handle_gateway_data4()
507 wil_dbg_fw(wil, "gw4 write record [%3d] blocks, cmd 0x%08x\n", in fw_handle_gateway_data4()
510 if (!wil_fw_addr_check(wil, &gwa_addr, d->gateway_addr_addr, 0, in fw_handle_gateway_data4()
512 return -EINVAL; in fw_handle_gateway_data4()
513 for (k = 0; k < ARRAY_SIZE(block->value); k++) in fw_handle_gateway_data4()
515 d->gateway_value_addr[k], in fw_handle_gateway_data4()
517 return -EINVAL; in fw_handle_gateway_data4()
518 if (!wil_fw_addr_check(wil, &gwa_cmd, d->gateway_cmd_addr, 0, in fw_handle_gateway_data4()
520 !wil_fw_addr_check(wil, &gwa_ctl, d->gateway_ctrl_address, 0, in fw_handle_gateway_data4()
522 return -EINVAL; in fw_handle_gateway_data4()
524 wil_dbg_fw(wil, "gw4 addresses: addr 0x%08x cmd 0x%08x ctl 0x%08x\n", in fw_handle_gateway_data4()
525 le32_to_cpu(d->gateway_addr_addr), in fw_handle_gateway_data4()
526 le32_to_cpu(d->gateway_cmd_addr), in fw_handle_gateway_data4()
527 le32_to_cpu(d->gateway_ctrl_address)); in fw_handle_gateway_data4()
529 d->gateway_value_addr, sizeof(d->gateway_value_addr), in fw_handle_gateway_data4()
533 int rc; in fw_handle_gateway_data4() local
535 u32 v[ARRAY_SIZE(block->value)]; in fw_handle_gateway_data4()
537 for (k = 0; k < ARRAY_SIZE(block->value); k++) in fw_handle_gateway_data4()
540 wil_dbg_fw(wil, " gw4 write[%3d] [0x%08x] <==\n", i, a); in fw_handle_gateway_data4()
544 for (k = 0; k < ARRAY_SIZE(block->value); k++) in fw_handle_gateway_data4()
546 rc = gw_write(wil, gwa_addr, gwa_cmd, gwa_ctl, gw_cmd, a); in fw_handle_gateway_data4()
547 if (rc) in fw_handle_gateway_data4()
548 return rc; in fw_handle_gateway_data4()
588 return -EINVAL; in wil_fw_handle_record()
592 * wil_fw_process - process section from FW file
602 int rc = 0; in wil_fw_process() local
606 for (hdr = data;; hdr = (const void *)hdr + s, size -= s) { in wil_fw_process()
609 hdr_sz = le32_to_cpu(hdr->size); in wil_fw_process()
616 return -EINVAL; in wil_fw_process()
618 rc = wil_fw_handle_record(wil, le16_to_cpu(hdr->type), in wil_fw_process()
620 if (rc) in wil_fw_process()
621 return rc; in wil_fw_process()
628 (long)((const void *)hdr - data), in wil_fw_process()
629 le16_to_cpu(hdr->type), hdr_sz); in wil_fw_process()
631 return -EINVAL; in wil_fw_process()
634 return rc; in wil_fw_process()
638 * wil_request_firmware - Request firmware
649 int rc, rc1; in wil_request_firmware() local
654 rc = request_firmware(&fw, name, wil_to_dev(wil)); in wil_request_firmware()
655 if (rc) { in wil_request_firmware()
656 wil_err_fw(wil, "Failed to load firmware %s rc %d\n", name, rc); in wil_request_firmware()
657 return rc; in wil_request_firmware()
659 wil_dbg_fw(wil, "Loading <%s>, %zu bytes\n", name, fw->size); in wil_request_firmware()
661 /* re-initialize board info params */ in wil_request_firmware()
662 wil->num_of_brd_entries = 0; in wil_request_firmware()
663 kfree(wil->brd_info); in wil_request_firmware()
664 wil->brd_info = NULL; in wil_request_firmware()
666 for (sz = fw->size, d = fw->data; sz; sz -= rc1, d += rc1) { in wil_request_firmware()
669 rc = rc1; in wil_request_firmware()
672 rc = wil_fw_process(wil, d, rc1, load); in wil_request_firmware()
673 if (rc < 0) in wil_request_firmware()
679 if (rc) in wil_request_firmware()
680 wil_err_fw(wil, "Loading <%s> failed, rc %d\n", name, rc); in wil_request_firmware()
681 return rc; in wil_request_firmware()
685 * wil_brd_process - process section from BRD file
692 int rc = 0; in wil_brd_process() local
703 return -EINVAL; in wil_brd_process()
704 s = sizeof(*hdr) + le32_to_cpu(hdr->size); in wil_brd_process()
706 return -EINVAL; in wil_brd_process()
709 size -= s; in wil_brd_process()
711 for (hdr = data + s;; hdr = (const void *)hdr + s, size -= s, i++) { in wil_brd_process()
715 if (i >= wil->num_of_brd_entries) { in wil_brd_process()
718 i, wil->num_of_brd_entries); in wil_brd_process()
722 hdr_sz = le32_to_cpu(hdr->size); in wil_brd_process()
724 if (wil->brd_info[i].file_max_size && in wil_brd_process()
725 hdr_sz > wil->brd_info[i].file_max_size) in wil_brd_process()
726 return -EINVAL; in wil_brd_process()
728 return -EINVAL; in wil_brd_process()
732 return -EINVAL; in wil_brd_process()
734 type = le16_to_cpu(hdr->type); in wil_brd_process()
739 return -EINVAL; in wil_brd_process()
743 return -EINVAL; in wil_brd_process()
747 "using info from fw file for record %d: addr[0x%08x], max size %d\n", in wil_brd_process()
748 i, wil->brd_info[i].file_addr, in wil_brd_process()
749 wil->brd_info[i].file_max_size); in wil_brd_process()
751 rc = __fw_handle_data(wil, &hdr[1], hdr_sz, in wil_brd_process()
752 cpu_to_le32(wil->brd_info[i].file_addr)); in wil_brd_process()
753 if (rc) in wil_brd_process()
754 return rc; in wil_brd_process()
762 (long)((const void *)hdr - data), in wil_brd_process()
763 le16_to_cpu(hdr->type), hdr_sz); in wil_brd_process()
765 return -EINVAL; in wil_brd_process()
772 * wil_request_board - Request board file
783 int rc, dlen; in wil_request_board() local
786 rc = request_firmware(&brd, name, wil_to_dev(wil)); in wil_request_board()
787 if (rc) { in wil_request_board()
789 return rc; in wil_request_board()
791 wil_dbg_fw(wil, "Loading <%s>, %zu bytes\n", name, brd->size); in wil_request_board()
794 dlen = wil_fw_verify(wil, brd->data, brd->size); in wil_request_board()
796 rc = dlen; in wil_request_board()
801 rc = wil_brd_process(wil, brd->data, dlen); in wil_request_board()
805 if (rc) in wil_request_board()
806 wil_err_fw(wil, "Loading <%s> failed, rc %d\n", name, rc); in wil_request_board()
807 return rc; in wil_request_board()
811 * wil_fw_verify_file_exists - checks if firmware file exist
816 * return value - boolean, true for success, false for failure
821 int rc; in wil_fw_verify_file_exists() local
823 rc = request_firmware(&fw, name, wil_to_dev(wil)); in wil_fw_verify_file_exists()
824 if (!rc) in wil_fw_verify_file_exists()
827 wil_dbg_fw(wil, "<%s> not available: %d\n", name, rc); in wil_fw_verify_file_exists()
828 return !rc; in wil_fw_verify_file_exists()