| .. | .. |
|---|
| 5 | 5 | * |
|---|
| 6 | 6 | * GPL LICENSE SUMMARY |
|---|
| 7 | 7 | * |
|---|
| 8 | | - * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
|---|
| 8 | + * Copyright(c) 2007 - 2014, 2018 - 2020 Intel Corporation. All rights reserved. |
|---|
| 9 | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
|---|
| 10 | 10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
|---|
| 11 | 11 | * |
|---|
| .. | .. |
|---|
| 18 | 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 19 | 19 | * General Public License for more details. |
|---|
| 20 | 20 | * |
|---|
| 21 | | - * You should have received a copy of the GNU General Public License |
|---|
| 22 | | - * along with this program; if not, write to the Free Software |
|---|
| 23 | | - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, |
|---|
| 24 | | - * USA |
|---|
| 25 | | - * |
|---|
| 26 | 21 | * The full GNU General Public License is included in this distribution |
|---|
| 27 | 22 | * in the file called COPYING. |
|---|
| 28 | 23 | * |
|---|
| .. | .. |
|---|
| 32 | 27 | * |
|---|
| 33 | 28 | * BSD LICENSE |
|---|
| 34 | 29 | * |
|---|
| 35 | | - * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
|---|
| 30 | + * Copyright(c) 2005 - 2014, 2018 - 2020 Intel Corporation. All rights reserved. |
|---|
| 36 | 31 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
|---|
| 37 | 32 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
|---|
| 38 | 33 | * All rights reserved. |
|---|
| .. | .. |
|---|
| 77 | 72 | #include "iwl-op-mode.h" |
|---|
| 78 | 73 | #include "iwl-agn-hw.h" |
|---|
| 79 | 74 | #include "fw/img.h" |
|---|
| 75 | +#include "iwl-dbg-tlv.h" |
|---|
| 80 | 76 | #include "iwl-config.h" |
|---|
| 81 | 77 | #include "iwl-modparams.h" |
|---|
| 78 | +#include "fw/api/alive.h" |
|---|
| 79 | +#include "fw/api/mac.h" |
|---|
| 82 | 80 | |
|---|
| 83 | 81 | /****************************************************************************** |
|---|
| 84 | 82 | * |
|---|
| .. | .. |
|---|
| 88 | 86 | |
|---|
| 89 | 87 | #define DRV_DESCRIPTION "Intel(R) Wireless WiFi driver for Linux" |
|---|
| 90 | 88 | MODULE_DESCRIPTION(DRV_DESCRIPTION); |
|---|
| 91 | | -MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); |
|---|
| 89 | +MODULE_AUTHOR(DRV_AUTHOR); |
|---|
| 92 | 90 | MODULE_LICENSE("GPL"); |
|---|
| 93 | 91 | |
|---|
| 94 | 92 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
|---|
| .. | .. |
|---|
| 105 | 103 | * @fw_index: firmware revision to try loading |
|---|
| 106 | 104 | * @firmware_name: composite filename of ucode file to load |
|---|
| 107 | 105 | * @request_firmware_complete: the firmware has been obtained from user space |
|---|
| 106 | + * @dbgfs_drv: debugfs root directory entry |
|---|
| 107 | + * @dbgfs_trans: debugfs transport directory entry |
|---|
| 108 | + * @dbgfs_op_mode: debugfs op_mode directory entry |
|---|
| 108 | 109 | */ |
|---|
| 109 | 110 | struct iwl_drv { |
|---|
| 110 | 111 | struct list_head list; |
|---|
| .. | .. |
|---|
| 173 | 174 | { |
|---|
| 174 | 175 | int i; |
|---|
| 175 | 176 | |
|---|
| 176 | | - kfree(drv->fw.dbg_dest_tlv); |
|---|
| 177 | | - for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_conf_tlv); i++) |
|---|
| 178 | | - kfree(drv->fw.dbg_conf_tlv[i]); |
|---|
| 179 | | - for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++) |
|---|
| 180 | | - kfree(drv->fw.dbg_trigger_tlv[i]); |
|---|
| 181 | | - kfree(drv->fw.dbg_mem_tlv); |
|---|
| 177 | + kfree(drv->fw.dbg.dest_tlv); |
|---|
| 178 | + for (i = 0; i < ARRAY_SIZE(drv->fw.dbg.conf_tlv); i++) |
|---|
| 179 | + kfree(drv->fw.dbg.conf_tlv[i]); |
|---|
| 180 | + for (i = 0; i < ARRAY_SIZE(drv->fw.dbg.trigger_tlv); i++) |
|---|
| 181 | + kfree(drv->fw.dbg.trigger_tlv[i]); |
|---|
| 182 | + kfree(drv->fw.dbg.mem_tlv); |
|---|
| 182 | 183 | kfree(drv->fw.iml); |
|---|
| 184 | + kfree(drv->fw.ucode_capa.cmd_versions); |
|---|
| 183 | 185 | |
|---|
| 184 | 186 | for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) |
|---|
| 185 | 187 | iwl_free_fw_img(drv, drv->fw.img + i); |
|---|
| .. | .. |
|---|
| 217 | 219 | { |
|---|
| 218 | 220 | const struct iwl_cfg *cfg = drv->trans->cfg; |
|---|
| 219 | 221 | char tag[8]; |
|---|
| 220 | | - const char *fw_pre_name; |
|---|
| 221 | 222 | |
|---|
| 222 | | - if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_9000 && |
|---|
| 223 | | - (CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_B_STEP || |
|---|
| 224 | | - CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_C_STEP)) |
|---|
| 225 | | - fw_pre_name = cfg->fw_name_pre_b_or_c_step; |
|---|
| 226 | | - else if (drv->trans->cfg->integrated && |
|---|
| 227 | | - CSR_HW_RFID_STEP(drv->trans->hw_rf_id) == SILICON_B_STEP && |
|---|
| 228 | | - cfg->fw_name_pre_rf_next_step) |
|---|
| 229 | | - fw_pre_name = cfg->fw_name_pre_rf_next_step; |
|---|
| 230 | | - else |
|---|
| 231 | | - fw_pre_name = cfg->fw_name_pre; |
|---|
| 223 | + if (drv->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_9000 && |
|---|
| 224 | + (CSR_HW_REV_STEP(drv->trans->hw_rev) != SILICON_B_STEP && |
|---|
| 225 | + CSR_HW_REV_STEP(drv->trans->hw_rev) != SILICON_C_STEP)) { |
|---|
| 226 | + IWL_ERR(drv, |
|---|
| 227 | + "Only HW steps B and C are currently supported (0x%0x)\n", |
|---|
| 228 | + drv->trans->hw_rev); |
|---|
| 229 | + return -EINVAL; |
|---|
| 230 | + } |
|---|
| 232 | 231 | |
|---|
| 233 | 232 | if (first) { |
|---|
| 234 | 233 | drv->fw_index = cfg->ucode_api_max; |
|---|
| .. | .. |
|---|
| 242 | 241 | IWL_ERR(drv, "no suitable firmware found!\n"); |
|---|
| 243 | 242 | |
|---|
| 244 | 243 | if (cfg->ucode_api_min == cfg->ucode_api_max) { |
|---|
| 245 | | - IWL_ERR(drv, "%s%d is required\n", fw_pre_name, |
|---|
| 244 | + IWL_ERR(drv, "%s%d is required\n", cfg->fw_name_pre, |
|---|
| 246 | 245 | cfg->ucode_api_max); |
|---|
| 247 | 246 | } else { |
|---|
| 248 | 247 | IWL_ERR(drv, "minimum version required: %s%d\n", |
|---|
| 249 | | - fw_pre_name, |
|---|
| 250 | | - cfg->ucode_api_min); |
|---|
| 248 | + cfg->fw_name_pre, cfg->ucode_api_min); |
|---|
| 251 | 249 | IWL_ERR(drv, "maximum version supported: %s%d\n", |
|---|
| 252 | | - fw_pre_name, |
|---|
| 253 | | - cfg->ucode_api_max); |
|---|
| 250 | + cfg->fw_name_pre, cfg->ucode_api_max); |
|---|
| 254 | 251 | } |
|---|
| 255 | 252 | |
|---|
| 256 | 253 | IWL_ERR(drv, |
|---|
| .. | .. |
|---|
| 259 | 256 | } |
|---|
| 260 | 257 | |
|---|
| 261 | 258 | snprintf(drv->firmware_name, sizeof(drv->firmware_name), "%s%s.ucode", |
|---|
| 262 | | - fw_pre_name, tag); |
|---|
| 259 | + cfg->fw_name_pre, tag); |
|---|
| 263 | 260 | |
|---|
| 264 | | - IWL_DEBUG_INFO(drv, "attempting to load firmware '%s'\n", |
|---|
| 265 | | - drv->firmware_name); |
|---|
| 261 | + IWL_DEBUG_FW_INFO(drv, "attempting to load firmware '%s'\n", |
|---|
| 262 | + drv->firmware_name); |
|---|
| 266 | 263 | |
|---|
| 267 | 264 | return request_firmware_nowait(THIS_MODULE, 1, drv->firmware_name, |
|---|
| 268 | 265 | drv->trans->dev, |
|---|
| .. | .. |
|---|
| 311 | 308 | struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX]; |
|---|
| 312 | 309 | size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX]; |
|---|
| 313 | 310 | struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv; |
|---|
| 314 | | - size_t n_dbg_mem_tlv; |
|---|
| 311 | + size_t n_mem_tlv; |
|---|
| 315 | 312 | }; |
|---|
| 316 | 313 | |
|---|
| 317 | 314 | /* |
|---|
| .. | .. |
|---|
| 501 | 498 | } |
|---|
| 502 | 499 | } |
|---|
| 503 | 500 | |
|---|
| 501 | +static const char *iwl_reduced_fw_name(struct iwl_drv *drv) |
|---|
| 502 | +{ |
|---|
| 503 | + const char *name = drv->firmware_name; |
|---|
| 504 | + |
|---|
| 505 | + if (strncmp(name, "iwlwifi-", 8) == 0) |
|---|
| 506 | + name += 8; |
|---|
| 507 | + |
|---|
| 508 | + return name; |
|---|
| 509 | +} |
|---|
| 510 | + |
|---|
| 504 | 511 | static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, |
|---|
| 505 | 512 | const struct firmware *ucode_raw, |
|---|
| 506 | 513 | struct iwl_firmware_pieces *pieces) |
|---|
| .. | .. |
|---|
| 559 | 566 | |
|---|
| 560 | 567 | snprintf(drv->fw.fw_version, |
|---|
| 561 | 568 | sizeof(drv->fw.fw_version), |
|---|
| 562 | | - "%u.%u.%u.%u%s", |
|---|
| 569 | + "%u.%u.%u.%u%s %s", |
|---|
| 563 | 570 | IWL_UCODE_MAJOR(drv->fw.ucode_ver), |
|---|
| 564 | 571 | IWL_UCODE_MINOR(drv->fw.ucode_ver), |
|---|
| 565 | 572 | IWL_UCODE_API(drv->fw.ucode_ver), |
|---|
| 566 | 573 | IWL_UCODE_SERIAL(drv->fw.ucode_ver), |
|---|
| 567 | | - buildstr); |
|---|
| 574 | + buildstr, iwl_reduced_fw_name(drv)); |
|---|
| 568 | 575 | |
|---|
| 569 | 576 | /* Verify size of file vs. image size info in file's header */ |
|---|
| 570 | 577 | |
|---|
| .. | .. |
|---|
| 599 | 606 | IWLAGN_RTC_DATA_LOWER_BOUND); |
|---|
| 600 | 607 | return 0; |
|---|
| 601 | 608 | } |
|---|
| 609 | + |
|---|
| 610 | +#define FW_ADDR_CACHE_CONTROL 0xC0000000 |
|---|
| 602 | 611 | |
|---|
| 603 | 612 | static int iwl_parse_tlv_firmware(struct iwl_drv *drv, |
|---|
| 604 | 613 | const struct firmware *ucode_raw, |
|---|
| .. | .. |
|---|
| 642 | 651 | |
|---|
| 643 | 652 | snprintf(drv->fw.fw_version, |
|---|
| 644 | 653 | sizeof(drv->fw.fw_version), |
|---|
| 645 | | - "%u.%u.%u.%u%s", |
|---|
| 654 | + "%u.%u.%u.%u%s %s", |
|---|
| 646 | 655 | IWL_UCODE_MAJOR(drv->fw.ucode_ver), |
|---|
| 647 | 656 | IWL_UCODE_MINOR(drv->fw.ucode_ver), |
|---|
| 648 | 657 | IWL_UCODE_API(drv->fw.ucode_ver), |
|---|
| 649 | 658 | IWL_UCODE_SERIAL(drv->fw.ucode_ver), |
|---|
| 650 | | - buildstr); |
|---|
| 659 | + buildstr, iwl_reduced_fw_name(drv)); |
|---|
| 651 | 660 | |
|---|
| 652 | 661 | data = ucode->data; |
|---|
| 653 | 662 | |
|---|
| .. | .. |
|---|
| 901 | 910 | if (major >= 35) |
|---|
| 902 | 911 | snprintf(drv->fw.fw_version, |
|---|
| 903 | 912 | sizeof(drv->fw.fw_version), |
|---|
| 904 | | - "%u.%08x.%u", major, minor, local_comp); |
|---|
| 913 | + "%u.%08x.%u %s", major, minor, |
|---|
| 914 | + local_comp, iwl_reduced_fw_name(drv)); |
|---|
| 905 | 915 | else |
|---|
| 906 | 916 | snprintf(drv->fw.fw_version, |
|---|
| 907 | 917 | sizeof(drv->fw.fw_version), |
|---|
| 908 | | - "%u.%u.%u", major, minor, local_comp); |
|---|
| 918 | + "%u.%u.%u %s", major, minor, |
|---|
| 919 | + local_comp, iwl_reduced_fw_name(drv)); |
|---|
| 909 | 920 | break; |
|---|
| 910 | 921 | } |
|---|
| 911 | 922 | case IWL_UCODE_TLV_FW_DBG_DEST: { |
|---|
| .. | .. |
|---|
| 944 | 955 | IWL_INFO(drv, "Found debug destination: %s\n", |
|---|
| 945 | 956 | get_fw_dbg_mode_string(mon_mode)); |
|---|
| 946 | 957 | |
|---|
| 947 | | - drv->fw.dbg_dest_reg_num = (dest_v1) ? |
|---|
| 958 | + drv->fw.dbg.n_dest_reg = (dest_v1) ? |
|---|
| 948 | 959 | tlv_len - |
|---|
| 949 | 960 | offsetof(struct iwl_fw_dbg_dest_tlv_v1, |
|---|
| 950 | 961 | reg_ops) : |
|---|
| .. | .. |
|---|
| 952 | 963 | offsetof(struct iwl_fw_dbg_dest_tlv, |
|---|
| 953 | 964 | reg_ops); |
|---|
| 954 | 965 | |
|---|
| 955 | | - drv->fw.dbg_dest_reg_num /= |
|---|
| 956 | | - sizeof(drv->fw.dbg_dest_tlv->reg_ops[0]); |
|---|
| 966 | + drv->fw.dbg.n_dest_reg /= |
|---|
| 967 | + sizeof(drv->fw.dbg.dest_tlv->reg_ops[0]); |
|---|
| 957 | 968 | |
|---|
| 958 | 969 | break; |
|---|
| 959 | 970 | } |
|---|
| .. | .. |
|---|
| 967 | 978 | break; |
|---|
| 968 | 979 | } |
|---|
| 969 | 980 | |
|---|
| 970 | | - if (conf->id >= ARRAY_SIZE(drv->fw.dbg_conf_tlv)) { |
|---|
| 981 | + if (conf->id >= ARRAY_SIZE(drv->fw.dbg.conf_tlv)) { |
|---|
| 971 | 982 | IWL_ERR(drv, |
|---|
| 972 | 983 | "Skip unknown configuration: %d\n", |
|---|
| 973 | 984 | conf->id); |
|---|
| .. | .. |
|---|
| 996 | 1007 | (void *)tlv_data; |
|---|
| 997 | 1008 | u32 trigger_id = le32_to_cpu(trigger->id); |
|---|
| 998 | 1009 | |
|---|
| 999 | | - if (trigger_id >= ARRAY_SIZE(drv->fw.dbg_trigger_tlv)) { |
|---|
| 1010 | + if (trigger_id >= ARRAY_SIZE(drv->fw.dbg.trigger_tlv)) { |
|---|
| 1000 | 1011 | IWL_ERR(drv, |
|---|
| 1001 | 1012 | "Skip unknown trigger: %u\n", |
|---|
| 1002 | 1013 | trigger->id); |
|---|
| .. | .. |
|---|
| 1023 | 1034 | break; |
|---|
| 1024 | 1035 | } |
|---|
| 1025 | 1036 | |
|---|
| 1026 | | - drv->fw.dbg_dump_mask = |
|---|
| 1037 | + drv->fw.dbg.dump_mask = |
|---|
| 1027 | 1038 | le32_to_cpup((__le32 *)tlv_data); |
|---|
| 1028 | 1039 | break; |
|---|
| 1029 | 1040 | } |
|---|
| .. | .. |
|---|
| 1068 | 1079 | case IWL_UCODE_TLV_FW_MEM_SEG: { |
|---|
| 1069 | 1080 | struct iwl_fw_dbg_mem_seg_tlv *dbg_mem = |
|---|
| 1070 | 1081 | (void *)tlv_data; |
|---|
| 1071 | | - u32 type; |
|---|
| 1072 | 1082 | size_t size; |
|---|
| 1073 | 1083 | struct iwl_fw_dbg_mem_seg_tlv *n; |
|---|
| 1074 | 1084 | |
|---|
| 1075 | 1085 | if (tlv_len != (sizeof(*dbg_mem))) |
|---|
| 1076 | 1086 | goto invalid_tlv_len; |
|---|
| 1077 | 1087 | |
|---|
| 1078 | | - type = le32_to_cpu(dbg_mem->data_type); |
|---|
| 1079 | | - |
|---|
| 1080 | 1088 | IWL_DEBUG_INFO(drv, "Found debug memory segment: %u\n", |
|---|
| 1081 | 1089 | dbg_mem->data_type); |
|---|
| 1082 | 1090 | |
|---|
| 1083 | | - switch (type & FW_DBG_MEM_TYPE_MASK) { |
|---|
| 1084 | | - case FW_DBG_MEM_TYPE_REGULAR: |
|---|
| 1085 | | - case FW_DBG_MEM_TYPE_PRPH: |
|---|
| 1086 | | - /* we know how to handle these */ |
|---|
| 1087 | | - break; |
|---|
| 1088 | | - default: |
|---|
| 1089 | | - IWL_ERR(drv, |
|---|
| 1090 | | - "Found debug memory segment with invalid type: 0x%x\n", |
|---|
| 1091 | | - type); |
|---|
| 1092 | | - return -EINVAL; |
|---|
| 1093 | | - } |
|---|
| 1094 | | - |
|---|
| 1095 | 1091 | size = sizeof(*pieces->dbg_mem_tlv) * |
|---|
| 1096 | | - (pieces->n_dbg_mem_tlv + 1); |
|---|
| 1092 | + (pieces->n_mem_tlv + 1); |
|---|
| 1097 | 1093 | n = krealloc(pieces->dbg_mem_tlv, size, GFP_KERNEL); |
|---|
| 1098 | 1094 | if (!n) |
|---|
| 1099 | 1095 | return -ENOMEM; |
|---|
| 1100 | 1096 | pieces->dbg_mem_tlv = n; |
|---|
| 1101 | | - pieces->dbg_mem_tlv[pieces->n_dbg_mem_tlv] = *dbg_mem; |
|---|
| 1102 | | - pieces->n_dbg_mem_tlv++; |
|---|
| 1097 | + pieces->dbg_mem_tlv[pieces->n_mem_tlv] = *dbg_mem; |
|---|
| 1098 | + pieces->n_mem_tlv++; |
|---|
| 1103 | 1099 | break; |
|---|
| 1104 | 1100 | } |
|---|
| 1105 | 1101 | case IWL_UCODE_TLV_IML: { |
|---|
| .. | .. |
|---|
| 1109 | 1105 | return -ENOMEM; |
|---|
| 1110 | 1106 | break; |
|---|
| 1111 | 1107 | } |
|---|
| 1108 | + case IWL_UCODE_TLV_FW_RECOVERY_INFO: { |
|---|
| 1109 | + struct { |
|---|
| 1110 | + __le32 buf_addr; |
|---|
| 1111 | + __le32 buf_size; |
|---|
| 1112 | + } *recov_info = (void *)tlv_data; |
|---|
| 1113 | + |
|---|
| 1114 | + if (tlv_len != sizeof(*recov_info)) |
|---|
| 1115 | + goto invalid_tlv_len; |
|---|
| 1116 | + capa->error_log_addr = |
|---|
| 1117 | + le32_to_cpu(recov_info->buf_addr); |
|---|
| 1118 | + capa->error_log_size = |
|---|
| 1119 | + le32_to_cpu(recov_info->buf_size); |
|---|
| 1120 | + } |
|---|
| 1121 | + break; |
|---|
| 1122 | + case IWL_UCODE_TLV_FW_FSEQ_VERSION: { |
|---|
| 1123 | + struct { |
|---|
| 1124 | + u8 version[32]; |
|---|
| 1125 | + u8 sha1[20]; |
|---|
| 1126 | + } *fseq_ver = (void *)tlv_data; |
|---|
| 1127 | + |
|---|
| 1128 | + if (tlv_len != sizeof(*fseq_ver)) |
|---|
| 1129 | + goto invalid_tlv_len; |
|---|
| 1130 | + IWL_INFO(drv, "TLV_FW_FSEQ_VERSION: %s\n", |
|---|
| 1131 | + fseq_ver->version); |
|---|
| 1132 | + } |
|---|
| 1133 | + break; |
|---|
| 1134 | + case IWL_UCODE_TLV_FW_NUM_STATIONS: |
|---|
| 1135 | + if (tlv_len != sizeof(u32)) |
|---|
| 1136 | + goto invalid_tlv_len; |
|---|
| 1137 | + if (le32_to_cpup((__le32 *)tlv_data) > |
|---|
| 1138 | + IWL_MVM_STATION_COUNT_MAX) { |
|---|
| 1139 | + IWL_ERR(drv, |
|---|
| 1140 | + "%d is an invalid number of station\n", |
|---|
| 1141 | + le32_to_cpup((__le32 *)tlv_data)); |
|---|
| 1142 | + goto tlv_error; |
|---|
| 1143 | + } |
|---|
| 1144 | + capa->num_stations = |
|---|
| 1145 | + le32_to_cpup((__le32 *)tlv_data); |
|---|
| 1146 | + break; |
|---|
| 1147 | + case IWL_UCODE_TLV_UMAC_DEBUG_ADDRS: { |
|---|
| 1148 | + struct iwl_umac_debug_addrs *dbg_ptrs = |
|---|
| 1149 | + (void *)tlv_data; |
|---|
| 1150 | + |
|---|
| 1151 | + if (tlv_len != sizeof(*dbg_ptrs)) |
|---|
| 1152 | + goto invalid_tlv_len; |
|---|
| 1153 | + if (drv->trans->trans_cfg->device_family < |
|---|
| 1154 | + IWL_DEVICE_FAMILY_22000) |
|---|
| 1155 | + break; |
|---|
| 1156 | + drv->trans->dbg.umac_error_event_table = |
|---|
| 1157 | + le32_to_cpu(dbg_ptrs->error_info_addr) & |
|---|
| 1158 | + ~FW_ADDR_CACHE_CONTROL; |
|---|
| 1159 | + drv->trans->dbg.error_event_table_tlv_status |= |
|---|
| 1160 | + IWL_ERROR_EVENT_TABLE_UMAC; |
|---|
| 1161 | + break; |
|---|
| 1162 | + } |
|---|
| 1163 | + case IWL_UCODE_TLV_LMAC_DEBUG_ADDRS: { |
|---|
| 1164 | + struct iwl_lmac_debug_addrs *dbg_ptrs = |
|---|
| 1165 | + (void *)tlv_data; |
|---|
| 1166 | + |
|---|
| 1167 | + if (tlv_len != sizeof(*dbg_ptrs)) |
|---|
| 1168 | + goto invalid_tlv_len; |
|---|
| 1169 | + if (drv->trans->trans_cfg->device_family < |
|---|
| 1170 | + IWL_DEVICE_FAMILY_22000) |
|---|
| 1171 | + break; |
|---|
| 1172 | + drv->trans->dbg.lmac_error_event_table[0] = |
|---|
| 1173 | + le32_to_cpu(dbg_ptrs->error_event_table_ptr) & |
|---|
| 1174 | + ~FW_ADDR_CACHE_CONTROL; |
|---|
| 1175 | + drv->trans->dbg.error_event_table_tlv_status |= |
|---|
| 1176 | + IWL_ERROR_EVENT_TABLE_LMAC1; |
|---|
| 1177 | + break; |
|---|
| 1178 | + } |
|---|
| 1179 | + case IWL_UCODE_TLV_TYPE_DEBUG_INFO: |
|---|
| 1180 | + case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION: |
|---|
| 1181 | + case IWL_UCODE_TLV_TYPE_HCMD: |
|---|
| 1182 | + case IWL_UCODE_TLV_TYPE_REGIONS: |
|---|
| 1183 | + case IWL_UCODE_TLV_TYPE_TRIGGERS: |
|---|
| 1184 | + if (iwlwifi_mod_params.enable_ini) |
|---|
| 1185 | + iwl_dbg_tlv_alloc(drv->trans, tlv, false); |
|---|
| 1186 | + break; |
|---|
| 1187 | + case IWL_UCODE_TLV_CMD_VERSIONS: |
|---|
| 1188 | + if (tlv_len % sizeof(struct iwl_fw_cmd_version)) { |
|---|
| 1189 | + IWL_ERR(drv, |
|---|
| 1190 | + "Invalid length for command versions: %u\n", |
|---|
| 1191 | + tlv_len); |
|---|
| 1192 | + tlv_len /= sizeof(struct iwl_fw_cmd_version); |
|---|
| 1193 | + tlv_len *= sizeof(struct iwl_fw_cmd_version); |
|---|
| 1194 | + } |
|---|
| 1195 | + if (WARN_ON(capa->cmd_versions)) |
|---|
| 1196 | + return -EINVAL; |
|---|
| 1197 | + capa->cmd_versions = kmemdup(tlv_data, tlv_len, |
|---|
| 1198 | + GFP_KERNEL); |
|---|
| 1199 | + if (!capa->cmd_versions) |
|---|
| 1200 | + return -ENOMEM; |
|---|
| 1201 | + capa->n_cmd_versions = |
|---|
| 1202 | + tlv_len / sizeof(struct iwl_fw_cmd_version); |
|---|
| 1203 | + break; |
|---|
| 1112 | 1204 | default: |
|---|
| 1113 | 1205 | IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); |
|---|
| 1114 | 1206 | break; |
|---|
| .. | .. |
|---|
| 1214 | 1306 | const struct iwl_op_mode_ops *ops = op->ops; |
|---|
| 1215 | 1307 | struct dentry *dbgfs_dir = NULL; |
|---|
| 1216 | 1308 | struct iwl_op_mode *op_mode = NULL; |
|---|
| 1309 | + int retry, max_retry = !!iwlwifi_mod_params.fw_restart * IWL_MAX_INIT_RETRY; |
|---|
| 1310 | + |
|---|
| 1311 | + for (retry = 0; retry <= max_retry; retry++) { |
|---|
| 1217 | 1312 | |
|---|
| 1218 | 1313 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
|---|
| 1219 | | - drv->dbgfs_op_mode = debugfs_create_dir(op->name, |
|---|
| 1220 | | - drv->dbgfs_drv); |
|---|
| 1221 | | - if (!drv->dbgfs_op_mode) { |
|---|
| 1222 | | - IWL_ERR(drv, |
|---|
| 1223 | | - "failed to create opmode debugfs directory\n"); |
|---|
| 1224 | | - return op_mode; |
|---|
| 1225 | | - } |
|---|
| 1226 | | - dbgfs_dir = drv->dbgfs_op_mode; |
|---|
| 1314 | + drv->dbgfs_op_mode = debugfs_create_dir(op->name, |
|---|
| 1315 | + drv->dbgfs_drv); |
|---|
| 1316 | + dbgfs_dir = drv->dbgfs_op_mode; |
|---|
| 1227 | 1317 | #endif |
|---|
| 1228 | 1318 | |
|---|
| 1229 | | - op_mode = ops->start(drv->trans, drv->trans->cfg, &drv->fw, dbgfs_dir); |
|---|
| 1319 | + op_mode = ops->start(drv->trans, drv->trans->cfg, |
|---|
| 1320 | + &drv->fw, dbgfs_dir); |
|---|
| 1321 | + |
|---|
| 1322 | + if (op_mode) |
|---|
| 1323 | + return op_mode; |
|---|
| 1324 | + |
|---|
| 1325 | + IWL_ERR(drv, "retry init count %d\n", retry); |
|---|
| 1230 | 1326 | |
|---|
| 1231 | 1327 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
|---|
| 1232 | | - if (!op_mode) { |
|---|
| 1233 | 1328 | debugfs_remove_recursive(drv->dbgfs_op_mode); |
|---|
| 1234 | 1329 | drv->dbgfs_op_mode = NULL; |
|---|
| 1235 | | - } |
|---|
| 1236 | 1330 | #endif |
|---|
| 1331 | + } |
|---|
| 1237 | 1332 | |
|---|
| 1238 | | - return op_mode; |
|---|
| 1333 | + return NULL; |
|---|
| 1239 | 1334 | } |
|---|
| 1240 | 1335 | |
|---|
| 1241 | 1336 | static void _iwl_op_mode_stop(struct iwl_drv *drv) |
|---|
| .. | .. |
|---|
| 1252 | 1347 | } |
|---|
| 1253 | 1348 | } |
|---|
| 1254 | 1349 | |
|---|
| 1255 | | -/** |
|---|
| 1350 | +/* |
|---|
| 1256 | 1351 | * iwl_req_fw_callback - callback when firmware was loaded |
|---|
| 1257 | 1352 | * |
|---|
| 1258 | 1353 | * If loaded successfully, copies the firmware into buffers |
|---|
| .. | .. |
|---|
| 1279 | 1374 | fw->ucode_capa.standard_phy_calibration_size = |
|---|
| 1280 | 1375 | IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE; |
|---|
| 1281 | 1376 | fw->ucode_capa.n_scan_channels = IWL_DEFAULT_SCAN_CHANNELS; |
|---|
| 1377 | + fw->ucode_capa.num_stations = IWL_MVM_STATION_COUNT_MAX; |
|---|
| 1282 | 1378 | /* dump all fw memory areas by default */ |
|---|
| 1283 | | - fw->dbg_dump_mask = 0xffffffff; |
|---|
| 1379 | + fw->dbg.dump_mask = 0xffffffff; |
|---|
| 1284 | 1380 | |
|---|
| 1285 | 1381 | pieces = kzalloc(sizeof(*pieces), GFP_KERNEL); |
|---|
| 1286 | 1382 | if (!pieces) |
|---|
| .. | .. |
|---|
| 1289 | 1385 | if (!ucode_raw) |
|---|
| 1290 | 1386 | goto try_again; |
|---|
| 1291 | 1387 | |
|---|
| 1292 | | - IWL_DEBUG_INFO(drv, "Loaded firmware file '%s' (%zd bytes).\n", |
|---|
| 1293 | | - drv->firmware_name, ucode_raw->size); |
|---|
| 1388 | + IWL_DEBUG_FW_INFO(drv, "Loaded firmware file '%s' (%zd bytes).\n", |
|---|
| 1389 | + drv->firmware_name, ucode_raw->size); |
|---|
| 1294 | 1390 | |
|---|
| 1295 | 1391 | /* Make sure that we got at least the API version number */ |
|---|
| 1296 | 1392 | if (ucode_raw->size < 4) { |
|---|
| .. | .. |
|---|
| 1347 | 1443 | goto out_free_fw; |
|---|
| 1348 | 1444 | |
|---|
| 1349 | 1445 | if (pieces->dbg_dest_tlv_init) { |
|---|
| 1350 | | - size_t dbg_dest_size = sizeof(*drv->fw.dbg_dest_tlv) + |
|---|
| 1351 | | - sizeof(drv->fw.dbg_dest_tlv->reg_ops[0]) * |
|---|
| 1352 | | - drv->fw.dbg_dest_reg_num; |
|---|
| 1446 | + size_t dbg_dest_size = sizeof(*drv->fw.dbg.dest_tlv) + |
|---|
| 1447 | + sizeof(drv->fw.dbg.dest_tlv->reg_ops[0]) * |
|---|
| 1448 | + drv->fw.dbg.n_dest_reg; |
|---|
| 1353 | 1449 | |
|---|
| 1354 | | - drv->fw.dbg_dest_tlv = kmalloc(dbg_dest_size, GFP_KERNEL); |
|---|
| 1450 | + drv->fw.dbg.dest_tlv = kmalloc(dbg_dest_size, GFP_KERNEL); |
|---|
| 1355 | 1451 | |
|---|
| 1356 | | - if (!drv->fw.dbg_dest_tlv) |
|---|
| 1452 | + if (!drv->fw.dbg.dest_tlv) |
|---|
| 1357 | 1453 | goto out_free_fw; |
|---|
| 1358 | 1454 | |
|---|
| 1359 | 1455 | if (*pieces->dbg_dest_ver == 0) { |
|---|
| 1360 | | - memcpy(drv->fw.dbg_dest_tlv, pieces->dbg_dest_tlv_v1, |
|---|
| 1456 | + memcpy(drv->fw.dbg.dest_tlv, pieces->dbg_dest_tlv_v1, |
|---|
| 1361 | 1457 | dbg_dest_size); |
|---|
| 1362 | 1458 | } else { |
|---|
| 1363 | 1459 | struct iwl_fw_dbg_dest_tlv_v1 *dest_tlv = |
|---|
| 1364 | | - drv->fw.dbg_dest_tlv; |
|---|
| 1460 | + drv->fw.dbg.dest_tlv; |
|---|
| 1365 | 1461 | |
|---|
| 1366 | 1462 | dest_tlv->version = pieces->dbg_dest_tlv->version; |
|---|
| 1367 | 1463 | dest_tlv->monitor_mode = |
|---|
| .. | .. |
|---|
| 1376 | 1472 | pieces->dbg_dest_tlv->base_shift; |
|---|
| 1377 | 1473 | memcpy(dest_tlv->reg_ops, |
|---|
| 1378 | 1474 | pieces->dbg_dest_tlv->reg_ops, |
|---|
| 1379 | | - sizeof(drv->fw.dbg_dest_tlv->reg_ops[0]) * |
|---|
| 1380 | | - drv->fw.dbg_dest_reg_num); |
|---|
| 1475 | + sizeof(drv->fw.dbg.dest_tlv->reg_ops[0]) * |
|---|
| 1476 | + drv->fw.dbg.n_dest_reg); |
|---|
| 1381 | 1477 | |
|---|
| 1382 | 1478 | /* In version 1 of the destination tlv, which is |
|---|
| 1383 | 1479 | * relevant for internal buffer exclusively, |
|---|
| .. | .. |
|---|
| 1393 | 1489 | } |
|---|
| 1394 | 1490 | } |
|---|
| 1395 | 1491 | |
|---|
| 1396 | | - for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_conf_tlv); i++) { |
|---|
| 1492 | + for (i = 0; i < ARRAY_SIZE(drv->fw.dbg.conf_tlv); i++) { |
|---|
| 1397 | 1493 | if (pieces->dbg_conf_tlv[i]) { |
|---|
| 1398 | | - drv->fw.dbg_conf_tlv_len[i] = |
|---|
| 1399 | | - pieces->dbg_conf_tlv_len[i]; |
|---|
| 1400 | | - drv->fw.dbg_conf_tlv[i] = |
|---|
| 1494 | + drv->fw.dbg.conf_tlv[i] = |
|---|
| 1401 | 1495 | kmemdup(pieces->dbg_conf_tlv[i], |
|---|
| 1402 | | - drv->fw.dbg_conf_tlv_len[i], |
|---|
| 1496 | + pieces->dbg_conf_tlv_len[i], |
|---|
| 1403 | 1497 | GFP_KERNEL); |
|---|
| 1404 | | - if (!drv->fw.dbg_conf_tlv[i]) |
|---|
| 1498 | + if (!drv->fw.dbg.conf_tlv[i]) |
|---|
| 1405 | 1499 | goto out_free_fw; |
|---|
| 1406 | 1500 | } |
|---|
| 1407 | 1501 | } |
|---|
| .. | .. |
|---|
| 1428 | 1522 | trigger_tlv_sz[FW_DBG_TRIGGER_TDLS] = |
|---|
| 1429 | 1523 | sizeof(struct iwl_fw_dbg_trigger_tdls); |
|---|
| 1430 | 1524 | |
|---|
| 1431 | | - for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++) { |
|---|
| 1525 | + for (i = 0; i < ARRAY_SIZE(drv->fw.dbg.trigger_tlv); i++) { |
|---|
| 1432 | 1526 | if (pieces->dbg_trigger_tlv[i]) { |
|---|
| 1433 | 1527 | /* |
|---|
| 1434 | 1528 | * If the trigger isn't long enough, WARN and exit. |
|---|
| .. | .. |
|---|
| 1441 | 1535 | (trigger_tlv_sz[i] + |
|---|
| 1442 | 1536 | sizeof(struct iwl_fw_dbg_trigger_tlv)))) |
|---|
| 1443 | 1537 | goto out_free_fw; |
|---|
| 1444 | | - drv->fw.dbg_trigger_tlv_len[i] = |
|---|
| 1538 | + drv->fw.dbg.trigger_tlv_len[i] = |
|---|
| 1445 | 1539 | pieces->dbg_trigger_tlv_len[i]; |
|---|
| 1446 | | - drv->fw.dbg_trigger_tlv[i] = |
|---|
| 1540 | + drv->fw.dbg.trigger_tlv[i] = |
|---|
| 1447 | 1541 | kmemdup(pieces->dbg_trigger_tlv[i], |
|---|
| 1448 | | - drv->fw.dbg_trigger_tlv_len[i], |
|---|
| 1542 | + drv->fw.dbg.trigger_tlv_len[i], |
|---|
| 1449 | 1543 | GFP_KERNEL); |
|---|
| 1450 | | - if (!drv->fw.dbg_trigger_tlv[i]) |
|---|
| 1544 | + if (!drv->fw.dbg.trigger_tlv[i]) |
|---|
| 1451 | 1545 | goto out_free_fw; |
|---|
| 1452 | 1546 | } |
|---|
| 1453 | 1547 | } |
|---|
| 1454 | 1548 | |
|---|
| 1455 | 1549 | /* Now that we can no longer fail, copy information */ |
|---|
| 1456 | 1550 | |
|---|
| 1457 | | - drv->fw.dbg_mem_tlv = pieces->dbg_mem_tlv; |
|---|
| 1551 | + drv->fw.dbg.mem_tlv = pieces->dbg_mem_tlv; |
|---|
| 1458 | 1552 | pieces->dbg_mem_tlv = NULL; |
|---|
| 1459 | | - drv->fw.n_dbg_mem_tlv = pieces->n_dbg_mem_tlv; |
|---|
| 1553 | + drv->fw.dbg.n_mem_tlv = pieces->n_mem_tlv; |
|---|
| 1460 | 1554 | |
|---|
| 1461 | 1555 | /* |
|---|
| 1462 | 1556 | * The (size - 16) / 12 formula is based on the information recorded |
|---|
| .. | .. |
|---|
| 1468 | 1562 | fw->init_evtlog_size = (pieces->init_evtlog_size - 16)/12; |
|---|
| 1469 | 1563 | else |
|---|
| 1470 | 1564 | fw->init_evtlog_size = |
|---|
| 1471 | | - drv->trans->cfg->base_params->max_event_log_size; |
|---|
| 1565 | + drv->trans->trans_cfg->base_params->max_event_log_size; |
|---|
| 1472 | 1566 | fw->init_errlog_ptr = pieces->init_errlog_ptr; |
|---|
| 1473 | 1567 | fw->inst_evtlog_ptr = pieces->inst_evtlog_ptr; |
|---|
| 1474 | 1568 | if (pieces->inst_evtlog_size) |
|---|
| 1475 | 1569 | fw->inst_evtlog_size = (pieces->inst_evtlog_size - 16)/12; |
|---|
| 1476 | 1570 | else |
|---|
| 1477 | 1571 | fw->inst_evtlog_size = |
|---|
| 1478 | | - drv->trans->cfg->base_params->max_event_log_size; |
|---|
| 1572 | + drv->trans->trans_cfg->base_params->max_event_log_size; |
|---|
| 1479 | 1573 | fw->inst_errlog_ptr = pieces->inst_errlog_ptr; |
|---|
| 1480 | 1574 | |
|---|
| 1481 | 1575 | /* |
|---|
| .. | .. |
|---|
| 1497 | 1591 | break; |
|---|
| 1498 | 1592 | default: |
|---|
| 1499 | 1593 | WARN(1, "Invalid fw type %d\n", fw->type); |
|---|
| 1594 | + /* fall through */ |
|---|
| 1500 | 1595 | case IWL_FW_MVM: |
|---|
| 1501 | 1596 | op = &iwlwifi_opmode_table[MVM_OP_MODE]; |
|---|
| 1502 | 1597 | break; |
|---|
| .. | .. |
|---|
| 1504 | 1599 | |
|---|
| 1505 | 1600 | IWL_INFO(drv, "loaded firmware version %s op_mode %s\n", |
|---|
| 1506 | 1601 | drv->fw.fw_version, op->name); |
|---|
| 1602 | + |
|---|
| 1603 | + iwl_dbg_tlv_load_bin(drv->trans->dev, drv->trans); |
|---|
| 1507 | 1604 | |
|---|
| 1508 | 1605 | /* add this device to the list of devices using this op_mode */ |
|---|
| 1509 | 1606 | list_add_tail(&drv->list, &op->drv); |
|---|
| .. | .. |
|---|
| 1585 | 1682 | drv->dbgfs_drv = debugfs_create_dir(dev_name(trans->dev), |
|---|
| 1586 | 1683 | iwl_dbgfs_root); |
|---|
| 1587 | 1684 | |
|---|
| 1588 | | - if (!drv->dbgfs_drv) { |
|---|
| 1589 | | - IWL_ERR(drv, "failed to create debugfs directory\n"); |
|---|
| 1590 | | - ret = -ENOMEM; |
|---|
| 1591 | | - goto err_free_drv; |
|---|
| 1592 | | - } |
|---|
| 1593 | | - |
|---|
| 1594 | 1685 | /* Create transport layer debugfs dir */ |
|---|
| 1595 | 1686 | drv->trans->dbgfs_dir = debugfs_create_dir("trans", drv->dbgfs_drv); |
|---|
| 1596 | | - |
|---|
| 1597 | | - if (!drv->trans->dbgfs_dir) { |
|---|
| 1598 | | - IWL_ERR(drv, "failed to create transport debugfs directory\n"); |
|---|
| 1599 | | - ret = -ENOMEM; |
|---|
| 1600 | | - goto err_free_dbgfs; |
|---|
| 1601 | | - } |
|---|
| 1602 | 1687 | #endif |
|---|
| 1688 | + |
|---|
| 1689 | + drv->trans->dbg.domains_bitmap = IWL_TRANS_FW_DBG_DOMAIN(drv->trans); |
|---|
| 1603 | 1690 | |
|---|
| 1604 | 1691 | ret = iwl_request_firmware(drv, true); |
|---|
| 1605 | 1692 | if (ret) { |
|---|
| .. | .. |
|---|
| 1611 | 1698 | |
|---|
| 1612 | 1699 | err_fw: |
|---|
| 1613 | 1700 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
|---|
| 1614 | | -err_free_dbgfs: |
|---|
| 1615 | 1701 | debugfs_remove_recursive(drv->dbgfs_drv); |
|---|
| 1616 | | -err_free_drv: |
|---|
| 1702 | + iwl_dbg_tlv_free(drv->trans); |
|---|
| 1617 | 1703 | #endif |
|---|
| 1618 | 1704 | kfree(drv); |
|---|
| 1619 | 1705 | err: |
|---|
| .. | .. |
|---|
| 1639 | 1725 | mutex_unlock(&iwlwifi_opmode_table_mtx); |
|---|
| 1640 | 1726 | |
|---|
| 1641 | 1727 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
|---|
| 1728 | + drv->trans->ops->debugfs_cleanup(drv->trans); |
|---|
| 1729 | + |
|---|
| 1642 | 1730 | debugfs_remove_recursive(drv->dbgfs_drv); |
|---|
| 1643 | 1731 | #endif |
|---|
| 1732 | + |
|---|
| 1733 | + iwl_dbg_tlv_free(drv->trans); |
|---|
| 1644 | 1734 | |
|---|
| 1645 | 1735 | kfree(drv); |
|---|
| 1646 | 1736 | } |
|---|
| .. | .. |
|---|
| 1651 | 1741 | .fw_restart = true, |
|---|
| 1652 | 1742 | .bt_coex_active = true, |
|---|
| 1653 | 1743 | .power_level = IWL_POWER_INDEX_1, |
|---|
| 1654 | | - .d0i3_disable = true, |
|---|
| 1655 | | - .d0i3_timeout = 1000, |
|---|
| 1656 | 1744 | .uapsd_disable = IWL_DISABLE_UAPSD_BSS | IWL_DISABLE_UAPSD_P2P_CLIENT, |
|---|
| 1745 | + .enable_ini = true, |
|---|
| 1657 | 1746 | /* the rest are 0 by default */ |
|---|
| 1658 | 1747 | }; |
|---|
| 1659 | 1748 | IWL_EXPORT_SYMBOL(iwlwifi_mod_params); |
|---|
| .. | .. |
|---|
| 1706 | 1795 | |
|---|
| 1707 | 1796 | static int __init iwl_drv_init(void) |
|---|
| 1708 | 1797 | { |
|---|
| 1709 | | - int i; |
|---|
| 1798 | + int i, err; |
|---|
| 1710 | 1799 | |
|---|
| 1711 | 1800 | mutex_init(&iwlwifi_opmode_table_mtx); |
|---|
| 1712 | 1801 | |
|---|
| .. | .. |
|---|
| 1714 | 1803 | INIT_LIST_HEAD(&iwlwifi_opmode_table[i].drv); |
|---|
| 1715 | 1804 | |
|---|
| 1716 | 1805 | pr_info(DRV_DESCRIPTION "\n"); |
|---|
| 1717 | | - pr_info(DRV_COPYRIGHT "\n"); |
|---|
| 1718 | 1806 | |
|---|
| 1719 | 1807 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
|---|
| 1720 | 1808 | /* Create the root of iwlwifi debugfs subsystem. */ |
|---|
| 1721 | 1809 | iwl_dbgfs_root = debugfs_create_dir(DRV_NAME, NULL); |
|---|
| 1722 | | - |
|---|
| 1723 | | - if (!iwl_dbgfs_root) |
|---|
| 1724 | | - return -EFAULT; |
|---|
| 1725 | 1810 | #endif |
|---|
| 1726 | 1811 | |
|---|
| 1727 | | - return iwl_pci_register_driver(); |
|---|
| 1812 | + err = iwl_pci_register_driver(); |
|---|
| 1813 | + if (err) |
|---|
| 1814 | + goto cleanup_debugfs; |
|---|
| 1815 | + |
|---|
| 1816 | + return 0; |
|---|
| 1817 | + |
|---|
| 1818 | +cleanup_debugfs: |
|---|
| 1819 | +#ifdef CONFIG_IWLWIFI_DEBUGFS |
|---|
| 1820 | + debugfs_remove_recursive(iwl_dbgfs_root); |
|---|
| 1821 | +#endif |
|---|
| 1822 | + return err; |
|---|
| 1728 | 1823 | } |
|---|
| 1729 | 1824 | module_init(iwl_drv_init); |
|---|
| 1730 | 1825 | |
|---|
| .. | .. |
|---|
| 1750 | 1845 | "disable 11n functionality, bitmap: 1: full, 2: disable agg TX, 4: disable agg RX, 8 enable agg TX"); |
|---|
| 1751 | 1846 | module_param_named(amsdu_size, iwlwifi_mod_params.amsdu_size, int, 0444); |
|---|
| 1752 | 1847 | MODULE_PARM_DESC(amsdu_size, |
|---|
| 1753 | | - "amsdu size 0: 12K for multi Rx queue devices, 2K for 22560 devices, " |
|---|
| 1848 | + "amsdu size 0: 12K for multi Rx queue devices, 2K for AX210 devices, " |
|---|
| 1754 | 1849 | "4K for other devices 1:4K 2:8K 3:12K 4: 2K (default 0)"); |
|---|
| 1755 | 1850 | module_param_named(fw_restart, iwlwifi_mod_params.fw_restart, bool, 0444); |
|---|
| 1756 | 1851 | MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)"); |
|---|
| 1757 | 1852 | |
|---|
| 1758 | | -module_param_named(antenna_coupling, iwlwifi_mod_params.antenna_coupling, |
|---|
| 1759 | | - int, 0444); |
|---|
| 1760 | | -MODULE_PARM_DESC(antenna_coupling, |
|---|
| 1761 | | - "specify antenna coupling in dB (default: 0 dB)"); |
|---|
| 1762 | | - |
|---|
| 1763 | 1853 | module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, 0444); |
|---|
| 1764 | 1854 | MODULE_PARM_DESC(nvm_file, "NVM file name"); |
|---|
| 1765 | | - |
|---|
| 1766 | | -module_param_named(d0i3_disable, iwlwifi_mod_params.d0i3_disable, bool, 0444); |
|---|
| 1767 | | -MODULE_PARM_DESC(d0i3_disable, "disable d0i3 functionality (default: Y)"); |
|---|
| 1768 | | - |
|---|
| 1769 | | -module_param_named(lar_disable, iwlwifi_mod_params.lar_disable, bool, 0444); |
|---|
| 1770 | | -MODULE_PARM_DESC(lar_disable, "disable LAR functionality (default: N)"); |
|---|
| 1771 | 1855 | |
|---|
| 1772 | 1856 | module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable, uint, 0644); |
|---|
| 1773 | 1857 | MODULE_PARM_DESC(uapsd_disable, |
|---|
| 1774 | 1858 | "disable U-APSD functionality bitmap 1: BSS 2: P2P Client (default: 3)"); |
|---|
| 1859 | +module_param_named(enable_ini, iwlwifi_mod_params.enable_ini, |
|---|
| 1860 | + bool, S_IRUGO | S_IWUSR); |
|---|
| 1861 | +MODULE_PARM_DESC(enable_ini, |
|---|
| 1862 | + "Enable debug INI TLV FW debug infrastructure (default: true"); |
|---|
| 1775 | 1863 | |
|---|
| 1776 | 1864 | /* |
|---|
| 1777 | 1865 | * set bt_coex_active to true, uCode will do kill/defer |
|---|
| .. | .. |
|---|
| 1804 | 1892 | module_param_named(power_level, iwlwifi_mod_params.power_level, int, 0444); |
|---|
| 1805 | 1893 | MODULE_PARM_DESC(power_level, |
|---|
| 1806 | 1894 | "default power save level (range from 1 - 5, default: 1)"); |
|---|
| 1807 | | - |
|---|
| 1808 | | -module_param_named(fw_monitor, iwlwifi_mod_params.fw_monitor, bool, 0444); |
|---|
| 1809 | | -MODULE_PARM_DESC(fw_monitor, |
|---|
| 1810 | | - "firmware monitor - to debug FW (default: false - needs lots of memory)"); |
|---|
| 1811 | | - |
|---|
| 1812 | | -module_param_named(d0i3_timeout, iwlwifi_mod_params.d0i3_timeout, uint, 0444); |
|---|
| 1813 | | -MODULE_PARM_DESC(d0i3_timeout, "Timeout to D0i3 entry when idle (ms)"); |
|---|
| 1814 | 1895 | |
|---|
| 1815 | 1896 | module_param_named(disable_11ac, iwlwifi_mod_params.disable_11ac, bool, 0444); |
|---|
| 1816 | 1897 | MODULE_PARM_DESC(disable_11ac, "Disable VHT capabilities (default: false)"); |
|---|