.. | .. |
---|
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)"); |
---|