Lines Matching +full:drv +full:- +full:id
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2005-2014, 2018-2025 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>
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"
28 #include "fw/api/mac-cfg.h"
57 * struct iwl_drv - drv common data
58 * @list: list of drv structures using this opmode
101 /* Protects the table contents, i.e. the ops pointer & drv list */
106 struct list_head drv; /* list of devices using this op_mode */ member
127 static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc) in iwl_free_fw_desc() argument
129 vfree(desc->data); in iwl_free_fw_desc()
130 desc->data = NULL; in iwl_free_fw_desc()
131 desc->len = 0; in iwl_free_fw_desc()
134 static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img) in iwl_free_fw_img() argument
137 for (i = 0; i < img->num_sec; i++) in iwl_free_fw_img()
138 iwl_free_fw_desc(drv, &img->sec[i]); in iwl_free_fw_img()
139 kfree(img->sec); in iwl_free_fw_img()
142 static void iwl_dealloc_ucode(struct iwl_drv *drv) in iwl_dealloc_ucode() argument
146 kfree(drv->fw.dbg.dest_tlv); in iwl_dealloc_ucode()
147 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg.conf_tlv); i++) in iwl_dealloc_ucode()
148 kfree(drv->fw.dbg.conf_tlv[i]); in iwl_dealloc_ucode()
149 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg.trigger_tlv); i++) in iwl_dealloc_ucode()
150 kfree(drv->fw.dbg.trigger_tlv[i]); in iwl_dealloc_ucode()
151 kfree(drv->fw.dbg.mem_tlv); in iwl_dealloc_ucode()
152 kfree(drv->fw.iml); in iwl_dealloc_ucode()
153 kfree(drv->fw.ucode_capa.cmd_versions); in iwl_dealloc_ucode()
154 kfree(drv->fw.phy_integration_ver); in iwl_dealloc_ucode()
155 kfree(drv->trans->dbg.pc_data); in iwl_dealloc_ucode()
156 drv->trans->dbg.pc_data = NULL; in iwl_dealloc_ucode()
157 kvfree(drv->fw.pnvm_data); in iwl_dealloc_ucode()
158 drv->fw.pnvm_data = NULL; in iwl_dealloc_ucode()
159 drv->fw.pnvm_size = 0; in iwl_dealloc_ucode()
162 iwl_free_fw_img(drv, drv->fw.img + i); in iwl_dealloc_ucode()
165 memset(&drv->fw, 0, sizeof(drv->fw)); in iwl_dealloc_ucode()
172 desc->data = NULL; in iwl_alloc_fw_desc()
174 if (!sec || !sec->size) in iwl_alloc_fw_desc()
175 return -EINVAL; in iwl_alloc_fw_desc()
177 data = vmalloc(sec->size); in iwl_alloc_fw_desc()
179 return -ENOMEM; in iwl_alloc_fw_desc()
181 desc->len = sec->size; in iwl_alloc_fw_desc()
182 desc->offset = sec->offset; in iwl_alloc_fw_desc()
183 memcpy(data, sec->data, desc->len); in iwl_alloc_fw_desc()
184 desc->data = data; in iwl_alloc_fw_desc()
200 return CSR_HW_RFID_TYPE(trans->info.hw_rf_id) >= IWL_CFG_RF_TYPE_FM; in iwl_drv_is_wifi7_supported()
208 if (trans->cfg->fw_name_pre) in iwl_drv_get_fwname_pre()
209 return trans->cfg->fw_name_pre; in iwl_drv_get_fwname_pre()
211 mac_step = iwl_drv_get_step(trans->info.hw_rev_step); in iwl_drv_get_fwname_pre()
213 switch (CSR_HW_REV_TYPE(trans->info.hw_rev)) { in iwl_drv_get_fwname_pre()
215 mac = "9000-pu"; in iwl_drv_get_fwname_pre()
219 mac = "9260-th"; in iwl_drv_get_fwname_pre()
226 /* special case - no RF since it's fixed (discrete) */ in iwl_drv_get_fwname_pre()
227 scnprintf(buf, FW_NAME_PRE_BUFSIZE, "iwlwifi-cc-a0"); in iwl_drv_get_fwname_pre()
268 return "unknown-mac"; in iwl_drv_get_fwname_pre()
271 rf_step = iwl_drv_get_step(CSR_HW_RFID_STEP(trans->info.hw_rf_id)); in iwl_drv_get_fwname_pre()
273 switch (CSR_HW_RFID_TYPE(trans->info.hw_rf_id)) { in iwl_drv_get_fwname_pre()
298 return "unknown-rf"; in iwl_drv_get_fwname_pre()
301 cdb = CSR_HW_RFID_IS_CDB(trans->info.hw_rf_id) ? "4" : ""; in iwl_drv_get_fwname_pre()
304 "iwlwifi-%s-%c0-%s%s-%c0", in iwl_drv_get_fwname_pre()
318 const struct iwl_family_base_params *base = trans->mac_cfg->base; in iwl_get_ucode_api_versions()
319 const struct iwl_rf_cfg *cfg = trans->cfg; in iwl_get_ucode_api_versions()
322 if (!base->ucode_api_max || in iwl_get_ucode_api_versions()
323 (cfg->ucode_api_max && base->ucode_api_min > cfg->ucode_api_max)) { in iwl_get_ucode_api_versions()
324 *api_min = cfg->ucode_api_min; in iwl_get_ucode_api_versions()
325 *api_max = cfg->ucode_api_max; in iwl_get_ucode_api_versions()
330 if (!cfg->ucode_api_max || in iwl_get_ucode_api_versions()
331 (base->ucode_api_max && cfg->ucode_api_min > base->ucode_api_max)) { in iwl_get_ucode_api_versions()
332 *api_min = base->ucode_api_min; in iwl_get_ucode_api_versions()
333 *api_max = base->ucode_api_max; in iwl_get_ucode_api_versions()
337 *api_min = max(cfg->ucode_api_min, base->ucode_api_min); in iwl_get_ucode_api_versions()
338 *api_max = min(cfg->ucode_api_max, base->ucode_api_max); in iwl_get_ucode_api_versions()
341 static int iwl_request_firmware(struct iwl_drv *drv, bool first) in iwl_request_firmware() argument
347 iwl_get_ucode_api_versions(drv->trans, &ucode_api_min, &ucode_api_max); in iwl_request_firmware()
349 if (drv->trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_9000 && in iwl_request_firmware()
350 (drv->trans->info.hw_rev_step != SILICON_B_STEP && in iwl_request_firmware()
351 drv->trans->info.hw_rev_step != SILICON_C_STEP)) { in iwl_request_firmware()
352 IWL_ERR(drv, in iwl_request_firmware()
354 drv->trans->info.hw_rev); in iwl_request_firmware()
355 return -EINVAL; in iwl_request_firmware()
358 fw_name_pre = iwl_drv_get_fwname_pre(drv->trans, _fw_name_pre); in iwl_request_firmware()
361 drv->fw_index = ucode_api_max; in iwl_request_firmware()
363 drv->fw_index--; in iwl_request_firmware()
365 if (drv->fw_index < ucode_api_min) { in iwl_request_firmware()
366 IWL_ERR(drv, "no suitable firmware found!\n"); in iwl_request_firmware()
369 IWL_ERR(drv, "%s-%d is required\n", fw_name_pre, in iwl_request_firmware()
372 IWL_ERR(drv, "minimum version required: %s-%d\n", in iwl_request_firmware()
374 IWL_ERR(drv, "maximum version supported: %s-%d\n", in iwl_request_firmware()
378 IWL_ERR(drv, in iwl_request_firmware()
379 "check git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git\n"); in iwl_request_firmware()
381 IWL_ERR(drv, "On FreeBSD the firmware package can be installed running fwget(8).\n"); in iwl_request_firmware()
383 return -ENOENT; in iwl_request_firmware()
386 snprintf(drv->firmware_name, sizeof(drv->firmware_name), "%s-%d.ucode", in iwl_request_firmware()
387 fw_name_pre, drv->fw_index); in iwl_request_firmware()
389 IWL_DEBUG_FW_INFO(drv, "attempting to load firmware '%s'\n", in iwl_request_firmware()
390 drv->firmware_name); in iwl_request_firmware()
392 return request_firmware_nowait(THIS_MODULE, 1, drv->firmware_name, in iwl_request_firmware()
393 drv->trans->dev, in iwl_request_firmware()
394 GFP_KERNEL, drv, iwl_req_fw_callback); in iwl_request_firmware()
411 * struct iwl_tlv_calib_data - parse the default calib data from TLV
447 struct fw_img_parsing *img = &pieces->img[type]; in alloc_sec_data()
450 size_t alloc_size = sizeof(*img->sec) * size; in alloc_sec_data()
452 if (img->sec && img->sec_counter >= size) in alloc_sec_data()
455 sec_memory = krealloc(img->sec, alloc_size, GFP_KERNEL); in alloc_sec_data()
459 img->sec = sec_memory; in alloc_sec_data()
460 img->sec_counter = size; in alloc_sec_data()
470 pieces->img[type].sec[sec].data = data; in set_sec_data()
480 pieces->img[type].sec[sec].size = size; in set_sec_size()
487 return pieces->img[type].sec[sec].size; in get_sec_size()
497 pieces->img[type].sec[sec].offset = offset; in set_sec_offset()
511 return -EINVAL; in iwl_store_ucode_sec()
515 alloc_size = sizeof(*img->sec) * (img->sec_counter + 1); in iwl_store_ucode_sec()
516 sec = krealloc(img->sec, alloc_size, GFP_KERNEL); in iwl_store_ucode_sec()
518 return -ENOMEM; in iwl_store_ucode_sec()
519 img->sec = sec; in iwl_store_ucode_sec()
521 sec = &img->sec[img->sec_counter]; in iwl_store_ucode_sec()
523 sec->offset = le32_to_cpu(sec_parse->offset); in iwl_store_ucode_sec()
524 sec->data = sec_parse->data; in iwl_store_ucode_sec()
525 sec->size = size - sizeof(sec_parse->offset); in iwl_store_ucode_sec()
527 ++img->sec_counter; in iwl_store_ucode_sec()
532 static int iwl_set_default_calib(struct iwl_drv *drv, const u8 *data) in iwl_set_default_calib() argument
536 u32 ucode_type = le32_to_cpu(def_calib->ucode_type); in iwl_set_default_calib()
538 IWL_ERR(drv, "Wrong ucode_type %u for default calibration.\n", in iwl_set_default_calib()
540 return -EINVAL; in iwl_set_default_calib()
542 drv->fw.default_calib[ucode_type].flow_trigger = in iwl_set_default_calib()
543 def_calib->calib.flow_trigger; in iwl_set_default_calib()
544 drv->fw.default_calib[ucode_type].event_trigger = in iwl_set_default_calib()
545 def_calib->calib.event_trigger; in iwl_set_default_calib()
550 static void iwl_set_ucode_api_flags(struct iwl_drv *drv, const u8 *data, in iwl_set_ucode_api_flags() argument
554 u32 api_index = le32_to_cpu(ucode_api->api_index); in iwl_set_ucode_api_flags()
555 u32 api_flags = le32_to_cpu(ucode_api->api_flags); in iwl_set_ucode_api_flags()
559 IWL_WARN(drv, in iwl_set_ucode_api_flags()
567 __set_bit(i + 32 * api_index, capa->_api); in iwl_set_ucode_api_flags()
571 static void iwl_set_ucode_capabilities(struct iwl_drv *drv, const u8 *data, in iwl_set_ucode_capabilities() argument
575 u32 api_index = le32_to_cpu(ucode_capa->api_index); in iwl_set_ucode_capabilities()
576 u32 api_flags = le32_to_cpu(ucode_capa->api_capa); in iwl_set_ucode_capabilities()
580 IWL_WARN(drv, in iwl_set_ucode_capabilities()
588 __set_bit(i + 32 * api_index, capa->_capa); in iwl_set_ucode_capabilities()
592 static const char *iwl_reduced_fw_name(struct iwl_drv *drv) in iwl_reduced_fw_name() argument
594 const char *name = drv->firmware_name; in iwl_reduced_fw_name()
596 if (strncmp(name, "iwlwifi-", 8) == 0) in iwl_reduced_fw_name()
602 static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, in iwl_parse_v1_v2_firmware() argument
606 const struct iwl_ucode_header *ucode = (const void *)ucode_raw->data; in iwl_parse_v1_v2_firmware()
611 drv->fw.ucode_ver = le32_to_cpu(ucode->ver); in iwl_parse_v1_v2_firmware()
612 api_ver = IWL_UCODE_API(drv->fw.ucode_ver); in iwl_parse_v1_v2_firmware()
617 if (ucode_raw->size < hdr_size) { in iwl_parse_v1_v2_firmware()
618 IWL_ERR(drv, "File size too small!\n"); in iwl_parse_v1_v2_firmware()
619 return -EINVAL; in iwl_parse_v1_v2_firmware()
621 build = le32_to_cpu(ucode->u.v2.build); in iwl_parse_v1_v2_firmware()
623 le32_to_cpu(ucode->u.v2.inst_size)); in iwl_parse_v1_v2_firmware()
625 le32_to_cpu(ucode->u.v2.data_size)); in iwl_parse_v1_v2_firmware()
627 le32_to_cpu(ucode->u.v2.init_size)); in iwl_parse_v1_v2_firmware()
629 le32_to_cpu(ucode->u.v2.init_data_size)); in iwl_parse_v1_v2_firmware()
630 src = ucode->u.v2.data; in iwl_parse_v1_v2_firmware()
636 if (ucode_raw->size < hdr_size) { in iwl_parse_v1_v2_firmware()
637 IWL_ERR(drv, "File size too small!\n"); in iwl_parse_v1_v2_firmware()
638 return -EINVAL; in iwl_parse_v1_v2_firmware()
642 le32_to_cpu(ucode->u.v1.inst_size)); in iwl_parse_v1_v2_firmware()
644 le32_to_cpu(ucode->u.v1.data_size)); in iwl_parse_v1_v2_firmware()
646 le32_to_cpu(ucode->u.v1.init_size)); in iwl_parse_v1_v2_firmware()
648 le32_to_cpu(ucode->u.v1.init_data_size)); in iwl_parse_v1_v2_firmware()
649 src = ucode->u.v1.data; in iwl_parse_v1_v2_firmware()
658 snprintf(drv->fw.fw_version, in iwl_parse_v1_v2_firmware()
659 sizeof(drv->fw.fw_version), in iwl_parse_v1_v2_firmware()
661 IWL_UCODE_MAJOR(drv->fw.ucode_ver), in iwl_parse_v1_v2_firmware()
662 IWL_UCODE_MINOR(drv->fw.ucode_ver), in iwl_parse_v1_v2_firmware()
663 IWL_UCODE_API(drv->fw.ucode_ver), in iwl_parse_v1_v2_firmware()
664 IWL_UCODE_SERIAL(drv->fw.ucode_ver), in iwl_parse_v1_v2_firmware()
665 buildstr, iwl_reduced_fw_name(drv)); in iwl_parse_v1_v2_firmware()
669 if (ucode_raw->size != hdr_size + in iwl_parse_v1_v2_firmware()
675 IWL_ERR(drv, in iwl_parse_v1_v2_firmware()
677 (int)ucode_raw->size); in iwl_parse_v1_v2_firmware()
678 return -EINVAL; in iwl_parse_v1_v2_firmware()
701 static void iwl_drv_set_dump_exclude(struct iwl_drv *drv, in iwl_drv_set_dump_exclude() argument
712 excl = &drv->fw.dump_excl[0]; in iwl_drv_set_dump_exclude()
715 if (excl->addr) in iwl_drv_set_dump_exclude()
716 excl = &drv->fw.dump_excl_wowlan[0]; in iwl_drv_set_dump_exclude()
717 } else if (fw_has_capa(&drv->fw.ucode_capa, in iwl_drv_set_dump_exclude()
720 excl = &drv->fw.dump_excl[0]; in iwl_drv_set_dump_exclude()
723 excl = &drv->fw.dump_excl_wowlan[0]; in iwl_drv_set_dump_exclude()
726 if (excl->addr) in iwl_drv_set_dump_exclude()
729 if (excl->addr) { in iwl_drv_set_dump_exclude()
730 IWL_DEBUG_FW_INFO(drv, "found too many excludes in fw file\n"); in iwl_drv_set_dump_exclude()
734 excl->addr = le32_to_cpu(fw->addr) & ~FW_ADDR_CACHE_CONTROL; in iwl_drv_set_dump_exclude()
735 excl->size = le32_to_cpu(fw->size); in iwl_drv_set_dump_exclude()
738 static void iwl_parse_dbg_tlv_assert_tables(struct iwl_drv *drv, in iwl_parse_dbg_tlv_assert_tables() argument
742 u32 length = le32_to_cpu(tlv->length); in iwl_parse_dbg_tlv_assert_tables()
746 sizeof(region->special_mem)) in iwl_parse_dbg_tlv_assert_tables()
749 region = (const void *)tlv->data; in iwl_parse_dbg_tlv_assert_tables()
750 addr = le32_to_cpu(region->special_mem.base_addr); in iwl_parse_dbg_tlv_assert_tables()
751 addr += le32_to_cpu(region->special_mem.offset); in iwl_parse_dbg_tlv_assert_tables()
754 if (region->type != IWL_FW_INI_REGION_SPECIAL_DEVICE_MEMORY) in iwl_parse_dbg_tlv_assert_tables()
757 switch (region->sub_type) { in iwl_parse_dbg_tlv_assert_tables()
759 drv->trans->dbg.umac_error_event_table = addr; in iwl_parse_dbg_tlv_assert_tables()
760 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
764 drv->trans->dbg.lmac_error_event_table[0] = addr; in iwl_parse_dbg_tlv_assert_tables()
765 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
769 drv->trans->dbg.lmac_error_event_table[1] = addr; in iwl_parse_dbg_tlv_assert_tables()
770 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
774 drv->trans->dbg.tcm_error_event_table[0] = addr; in iwl_parse_dbg_tlv_assert_tables()
775 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
779 drv->trans->dbg.tcm_error_event_table[1] = addr; in iwl_parse_dbg_tlv_assert_tables()
780 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
784 drv->trans->dbg.rcm_error_event_table[0] = addr; in iwl_parse_dbg_tlv_assert_tables()
785 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
789 drv->trans->dbg.rcm_error_event_table[1] = addr; in iwl_parse_dbg_tlv_assert_tables()
790 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
798 static int iwl_parse_tlv_firmware(struct iwl_drv *drv, in iwl_parse_tlv_firmware() argument
804 const struct iwl_tlv_ucode_header *ucode = (const void *)ucode_raw->data; in iwl_parse_tlv_firmware()
806 size_t len = ucode_raw->size; in iwl_parse_tlv_firmware()
818 IWL_ERR(drv, "uCode has invalid length: %zd\n", len); in iwl_parse_tlv_firmware()
819 return -EINVAL; in iwl_parse_tlv_firmware()
822 if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { in iwl_parse_tlv_firmware()
823 IWL_ERR(drv, "invalid uCode magic: 0X%x\n", in iwl_parse_tlv_firmware()
824 le32_to_cpu(ucode->magic)); in iwl_parse_tlv_firmware()
825 return -EINVAL; in iwl_parse_tlv_firmware()
828 drv->fw.ucode_ver = le32_to_cpu(ucode->ver); in iwl_parse_tlv_firmware()
829 memcpy(drv->fw.human_readable, ucode->human_readable, in iwl_parse_tlv_firmware()
830 sizeof(drv->fw.human_readable)); in iwl_parse_tlv_firmware()
831 build = le32_to_cpu(ucode->build); in iwl_parse_tlv_firmware()
838 snprintf(drv->fw.fw_version, in iwl_parse_tlv_firmware()
839 sizeof(drv->fw.fw_version), in iwl_parse_tlv_firmware()
841 IWL_UCODE_MAJOR(drv->fw.ucode_ver), in iwl_parse_tlv_firmware()
842 IWL_UCODE_MINOR(drv->fw.ucode_ver), in iwl_parse_tlv_firmware()
843 IWL_UCODE_API(drv->fw.ucode_ver), in iwl_parse_tlv_firmware()
844 IWL_UCODE_SERIAL(drv->fw.ucode_ver), in iwl_parse_tlv_firmware()
845 buildstr, iwl_reduced_fw_name(drv)); in iwl_parse_tlv_firmware()
847 data = ucode->data; in iwl_parse_tlv_firmware()
849 len -= sizeof(*ucode); in iwl_parse_tlv_firmware()
852 len -= sizeof(*tlv); in iwl_parse_tlv_firmware()
855 tlv_len = le32_to_cpu(tlv->length); in iwl_parse_tlv_firmware()
856 tlv_type = le32_to_cpu(tlv->type); in iwl_parse_tlv_firmware()
857 tlv_data = tlv->data; in iwl_parse_tlv_firmware()
860 IWL_ERR(drv, "invalid TLV len: %zd/%u\n", in iwl_parse_tlv_firmware()
862 return -EINVAL; in iwl_parse_tlv_firmware()
864 len -= ALIGN(tlv_len, 4); in iwl_parse_tlv_firmware()
905 IWL_ERR(drv, "Found unexpected BOOT ucode\n"); in iwl_parse_tlv_firmware()
910 capa->max_probe_length = in iwl_parse_tlv_firmware()
916 capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; in iwl_parse_tlv_firmware()
932 capa->flags = le32_to_cpup((const __le32 *)tlv_data); in iwl_parse_tlv_firmware()
937 iwl_set_ucode_api_flags(drv, tlv_data, capa); in iwl_parse_tlv_firmware()
942 iwl_set_ucode_capabilities(drv, tlv_data, capa); in iwl_parse_tlv_firmware()
947 pieces->init_evtlog_ptr = in iwl_parse_tlv_firmware()
953 pieces->init_evtlog_size = in iwl_parse_tlv_firmware()
959 pieces->init_errlog_ptr = in iwl_parse_tlv_firmware()
965 pieces->inst_evtlog_ptr = in iwl_parse_tlv_firmware()
971 pieces->inst_evtlog_size = in iwl_parse_tlv_firmware()
977 pieces->inst_errlog_ptr = in iwl_parse_tlv_firmware()
983 drv->fw.enhance_sensitivity_table = true; in iwl_parse_tlv_firmware()
1006 capa->standard_phy_calibration_size = in iwl_parse_tlv_firmware()
1010 iwl_store_ucode_sec(&pieces->img[IWL_UCODE_REGULAR], in iwl_parse_tlv_firmware()
1012 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
1015 iwl_store_ucode_sec(&pieces->img[IWL_UCODE_INIT], in iwl_parse_tlv_firmware()
1017 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
1020 iwl_store_ucode_sec(&pieces->img[IWL_UCODE_WOWLAN], in iwl_parse_tlv_firmware()
1022 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
1027 if (iwl_set_default_calib(drv, tlv_data)) in iwl_parse_tlv_firmware()
1033 drv->fw.phy_config = le32_to_cpup((const __le32 *)tlv_data); in iwl_parse_tlv_firmware()
1034 drv->fw.valid_tx_ant = (drv->fw.phy_config & in iwl_parse_tlv_firmware()
1037 drv->fw.valid_rx_ant = (drv->fw.phy_config & in iwl_parse_tlv_firmware()
1042 iwl_store_ucode_sec(&pieces->img[IWL_UCODE_REGULAR], in iwl_parse_tlv_firmware()
1044 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
1047 iwl_store_ucode_sec(&pieces->img[IWL_UCODE_INIT], in iwl_parse_tlv_firmware()
1049 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
1052 iwl_store_ucode_sec(&pieces->img[IWL_UCODE_WOWLAN], in iwl_parse_tlv_firmware()
1054 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
1063 drv->fw.img[IWL_UCODE_REGULAR].is_dual_cpus = in iwl_parse_tlv_firmware()
1065 drv->fw.img[IWL_UCODE_INIT].is_dual_cpus = in iwl_parse_tlv_firmware()
1067 drv->fw.img[IWL_UCODE_WOWLAN].is_dual_cpus = in iwl_parse_tlv_firmware()
1070 IWL_ERR(drv, "Driver support up to 2 CPUs\n"); in iwl_parse_tlv_firmware()
1071 return -EINVAL; in iwl_parse_tlv_firmware()
1077 capa->n_scan_channels = in iwl_parse_tlv_firmware()
1088 pieces->major = le32_to_cpup(ptr++); in iwl_parse_tlv_firmware()
1092 snprintf(drv->fw.fw_version, in iwl_parse_tlv_firmware()
1093 sizeof(drv->fw.fw_version), in iwl_parse_tlv_firmware()
1094 "%u.%08x.%u %s", pieces->major, minor, in iwl_parse_tlv_firmware()
1095 local_comp, iwl_reduced_fw_name(drv)); in iwl_parse_tlv_firmware()
1103 pieces->dbg_dest_ver = (const u8 *)tlv_data; in iwl_parse_tlv_firmware()
1104 if (*pieces->dbg_dest_ver == 1) { in iwl_parse_tlv_firmware()
1106 } else if (*pieces->dbg_dest_ver == 0) { in iwl_parse_tlv_firmware()
1109 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1111 *pieces->dbg_dest_ver); in iwl_parse_tlv_firmware()
1115 if (pieces->dbg_dest_tlv_init) { in iwl_parse_tlv_firmware()
1116 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1121 pieces->dbg_dest_tlv_init = true; in iwl_parse_tlv_firmware()
1124 pieces->dbg_dest_tlv_v1 = dest_v1; in iwl_parse_tlv_firmware()
1125 mon_mode = dest_v1->monitor_mode; in iwl_parse_tlv_firmware()
1127 pieces->dbg_dest_tlv = dest; in iwl_parse_tlv_firmware()
1128 mon_mode = dest->monitor_mode; in iwl_parse_tlv_firmware()
1131 IWL_INFO(drv, "Found debug destination: %s\n", in iwl_parse_tlv_firmware()
1134 drv->fw.dbg.n_dest_reg = (dest_v1) ? in iwl_parse_tlv_firmware()
1135 tlv_len - in iwl_parse_tlv_firmware()
1138 tlv_len - in iwl_parse_tlv_firmware()
1142 drv->fw.dbg.n_dest_reg /= in iwl_parse_tlv_firmware()
1143 sizeof(drv->fw.dbg.dest_tlv->reg_ops[0]); in iwl_parse_tlv_firmware()
1151 if (!pieces->dbg_dest_tlv_init) { in iwl_parse_tlv_firmware()
1152 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1153 "Ignore dbg config %d - no destination configured\n", in iwl_parse_tlv_firmware()
1154 conf->id); in iwl_parse_tlv_firmware()
1158 if (conf->id >= ARRAY_SIZE(drv->fw.dbg.conf_tlv)) { in iwl_parse_tlv_firmware()
1159 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1161 conf->id); in iwl_parse_tlv_firmware()
1165 if (pieces->dbg_conf_tlv[conf->id]) { in iwl_parse_tlv_firmware()
1166 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1168 conf->id); in iwl_parse_tlv_firmware()
1172 if (conf->usniffer) in iwl_parse_tlv_firmware()
1175 IWL_INFO(drv, "Found debug configuration: %d\n", in iwl_parse_tlv_firmware()
1176 conf->id); in iwl_parse_tlv_firmware()
1178 pieces->dbg_conf_tlv[conf->id] = conf; in iwl_parse_tlv_firmware()
1179 pieces->dbg_conf_tlv_len[conf->id] = tlv_len; in iwl_parse_tlv_firmware()
1185 u32 trigger_id = le32_to_cpu(trigger->id); in iwl_parse_tlv_firmware()
1187 if (trigger_id >= ARRAY_SIZE(drv->fw.dbg.trigger_tlv)) { in iwl_parse_tlv_firmware()
1188 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1190 trigger->id); in iwl_parse_tlv_firmware()
1194 if (pieces->dbg_trigger_tlv[trigger_id]) { in iwl_parse_tlv_firmware()
1195 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1197 trigger->id); in iwl_parse_tlv_firmware()
1201 IWL_INFO(drv, "Found debug trigger: %u\n", trigger->id); in iwl_parse_tlv_firmware()
1203 pieces->dbg_trigger_tlv[trigger_id] = trigger; in iwl_parse_tlv_firmware()
1204 pieces->dbg_trigger_tlv_len[trigger_id] = tlv_len; in iwl_parse_tlv_firmware()
1209 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1214 drv->fw.dbg.dump_mask = in iwl_parse_tlv_firmware()
1220 iwl_store_ucode_sec(&pieces->img[IWL_UCODE_REGULAR_USNIFFER], in iwl_parse_tlv_firmware()
1228 IWL_DEBUG_FW(drv, in iwl_parse_tlv_firmware()
1233 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1236 return -EINVAL; in iwl_parse_tlv_firmware()
1239 if (paging_mem_size & (FW_PAGING_SIZE - 1)) { in iwl_parse_tlv_firmware()
1240 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1243 return -EINVAL; in iwl_parse_tlv_firmware()
1246 drv->fw.img[IWL_UCODE_REGULAR].paging_mem_size = in iwl_parse_tlv_firmware()
1249 drv->fw.img[usniffer_img].paging_mem_size = in iwl_parse_tlv_firmware()
1264 IWL_DEBUG_INFO(drv, "Found debug memory segment: %u\n", in iwl_parse_tlv_firmware()
1265 dbg_mem->data_type); in iwl_parse_tlv_firmware()
1267 size = sizeof(*pieces->dbg_mem_tlv) * in iwl_parse_tlv_firmware()
1268 (pieces->n_mem_tlv + 1); in iwl_parse_tlv_firmware()
1269 n = krealloc(pieces->dbg_mem_tlv, size, GFP_KERNEL); in iwl_parse_tlv_firmware()
1271 return -ENOMEM; in iwl_parse_tlv_firmware()
1272 pieces->dbg_mem_tlv = n; in iwl_parse_tlv_firmware()
1273 pieces->dbg_mem_tlv[pieces->n_mem_tlv] = *dbg_mem; in iwl_parse_tlv_firmware()
1274 pieces->n_mem_tlv++; in iwl_parse_tlv_firmware()
1278 drv->fw.iml_len = tlv_len; in iwl_parse_tlv_firmware()
1279 drv->fw.iml = kmemdup(tlv_data, tlv_len, GFP_KERNEL); in iwl_parse_tlv_firmware()
1280 if (!drv->fw.iml) in iwl_parse_tlv_firmware()
1281 return -ENOMEM; in iwl_parse_tlv_firmware()
1292 capa->error_log_addr = in iwl_parse_tlv_firmware()
1293 le32_to_cpu(recov_info->buf_addr); in iwl_parse_tlv_firmware()
1294 capa->error_log_size = in iwl_parse_tlv_firmware()
1295 le32_to_cpu(recov_info->buf_size); in iwl_parse_tlv_firmware()
1306 IWL_DEBUG_INFO(drv, "TLV_FW_FSEQ_VERSION: %.32s\n", in iwl_parse_tlv_firmware()
1307 fseq_ver->version); in iwl_parse_tlv_firmware()
1315 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1320 capa->num_stations = in iwl_parse_tlv_firmware()
1328 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1333 capa->num_links = in iwl_parse_tlv_firmware()
1339 capa->num_beacons = in iwl_parse_tlv_firmware()
1348 if (drv->trans->mac_cfg->device_family < in iwl_parse_tlv_firmware()
1351 drv->trans->dbg.umac_error_event_table = in iwl_parse_tlv_firmware()
1352 le32_to_cpu(dbg_ptrs->error_info_addr) & in iwl_parse_tlv_firmware()
1354 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_tlv_firmware()
1364 if (drv->trans->mac_cfg->device_family < in iwl_parse_tlv_firmware()
1367 drv->trans->dbg.lmac_error_event_table[0] = in iwl_parse_tlv_firmware()
1368 le32_to_cpu(dbg_ptrs->error_event_table_ptr) & in iwl_parse_tlv_firmware()
1370 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_tlv_firmware()
1375 iwl_parse_dbg_tlv_assert_tables(drv, tlv); in iwl_parse_tlv_firmware()
1383 iwl_dbg_tlv_alloc(drv->trans, tlv, false); in iwl_parse_tlv_firmware()
1387 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1393 if (WARN_ON(capa->cmd_versions)) in iwl_parse_tlv_firmware()
1394 return -EINVAL; in iwl_parse_tlv_firmware()
1395 capa->cmd_versions = kmemdup(tlv_data, tlv_len, in iwl_parse_tlv_firmware()
1397 if (!capa->cmd_versions) in iwl_parse_tlv_firmware()
1398 return -ENOMEM; in iwl_parse_tlv_firmware()
1399 capa->n_cmd_versions = in iwl_parse_tlv_firmware()
1403 if (drv->fw.phy_integration_ver) { in iwl_parse_tlv_firmware()
1404 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1409 drv->fw.phy_integration_ver = in iwl_parse_tlv_firmware()
1411 if (!drv->fw.phy_integration_ver) in iwl_parse_tlv_firmware()
1412 return -ENOMEM; in iwl_parse_tlv_firmware()
1413 drv->fw.phy_integration_ver_len = tlv_len; in iwl_parse_tlv_firmware()
1417 iwl_drv_set_dump_exclude(drv, tlv_type, in iwl_parse_tlv_firmware()
1423 drv->trans->dbg.pc_data = in iwl_parse_tlv_firmware()
1425 if (!drv->trans->dbg.pc_data) in iwl_parse_tlv_firmware()
1426 return -ENOMEM; in iwl_parse_tlv_firmware()
1427 drv->trans->dbg.num_pc = in iwl_parse_tlv_firmware()
1431 if (drv->fw.pnvm_data) in iwl_parse_tlv_firmware()
1433 drv->fw.pnvm_data = in iwl_parse_tlv_firmware()
1435 if (!drv->fw.pnvm_data) in iwl_parse_tlv_firmware()
1436 return -ENOMEM; in iwl_parse_tlv_firmware()
1437 drv->fw.pnvm_size = tlv_len; in iwl_parse_tlv_firmware()
1440 IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); in iwl_parse_tlv_firmware()
1447 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1449 return -EINVAL; in iwl_parse_tlv_firmware()
1453 IWL_ERR(drv, "invalid TLV after parsing: %zd\n", len); in iwl_parse_tlv_firmware()
1455 iwl_print_hex_dump(drv, IWL_DL_FW, data, len); in iwl_parse_tlv_firmware()
1458 iwl_print_hex_dump(drv, IWL_DL_FW, "TLV ", data, len); in iwl_parse_tlv_firmware()
1461 return -EINVAL; in iwl_parse_tlv_firmware()
1467 IWL_ERR(drv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); in iwl_parse_tlv_firmware()
1470 iwl_print_hex_dump(drv, IWL_DL_FW, tlv_data, tlv_len); in iwl_parse_tlv_firmware()
1473 iwl_print_hex_dump(drv, IWL_DL_FW, "TLV ", tlv_data, tlv_len); in iwl_parse_tlv_firmware()
1477 return -EINVAL; in iwl_parse_tlv_firmware()
1484 sec = kcalloc(img->sec_counter, sizeof(*sec), GFP_KERNEL); in iwl_alloc_ucode_mem()
1486 return -ENOMEM; in iwl_alloc_ucode_mem()
1488 out->sec = sec; in iwl_alloc_ucode_mem()
1489 out->num_sec = img->sec_counter; in iwl_alloc_ucode_mem()
1491 for (int i = 0; i < out->num_sec; i++) in iwl_alloc_ucode_mem()
1492 if (iwl_alloc_fw_desc(&sec[i], &img->sec[i])) in iwl_alloc_ucode_mem()
1493 return -ENOMEM; in iwl_alloc_ucode_mem()
1498 static int iwl_alloc_ucode(struct iwl_drv *drv, in iwl_alloc_ucode() argument
1502 return iwl_alloc_ucode_mem(&drv->fw.img[type], &pieces->img[type]); in iwl_alloc_ucode()
1505 static int validate_sec_sizes(struct iwl_drv *drv, in validate_sec_sizes() argument
1509 IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %zd\n", in validate_sec_sizes()
1512 IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %zd\n", in validate_sec_sizes()
1515 IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %zd\n", in validate_sec_sizes()
1517 IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %zd\n", in validate_sec_sizes()
1522 cfg->max_inst_size) { in validate_sec_sizes()
1523 IWL_ERR(drv, "uCode instr len %zd too large to fit in\n", in validate_sec_sizes()
1526 return -1; in validate_sec_sizes()
1530 cfg->max_data_size) { in validate_sec_sizes()
1531 IWL_ERR(drv, "uCode data len %zd too large to fit in\n", in validate_sec_sizes()
1534 return -1; in validate_sec_sizes()
1538 cfg->max_inst_size) { in validate_sec_sizes()
1539 IWL_ERR(drv, "uCode init instr len %zd too large to fit in\n", in validate_sec_sizes()
1542 return -1; in validate_sec_sizes()
1546 cfg->max_data_size) { in validate_sec_sizes()
1547 IWL_ERR(drv, "uCode init data len %zd too large to fit in\n", in validate_sec_sizes()
1550 return -1; in validate_sec_sizes()
1556 _iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op) in _iwl_op_mode_start() argument
1558 const struct iwl_op_mode_ops *ops = op->ops; in _iwl_op_mode_start()
1569 drv->dbgfs_op_mode = debugfs_create_dir(op->name, in _iwl_op_mode_start()
1570 drv->dbgfs_drv); in _iwl_op_mode_start()
1571 dbgfs_dir = drv->dbgfs_op_mode; in _iwl_op_mode_start()
1574 op_mode = ops->start(drv->trans, drv->trans->cfg, in _iwl_op_mode_start()
1575 &drv->fw, dbgfs_dir); in _iwl_op_mode_start()
1580 if (iwl_trans_is_dead(drv->trans)) in _iwl_op_mode_start()
1584 debugfs_remove_recursive(drv->dbgfs_op_mode); in _iwl_op_mode_start()
1585 drv->dbgfs_op_mode = NULL; in _iwl_op_mode_start()
1588 if (PTR_ERR(op_mode) != -ETIMEDOUT) in _iwl_op_mode_start()
1591 IWL_ERR(drv, "retry init count %d\n", retry); in _iwl_op_mode_start()
1597 static void _iwl_op_mode_stop(struct iwl_drv *drv) in _iwl_op_mode_stop() argument
1603 if (drv->op_mode) { in _iwl_op_mode_stop()
1604 iwl_op_mode_stop(drv->op_mode); in _iwl_op_mode_stop()
1605 drv->op_mode = NULL; in _iwl_op_mode_stop()
1608 debugfs_remove_recursive(drv->dbgfs_op_mode); in _iwl_op_mode_stop()
1609 drv->dbgfs_op_mode = NULL; in _iwl_op_mode_stop()
1617 * iwl_req_fw_callback - callback when firmware was loaded
1624 struct iwl_drv *drv = context; in iwl_req_fw_callback() local
1625 struct iwl_fw *fw = &drv->fw; in iwl_req_fw_callback()
1637 iwl_get_ucode_api_versions(drv->trans, &api_min, &api_max); in iwl_req_fw_callback()
1639 fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH; in iwl_req_fw_callback()
1640 fw->ucode_capa.standard_phy_calibration_size = in iwl_req_fw_callback()
1642 fw->ucode_capa.n_scan_channels = IWL_DEFAULT_SCAN_CHANNELS; in iwl_req_fw_callback()
1643 fw->ucode_capa.num_stations = IWL_STATION_COUNT_MAX; in iwl_req_fw_callback()
1644 fw->ucode_capa.num_beacons = 1; in iwl_req_fw_callback()
1646 fw->dbg.dump_mask = 0xffffffff; in iwl_req_fw_callback()
1655 IWL_DEBUG_FW_INFO(drv, "Loaded firmware file '%s' (%zd bytes).\n", in iwl_req_fw_callback()
1656 drv->firmware_name, ucode_raw->size); in iwl_req_fw_callback()
1659 if (ucode_raw->size < 4) { in iwl_req_fw_callback()
1660 IWL_ERR(drv, "File size way too small!\n"); in iwl_req_fw_callback()
1665 ucode = (const struct iwl_ucode_header *)ucode_raw->data; in iwl_req_fw_callback()
1667 if (ucode->ver) in iwl_req_fw_callback()
1668 err = iwl_parse_v1_v2_firmware(drv, ucode_raw, pieces); in iwl_req_fw_callback()
1670 err = iwl_parse_tlv_firmware(drv, ucode_raw, pieces, in iwl_req_fw_callback()
1671 &fw->ucode_capa, &usniffer_images); in iwl_req_fw_callback()
1676 if (fw_has_api(&drv->fw.ucode_capa, IWL_UCODE_TLV_API_NEW_VERSION)) in iwl_req_fw_callback()
1677 api_ver = drv->fw.ucode_ver; in iwl_req_fw_callback()
1679 api_ver = IWL_UCODE_API(drv->fw.ucode_ver); in iwl_req_fw_callback()
1687 IWL_ERR(drv, in iwl_req_fw_callback()
1698 if (fw->type == IWL_FW_DVM && validate_sec_sizes(drv, pieces, in iwl_req_fw_callback()
1699 drv->trans->cfg)) in iwl_req_fw_callback()
1702 /* Allocate ucode buffers for card's bus-master loading ... */ in iwl_req_fw_callback()
1706 * 2) backup cache for save/restore during power-downs in iwl_req_fw_callback()
1709 if (iwl_alloc_ucode(drv, pieces, i)) in iwl_req_fw_callback()
1712 if (pieces->dbg_dest_tlv_init) { in iwl_req_fw_callback()
1713 size_t dbg_dest_size = sizeof(*drv->fw.dbg.dest_tlv) + in iwl_req_fw_callback()
1714 sizeof(drv->fw.dbg.dest_tlv->reg_ops[0]) * in iwl_req_fw_callback()
1715 drv->fw.dbg.n_dest_reg; in iwl_req_fw_callback()
1717 drv->fw.dbg.dest_tlv = kmalloc(dbg_dest_size, GFP_KERNEL); in iwl_req_fw_callback()
1719 if (!drv->fw.dbg.dest_tlv) in iwl_req_fw_callback()
1722 if (*pieces->dbg_dest_ver == 0) { in iwl_req_fw_callback()
1723 memcpy(drv->fw.dbg.dest_tlv, pieces->dbg_dest_tlv_v1, in iwl_req_fw_callback()
1727 drv->fw.dbg.dest_tlv; in iwl_req_fw_callback()
1729 dest_tlv->version = pieces->dbg_dest_tlv->version; in iwl_req_fw_callback()
1730 dest_tlv->monitor_mode = in iwl_req_fw_callback()
1731 pieces->dbg_dest_tlv->monitor_mode; in iwl_req_fw_callback()
1732 dest_tlv->size_power = in iwl_req_fw_callback()
1733 pieces->dbg_dest_tlv->size_power; in iwl_req_fw_callback()
1734 dest_tlv->wrap_count = in iwl_req_fw_callback()
1735 pieces->dbg_dest_tlv->wrap_count; in iwl_req_fw_callback()
1736 dest_tlv->write_ptr_reg = in iwl_req_fw_callback()
1737 pieces->dbg_dest_tlv->write_ptr_reg; in iwl_req_fw_callback()
1738 dest_tlv->base_shift = in iwl_req_fw_callback()
1739 pieces->dbg_dest_tlv->base_shift; in iwl_req_fw_callback()
1740 memcpy(dest_tlv->reg_ops, in iwl_req_fw_callback()
1741 pieces->dbg_dest_tlv->reg_ops, in iwl_req_fw_callback()
1742 sizeof(drv->fw.dbg.dest_tlv->reg_ops[0]) * in iwl_req_fw_callback()
1743 drv->fw.dbg.n_dest_reg); in iwl_req_fw_callback()
1753 dest_tlv->base_reg = pieces->dbg_dest_tlv->cfg_reg; in iwl_req_fw_callback()
1754 dest_tlv->end_shift = in iwl_req_fw_callback()
1755 pieces->dbg_dest_tlv->size_shift; in iwl_req_fw_callback()
1759 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg.conf_tlv); i++) { in iwl_req_fw_callback()
1760 if (pieces->dbg_conf_tlv[i]) { in iwl_req_fw_callback()
1761 drv->fw.dbg.conf_tlv[i] = in iwl_req_fw_callback()
1762 kmemdup(pieces->dbg_conf_tlv[i], in iwl_req_fw_callback()
1763 pieces->dbg_conf_tlv_len[i], in iwl_req_fw_callback()
1765 if (!drv->fw.dbg.conf_tlv[i]) in iwl_req_fw_callback()
1792 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg.trigger_tlv); i++) { in iwl_req_fw_callback()
1793 if (pieces->dbg_trigger_tlv[i]) { in iwl_req_fw_callback()
1801 if (WARN_ON(pieces->dbg_trigger_tlv_len[i] < in iwl_req_fw_callback()
1805 drv->fw.dbg.trigger_tlv_len[i] = in iwl_req_fw_callback()
1806 pieces->dbg_trigger_tlv_len[i]; in iwl_req_fw_callback()
1807 drv->fw.dbg.trigger_tlv[i] = in iwl_req_fw_callback()
1808 kmemdup(pieces->dbg_trigger_tlv[i], in iwl_req_fw_callback()
1809 drv->fw.dbg.trigger_tlv_len[i], in iwl_req_fw_callback()
1811 if (!drv->fw.dbg.trigger_tlv[i]) in iwl_req_fw_callback()
1818 drv->fw.dbg.mem_tlv = pieces->dbg_mem_tlv; in iwl_req_fw_callback()
1819 pieces->dbg_mem_tlv = NULL; in iwl_req_fw_callback()
1820 drv->fw.dbg.n_mem_tlv = pieces->n_mem_tlv; in iwl_req_fw_callback()
1823 * The (size - 16) / 12 formula is based on the information recorded in iwl_req_fw_callback()
1827 fw->init_evtlog_ptr = pieces->init_evtlog_ptr; in iwl_req_fw_callback()
1828 if (pieces->init_evtlog_size) in iwl_req_fw_callback()
1829 fw->init_evtlog_size = (pieces->init_evtlog_size - 16)/12; in iwl_req_fw_callback()
1831 fw->init_evtlog_size = in iwl_req_fw_callback()
1832 drv->trans->mac_cfg->base->max_event_log_size; in iwl_req_fw_callback()
1833 fw->init_errlog_ptr = pieces->init_errlog_ptr; in iwl_req_fw_callback()
1834 fw->inst_evtlog_ptr = pieces->inst_evtlog_ptr; in iwl_req_fw_callback()
1835 if (pieces->inst_evtlog_size) in iwl_req_fw_callback()
1836 fw->inst_evtlog_size = (pieces->inst_evtlog_size - 16)/12; in iwl_req_fw_callback()
1838 fw->inst_evtlog_size = in iwl_req_fw_callback()
1839 drv->trans->mac_cfg->base->max_event_log_size; in iwl_req_fw_callback()
1840 fw->inst_errlog_ptr = pieces->inst_errlog_ptr; in iwl_req_fw_callback()
1846 if (fw->ucode_capa.standard_phy_calibration_size > in iwl_req_fw_callback()
1848 fw->ucode_capa.standard_phy_calibration_size = in iwl_req_fw_callback()
1854 iwl_dbg_tlv_load_bin(drv->trans->dev, drv->trans); in iwl_req_fw_callback()
1857 switch (fw->type) { in iwl_req_fw_callback()
1862 WARN(1, "Invalid fw type %d\n", fw->type); in iwl_req_fw_callback()
1870 if (pieces->major >= IWL_MLD_SUPPORTED_FW_VERSION && in iwl_req_fw_callback()
1871 iwl_drv_is_wifi7_supported(drv->trans)) in iwl_req_fw_callback()
1874 if (pieces->major >= IWL_MLD_SUPPORTED_FW_VERSION && in iwl_req_fw_callback()
1875 iwl_drv_is_wifi7_supported(drv->trans)) { in iwl_req_fw_callback()
1876 IWL_ERR(drv, in iwl_req_fw_callback()
1883 IWL_INFO(drv, "loaded firmware version %s op_mode %s\n", in iwl_req_fw_callback()
1884 drv->fw.fw_version, op->name); in iwl_req_fw_callback()
1887 list_add_tail(&drv->list, &op->drv); in iwl_req_fw_callback()
1889 if (op->ops) { in iwl_req_fw_callback()
1890 drv->op_mode = _iwl_op_mode_start(drv, op); in iwl_req_fw_callback()
1892 if (!drv->op_mode) { in iwl_req_fw_callback()
1898 request_module_nowait("%s", op->name); in iwl_req_fw_callback()
1901 * In FreeBSD if_iwlwifi contains all drv modules in a single in iwl_req_fw_callback()
1909 __func__, op->name); in iwl_req_fw_callback()
1914 complete(&drv->request_firmware_complete); in iwl_req_fw_callback()
1922 if (iwl_request_firmware(drv, false)) in iwl_req_fw_callback()
1929 complete(&drv->request_firmware_complete); in iwl_req_fw_callback()
1930 device_release_driver(drv->trans->dev); in iwl_req_fw_callback()
1931 /* drv has just been freed by the release */ in iwl_req_fw_callback()
1935 iwl_dealloc_ucode(drv); in iwl_req_fw_callback()
1938 for (i = 0; i < ARRAY_SIZE(pieces->img); i++) in iwl_req_fw_callback()
1939 kfree(pieces->img[i].sec); in iwl_req_fw_callback()
1940 kfree(pieces->dbg_mem_tlv); in iwl_req_fw_callback()
1947 struct iwl_drv *drv; in iwl_drv_start() local
1950 drv = kzalloc(sizeof(*drv), GFP_KERNEL); in iwl_drv_start()
1951 if (!drv) { in iwl_drv_start()
1952 ret = -ENOMEM; in iwl_drv_start()
1956 drv->trans = trans; in iwl_drv_start()
1957 drv->dev = trans->dev; in iwl_drv_start()
1959 init_completion(&drv->request_firmware_complete); in iwl_drv_start()
1961 init_completion(&drv->drv_start_complete); in iwl_drv_start()
1963 INIT_LIST_HEAD(&drv->list); in iwl_drv_start()
1967 drv->dbgfs_drv = debugfs_create_dir(dev_name(trans->dev), in iwl_drv_start()
1971 drv->trans->dbgfs_dir = debugfs_create_dir("trans", drv->dbgfs_drv); in iwl_drv_start()
1974 drv->trans->dbg.domains_bitmap = IWL_TRANS_FW_DBG_DOMAIN(drv->trans); in iwl_drv_start()
1976 /* We have a non-default value in the module parameter, in iwl_drv_start()
1979 drv->trans->dbg.domains_bitmap &= 0xffff; in iwl_drv_start()
1987 drv->trans->dbg.domains_bitmap = in iwl_drv_start()
1992 ret = iwl_request_firmware(drv, true); in iwl_drv_start()
2001 * replicate FreeBSD's synchronous behaviour -- we cannot create in iwl_drv_start()
2005 wait_for_completion(&drv->request_firmware_complete); in iwl_drv_start()
2006 complete(&drv->drv_start_complete); in iwl_drv_start()
2009 return drv; in iwl_drv_start()
2013 debugfs_remove_recursive(drv->dbgfs_drv); in iwl_drv_start()
2015 iwl_dbg_tlv_free(drv->trans); in iwl_drv_start()
2016 kfree(drv); in iwl_drv_start()
2021 void iwl_drv_stop(struct iwl_drv *drv) in iwl_drv_stop() argument
2024 wait_for_completion(&drv->request_firmware_complete); in iwl_drv_stop()
2026 wait_for_completion(&drv->drv_start_complete); in iwl_drv_stop()
2031 _iwl_op_mode_stop(drv); in iwl_drv_stop()
2033 iwl_dealloc_ucode(drv); in iwl_drv_stop()
2037 * when firmware loading failed -- in that in iwl_drv_stop()
2040 if (!list_empty(&drv->list)) in iwl_drv_stop()
2041 list_del(&drv->list); in iwl_drv_stop()
2045 iwl_trans_debugfs_cleanup(drv->trans); in iwl_drv_stop()
2047 debugfs_remove_recursive(drv->dbgfs_drv); in iwl_drv_stop()
2050 iwl_dbg_tlv_free(drv->trans); in iwl_drv_stop()
2052 kfree(drv); in iwl_drv_stop()
2075 struct iwl_drv *drv; in iwl_opmode_register() local
2081 if (strcmp(op->name, name)) in iwl_opmode_register()
2083 op->ops = ops; in iwl_opmode_register()
2085 list_for_each_entry(drv, &op->drv, list) in iwl_opmode_register()
2086 drv->op_mode = _iwl_op_mode_start(drv, op); in iwl_opmode_register()
2092 return -EIO; in iwl_opmode_register()
2099 struct iwl_drv *drv; in iwl_opmode_deregister() local
2108 list_for_each_entry(drv, &iwlwifi_opmode_table[i].drv, list) in iwl_opmode_deregister()
2109 _iwl_op_mode_stop(drv); in iwl_opmode_deregister()
2123 INIT_LIST_HEAD(&iwlwifi_opmode_table[i].drv); in iwl_drv_init()
2177 "disable U-APSD functionality bitmap 1: BSS 2: P2P Client (default: 3)");
2181 "0:disable, 1-15:FW_DBG_PRESET Values, 16:enabled without preset value defined,"
2192 * co-exist problem. The possible behaviors are:
2202 MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)");
2214 "default power save level (range from 1 - 5, default: 1)");