Lines Matching +full:drv +full:- +full:0
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
8 #include <linux/dma-mapping.h>
13 #include "iwl-drv.h"
14 #include "iwl-csr.h"
15 #include "iwl-debug.h"
16 #include "iwl-trans.h"
17 #include "iwl-op-mode.h"
18 #include "iwl-agn-hw.h"
20 #include "iwl-dbg-tlv.h"
21 #include "iwl-config.h"
22 #include "iwl-modparams.h"
41 * struct iwl_drv - drv common data
42 * @list: list of drv structures using this opmode
79 /* Protects the table contents, i.e. the ops pointer & drv list */
84 struct list_head drv; /* list of devices using this op_mode */ member
102 static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc) in iwl_free_fw_desc() argument
104 vfree(desc->data); in iwl_free_fw_desc()
105 desc->data = NULL; in iwl_free_fw_desc()
106 desc->len = 0; in iwl_free_fw_desc()
109 static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img) in iwl_free_fw_img() argument
112 for (i = 0; i < img->num_sec; i++) in iwl_free_fw_img()
113 iwl_free_fw_desc(drv, &img->sec[i]); in iwl_free_fw_img()
114 kfree(img->sec); in iwl_free_fw_img()
117 static void iwl_dealloc_ucode(struct iwl_drv *drv) in iwl_dealloc_ucode() argument
121 kfree(drv->fw.dbg.dest_tlv); in iwl_dealloc_ucode()
122 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg.conf_tlv); i++) in iwl_dealloc_ucode()
123 kfree(drv->fw.dbg.conf_tlv[i]); in iwl_dealloc_ucode()
124 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg.trigger_tlv); i++) in iwl_dealloc_ucode()
125 kfree(drv->fw.dbg.trigger_tlv[i]); in iwl_dealloc_ucode()
126 kfree(drv->fw.dbg.mem_tlv); in iwl_dealloc_ucode()
127 kfree(drv->fw.iml); in iwl_dealloc_ucode()
128 kfree(drv->fw.ucode_capa.cmd_versions); in iwl_dealloc_ucode()
129 kfree(drv->fw.phy_integration_ver); in iwl_dealloc_ucode()
130 kfree(drv->trans->dbg.pc_data); in iwl_dealloc_ucode()
131 drv->trans->dbg.pc_data = NULL; in iwl_dealloc_ucode()
133 for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) in iwl_dealloc_ucode()
134 iwl_free_fw_img(drv, drv->fw.img + i); in iwl_dealloc_ucode()
137 memset(&drv->fw, 0, sizeof(drv->fw)); in iwl_dealloc_ucode()
140 static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc, in iwl_alloc_fw_desc() argument
145 desc->data = NULL; in iwl_alloc_fw_desc()
147 if (!sec || !sec->size) in iwl_alloc_fw_desc()
148 return -EINVAL; in iwl_alloc_fw_desc()
150 data = vmalloc(sec->size); in iwl_alloc_fw_desc()
152 return -ENOMEM; in iwl_alloc_fw_desc()
154 desc->len = sec->size; in iwl_alloc_fw_desc()
155 desc->offset = sec->offset; in iwl_alloc_fw_desc()
156 memcpy(data, sec->data, desc->len); in iwl_alloc_fw_desc()
157 desc->data = data; in iwl_alloc_fw_desc()
159 return 0; in iwl_alloc_fw_desc()
176 if (trans->cfg->fw_name_pre) in iwl_drv_get_fwname_pre()
177 return trans->cfg->fw_name_pre; in iwl_drv_get_fwname_pre()
179 if (WARN_ON(!trans->cfg->fw_name_mac)) in iwl_drv_get_fwname_pre()
182 mac_step = iwl_drv_get_step(trans->hw_rev_step); in iwl_drv_get_fwname_pre()
184 rf_step = iwl_drv_get_step(CSR_HW_RFID_STEP(trans->hw_rf_id)); in iwl_drv_get_fwname_pre()
186 switch (CSR_HW_RFID_TYPE(trans->hw_rf_id)) { in iwl_drv_get_fwname_pre()
200 CSR_HW_RFID_STEP(trans->hw_rf_id)) { in iwl_drv_get_fwname_pre()
208 return "unknown-rf"; in iwl_drv_get_fwname_pre()
211 cdb = CSR_HW_RFID_IS_CDB(trans->hw_rf_id) ? "4" : ""; in iwl_drv_get_fwname_pre()
214 "iwlwifi-%s-%c0-%s%s-%c0", in iwl_drv_get_fwname_pre()
215 trans->cfg->fw_name_mac, mac_step, in iwl_drv_get_fwname_pre()
225 static int iwl_request_firmware(struct iwl_drv *drv, bool first) in iwl_request_firmware() argument
227 const struct iwl_cfg *cfg = drv->trans->cfg; in iwl_request_firmware()
231 if (drv->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_9000 && in iwl_request_firmware()
232 (drv->trans->hw_rev_step != SILICON_B_STEP && in iwl_request_firmware()
233 drv->trans->hw_rev_step != SILICON_C_STEP)) { in iwl_request_firmware()
234 IWL_ERR(drv, in iwl_request_firmware()
235 "Only HW steps B and C are currently supported (0x%0x)\n", in iwl_request_firmware()
236 drv->trans->hw_rev); in iwl_request_firmware()
237 return -EINVAL; in iwl_request_firmware()
240 fw_name_pre = iwl_drv_get_fwname_pre(drv->trans, _fw_name_pre); in iwl_request_firmware()
243 drv->fw_index = cfg->ucode_api_max; in iwl_request_firmware()
245 drv->fw_index--; in iwl_request_firmware()
247 if (drv->fw_index < cfg->ucode_api_min) { in iwl_request_firmware()
248 IWL_ERR(drv, "no suitable firmware found!\n"); in iwl_request_firmware()
250 if (cfg->ucode_api_min == cfg->ucode_api_max) { in iwl_request_firmware()
251 IWL_ERR(drv, "%s-%d is required\n", fw_name_pre, in iwl_request_firmware()
252 cfg->ucode_api_max); in iwl_request_firmware()
254 IWL_ERR(drv, "minimum version required: %s-%d\n", in iwl_request_firmware()
255 fw_name_pre, cfg->ucode_api_min); in iwl_request_firmware()
256 IWL_ERR(drv, "maximum version supported: %s-%d\n", in iwl_request_firmware()
257 fw_name_pre, cfg->ucode_api_max); in iwl_request_firmware()
260 IWL_ERR(drv, in iwl_request_firmware()
261 "check git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git\n"); in iwl_request_firmware()
262 return -ENOENT; in iwl_request_firmware()
265 snprintf(drv->firmware_name, sizeof(drv->firmware_name), "%s-%d.ucode", in iwl_request_firmware()
266 fw_name_pre, drv->fw_index); in iwl_request_firmware()
268 IWL_DEBUG_FW_INFO(drv, "attempting to load firmware '%s'\n", in iwl_request_firmware()
269 drv->firmware_name); in iwl_request_firmware()
271 return request_firmware_nowait(THIS_MODULE, 1, drv->firmware_name, in iwl_request_firmware()
272 drv->trans->dev, in iwl_request_firmware()
273 GFP_KERNEL, drv, iwl_req_fw_callback); in iwl_request_firmware()
290 * struct iwl_tlv_calib_data - parse the default calib data from TLV
329 return &pieces->img[type].sec[sec]; in get_sec()
336 struct fw_img_parsing *img = &pieces->img[type]; in alloc_sec_data()
339 size_t alloc_size = sizeof(*img->sec) * size; in alloc_sec_data()
341 if (img->sec && img->sec_counter >= size) in alloc_sec_data()
344 sec_memory = krealloc(img->sec, alloc_size, GFP_KERNEL); in alloc_sec_data()
348 img->sec = sec_memory; in alloc_sec_data()
349 img->sec_counter = size; in alloc_sec_data()
359 pieces->img[type].sec[sec].data = data; in set_sec_data()
369 pieces->img[type].sec[sec].size = size; in set_sec_size()
376 return pieces->img[type].sec[sec].size; in get_sec_size()
386 pieces->img[type].sec[sec].offset = offset; in set_sec_offset()
402 return -1; in iwl_store_ucode_sec()
406 img = &pieces->img[type]; in iwl_store_ucode_sec()
408 alloc_size = sizeof(*img->sec) * (img->sec_counter + 1); in iwl_store_ucode_sec()
409 sec = krealloc(img->sec, alloc_size, GFP_KERNEL); in iwl_store_ucode_sec()
411 return -ENOMEM; in iwl_store_ucode_sec()
412 img->sec = sec; in iwl_store_ucode_sec()
414 sec = &img->sec[img->sec_counter]; in iwl_store_ucode_sec()
416 sec->offset = le32_to_cpu(sec_parse->offset); in iwl_store_ucode_sec()
417 sec->data = sec_parse->data; in iwl_store_ucode_sec()
418 sec->size = size - sizeof(sec_parse->offset); in iwl_store_ucode_sec()
420 ++img->sec_counter; in iwl_store_ucode_sec()
422 return 0; in iwl_store_ucode_sec()
425 static int iwl_set_default_calib(struct iwl_drv *drv, const u8 *data) in iwl_set_default_calib() argument
429 u32 ucode_type = le32_to_cpu(def_calib->ucode_type); in iwl_set_default_calib()
431 IWL_ERR(drv, "Wrong ucode_type %u for default calibration.\n", in iwl_set_default_calib()
433 return -EINVAL; in iwl_set_default_calib()
435 drv->fw.default_calib[ucode_type].flow_trigger = in iwl_set_default_calib()
436 def_calib->calib.flow_trigger; in iwl_set_default_calib()
437 drv->fw.default_calib[ucode_type].event_trigger = in iwl_set_default_calib()
438 def_calib->calib.event_trigger; in iwl_set_default_calib()
440 return 0; in iwl_set_default_calib()
443 static void iwl_set_ucode_api_flags(struct iwl_drv *drv, const u8 *data, in iwl_set_ucode_api_flags() argument
447 u32 api_index = le32_to_cpu(ucode_api->api_index); in iwl_set_ucode_api_flags()
448 u32 api_flags = le32_to_cpu(ucode_api->api_flags); in iwl_set_ucode_api_flags()
452 IWL_WARN(drv, in iwl_set_ucode_api_flags()
458 for (i = 0; i < 32; i++) { in iwl_set_ucode_api_flags()
460 __set_bit(i + 32 * api_index, capa->_api); in iwl_set_ucode_api_flags()
464 static void iwl_set_ucode_capabilities(struct iwl_drv *drv, const u8 *data, in iwl_set_ucode_capabilities() argument
468 u32 api_index = le32_to_cpu(ucode_capa->api_index); in iwl_set_ucode_capabilities()
469 u32 api_flags = le32_to_cpu(ucode_capa->api_capa); in iwl_set_ucode_capabilities()
473 IWL_WARN(drv, in iwl_set_ucode_capabilities()
479 for (i = 0; i < 32; i++) { in iwl_set_ucode_capabilities()
481 __set_bit(i + 32 * api_index, capa->_capa); in iwl_set_ucode_capabilities()
485 static const char *iwl_reduced_fw_name(struct iwl_drv *drv) in iwl_reduced_fw_name() argument
487 const char *name = drv->firmware_name; in iwl_reduced_fw_name()
489 if (strncmp(name, "iwlwifi-", 8) == 0) in iwl_reduced_fw_name()
495 static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, in iwl_parse_v1_v2_firmware() argument
499 const struct iwl_ucode_header *ucode = (const void *)ucode_raw->data; in iwl_parse_v1_v2_firmware()
504 drv->fw.ucode_ver = le32_to_cpu(ucode->ver); in iwl_parse_v1_v2_firmware()
505 api_ver = IWL_UCODE_API(drv->fw.ucode_ver); in iwl_parse_v1_v2_firmware()
510 if (ucode_raw->size < hdr_size) { in iwl_parse_v1_v2_firmware()
511 IWL_ERR(drv, "File size too small!\n"); in iwl_parse_v1_v2_firmware()
512 return -EINVAL; in iwl_parse_v1_v2_firmware()
514 build = le32_to_cpu(ucode->u.v2.build); in iwl_parse_v1_v2_firmware()
516 le32_to_cpu(ucode->u.v2.inst_size)); in iwl_parse_v1_v2_firmware()
518 le32_to_cpu(ucode->u.v2.data_size)); in iwl_parse_v1_v2_firmware()
520 le32_to_cpu(ucode->u.v2.init_size)); in iwl_parse_v1_v2_firmware()
522 le32_to_cpu(ucode->u.v2.init_data_size)); in iwl_parse_v1_v2_firmware()
523 src = ucode->u.v2.data; in iwl_parse_v1_v2_firmware()
525 case 0: in iwl_parse_v1_v2_firmware()
529 if (ucode_raw->size < hdr_size) { in iwl_parse_v1_v2_firmware()
530 IWL_ERR(drv, "File size too small!\n"); in iwl_parse_v1_v2_firmware()
531 return -EINVAL; in iwl_parse_v1_v2_firmware()
533 build = 0; in iwl_parse_v1_v2_firmware()
535 le32_to_cpu(ucode->u.v1.inst_size)); in iwl_parse_v1_v2_firmware()
537 le32_to_cpu(ucode->u.v1.data_size)); in iwl_parse_v1_v2_firmware()
539 le32_to_cpu(ucode->u.v1.init_size)); in iwl_parse_v1_v2_firmware()
541 le32_to_cpu(ucode->u.v1.init_data_size)); in iwl_parse_v1_v2_firmware()
542 src = ucode->u.v1.data; in iwl_parse_v1_v2_firmware()
549 buildstr[0] = '\0'; in iwl_parse_v1_v2_firmware()
551 snprintf(drv->fw.fw_version, in iwl_parse_v1_v2_firmware()
552 sizeof(drv->fw.fw_version), in iwl_parse_v1_v2_firmware()
554 IWL_UCODE_MAJOR(drv->fw.ucode_ver), in iwl_parse_v1_v2_firmware()
555 IWL_UCODE_MINOR(drv->fw.ucode_ver), in iwl_parse_v1_v2_firmware()
556 IWL_UCODE_API(drv->fw.ucode_ver), in iwl_parse_v1_v2_firmware()
557 IWL_UCODE_SERIAL(drv->fw.ucode_ver), in iwl_parse_v1_v2_firmware()
558 buildstr, iwl_reduced_fw_name(drv)); in iwl_parse_v1_v2_firmware()
562 if (ucode_raw->size != hdr_size + in iwl_parse_v1_v2_firmware()
568 IWL_ERR(drv, in iwl_parse_v1_v2_firmware()
570 (int)ucode_raw->size); in iwl_parse_v1_v2_firmware()
571 return -EINVAL; in iwl_parse_v1_v2_firmware()
591 return 0; in iwl_parse_v1_v2_firmware()
594 static void iwl_drv_set_dump_exclude(struct iwl_drv *drv, in iwl_drv_set_dump_exclude() argument
605 excl = &drv->fw.dump_excl[0]; in iwl_drv_set_dump_exclude()
608 if (excl->addr) in iwl_drv_set_dump_exclude()
609 excl = &drv->fw.dump_excl_wowlan[0]; in iwl_drv_set_dump_exclude()
610 } else if (fw_has_capa(&drv->fw.ucode_capa, in iwl_drv_set_dump_exclude()
613 excl = &drv->fw.dump_excl[0]; in iwl_drv_set_dump_exclude()
616 excl = &drv->fw.dump_excl_wowlan[0]; in iwl_drv_set_dump_exclude()
619 if (excl->addr) in iwl_drv_set_dump_exclude()
622 if (excl->addr) { in iwl_drv_set_dump_exclude()
623 IWL_DEBUG_FW_INFO(drv, "found too many excludes in fw file\n"); in iwl_drv_set_dump_exclude()
627 excl->addr = le32_to_cpu(fw->addr) & ~FW_ADDR_CACHE_CONTROL; in iwl_drv_set_dump_exclude()
628 excl->size = le32_to_cpu(fw->size); in iwl_drv_set_dump_exclude()
631 static void iwl_parse_dbg_tlv_assert_tables(struct iwl_drv *drv, in iwl_parse_dbg_tlv_assert_tables() argument
635 u32 length = le32_to_cpu(tlv->length); in iwl_parse_dbg_tlv_assert_tables()
639 sizeof(region->special_mem)) in iwl_parse_dbg_tlv_assert_tables()
642 region = (const void *)tlv->data; in iwl_parse_dbg_tlv_assert_tables()
643 addr = le32_to_cpu(region->special_mem.base_addr); in iwl_parse_dbg_tlv_assert_tables()
644 addr += le32_to_cpu(region->special_mem.offset); in iwl_parse_dbg_tlv_assert_tables()
647 if (region->type != IWL_FW_INI_REGION_SPECIAL_DEVICE_MEMORY) in iwl_parse_dbg_tlv_assert_tables()
650 switch (region->sub_type) { in iwl_parse_dbg_tlv_assert_tables()
652 drv->trans->dbg.umac_error_event_table = addr; in iwl_parse_dbg_tlv_assert_tables()
653 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
657 drv->trans->dbg.lmac_error_event_table[0] = addr; in iwl_parse_dbg_tlv_assert_tables()
658 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
662 drv->trans->dbg.lmac_error_event_table[1] = addr; in iwl_parse_dbg_tlv_assert_tables()
663 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
667 drv->trans->dbg.tcm_error_event_table[0] = addr; in iwl_parse_dbg_tlv_assert_tables()
668 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
672 drv->trans->dbg.tcm_error_event_table[1] = addr; in iwl_parse_dbg_tlv_assert_tables()
673 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
677 drv->trans->dbg.rcm_error_event_table[0] = addr; in iwl_parse_dbg_tlv_assert_tables()
678 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
682 drv->trans->dbg.rcm_error_event_table[1] = addr; in iwl_parse_dbg_tlv_assert_tables()
683 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_dbg_tlv_assert_tables()
691 static int iwl_parse_tlv_firmware(struct iwl_drv *drv, in iwl_parse_tlv_firmware() argument
697 const struct iwl_tlv_ucode_header *ucode = (const void *)ucode_raw->data; in iwl_parse_tlv_firmware()
699 size_t len = ucode_raw->size; in iwl_parse_tlv_firmware()
711 IWL_ERR(drv, "uCode has invalid length: %zd\n", len); in iwl_parse_tlv_firmware()
712 return -EINVAL; in iwl_parse_tlv_firmware()
715 if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { in iwl_parse_tlv_firmware()
716 IWL_ERR(drv, "invalid uCode magic: 0X%x\n", in iwl_parse_tlv_firmware()
717 le32_to_cpu(ucode->magic)); in iwl_parse_tlv_firmware()
718 return -EINVAL; in iwl_parse_tlv_firmware()
721 drv->fw.ucode_ver = le32_to_cpu(ucode->ver); in iwl_parse_tlv_firmware()
722 memcpy(drv->fw.human_readable, ucode->human_readable, in iwl_parse_tlv_firmware()
723 sizeof(drv->fw.human_readable)); in iwl_parse_tlv_firmware()
724 build = le32_to_cpu(ucode->build); in iwl_parse_tlv_firmware()
729 buildstr[0] = '\0'; in iwl_parse_tlv_firmware()
731 snprintf(drv->fw.fw_version, in iwl_parse_tlv_firmware()
732 sizeof(drv->fw.fw_version), in iwl_parse_tlv_firmware()
734 IWL_UCODE_MAJOR(drv->fw.ucode_ver), in iwl_parse_tlv_firmware()
735 IWL_UCODE_MINOR(drv->fw.ucode_ver), in iwl_parse_tlv_firmware()
736 IWL_UCODE_API(drv->fw.ucode_ver), in iwl_parse_tlv_firmware()
737 IWL_UCODE_SERIAL(drv->fw.ucode_ver), in iwl_parse_tlv_firmware()
738 buildstr, iwl_reduced_fw_name(drv)); in iwl_parse_tlv_firmware()
740 data = ucode->data; in iwl_parse_tlv_firmware()
742 len -= sizeof(*ucode); in iwl_parse_tlv_firmware()
745 len -= sizeof(*tlv); in iwl_parse_tlv_firmware()
748 tlv_len = le32_to_cpu(tlv->length); in iwl_parse_tlv_firmware()
749 tlv_type = le32_to_cpu(tlv->type); in iwl_parse_tlv_firmware()
750 tlv_data = tlv->data; in iwl_parse_tlv_firmware()
753 IWL_ERR(drv, "invalid TLV len: %zd/%u\n", in iwl_parse_tlv_firmware()
755 return -EINVAL; in iwl_parse_tlv_firmware()
757 len -= ALIGN(tlv_len, 4); in iwl_parse_tlv_firmware()
798 IWL_ERR(drv, "Found unexpected BOOT ucode\n"); in iwl_parse_tlv_firmware()
803 capa->max_probe_length = in iwl_parse_tlv_firmware()
809 capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; in iwl_parse_tlv_firmware()
825 capa->flags = le32_to_cpup((const __le32 *)tlv_data); in iwl_parse_tlv_firmware()
830 iwl_set_ucode_api_flags(drv, tlv_data, capa); in iwl_parse_tlv_firmware()
835 iwl_set_ucode_capabilities(drv, tlv_data, capa); in iwl_parse_tlv_firmware()
840 pieces->init_evtlog_ptr = in iwl_parse_tlv_firmware()
846 pieces->init_evtlog_size = in iwl_parse_tlv_firmware()
852 pieces->init_errlog_ptr = in iwl_parse_tlv_firmware()
858 pieces->inst_evtlog_ptr = in iwl_parse_tlv_firmware()
864 pieces->inst_evtlog_size = in iwl_parse_tlv_firmware()
870 pieces->inst_errlog_ptr = in iwl_parse_tlv_firmware()
876 drv->fw.enhance_sensitivity_table = true; in iwl_parse_tlv_firmware()
899 capa->standard_phy_calibration_size = in iwl_parse_tlv_firmware()
905 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
910 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
915 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
920 if (iwl_set_default_calib(drv, tlv_data)) in iwl_parse_tlv_firmware()
926 drv->fw.phy_config = le32_to_cpup((const __le32 *)tlv_data); in iwl_parse_tlv_firmware()
927 drv->fw.valid_tx_ant = (drv->fw.phy_config & in iwl_parse_tlv_firmware()
930 drv->fw.valid_rx_ant = (drv->fw.phy_config & in iwl_parse_tlv_firmware()
937 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
942 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
947 drv->fw.type = IWL_FW_MVM; in iwl_parse_tlv_firmware()
956 drv->fw.img[IWL_UCODE_REGULAR].is_dual_cpus = in iwl_parse_tlv_firmware()
958 drv->fw.img[IWL_UCODE_INIT].is_dual_cpus = in iwl_parse_tlv_firmware()
960 drv->fw.img[IWL_UCODE_WOWLAN].is_dual_cpus = in iwl_parse_tlv_firmware()
963 IWL_ERR(drv, "Driver support up to 2 CPUs\n"); in iwl_parse_tlv_firmware()
964 return -EINVAL; in iwl_parse_tlv_firmware()
970 capa->n_scan_channels = in iwl_parse_tlv_firmware()
985 snprintf(drv->fw.fw_version, in iwl_parse_tlv_firmware()
986 sizeof(drv->fw.fw_version), in iwl_parse_tlv_firmware()
988 local_comp, iwl_reduced_fw_name(drv)); in iwl_parse_tlv_firmware()
996 pieces->dbg_dest_ver = (const u8 *)tlv_data; in iwl_parse_tlv_firmware()
997 if (*pieces->dbg_dest_ver == 1) { in iwl_parse_tlv_firmware()
999 } else if (*pieces->dbg_dest_ver == 0) { in iwl_parse_tlv_firmware()
1002 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1004 *pieces->dbg_dest_ver); in iwl_parse_tlv_firmware()
1008 if (pieces->dbg_dest_tlv_init) { in iwl_parse_tlv_firmware()
1009 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1014 pieces->dbg_dest_tlv_init = true; in iwl_parse_tlv_firmware()
1017 pieces->dbg_dest_tlv_v1 = dest_v1; in iwl_parse_tlv_firmware()
1018 mon_mode = dest_v1->monitor_mode; in iwl_parse_tlv_firmware()
1020 pieces->dbg_dest_tlv = dest; in iwl_parse_tlv_firmware()
1021 mon_mode = dest->monitor_mode; in iwl_parse_tlv_firmware()
1024 IWL_INFO(drv, "Found debug destination: %s\n", in iwl_parse_tlv_firmware()
1027 drv->fw.dbg.n_dest_reg = (dest_v1) ? in iwl_parse_tlv_firmware()
1028 tlv_len - in iwl_parse_tlv_firmware()
1031 tlv_len - in iwl_parse_tlv_firmware()
1035 drv->fw.dbg.n_dest_reg /= in iwl_parse_tlv_firmware()
1036 sizeof(drv->fw.dbg.dest_tlv->reg_ops[0]); in iwl_parse_tlv_firmware()
1044 if (!pieces->dbg_dest_tlv_init) { in iwl_parse_tlv_firmware()
1045 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1046 "Ignore dbg config %d - no destination configured\n", in iwl_parse_tlv_firmware()
1047 conf->id); in iwl_parse_tlv_firmware()
1051 if (conf->id >= ARRAY_SIZE(drv->fw.dbg.conf_tlv)) { in iwl_parse_tlv_firmware()
1052 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1054 conf->id); in iwl_parse_tlv_firmware()
1058 if (pieces->dbg_conf_tlv[conf->id]) { in iwl_parse_tlv_firmware()
1059 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1061 conf->id); in iwl_parse_tlv_firmware()
1065 if (conf->usniffer) in iwl_parse_tlv_firmware()
1068 IWL_INFO(drv, "Found debug configuration: %d\n", in iwl_parse_tlv_firmware()
1069 conf->id); in iwl_parse_tlv_firmware()
1071 pieces->dbg_conf_tlv[conf->id] = conf; in iwl_parse_tlv_firmware()
1072 pieces->dbg_conf_tlv_len[conf->id] = tlv_len; in iwl_parse_tlv_firmware()
1078 u32 trigger_id = le32_to_cpu(trigger->id); in iwl_parse_tlv_firmware()
1080 if (trigger_id >= ARRAY_SIZE(drv->fw.dbg.trigger_tlv)) { in iwl_parse_tlv_firmware()
1081 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1083 trigger->id); in iwl_parse_tlv_firmware()
1087 if (pieces->dbg_trigger_tlv[trigger_id]) { in iwl_parse_tlv_firmware()
1088 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1090 trigger->id); in iwl_parse_tlv_firmware()
1094 IWL_INFO(drv, "Found debug trigger: %u\n", trigger->id); in iwl_parse_tlv_firmware()
1096 pieces->dbg_trigger_tlv[trigger_id] = trigger; in iwl_parse_tlv_firmware()
1097 pieces->dbg_trigger_tlv_len[trigger_id] = tlv_len; in iwl_parse_tlv_firmware()
1102 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1107 drv->fw.dbg.dump_mask = in iwl_parse_tlv_firmware()
1122 IWL_DEBUG_FW(drv, in iwl_parse_tlv_firmware()
1127 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1130 return -EINVAL; in iwl_parse_tlv_firmware()
1133 if (paging_mem_size & (FW_PAGING_SIZE - 1)) { in iwl_parse_tlv_firmware()
1134 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1137 return -EINVAL; in iwl_parse_tlv_firmware()
1140 drv->fw.img[IWL_UCODE_REGULAR].paging_mem_size = in iwl_parse_tlv_firmware()
1143 drv->fw.img[usniffer_img].paging_mem_size = in iwl_parse_tlv_firmware()
1158 IWL_DEBUG_INFO(drv, "Found debug memory segment: %u\n", in iwl_parse_tlv_firmware()
1159 dbg_mem->data_type); in iwl_parse_tlv_firmware()
1161 size = sizeof(*pieces->dbg_mem_tlv) * in iwl_parse_tlv_firmware()
1162 (pieces->n_mem_tlv + 1); in iwl_parse_tlv_firmware()
1163 n = krealloc(pieces->dbg_mem_tlv, size, GFP_KERNEL); in iwl_parse_tlv_firmware()
1165 return -ENOMEM; in iwl_parse_tlv_firmware()
1166 pieces->dbg_mem_tlv = n; in iwl_parse_tlv_firmware()
1167 pieces->dbg_mem_tlv[pieces->n_mem_tlv] = *dbg_mem; in iwl_parse_tlv_firmware()
1168 pieces->n_mem_tlv++; in iwl_parse_tlv_firmware()
1172 drv->fw.iml_len = tlv_len; in iwl_parse_tlv_firmware()
1173 drv->fw.iml = kmemdup(tlv_data, tlv_len, GFP_KERNEL); in iwl_parse_tlv_firmware()
1174 if (!drv->fw.iml) in iwl_parse_tlv_firmware()
1175 return -ENOMEM; in iwl_parse_tlv_firmware()
1186 capa->error_log_addr = in iwl_parse_tlv_firmware()
1187 le32_to_cpu(recov_info->buf_addr); in iwl_parse_tlv_firmware()
1188 capa->error_log_size = in iwl_parse_tlv_firmware()
1189 le32_to_cpu(recov_info->buf_size); in iwl_parse_tlv_firmware()
1200 IWL_INFO(drv, "TLV_FW_FSEQ_VERSION: %s\n", in iwl_parse_tlv_firmware()
1201 fseq_ver->version); in iwl_parse_tlv_firmware()
1209 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1214 capa->num_stations = in iwl_parse_tlv_firmware()
1220 capa->num_beacons = in iwl_parse_tlv_firmware()
1229 if (drv->trans->trans_cfg->device_family < in iwl_parse_tlv_firmware()
1232 drv->trans->dbg.umac_error_event_table = in iwl_parse_tlv_firmware()
1233 le32_to_cpu(dbg_ptrs->error_info_addr) & in iwl_parse_tlv_firmware()
1235 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_tlv_firmware()
1245 if (drv->trans->trans_cfg->device_family < in iwl_parse_tlv_firmware()
1248 drv->trans->dbg.lmac_error_event_table[0] = in iwl_parse_tlv_firmware()
1249 le32_to_cpu(dbg_ptrs->error_event_table_ptr) & in iwl_parse_tlv_firmware()
1251 drv->trans->dbg.error_event_table_tlv_status |= in iwl_parse_tlv_firmware()
1256 iwl_parse_dbg_tlv_assert_tables(drv, tlv); in iwl_parse_tlv_firmware()
1264 iwl_dbg_tlv_alloc(drv->trans, tlv, false); in iwl_parse_tlv_firmware()
1268 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1274 if (WARN_ON(capa->cmd_versions)) in iwl_parse_tlv_firmware()
1275 return -EINVAL; in iwl_parse_tlv_firmware()
1276 capa->cmd_versions = kmemdup(tlv_data, tlv_len, in iwl_parse_tlv_firmware()
1278 if (!capa->cmd_versions) in iwl_parse_tlv_firmware()
1279 return -ENOMEM; in iwl_parse_tlv_firmware()
1280 capa->n_cmd_versions = in iwl_parse_tlv_firmware()
1284 if (drv->fw.phy_integration_ver) { in iwl_parse_tlv_firmware()
1285 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1290 drv->fw.phy_integration_ver = in iwl_parse_tlv_firmware()
1292 if (!drv->fw.phy_integration_ver) in iwl_parse_tlv_firmware()
1293 return -ENOMEM; in iwl_parse_tlv_firmware()
1294 drv->fw.phy_integration_ver_len = tlv_len; in iwl_parse_tlv_firmware()
1298 iwl_drv_set_dump_exclude(drv, tlv_type, in iwl_parse_tlv_firmware()
1304 drv->trans->dbg.pc_data = in iwl_parse_tlv_firmware()
1306 if (!drv->trans->dbg.pc_data) in iwl_parse_tlv_firmware()
1307 return -ENOMEM; in iwl_parse_tlv_firmware()
1308 drv->trans->dbg.num_pc = in iwl_parse_tlv_firmware()
1312 IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); in iwl_parse_tlv_firmware()
1319 IWL_ERR(drv, in iwl_parse_tlv_firmware()
1321 return -EINVAL; in iwl_parse_tlv_firmware()
1325 IWL_ERR(drv, "invalid TLV after parsing: %zd\n", len); in iwl_parse_tlv_firmware()
1326 iwl_print_hex_dump(drv, IWL_DL_FW, data, len); in iwl_parse_tlv_firmware()
1327 return -EINVAL; in iwl_parse_tlv_firmware()
1330 return 0; in iwl_parse_tlv_firmware()
1333 IWL_ERR(drv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); in iwl_parse_tlv_firmware()
1335 iwl_print_hex_dump(drv, IWL_DL_FW, tlv_data, tlv_len); in iwl_parse_tlv_firmware()
1337 return -EINVAL; in iwl_parse_tlv_firmware()
1340 static int iwl_alloc_ucode(struct iwl_drv *drv, in iwl_alloc_ucode() argument
1347 sec = kcalloc(pieces->img[type].sec_counter, sizeof(*sec), GFP_KERNEL); in iwl_alloc_ucode()
1349 return -ENOMEM; in iwl_alloc_ucode()
1350 drv->fw.img[type].sec = sec; in iwl_alloc_ucode()
1351 drv->fw.img[type].num_sec = pieces->img[type].sec_counter; in iwl_alloc_ucode()
1353 for (i = 0; i < pieces->img[type].sec_counter; i++) in iwl_alloc_ucode()
1354 if (iwl_alloc_fw_desc(drv, &sec[i], get_sec(pieces, type, i))) in iwl_alloc_ucode()
1355 return -ENOMEM; in iwl_alloc_ucode()
1357 return 0; in iwl_alloc_ucode()
1360 static int validate_sec_sizes(struct iwl_drv *drv, in validate_sec_sizes() argument
1364 IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %zd\n", in validate_sec_sizes()
1367 IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %zd\n", in validate_sec_sizes()
1370 IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %zd\n", in validate_sec_sizes()
1372 IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %zd\n", in validate_sec_sizes()
1377 cfg->max_inst_size) { in validate_sec_sizes()
1378 IWL_ERR(drv, "uCode instr len %zd too large to fit in\n", in validate_sec_sizes()
1381 return -1; in validate_sec_sizes()
1385 cfg->max_data_size) { in validate_sec_sizes()
1386 IWL_ERR(drv, "uCode data len %zd too large to fit in\n", in validate_sec_sizes()
1389 return -1; in validate_sec_sizes()
1393 cfg->max_inst_size) { in validate_sec_sizes()
1394 IWL_ERR(drv, "uCode init instr len %zd too large to fit in\n", in validate_sec_sizes()
1397 return -1; in validate_sec_sizes()
1401 cfg->max_data_size) { in validate_sec_sizes()
1402 IWL_ERR(drv, "uCode init data len %zd too large to fit in\n", in validate_sec_sizes()
1405 return -1; in validate_sec_sizes()
1407 return 0; in validate_sec_sizes()
1411 _iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op) in _iwl_op_mode_start() argument
1413 const struct iwl_op_mode_ops *ops = op->ops; in _iwl_op_mode_start()
1421 for (retry = 0; retry <= max_retry; retry++) { in _iwl_op_mode_start()
1424 drv->dbgfs_op_mode = debugfs_create_dir(op->name, in _iwl_op_mode_start()
1425 drv->dbgfs_drv); in _iwl_op_mode_start()
1426 dbgfs_dir = drv->dbgfs_op_mode; in _iwl_op_mode_start()
1429 op_mode = ops->start(drv->trans, drv->trans->cfg, in _iwl_op_mode_start()
1430 &drv->fw, dbgfs_dir); in _iwl_op_mode_start()
1435 if (test_bit(STATUS_TRANS_DEAD, &drv->trans->status)) in _iwl_op_mode_start()
1438 IWL_ERR(drv, "retry init count %d\n", retry); in _iwl_op_mode_start()
1441 debugfs_remove_recursive(drv->dbgfs_op_mode); in _iwl_op_mode_start()
1442 drv->dbgfs_op_mode = NULL; in _iwl_op_mode_start()
1449 static void _iwl_op_mode_stop(struct iwl_drv *drv) in _iwl_op_mode_stop() argument
1455 if (drv->op_mode) { in _iwl_op_mode_stop()
1456 iwl_op_mode_stop(drv->op_mode); in _iwl_op_mode_stop()
1457 drv->op_mode = NULL; in _iwl_op_mode_stop()
1460 debugfs_remove_recursive(drv->dbgfs_op_mode); in _iwl_op_mode_stop()
1461 drv->dbgfs_op_mode = NULL; in _iwl_op_mode_stop()
1467 * iwl_req_fw_callback - callback when firmware was loaded
1474 struct iwl_drv *drv = context; in iwl_req_fw_callback() local
1475 struct iwl_fw *fw = &drv->fw; in iwl_req_fw_callback()
1480 const unsigned int api_max = drv->trans->cfg->ucode_api_max; in iwl_req_fw_callback()
1481 const unsigned int api_min = drv->trans->cfg->ucode_api_min; in iwl_req_fw_callback()
1488 fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH; in iwl_req_fw_callback()
1489 fw->ucode_capa.standard_phy_calibration_size = in iwl_req_fw_callback()
1491 fw->ucode_capa.n_scan_channels = IWL_DEFAULT_SCAN_CHANNELS; in iwl_req_fw_callback()
1492 fw->ucode_capa.num_stations = IWL_STATION_COUNT_MAX; in iwl_req_fw_callback()
1493 fw->ucode_capa.num_beacons = 1; in iwl_req_fw_callback()
1495 fw->dbg.dump_mask = 0xffffffff; in iwl_req_fw_callback()
1504 IWL_DEBUG_FW_INFO(drv, "Loaded firmware file '%s' (%zd bytes).\n", in iwl_req_fw_callback()
1505 drv->firmware_name, ucode_raw->size); in iwl_req_fw_callback()
1508 if (ucode_raw->size < 4) { in iwl_req_fw_callback()
1509 IWL_ERR(drv, "File size way too small!\n"); in iwl_req_fw_callback()
1514 ucode = (const struct iwl_ucode_header *)ucode_raw->data; in iwl_req_fw_callback()
1516 if (ucode->ver) in iwl_req_fw_callback()
1517 err = iwl_parse_v1_v2_firmware(drv, ucode_raw, pieces); in iwl_req_fw_callback()
1519 err = iwl_parse_tlv_firmware(drv, ucode_raw, pieces, in iwl_req_fw_callback()
1520 &fw->ucode_capa, &usniffer_images); in iwl_req_fw_callback()
1525 if (fw_has_api(&drv->fw.ucode_capa, IWL_UCODE_TLV_API_NEW_VERSION)) in iwl_req_fw_callback()
1526 api_ver = drv->fw.ucode_ver; in iwl_req_fw_callback()
1528 api_ver = IWL_UCODE_API(drv->fw.ucode_ver); in iwl_req_fw_callback()
1536 IWL_ERR(drv, in iwl_req_fw_callback()
1547 if (fw->type == IWL_FW_DVM && validate_sec_sizes(drv, pieces, in iwl_req_fw_callback()
1548 drv->trans->cfg)) in iwl_req_fw_callback()
1551 /* Allocate ucode buffers for card's bus-master loading ... */ in iwl_req_fw_callback()
1555 * 2) backup cache for save/restore during power-downs in iwl_req_fw_callback()
1557 for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) in iwl_req_fw_callback()
1558 if (iwl_alloc_ucode(drv, pieces, i)) in iwl_req_fw_callback()
1561 if (pieces->dbg_dest_tlv_init) { in iwl_req_fw_callback()
1562 size_t dbg_dest_size = sizeof(*drv->fw.dbg.dest_tlv) + in iwl_req_fw_callback()
1563 sizeof(drv->fw.dbg.dest_tlv->reg_ops[0]) * in iwl_req_fw_callback()
1564 drv->fw.dbg.n_dest_reg; in iwl_req_fw_callback()
1566 drv->fw.dbg.dest_tlv = kmalloc(dbg_dest_size, GFP_KERNEL); in iwl_req_fw_callback()
1568 if (!drv->fw.dbg.dest_tlv) in iwl_req_fw_callback()
1571 if (*pieces->dbg_dest_ver == 0) { in iwl_req_fw_callback()
1572 memcpy(drv->fw.dbg.dest_tlv, pieces->dbg_dest_tlv_v1, in iwl_req_fw_callback()
1576 drv->fw.dbg.dest_tlv; in iwl_req_fw_callback()
1578 dest_tlv->version = pieces->dbg_dest_tlv->version; in iwl_req_fw_callback()
1579 dest_tlv->monitor_mode = in iwl_req_fw_callback()
1580 pieces->dbg_dest_tlv->monitor_mode; in iwl_req_fw_callback()
1581 dest_tlv->size_power = in iwl_req_fw_callback()
1582 pieces->dbg_dest_tlv->size_power; in iwl_req_fw_callback()
1583 dest_tlv->wrap_count = in iwl_req_fw_callback()
1584 pieces->dbg_dest_tlv->wrap_count; in iwl_req_fw_callback()
1585 dest_tlv->write_ptr_reg = in iwl_req_fw_callback()
1586 pieces->dbg_dest_tlv->write_ptr_reg; in iwl_req_fw_callback()
1587 dest_tlv->base_shift = in iwl_req_fw_callback()
1588 pieces->dbg_dest_tlv->base_shift; in iwl_req_fw_callback()
1589 memcpy(dest_tlv->reg_ops, in iwl_req_fw_callback()
1590 pieces->dbg_dest_tlv->reg_ops, in iwl_req_fw_callback()
1591 sizeof(drv->fw.dbg.dest_tlv->reg_ops[0]) * in iwl_req_fw_callback()
1592 drv->fw.dbg.n_dest_reg); in iwl_req_fw_callback()
1602 dest_tlv->base_reg = pieces->dbg_dest_tlv->cfg_reg; in iwl_req_fw_callback()
1603 dest_tlv->end_shift = in iwl_req_fw_callback()
1604 pieces->dbg_dest_tlv->size_shift; in iwl_req_fw_callback()
1608 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg.conf_tlv); i++) { in iwl_req_fw_callback()
1609 if (pieces->dbg_conf_tlv[i]) { in iwl_req_fw_callback()
1610 drv->fw.dbg.conf_tlv[i] = in iwl_req_fw_callback()
1611 kmemdup(pieces->dbg_conf_tlv[i], in iwl_req_fw_callback()
1612 pieces->dbg_conf_tlv_len[i], in iwl_req_fw_callback()
1614 if (!drv->fw.dbg.conf_tlv[i]) in iwl_req_fw_callback()
1619 memset(&trigger_tlv_sz, 0xff, sizeof(trigger_tlv_sz)); in iwl_req_fw_callback()
1623 trigger_tlv_sz[FW_DBG_TRIGGER_CHANNEL_SWITCH] = 0; in iwl_req_fw_callback()
1641 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg.trigger_tlv); i++) { in iwl_req_fw_callback()
1642 if (pieces->dbg_trigger_tlv[i]) { in iwl_req_fw_callback()
1650 if (WARN_ON(pieces->dbg_trigger_tlv_len[i] < in iwl_req_fw_callback()
1654 drv->fw.dbg.trigger_tlv_len[i] = in iwl_req_fw_callback()
1655 pieces->dbg_trigger_tlv_len[i]; in iwl_req_fw_callback()
1656 drv->fw.dbg.trigger_tlv[i] = in iwl_req_fw_callback()
1657 kmemdup(pieces->dbg_trigger_tlv[i], in iwl_req_fw_callback()
1658 drv->fw.dbg.trigger_tlv_len[i], in iwl_req_fw_callback()
1660 if (!drv->fw.dbg.trigger_tlv[i]) in iwl_req_fw_callback()
1667 drv->fw.dbg.mem_tlv = pieces->dbg_mem_tlv; in iwl_req_fw_callback()
1668 pieces->dbg_mem_tlv = NULL; in iwl_req_fw_callback()
1669 drv->fw.dbg.n_mem_tlv = pieces->n_mem_tlv; in iwl_req_fw_callback()
1672 * The (size - 16) / 12 formula is based on the information recorded in iwl_req_fw_callback()
1676 fw->init_evtlog_ptr = pieces->init_evtlog_ptr; in iwl_req_fw_callback()
1677 if (pieces->init_evtlog_size) in iwl_req_fw_callback()
1678 fw->init_evtlog_size = (pieces->init_evtlog_size - 16)/12; in iwl_req_fw_callback()
1680 fw->init_evtlog_size = in iwl_req_fw_callback()
1681 drv->trans->trans_cfg->base_params->max_event_log_size; in iwl_req_fw_callback()
1682 fw->init_errlog_ptr = pieces->init_errlog_ptr; in iwl_req_fw_callback()
1683 fw->inst_evtlog_ptr = pieces->inst_evtlog_ptr; in iwl_req_fw_callback()
1684 if (pieces->inst_evtlog_size) in iwl_req_fw_callback()
1685 fw->inst_evtlog_size = (pieces->inst_evtlog_size - 16)/12; in iwl_req_fw_callback()
1687 fw->inst_evtlog_size = in iwl_req_fw_callback()
1688 drv->trans->trans_cfg->base_params->max_event_log_size; in iwl_req_fw_callback()
1689 fw->inst_errlog_ptr = pieces->inst_errlog_ptr; in iwl_req_fw_callback()
1695 if (fw->ucode_capa.standard_phy_calibration_size > in iwl_req_fw_callback()
1697 fw->ucode_capa.standard_phy_calibration_size = in iwl_req_fw_callback()
1703 iwl_dbg_tlv_load_bin(drv->trans->dev, drv->trans); in iwl_req_fw_callback()
1706 switch (fw->type) { in iwl_req_fw_callback()
1711 WARN(1, "Invalid fw type %d\n", fw->type); in iwl_req_fw_callback()
1718 IWL_INFO(drv, "loaded firmware version %s op_mode %s\n", in iwl_req_fw_callback()
1719 drv->fw.fw_version, op->name); in iwl_req_fw_callback()
1722 list_add_tail(&drv->list, &op->drv); in iwl_req_fw_callback()
1724 if (op->ops) { in iwl_req_fw_callback()
1725 drv->op_mode = _iwl_op_mode_start(drv, op); in iwl_req_fw_callback()
1727 if (!drv->op_mode) { in iwl_req_fw_callback()
1732 request_module_nowait("%s", op->name); in iwl_req_fw_callback()
1736 complete(&drv->request_firmware_complete); in iwl_req_fw_callback()
1744 if (iwl_request_firmware(drv, false)) in iwl_req_fw_callback()
1751 complete(&drv->request_firmware_complete); in iwl_req_fw_callback()
1752 device_release_driver(drv->trans->dev); in iwl_req_fw_callback()
1753 /* drv has just been freed by the release */ in iwl_req_fw_callback()
1757 iwl_dealloc_ucode(drv); in iwl_req_fw_callback()
1760 for (i = 0; i < ARRAY_SIZE(pieces->img); i++) in iwl_req_fw_callback()
1761 kfree(pieces->img[i].sec); in iwl_req_fw_callback()
1762 kfree(pieces->dbg_mem_tlv); in iwl_req_fw_callback()
1769 struct iwl_drv *drv; in iwl_drv_start() local
1772 drv = kzalloc(sizeof(*drv), GFP_KERNEL); in iwl_drv_start()
1773 if (!drv) { in iwl_drv_start()
1774 ret = -ENOMEM; in iwl_drv_start()
1778 drv->trans = trans; in iwl_drv_start()
1779 drv->dev = trans->dev; in iwl_drv_start()
1781 init_completion(&drv->request_firmware_complete); in iwl_drv_start()
1782 INIT_LIST_HEAD(&drv->list); in iwl_drv_start()
1786 drv->dbgfs_drv = debugfs_create_dir(dev_name(trans->dev), in iwl_drv_start()
1790 drv->trans->dbgfs_dir = debugfs_create_dir("trans", drv->dbgfs_drv); in iwl_drv_start()
1793 drv->trans->dbg.domains_bitmap = IWL_TRANS_FW_DBG_DOMAIN(drv->trans); in iwl_drv_start()
1795 /* We have a non-default value in the module parameter, in iwl_drv_start()
1798 drv->trans->dbg.domains_bitmap &= 0xffff; in iwl_drv_start()
1802 "invalid enable_ini module parameter value: max = %d, using 0 instead\n", in iwl_drv_start()
1804 iwlwifi_mod_params.enable_ini = 0; in iwl_drv_start()
1806 drv->trans->dbg.domains_bitmap = in iwl_drv_start()
1811 ret = iwl_request_firmware(drv, true); in iwl_drv_start()
1817 return drv; in iwl_drv_start()
1821 debugfs_remove_recursive(drv->dbgfs_drv); in iwl_drv_start()
1823 iwl_dbg_tlv_free(drv->trans); in iwl_drv_start()
1824 kfree(drv); in iwl_drv_start()
1829 void iwl_drv_stop(struct iwl_drv *drv) in iwl_drv_stop() argument
1831 wait_for_completion(&drv->request_firmware_complete); in iwl_drv_stop()
1835 _iwl_op_mode_stop(drv); in iwl_drv_stop()
1837 iwl_dealloc_ucode(drv); in iwl_drv_stop()
1841 * when firmware loading failed -- in that in iwl_drv_stop()
1844 if (!list_empty(&drv->list)) in iwl_drv_stop()
1845 list_del(&drv->list); in iwl_drv_stop()
1849 iwl_trans_debugfs_cleanup(drv->trans); in iwl_drv_stop()
1851 debugfs_remove_recursive(drv->dbgfs_drv); in iwl_drv_stop()
1854 iwl_dbg_tlv_free(drv->trans); in iwl_drv_stop()
1856 kfree(drv); in iwl_drv_stop()
1866 /* the rest are 0 by default */
1873 struct iwl_drv *drv; in iwl_opmode_register() local
1877 for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) { in iwl_opmode_register()
1879 if (strcmp(op->name, name)) in iwl_opmode_register()
1881 op->ops = ops; in iwl_opmode_register()
1883 list_for_each_entry(drv, &op->drv, list) in iwl_opmode_register()
1884 drv->op_mode = _iwl_op_mode_start(drv, op); in iwl_opmode_register()
1887 return 0; in iwl_opmode_register()
1890 return -EIO; in iwl_opmode_register()
1897 struct iwl_drv *drv; in iwl_opmode_deregister() local
1900 for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) { in iwl_opmode_deregister()
1906 list_for_each_entry(drv, &iwlwifi_opmode_table[i].drv, list) in iwl_opmode_deregister()
1907 _iwl_op_mode_stop(drv); in iwl_opmode_deregister()
1920 for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) in iwl_drv_init()
1921 INIT_LIST_HEAD(&iwlwifi_opmode_table[i].drv); in iwl_drv_init()
1934 return 0; in iwl_drv_init()
1960 MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
1966 "amsdu size 0: 12K for multi Rx queue devices, 2K for AX210 devices, "
1967 "4K for other devices 1:4K 2:8K 3:12K (16K buffers) 4: 2K (default 0)");
1976 "disable U-APSD functionality bitmap 1: BSS 2: P2P Client (default: 3)");
1980 "0:disable, 1-15:FW_DBG_PRESET Values, 16:enabled without preset value defined,"
1991 * co-exist problem. The possible behaviors are:
2001 MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)");
2004 MODULE_PARM_DESC(led_mode, "0=system default, "
2005 "1=On(RF On)/Off(RF Off), 2=blinking, 3=Off (default: 0)");
2013 "default power save level (range from 1 - 5, default: 1)");