Lines Matching +full:firmware +full:- +full:initialized

1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2005-2014, 2018-2024 Intel Corporation
4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
5 * Copyright (C) 2016-2017 Intel Deutschland GmbH
11 #include <linux/dma-mapping.h>
12 #include <linux/firmware.h>
16 #include "iwl-drv.h"
17 #include "iwl-csr.h"
18 #include "iwl-debug.h"
19 #include "iwl-trans.h"
20 #include "iwl-op-mode.h"
21 #include "iwl-agn-hw.h"
23 #include "iwl-dbg-tlv.h"
24 #include "iwl-config.h"
25 #include "iwl-modparams.h"
56 * struct iwl_drv - drv common data
62 * @fw_index: firmware revision to try loading
64 * @request_firmware_complete: the firmware has been obtained from user space
77 int fw_index; /* firmware we're trying to load */
78 char firmware_name[64]; /* name of firmware file to load */
103 } iwlwifi_opmode_table[] = { /* ops set when driver is initialized */
122 vfree(desc->data); in iwl_free_fw_desc()
123 desc->data = NULL; in iwl_free_fw_desc()
124 desc->len = 0; in iwl_free_fw_desc()
130 for (i = 0; i < img->num_sec; i++) in iwl_free_fw_img()
131 iwl_free_fw_desc(drv, &img->sec[i]); in iwl_free_fw_img()
132 kfree(img->sec); in iwl_free_fw_img()
139 kfree(drv->fw.dbg.dest_tlv); in iwl_dealloc_ucode()
140 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg.conf_tlv); i++) in iwl_dealloc_ucode()
141 kfree(drv->fw.dbg.conf_tlv[i]); in iwl_dealloc_ucode()
142 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg.trigger_tlv); i++) in iwl_dealloc_ucode()
143 kfree(drv->fw.dbg.trigger_tlv[i]); in iwl_dealloc_ucode()
144 kfree(drv->fw.dbg.mem_tlv); in iwl_dealloc_ucode()
145 kfree(drv->fw.iml); in iwl_dealloc_ucode()
146 kfree(drv->fw.ucode_capa.cmd_versions); in iwl_dealloc_ucode()
147 kfree(drv->fw.phy_integration_ver); in iwl_dealloc_ucode()
148 kfree(drv->trans->dbg.pc_data); in iwl_dealloc_ucode()
149 drv->trans->dbg.pc_data = NULL; in iwl_dealloc_ucode()
152 iwl_free_fw_img(drv, drv->fw.img + i); in iwl_dealloc_ucode()
155 memset(&drv->fw, 0, sizeof(drv->fw)); in iwl_dealloc_ucode()
163 desc->data = NULL; in iwl_alloc_fw_desc()
165 if (!sec || !sec->size) in iwl_alloc_fw_desc()
166 return -EINVAL; in iwl_alloc_fw_desc()
168 data = vmalloc(sec->size); in iwl_alloc_fw_desc()
170 return -ENOMEM; in iwl_alloc_fw_desc()
172 desc->len = sec->size; in iwl_alloc_fw_desc()
173 desc->offset = sec->offset; in iwl_alloc_fw_desc()
174 memcpy(data, sec->data, desc->len); in iwl_alloc_fw_desc()
175 desc->data = data; in iwl_alloc_fw_desc()
194 if (trans->cfg->fw_name_pre) in iwl_drv_get_fwname_pre()
195 return trans->cfg->fw_name_pre; in iwl_drv_get_fwname_pre()
197 if (WARN_ON(!trans->cfg->fw_name_mac)) in iwl_drv_get_fwname_pre()
200 mac_step = iwl_drv_get_step(trans->hw_rev_step); in iwl_drv_get_fwname_pre()
202 rf_step = iwl_drv_get_step(CSR_HW_RFID_STEP(trans->hw_rf_id)); in iwl_drv_get_fwname_pre()
204 switch (CSR_HW_RFID_TYPE(trans->hw_rf_id)) { in iwl_drv_get_fwname_pre()
218 CSR_HW_RFID_STEP(trans->hw_rf_id)) { in iwl_drv_get_fwname_pre()
226 return "unknown-rf"; in iwl_drv_get_fwname_pre()
229 cdb = CSR_HW_RFID_IS_CDB(trans->hw_rf_id) ? "4" : ""; in iwl_drv_get_fwname_pre()
232 "iwlwifi-%s-%c0-%s%s-%c0", in iwl_drv_get_fwname_pre()
233 trans->cfg->fw_name_mac, mac_step, in iwl_drv_get_fwname_pre()
240 static void iwl_req_fw_callback(const struct firmware *ucode_raw,
245 const struct iwl_cfg *cfg = drv->trans->cfg; in iwl_request_firmware()
249 if (drv->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_9000 && in iwl_request_firmware()
250 (drv->trans->hw_rev_step != SILICON_B_STEP && in iwl_request_firmware()
251 drv->trans->hw_rev_step != SILICON_C_STEP)) { in iwl_request_firmware()
254 drv->trans->hw_rev); in iwl_request_firmware()
255 return -EINVAL; in iwl_request_firmware()
258 fw_name_pre = iwl_drv_get_fwname_pre(drv->trans, _fw_name_pre); in iwl_request_firmware()
261 drv->fw_index = cfg->ucode_api_max; in iwl_request_firmware()
263 drv->fw_index--; in iwl_request_firmware()
265 if (drv->fw_index < cfg->ucode_api_min) { in iwl_request_firmware()
266 IWL_ERR(drv, "no suitable firmware found!\n"); in iwl_request_firmware()
268 if (cfg->ucode_api_min == cfg->ucode_api_max) { in iwl_request_firmware()
269 IWL_ERR(drv, "%s-%d is required\n", fw_name_pre, in iwl_request_firmware()
270 cfg->ucode_api_max); in iwl_request_firmware()
272 IWL_ERR(drv, "minimum version required: %s-%d\n", in iwl_request_firmware()
273 fw_name_pre, cfg->ucode_api_min); in iwl_request_firmware()
274 IWL_ERR(drv, "maximum version supported: %s-%d\n", in iwl_request_firmware()
275 fw_name_pre, cfg->ucode_api_max); in iwl_request_firmware()
279 "check git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git\n"); in iwl_request_firmware()
281 IWL_ERR(drv, "On FreeBSD the firmware package can be installed running fwget(8).\n"); in iwl_request_firmware()
283 return -ENOENT; in iwl_request_firmware()
286 snprintf(drv->firmware_name, sizeof(drv->firmware_name), "%s-%d.ucode", in iwl_request_firmware()
287 fw_name_pre, drv->fw_index); in iwl_request_firmware()
289 IWL_DEBUG_FW_INFO(drv, "attempting to load firmware '%s'\n", in iwl_request_firmware()
290 drv->firmware_name); in iwl_request_firmware()
292 return request_firmware_nowait(THIS_MODULE, 1, drv->firmware_name, in iwl_request_firmware()
293 drv->trans->dev, in iwl_request_firmware()
311 * struct iwl_tlv_calib_data - parse the default calib data from TLV
350 return &pieces->img[type].sec[sec]; in get_sec()
357 struct fw_img_parsing *img = &pieces->img[type]; in alloc_sec_data()
360 size_t alloc_size = sizeof(*img->sec) * size; in alloc_sec_data()
362 if (img->sec && img->sec_counter >= size) in alloc_sec_data()
365 sec_memory = krealloc(img->sec, alloc_size, GFP_KERNEL); in alloc_sec_data()
369 img->sec = sec_memory; in alloc_sec_data()
370 img->sec_counter = size; in alloc_sec_data()
380 pieces->img[type].sec[sec].data = data; in set_sec_data()
390 pieces->img[type].sec[sec].size = size; in set_sec_size()
397 return pieces->img[type].sec[sec].size; in get_sec_size()
407 pieces->img[type].sec[sec].offset = offset; in set_sec_offset()
423 return -1; in iwl_store_ucode_sec()
427 img = &pieces->img[type]; in iwl_store_ucode_sec()
429 alloc_size = sizeof(*img->sec) * (img->sec_counter + 1); in iwl_store_ucode_sec()
430 sec = krealloc(img->sec, alloc_size, GFP_KERNEL); in iwl_store_ucode_sec()
432 return -ENOMEM; in iwl_store_ucode_sec()
433 img->sec = sec; in iwl_store_ucode_sec()
435 sec = &img->sec[img->sec_counter]; in iwl_store_ucode_sec()
437 sec->offset = le32_to_cpu(sec_parse->offset); in iwl_store_ucode_sec()
438 sec->data = sec_parse->data; in iwl_store_ucode_sec()
439 sec->size = size - sizeof(sec_parse->offset); in iwl_store_ucode_sec()
441 ++img->sec_counter; in iwl_store_ucode_sec()
450 u32 ucode_type = le32_to_cpu(def_calib->ucode_type); in iwl_set_default_calib()
454 return -EINVAL; in iwl_set_default_calib()
456 drv->fw.default_calib[ucode_type].flow_trigger = in iwl_set_default_calib()
457 def_calib->calib.flow_trigger; in iwl_set_default_calib()
458 drv->fw.default_calib[ucode_type].event_trigger = in iwl_set_default_calib()
459 def_calib->calib.event_trigger; in iwl_set_default_calib()
468 u32 api_index = le32_to_cpu(ucode_api->api_index); in iwl_set_ucode_api_flags()
469 u32 api_flags = le32_to_cpu(ucode_api->api_flags); in iwl_set_ucode_api_flags()
481 __set_bit(i + 32 * api_index, capa->_api); in iwl_set_ucode_api_flags()
489 u32 api_index = le32_to_cpu(ucode_capa->api_index); in iwl_set_ucode_capabilities()
490 u32 api_flags = le32_to_cpu(ucode_capa->api_capa); in iwl_set_ucode_capabilities()
502 __set_bit(i + 32 * api_index, capa->_capa); in iwl_set_ucode_capabilities()
508 const char *name = drv->firmware_name; in iwl_reduced_fw_name()
510 if (strncmp(name, "iwlwifi-", 8) == 0) in iwl_reduced_fw_name()
517 const struct firmware *ucode_raw, in iwl_parse_v1_v2_firmware()
520 const struct iwl_ucode_header *ucode = (const void *)ucode_raw->data; in iwl_parse_v1_v2_firmware()
525 drv->fw.ucode_ver = le32_to_cpu(ucode->ver); in iwl_parse_v1_v2_firmware()
526 api_ver = IWL_UCODE_API(drv->fw.ucode_ver); in iwl_parse_v1_v2_firmware()
531 if (ucode_raw->size < hdr_size) { in iwl_parse_v1_v2_firmware()
533 return -EINVAL; in iwl_parse_v1_v2_firmware()
535 build = le32_to_cpu(ucode->u.v2.build); in iwl_parse_v1_v2_firmware()
537 le32_to_cpu(ucode->u.v2.inst_size)); in iwl_parse_v1_v2_firmware()
539 le32_to_cpu(ucode->u.v2.data_size)); in iwl_parse_v1_v2_firmware()
541 le32_to_cpu(ucode->u.v2.init_size)); in iwl_parse_v1_v2_firmware()
543 le32_to_cpu(ucode->u.v2.init_data_size)); in iwl_parse_v1_v2_firmware()
544 src = ucode->u.v2.data; in iwl_parse_v1_v2_firmware()
550 if (ucode_raw->size < hdr_size) { in iwl_parse_v1_v2_firmware()
552 return -EINVAL; in iwl_parse_v1_v2_firmware()
556 le32_to_cpu(ucode->u.v1.inst_size)); in iwl_parse_v1_v2_firmware()
558 le32_to_cpu(ucode->u.v1.data_size)); in iwl_parse_v1_v2_firmware()
560 le32_to_cpu(ucode->u.v1.init_size)); in iwl_parse_v1_v2_firmware()
562 le32_to_cpu(ucode->u.v1.init_data_size)); in iwl_parse_v1_v2_firmware()
563 src = ucode->u.v1.data; in iwl_parse_v1_v2_firmware()
572 snprintf(drv->fw.fw_version, in iwl_parse_v1_v2_firmware()
573 sizeof(drv->fw.fw_version), in iwl_parse_v1_v2_firmware()
575 IWL_UCODE_MAJOR(drv->fw.ucode_ver), in iwl_parse_v1_v2_firmware()
576 IWL_UCODE_MINOR(drv->fw.ucode_ver), in iwl_parse_v1_v2_firmware()
577 IWL_UCODE_API(drv->fw.ucode_ver), in iwl_parse_v1_v2_firmware()
578 IWL_UCODE_SERIAL(drv->fw.ucode_ver), in iwl_parse_v1_v2_firmware()
583 if (ucode_raw->size != hdr_size + in iwl_parse_v1_v2_firmware()
591 (int)ucode_raw->size); in iwl_parse_v1_v2_firmware()
592 return -EINVAL; in iwl_parse_v1_v2_firmware()
626 excl = &drv->fw.dump_excl[0]; in iwl_drv_set_dump_exclude()
629 if (excl->addr) in iwl_drv_set_dump_exclude()
630 excl = &drv->fw.dump_excl_wowlan[0]; in iwl_drv_set_dump_exclude()
631 } else if (fw_has_capa(&drv->fw.ucode_capa, in iwl_drv_set_dump_exclude()
634 excl = &drv->fw.dump_excl[0]; in iwl_drv_set_dump_exclude()
637 excl = &drv->fw.dump_excl_wowlan[0]; in iwl_drv_set_dump_exclude()
640 if (excl->addr) in iwl_drv_set_dump_exclude()
643 if (excl->addr) { in iwl_drv_set_dump_exclude()
648 excl->addr = le32_to_cpu(fw->addr) & ~FW_ADDR_CACHE_CONTROL; in iwl_drv_set_dump_exclude()
649 excl->size = le32_to_cpu(fw->size); in iwl_drv_set_dump_exclude()
656 u32 length = le32_to_cpu(tlv->length); in iwl_parse_dbg_tlv_assert_tables()
660 sizeof(region->special_mem)) in iwl_parse_dbg_tlv_assert_tables()
663 region = (const void *)tlv->data; in iwl_parse_dbg_tlv_assert_tables()
664 addr = le32_to_cpu(region->special_mem.base_addr); in iwl_parse_dbg_tlv_assert_tables()
665 addr += le32_to_cpu(region->special_mem.offset); in iwl_parse_dbg_tlv_assert_tables()
668 if (region->type != IWL_FW_INI_REGION_SPECIAL_DEVICE_MEMORY) in iwl_parse_dbg_tlv_assert_tables()
671 switch (region->sub_type) { in iwl_parse_dbg_tlv_assert_tables()
673 drv->trans->dbg.umac_error_event_table = addr; in iwl_parse_dbg_tlv_assert_tables()
674 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
678 drv->trans->dbg.lmac_error_event_table[0] = addr; in iwl_parse_dbg_tlv_assert_tables()
679 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
683 drv->trans->dbg.lmac_error_event_table[1] = addr; in iwl_parse_dbg_tlv_assert_tables()
684 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
688 drv->trans->dbg.tcm_error_event_table[0] = addr; in iwl_parse_dbg_tlv_assert_tables()
689 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
693 drv->trans->dbg.tcm_error_event_table[1] = addr; in iwl_parse_dbg_tlv_assert_tables()
694 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
698 drv->trans->dbg.rcm_error_event_table[0] = addr; in iwl_parse_dbg_tlv_assert_tables()
699 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
703 drv->trans->dbg.rcm_error_event_table[1] = addr; in iwl_parse_dbg_tlv_assert_tables()
704 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
713 const struct firmware *ucode_raw, in iwl_parse_tlv_firmware()
718 const struct iwl_tlv_ucode_header *ucode = (const void *)ucode_raw->data; in iwl_parse_tlv_firmware()
720 size_t len = ucode_raw->size; in iwl_parse_tlv_firmware()
733 return -EINVAL; in iwl_parse_tlv_firmware()
736 if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { in iwl_parse_tlv_firmware()
738 le32_to_cpu(ucode->magic)); in iwl_parse_tlv_firmware()
739 return -EINVAL; in iwl_parse_tlv_firmware()
742 drv->fw.ucode_ver = le32_to_cpu(ucode->ver); in iwl_parse_tlv_firmware()
743 memcpy(drv->fw.human_readable, ucode->human_readable, in iwl_parse_tlv_firmware()
744 sizeof(drv->fw.human_readable)); in iwl_parse_tlv_firmware()
745 build = le32_to_cpu(ucode->build); in iwl_parse_tlv_firmware()
752 snprintf(drv->fw.fw_version, in iwl_parse_tlv_firmware()
753 sizeof(drv->fw.fw_version), in iwl_parse_tlv_firmware()
755 IWL_UCODE_MAJOR(drv->fw.ucode_ver), in iwl_parse_tlv_firmware()
756 IWL_UCODE_MINOR(drv->fw.ucode_ver), in iwl_parse_tlv_firmware()
757 IWL_UCODE_API(drv->fw.ucode_ver), in iwl_parse_tlv_firmware()
758 IWL_UCODE_SERIAL(drv->fw.ucode_ver), in iwl_parse_tlv_firmware()
761 data = ucode->data; in iwl_parse_tlv_firmware()
763 len -= sizeof(*ucode); in iwl_parse_tlv_firmware()
766 len -= sizeof(*tlv); in iwl_parse_tlv_firmware()
769 tlv_len = le32_to_cpu(tlv->length); in iwl_parse_tlv_firmware()
770 tlv_type = le32_to_cpu(tlv->type); in iwl_parse_tlv_firmware()
771 tlv_data = tlv->data; in iwl_parse_tlv_firmware()
776 return -EINVAL; in iwl_parse_tlv_firmware()
778 len -= ALIGN(tlv_len, 4); in iwl_parse_tlv_firmware()
824 capa->max_probe_length = in iwl_parse_tlv_firmware()
830 capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; in iwl_parse_tlv_firmware()
843 * will not work with the new firmware, or in iwl_parse_tlv_firmware()
846 capa->flags = le32_to_cpup((const __le32 *)tlv_data); in iwl_parse_tlv_firmware()
861 pieces->init_evtlog_ptr = in iwl_parse_tlv_firmware()
867 pieces->init_evtlog_size = in iwl_parse_tlv_firmware()
873 pieces->init_errlog_ptr = in iwl_parse_tlv_firmware()
879 pieces->inst_evtlog_ptr = in iwl_parse_tlv_firmware()
885 pieces->inst_evtlog_size = in iwl_parse_tlv_firmware()
891 pieces->inst_errlog_ptr = in iwl_parse_tlv_firmware()
897 drv->fw.enhance_sensitivity_table = true; in iwl_parse_tlv_firmware()
920 capa->standard_phy_calibration_size = in iwl_parse_tlv_firmware()
926 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
931 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
936 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
947 drv->fw.phy_config = le32_to_cpup((const __le32 *)tlv_data); in iwl_parse_tlv_firmware()
948 drv->fw.valid_tx_ant = (drv->fw.phy_config & in iwl_parse_tlv_firmware()
951 drv->fw.valid_rx_ant = (drv->fw.phy_config & in iwl_parse_tlv_firmware()
958 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
963 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
968 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
977 drv->fw.img[IWL_UCODE_REGULAR].is_dual_cpus = in iwl_parse_tlv_firmware()
979 drv->fw.img[IWL_UCODE_INIT].is_dual_cpus = in iwl_parse_tlv_firmware()
981 drv->fw.img[IWL_UCODE_WOWLAN].is_dual_cpus = in iwl_parse_tlv_firmware()
985 return -EINVAL; in iwl_parse_tlv_firmware()
991 capa->n_scan_channels = in iwl_parse_tlv_firmware()
1006 snprintf(drv->fw.fw_version, in iwl_parse_tlv_firmware()
1007 sizeof(drv->fw.fw_version), in iwl_parse_tlv_firmware()
1017 pieces->dbg_dest_ver = (const u8 *)tlv_data; in iwl_parse_tlv_firmware()
1018 if (*pieces->dbg_dest_ver == 1) { in iwl_parse_tlv_firmware()
1020 } else if (*pieces->dbg_dest_ver == 0) { in iwl_parse_tlv_firmware()
1025 *pieces->dbg_dest_ver); in iwl_parse_tlv_firmware()
1029 if (pieces->dbg_dest_tlv_init) { in iwl_parse_tlv_firmware()
1035 pieces->dbg_dest_tlv_init = true; in iwl_parse_tlv_firmware()
1038 pieces->dbg_dest_tlv_v1 = dest_v1; in iwl_parse_tlv_firmware()
1039 mon_mode = dest_v1->monitor_mode; in iwl_parse_tlv_firmware()
1041 pieces->dbg_dest_tlv = dest; in iwl_parse_tlv_firmware()
1042 mon_mode = dest->monitor_mode; in iwl_parse_tlv_firmware()
1048 drv->fw.dbg.n_dest_reg = (dest_v1) ? in iwl_parse_tlv_firmware()
1049 tlv_len - in iwl_parse_tlv_firmware()
1052 tlv_len - in iwl_parse_tlv_firmware()
1056 drv->fw.dbg.n_dest_reg /= in iwl_parse_tlv_firmware()
1057 sizeof(drv->fw.dbg.dest_tlv->reg_ops[0]); in iwl_parse_tlv_firmware()
1065 if (!pieces->dbg_dest_tlv_init) { in iwl_parse_tlv_firmware()
1067 "Ignore dbg config %d - no destination configured\n", in iwl_parse_tlv_firmware()
1068 conf->id); in iwl_parse_tlv_firmware()
1072 if (conf->id >= ARRAY_SIZE(drv->fw.dbg.conf_tlv)) { in iwl_parse_tlv_firmware()
1075 conf->id); in iwl_parse_tlv_firmware()
1079 if (pieces->dbg_conf_tlv[conf->id]) { in iwl_parse_tlv_firmware()
1082 conf->id); in iwl_parse_tlv_firmware()
1086 if (conf->usniffer) in iwl_parse_tlv_firmware()
1090 conf->id); in iwl_parse_tlv_firmware()
1092 pieces->dbg_conf_tlv[conf->id] = conf; in iwl_parse_tlv_firmware()
1093 pieces->dbg_conf_tlv_len[conf->id] = tlv_len; in iwl_parse_tlv_firmware()
1099 u32 trigger_id = le32_to_cpu(trigger->id); in iwl_parse_tlv_firmware()
1101 if (trigger_id >= ARRAY_SIZE(drv->fw.dbg.trigger_tlv)) { in iwl_parse_tlv_firmware()
1104 trigger->id); in iwl_parse_tlv_firmware()
1108 if (pieces->dbg_trigger_tlv[trigger_id]) { in iwl_parse_tlv_firmware()
1111 trigger->id); in iwl_parse_tlv_firmware()
1115 IWL_INFO(drv, "Found debug trigger: %u\n", trigger->id); in iwl_parse_tlv_firmware()
1117 pieces->dbg_trigger_tlv[trigger_id] = trigger; in iwl_parse_tlv_firmware()
1118 pieces->dbg_trigger_tlv_len[trigger_id] = tlv_len; in iwl_parse_tlv_firmware()
1128 drv->fw.dbg.dump_mask = in iwl_parse_tlv_firmware()
1151 return -EINVAL; in iwl_parse_tlv_firmware()
1154 if (paging_mem_size & (FW_PAGING_SIZE - 1)) { in iwl_parse_tlv_firmware()
1158 return -EINVAL; in iwl_parse_tlv_firmware()
1161 drv->fw.img[IWL_UCODE_REGULAR].paging_mem_size = in iwl_parse_tlv_firmware()
1164 drv->fw.img[usniffer_img].paging_mem_size = in iwl_parse_tlv_firmware()
1180 dbg_mem->data_type); in iwl_parse_tlv_firmware()
1182 size = sizeof(*pieces->dbg_mem_tlv) * in iwl_parse_tlv_firmware()
1183 (pieces->n_mem_tlv + 1); in iwl_parse_tlv_firmware()
1184 n = krealloc(pieces->dbg_mem_tlv, size, GFP_KERNEL); in iwl_parse_tlv_firmware()
1186 return -ENOMEM; in iwl_parse_tlv_firmware()
1187 pieces->dbg_mem_tlv = n; in iwl_parse_tlv_firmware()
1188 pieces->dbg_mem_tlv[pieces->n_mem_tlv] = *dbg_mem; in iwl_parse_tlv_firmware()
1189 pieces->n_mem_tlv++; in iwl_parse_tlv_firmware()
1193 drv->fw.iml_len = tlv_len; in iwl_parse_tlv_firmware()
1194 drv->fw.iml = kmemdup(tlv_data, tlv_len, GFP_KERNEL); in iwl_parse_tlv_firmware()
1195 if (!drv->fw.iml) in iwl_parse_tlv_firmware()
1196 return -ENOMEM; in iwl_parse_tlv_firmware()
1207 capa->error_log_addr = in iwl_parse_tlv_firmware()
1208 le32_to_cpu(recov_info->buf_addr); in iwl_parse_tlv_firmware()
1209 capa->error_log_size = in iwl_parse_tlv_firmware()
1210 le32_to_cpu(recov_info->buf_size); in iwl_parse_tlv_firmware()
1222 fseq_ver->version); in iwl_parse_tlv_firmware()
1235 capa->num_stations = in iwl_parse_tlv_firmware()
1241 capa->num_beacons = in iwl_parse_tlv_firmware()
1250 if (drv->trans->trans_cfg->device_family < in iwl_parse_tlv_firmware()
1253 drv->trans->dbg.umac_error_event_table = in iwl_parse_tlv_firmware()
1254 le32_to_cpu(dbg_ptrs->error_info_addr) & in iwl_parse_tlv_firmware()
1256 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_tlv_firmware()
1266 if (drv->trans->trans_cfg->device_family < in iwl_parse_tlv_firmware()
1269 drv->trans->dbg.lmac_error_event_table[0] = in iwl_parse_tlv_firmware()
1270 le32_to_cpu(dbg_ptrs->error_event_table_ptr) & in iwl_parse_tlv_firmware()
1272 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_tlv_firmware()
1285 iwl_dbg_tlv_alloc(drv->trans, tlv, false); in iwl_parse_tlv_firmware()
1295 if (WARN_ON(capa->cmd_versions)) in iwl_parse_tlv_firmware()
1296 return -EINVAL; in iwl_parse_tlv_firmware()
1297 capa->cmd_versions = kmemdup(tlv_data, tlv_len, in iwl_parse_tlv_firmware()
1299 if (!capa->cmd_versions) in iwl_parse_tlv_firmware()
1300 return -ENOMEM; in iwl_parse_tlv_firmware()
1301 capa->n_cmd_versions = in iwl_parse_tlv_firmware()
1305 if (drv->fw.phy_integration_ver) { in iwl_parse_tlv_firmware()
1311 drv->fw.phy_integration_ver = in iwl_parse_tlv_firmware()
1313 if (!drv->fw.phy_integration_ver) in iwl_parse_tlv_firmware()
1314 return -ENOMEM; in iwl_parse_tlv_firmware()
1315 drv->fw.phy_integration_ver_len = tlv_len; in iwl_parse_tlv_firmware()
1325 drv->trans->dbg.pc_data = in iwl_parse_tlv_firmware()
1327 if (!drv->trans->dbg.pc_data) in iwl_parse_tlv_firmware()
1328 return -ENOMEM; in iwl_parse_tlv_firmware()
1329 drv->trans->dbg.num_pc = in iwl_parse_tlv_firmware()
1342 return -EINVAL; in iwl_parse_tlv_firmware()
1354 return -EINVAL; in iwl_parse_tlv_firmware()
1370 return -EINVAL; in iwl_parse_tlv_firmware()
1380 sec = kcalloc(pieces->img[type].sec_counter, sizeof(*sec), GFP_KERNEL); in iwl_alloc_ucode()
1382 return -ENOMEM; in iwl_alloc_ucode()
1383 drv->fw.img[type].sec = sec; in iwl_alloc_ucode()
1384 drv->fw.img[type].num_sec = pieces->img[type].sec_counter; in iwl_alloc_ucode()
1386 for (i = 0; i < pieces->img[type].sec_counter; i++) in iwl_alloc_ucode()
1388 return -ENOMEM; in iwl_alloc_ucode()
1410 cfg->max_inst_size) { in validate_sec_sizes()
1414 return -1; in validate_sec_sizes()
1418 cfg->max_data_size) { in validate_sec_sizes()
1422 return -1; in validate_sec_sizes()
1426 cfg->max_inst_size) { in validate_sec_sizes()
1430 return -1; in validate_sec_sizes()
1434 cfg->max_data_size) { in validate_sec_sizes()
1438 return -1; in validate_sec_sizes()
1446 const struct iwl_op_mode_ops *ops = op->ops; in _iwl_op_mode_start()
1454 drv->dbgfs_op_mode = debugfs_create_dir(op->name, in _iwl_op_mode_start()
1455 drv->dbgfs_drv); in _iwl_op_mode_start()
1456 dbgfs_dir = drv->dbgfs_op_mode; in _iwl_op_mode_start()
1459 op_mode = ops->start(drv->trans, drv->trans->cfg, in _iwl_op_mode_start()
1460 &drv->fw, dbgfs_dir); in _iwl_op_mode_start()
1465 debugfs_remove_recursive(drv->dbgfs_op_mode); in _iwl_op_mode_start()
1466 drv->dbgfs_op_mode = NULL; in _iwl_op_mode_start()
1478 if (drv->op_mode) { in _iwl_op_mode_stop()
1479 iwl_op_mode_stop(drv->op_mode); in _iwl_op_mode_stop()
1480 drv->op_mode = NULL; in _iwl_op_mode_stop()
1483 debugfs_remove_recursive(drv->dbgfs_op_mode); in _iwl_op_mode_stop()
1484 drv->dbgfs_op_mode = NULL; in _iwl_op_mode_stop()
1490 * iwl_req_fw_callback - callback when firmware was loaded
1492 * If loaded successfully, copies the firmware into buffers
1495 static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) in iwl_req_fw_callback()
1498 struct iwl_fw *fw = &drv->fw; in iwl_req_fw_callback()
1503 const unsigned int api_max = drv->trans->cfg->ucode_api_max; in iwl_req_fw_callback()
1504 const unsigned int api_min = drv->trans->cfg->ucode_api_min; in iwl_req_fw_callback()
1511 fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH; in iwl_req_fw_callback()
1512 fw->ucode_capa.standard_phy_calibration_size = in iwl_req_fw_callback()
1514 fw->ucode_capa.n_scan_channels = IWL_DEFAULT_SCAN_CHANNELS; in iwl_req_fw_callback()
1515 fw->ucode_capa.num_stations = IWL_MVM_STATION_COUNT_MAX; in iwl_req_fw_callback()
1516 fw->ucode_capa.num_beacons = 1; in iwl_req_fw_callback()
1518 fw->dbg.dump_mask = 0xffffffff; in iwl_req_fw_callback()
1527 IWL_DEBUG_FW_INFO(drv, "Loaded firmware file '%s' (%zd bytes).\n", in iwl_req_fw_callback()
1528 drv->firmware_name, ucode_raw->size); in iwl_req_fw_callback()
1531 if (ucode_raw->size < 4) { in iwl_req_fw_callback()
1537 ucode = (const struct iwl_ucode_header *)ucode_raw->data; in iwl_req_fw_callback()
1539 if (ucode->ver) in iwl_req_fw_callback()
1543 &fw->ucode_capa, &usniffer_images); in iwl_req_fw_callback()
1548 if (fw_has_api(&drv->fw.ucode_capa, IWL_UCODE_TLV_API_NEW_VERSION)) in iwl_req_fw_callback()
1549 api_ver = drv->fw.ucode_ver; in iwl_req_fw_callback()
1551 api_ver = IWL_UCODE_API(drv->fw.ucode_ver); in iwl_req_fw_callback()
1555 * firmware filename ... but we don't check for that and only rely in iwl_req_fw_callback()
1556 * on the API version read from firmware header from here on forward in iwl_req_fw_callback()
1560 "Driver unable to support your firmware API. " in iwl_req_fw_callback()
1561 "Driver supports v%u, firmware is v%u.\n", in iwl_req_fw_callback()
1570 if (fw->type == IWL_FW_DVM && validate_sec_sizes(drv, pieces, in iwl_req_fw_callback()
1571 drv->trans->cfg)) in iwl_req_fw_callback()
1574 /* Allocate ucode buffers for card's bus-master loading ... */ in iwl_req_fw_callback()
1578 * 2) backup cache for save/restore during power-downs in iwl_req_fw_callback()
1584 if (pieces->dbg_dest_tlv_init) { in iwl_req_fw_callback()
1585 size_t dbg_dest_size = sizeof(*drv->fw.dbg.dest_tlv) + in iwl_req_fw_callback()
1586 sizeof(drv->fw.dbg.dest_tlv->reg_ops[0]) * in iwl_req_fw_callback()
1587 drv->fw.dbg.n_dest_reg; in iwl_req_fw_callback()
1589 drv->fw.dbg.dest_tlv = kmalloc(dbg_dest_size, GFP_KERNEL); in iwl_req_fw_callback()
1591 if (!drv->fw.dbg.dest_tlv) in iwl_req_fw_callback()
1594 if (*pieces->dbg_dest_ver == 0) { in iwl_req_fw_callback()
1595 memcpy(drv->fw.dbg.dest_tlv, pieces->dbg_dest_tlv_v1, in iwl_req_fw_callback()
1599 drv->fw.dbg.dest_tlv; in iwl_req_fw_callback()
1601 dest_tlv->version = pieces->dbg_dest_tlv->version; in iwl_req_fw_callback()
1602 dest_tlv->monitor_mode = in iwl_req_fw_callback()
1603 pieces->dbg_dest_tlv->monitor_mode; in iwl_req_fw_callback()
1604 dest_tlv->size_power = in iwl_req_fw_callback()
1605 pieces->dbg_dest_tlv->size_power; in iwl_req_fw_callback()
1606 dest_tlv->wrap_count = in iwl_req_fw_callback()
1607 pieces->dbg_dest_tlv->wrap_count; in iwl_req_fw_callback()
1608 dest_tlv->write_ptr_reg = in iwl_req_fw_callback()
1609 pieces->dbg_dest_tlv->write_ptr_reg; in iwl_req_fw_callback()
1610 dest_tlv->base_shift = in iwl_req_fw_callback()
1611 pieces->dbg_dest_tlv->base_shift; in iwl_req_fw_callback()
1612 memcpy(dest_tlv->reg_ops, in iwl_req_fw_callback()
1613 pieces->dbg_dest_tlv->reg_ops, in iwl_req_fw_callback()
1614 sizeof(drv->fw.dbg.dest_tlv->reg_ops[0]) * in iwl_req_fw_callback()
1615 drv->fw.dbg.n_dest_reg); in iwl_req_fw_callback()
1625 dest_tlv->base_reg = pieces->dbg_dest_tlv->cfg_reg; in iwl_req_fw_callback()
1626 dest_tlv->end_shift = in iwl_req_fw_callback()
1627 pieces->dbg_dest_tlv->size_shift; in iwl_req_fw_callback()
1631 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg.conf_tlv); i++) { in iwl_req_fw_callback()
1632 if (pieces->dbg_conf_tlv[i]) { in iwl_req_fw_callback()
1633 drv->fw.dbg.conf_tlv[i] = in iwl_req_fw_callback()
1634 kmemdup(pieces->dbg_conf_tlv[i], in iwl_req_fw_callback()
1635 pieces->dbg_conf_tlv_len[i], in iwl_req_fw_callback()
1637 if (!drv->fw.dbg.conf_tlv[i]) in iwl_req_fw_callback()
1664 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg.trigger_tlv); i++) { in iwl_req_fw_callback()
1665 if (pieces->dbg_trigger_tlv[i]) { in iwl_req_fw_callback()
1673 if (WARN_ON(pieces->dbg_trigger_tlv_len[i] < in iwl_req_fw_callback()
1677 drv->fw.dbg.trigger_tlv_len[i] = in iwl_req_fw_callback()
1678 pieces->dbg_trigger_tlv_len[i]; in iwl_req_fw_callback()
1679 drv->fw.dbg.trigger_tlv[i] = in iwl_req_fw_callback()
1680 kmemdup(pieces->dbg_trigger_tlv[i], in iwl_req_fw_callback()
1681 drv->fw.dbg.trigger_tlv_len[i], in iwl_req_fw_callback()
1683 if (!drv->fw.dbg.trigger_tlv[i]) in iwl_req_fw_callback()
1690 drv->fw.dbg.mem_tlv = pieces->dbg_mem_tlv; in iwl_req_fw_callback()
1691 pieces->dbg_mem_tlv = NULL; in iwl_req_fw_callback()
1692 drv->fw.dbg.n_mem_tlv = pieces->n_mem_tlv; in iwl_req_fw_callback()
1695 * The (size - 16) / 12 formula is based on the information recorded in iwl_req_fw_callback()
1699 fw->init_evtlog_ptr = pieces->init_evtlog_ptr; in iwl_req_fw_callback()
1700 if (pieces->init_evtlog_size) in iwl_req_fw_callback()
1701 fw->init_evtlog_size = (pieces->init_evtlog_size - 16)/12; in iwl_req_fw_callback()
1703 fw->init_evtlog_size = in iwl_req_fw_callback()
1704 drv->trans->trans_cfg->base_params->max_event_log_size; in iwl_req_fw_callback()
1705 fw->init_errlog_ptr = pieces->init_errlog_ptr; in iwl_req_fw_callback()
1706 fw->inst_evtlog_ptr = pieces->inst_evtlog_ptr; in iwl_req_fw_callback()
1707 if (pieces->inst_evtlog_size) in iwl_req_fw_callback()
1708 fw->inst_evtlog_size = (pieces->inst_evtlog_size - 16)/12; in iwl_req_fw_callback()
1710 fw->inst_evtlog_size = in iwl_req_fw_callback()
1711 drv->trans->trans_cfg->base_params->max_event_log_size; in iwl_req_fw_callback()
1712 fw->inst_errlog_ptr = pieces->inst_errlog_ptr; in iwl_req_fw_callback()
1718 if (fw->ucode_capa.standard_phy_calibration_size > in iwl_req_fw_callback()
1720 fw->ucode_capa.standard_phy_calibration_size = in iwl_req_fw_callback()
1726 iwl_dbg_tlv_load_bin(drv->trans->dev, drv->trans); in iwl_req_fw_callback()
1729 switch (fw->type) { in iwl_req_fw_callback()
1734 WARN(1, "Invalid fw type %d\n", fw->type); in iwl_req_fw_callback()
1741 IWL_INFO(drv, "loaded firmware version %s op_mode %s\n", in iwl_req_fw_callback()
1742 drv->fw.fw_version, op->name); in iwl_req_fw_callback()
1745 list_add_tail(&drv->list, &op->drv); in iwl_req_fw_callback()
1747 if (op->ops) { in iwl_req_fw_callback()
1748 drv->op_mode = _iwl_op_mode_start(drv, op); in iwl_req_fw_callback()
1750 if (!drv->op_mode) { in iwl_req_fw_callback()
1756 request_module_nowait("%s", op->name); in iwl_req_fw_callback()
1766 printf("%s: module '%s' not yet available; will be initialized in a moment\n", in iwl_req_fw_callback()
1767 __func__, op->name); in iwl_req_fw_callback()
1772 complete(&drv->request_firmware_complete); in iwl_req_fw_callback()
1787 complete(&drv->request_firmware_complete); in iwl_req_fw_callback()
1788 device_release_driver(drv->trans->dev); in iwl_req_fw_callback()
1796 for (i = 0; i < ARRAY_SIZE(pieces->img); i++) in iwl_req_fw_callback()
1797 kfree(pieces->img[i].sec); in iwl_req_fw_callback()
1798 kfree(pieces->dbg_mem_tlv); in iwl_req_fw_callback()
1810 ret = -ENOMEM; in iwl_drv_start()
1814 drv->trans = trans; in iwl_drv_start()
1815 drv->dev = trans->dev; in iwl_drv_start()
1817 init_completion(&drv->request_firmware_complete); in iwl_drv_start()
1819 init_completion(&drv->drv_start_complete); in iwl_drv_start()
1821 INIT_LIST_HEAD(&drv->list); in iwl_drv_start()
1825 drv->dbgfs_drv = debugfs_create_dir(dev_name(trans->dev), in iwl_drv_start()
1829 drv->trans->dbgfs_dir = debugfs_create_dir("trans", drv->dbgfs_drv); in iwl_drv_start()
1832 drv->trans->dbg.domains_bitmap = IWL_TRANS_FW_DBG_DOMAIN(drv->trans); in iwl_drv_start()
1834 /* We have a non-default value in the module parameter, in iwl_drv_start()
1837 drv->trans->dbg.domains_bitmap &= 0xffff; in iwl_drv_start()
1845 drv->trans->dbg.domains_bitmap = in iwl_drv_start()
1859 * replicate FreeBSD's synchronous behaviour -- we cannot create in iwl_drv_start()
1863 wait_for_completion(&drv->request_firmware_complete); in iwl_drv_start()
1864 complete(&drv->drv_start_complete); in iwl_drv_start()
1871 debugfs_remove_recursive(drv->dbgfs_drv); in iwl_drv_start()
1873 iwl_dbg_tlv_free(drv->trans); in iwl_drv_start()
1882 wait_for_completion(&drv->request_firmware_complete); in iwl_drv_stop()
1884 wait_for_completion(&drv->drv_start_complete); in iwl_drv_stop()
1895 * when firmware loading failed -- in that in iwl_drv_stop()
1898 if (!list_empty(&drv->list)) in iwl_drv_stop()
1899 list_del(&drv->list); in iwl_drv_stop()
1903 iwl_trans_debugfs_cleanup(drv->trans); in iwl_drv_stop()
1905 debugfs_remove_recursive(drv->dbgfs_drv); in iwl_drv_stop()
1908 iwl_dbg_tlv_free(drv->trans); in iwl_drv_stop()
1939 if (strcmp(op->name, name)) in iwl_opmode_register()
1941 op->ops = ops; in iwl_opmode_register()
1943 list_for_each_entry(drv, &op->drv, list) in iwl_opmode_register()
1944 drv->op_mode = _iwl_op_mode_start(drv, op); in iwl_opmode_register()
1950 return -EIO; in iwl_opmode_register()
2029 MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)");
2036 "disable U-APSD functionality bitmap 1: BSS 2: P2P Client (default: 3)");
2040 "0:disable, 1-15:FW_DBG_PRESET Values, 16:enabled without preset value defined,"
2051 * co-exist problem. The possible behaviors are:
2061 MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)");
2073 "default power save level (range from 1 - 5, default: 1)");