aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-drv.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c195
1 files changed, 177 insertions, 18 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index d9fa8e034da2..38de1513e4de 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -78,9 +78,6 @@
78#include "iwl-config.h" 78#include "iwl-config.h"
79#include "iwl-modparams.h" 79#include "iwl-modparams.h"
80 80
81/* private includes */
82#include "iwl-fw-file.h"
83
84/****************************************************************************** 81/******************************************************************************
85 * 82 *
86 * module boiler plate 83 * module boiler plate
@@ -187,6 +184,11 @@ static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img)
187static void iwl_dealloc_ucode(struct iwl_drv *drv) 184static void iwl_dealloc_ucode(struct iwl_drv *drv)
188{ 185{
189 int i; 186 int i;
187
188 kfree(drv->fw.dbg_dest_tlv);
189 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_conf_tlv); i++)
190 kfree(drv->fw.dbg_conf_tlv[i]);
191
190 for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) 192 for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
191 iwl_free_fw_img(drv, drv->fw.img + i); 193 iwl_free_fw_img(drv, drv->fw.img + i);
192} 194}
@@ -248,6 +250,9 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
248 /* 250 /*
249 * Starting 8000B - FW name format has changed. This overwrites the 251 * Starting 8000B - FW name format has changed. This overwrites the
250 * previous name and uses the new format. 252 * previous name and uses the new format.
253 *
254 * TODO:
255 * Once there is only one supported step for 8000 family - delete this!
251 */ 256 */
252 if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) { 257 if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) {
253 char rev_step[2] = { 258 char rev_step[2] = {
@@ -258,6 +263,13 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
258 if (CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_A_STEP) 263 if (CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_A_STEP)
259 rev_step[0] = 0; 264 rev_step[0] = 0;
260 265
266 /*
267 * If hw_rev wasn't set yet - default as B-step. If it IS A-step
268 * we'll reload that FW later instead.
269 */
270 if (drv->trans->hw_rev == 0)
271 rev_step[0] = 'B';
272
261 snprintf(drv->firmware_name, sizeof(drv->firmware_name), 273 snprintf(drv->firmware_name, sizeof(drv->firmware_name),
262 "%s%s-%s.ucode", name_pre, rev_step, tag); 274 "%s%s-%s.ucode", name_pre, rev_step, tag);
263 } 275 }
@@ -301,6 +313,11 @@ struct iwl_firmware_pieces {
301 313
302 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; 314 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
303 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; 315 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
316
317 /* FW debug data parsed for driver usage */
318 struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
319 struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX];
320 size_t dbg_conf_tlv_len[FW_DBG_MAX];
304}; 321};
305 322
306/* 323/*
@@ -574,6 +591,8 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
574 char buildstr[25]; 591 char buildstr[25];
575 u32 build; 592 u32 build;
576 int num_of_cpus; 593 int num_of_cpus;
594 bool usniffer_images = false;
595 bool usniffer_req = false;
577 596
578 if (len < sizeof(*ucode)) { 597 if (len < sizeof(*ucode)) {
579 IWL_ERR(drv, "uCode has invalid length: %zd\n", len); 598 IWL_ERR(drv, "uCode has invalid length: %zd\n", len);
@@ -846,12 +865,79 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
846 capa->n_scan_channels = 865 capa->n_scan_channels =
847 le32_to_cpup((__le32 *)tlv_data); 866 le32_to_cpup((__le32 *)tlv_data);
848 break; 867 break;
868 case IWL_UCODE_TLV_FW_DBG_DEST: {
869 struct iwl_fw_dbg_dest_tlv *dest = (void *)tlv_data;
870
871 if (pieces->dbg_dest_tlv) {
872 IWL_ERR(drv,
873 "dbg destination ignored, already exists\n");
874 break;
875 }
876
877 pieces->dbg_dest_tlv = dest;
878 IWL_INFO(drv, "Found debug destination: %s\n",
879 get_fw_dbg_mode_string(dest->monitor_mode));
880
881 drv->fw.dbg_dest_reg_num =
882 tlv_len - offsetof(struct iwl_fw_dbg_dest_tlv,
883 reg_ops);
884 drv->fw.dbg_dest_reg_num /=
885 sizeof(drv->fw.dbg_dest_tlv->reg_ops[0]);
886
887 break;
888 }
889 case IWL_UCODE_TLV_FW_DBG_CONF: {
890 struct iwl_fw_dbg_conf_tlv *conf = (void *)tlv_data;
891
892 if (!pieces->dbg_dest_tlv) {
893 IWL_ERR(drv,
894 "Ignore dbg config %d - no destination configured\n",
895 conf->id);
896 break;
897 }
898
899 if (conf->id >= ARRAY_SIZE(drv->fw.dbg_conf_tlv)) {
900 IWL_ERR(drv,
901 "Skip unknown configuration: %d\n",
902 conf->id);
903 break;
904 }
905
906 if (pieces->dbg_conf_tlv[conf->id]) {
907 IWL_ERR(drv,
908 "Ignore duplicate dbg config %d\n",
909 conf->id);
910 break;
911 }
912
913 if (conf->usniffer)
914 usniffer_req = true;
915
916 IWL_INFO(drv, "Found debug configuration: %d\n",
917 conf->id);
918
919 pieces->dbg_conf_tlv[conf->id] = conf;
920 pieces->dbg_conf_tlv_len[conf->id] = tlv_len;
921 break;
922 }
923 case IWL_UCODE_TLV_SEC_RT_USNIFFER:
924 usniffer_images = true;
925 iwl_store_ucode_sec(pieces, tlv_data,
926 IWL_UCODE_REGULAR_USNIFFER,
927 tlv_len);
928 break;
849 default: 929 default:
850 IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); 930 IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
851 break; 931 break;
852 } 932 }
853 } 933 }
854 934
935 if (usniffer_req && !usniffer_images) {
936 IWL_ERR(drv,
937 "user selected to work with usniffer but usniffer image isn't available in ucode package\n");
938 return -EINVAL;
939 }
940
855 if (len) { 941 if (len) {
856 IWL_ERR(drv, "invalid TLV after parsing: %zd\n", len); 942 IWL_ERR(drv, "invalid TLV after parsing: %zd\n", len);
857 iwl_print_hex_dump(drv, IWL_DL_FW, (u8 *)data, len); 943 iwl_print_hex_dump(drv, IWL_DL_FW, (u8 *)data, len);
@@ -989,13 +1075,14 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
989 struct iwl_ucode_header *ucode; 1075 struct iwl_ucode_header *ucode;
990 struct iwlwifi_opmode_table *op; 1076 struct iwlwifi_opmode_table *op;
991 int err; 1077 int err;
992 struct iwl_firmware_pieces pieces; 1078 struct iwl_firmware_pieces *pieces;
993 const unsigned int api_max = drv->cfg->ucode_api_max; 1079 const unsigned int api_max = drv->cfg->ucode_api_max;
994 unsigned int api_ok = drv->cfg->ucode_api_ok; 1080 unsigned int api_ok = drv->cfg->ucode_api_ok;
995 const unsigned int api_min = drv->cfg->ucode_api_min; 1081 const unsigned int api_min = drv->cfg->ucode_api_min;
996 u32 api_ver; 1082 u32 api_ver;
997 int i; 1083 int i;
998 bool load_module = false; 1084 bool load_module = false;
1085 u32 hw_rev = drv->trans->hw_rev;
999 1086
1000 fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH; 1087 fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH;
1001 fw->ucode_capa.standard_phy_calibration_size = 1088 fw->ucode_capa.standard_phy_calibration_size =
@@ -1005,7 +1092,9 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1005 if (!api_ok) 1092 if (!api_ok)
1006 api_ok = api_max; 1093 api_ok = api_max;
1007 1094
1008 memset(&pieces, 0, sizeof(pieces)); 1095 pieces = kzalloc(sizeof(*pieces), GFP_KERNEL);
1096 if (!pieces)
1097 return;
1009 1098
1010 if (!ucode_raw) { 1099 if (!ucode_raw) {
1011 if (drv->fw_index <= api_ok) 1100 if (drv->fw_index <= api_ok)
@@ -1028,10 +1117,10 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1028 ucode = (struct iwl_ucode_header *)ucode_raw->data; 1117 ucode = (struct iwl_ucode_header *)ucode_raw->data;
1029 1118
1030 if (ucode->ver) 1119 if (ucode->ver)
1031 err = iwl_parse_v1_v2_firmware(drv, ucode_raw, &pieces); 1120 err = iwl_parse_v1_v2_firmware(drv, ucode_raw, pieces);
1032 else 1121 else
1033 err = iwl_parse_tlv_firmware(drv, ucode_raw, &pieces, 1122 err = iwl_parse_tlv_firmware(drv, ucode_raw, pieces,
1034 &fw->ucode_capa); 1123 &fw->ucode_capa);
1035 1124
1036 if (err) 1125 if (err)
1037 goto try_again; 1126 goto try_again;
@@ -1071,7 +1160,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1071 * In mvm uCode there is no difference between data and instructions 1160 * In mvm uCode there is no difference between data and instructions
1072 * sections. 1161 * sections.
1073 */ 1162 */
1074 if (!fw->mvm_fw && validate_sec_sizes(drv, &pieces, drv->cfg)) 1163 if (!fw->mvm_fw && validate_sec_sizes(drv, pieces, drv->cfg))
1075 goto try_again; 1164 goto try_again;
1076 1165
1077 /* Allocate ucode buffers for card's bus-master loading ... */ 1166 /* Allocate ucode buffers for card's bus-master loading ... */
@@ -1080,9 +1169,33 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1080 * 1) unmodified from disk 1169 * 1) unmodified from disk
1081 * 2) backup cache for save/restore during power-downs */ 1170 * 2) backup cache for save/restore during power-downs */
1082 for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) 1171 for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
1083 if (iwl_alloc_ucode(drv, &pieces, i)) 1172 if (iwl_alloc_ucode(drv, pieces, i))
1084 goto out_free_fw; 1173 goto out_free_fw;
1085 1174
1175 if (pieces->dbg_dest_tlv) {
1176 drv->fw.dbg_dest_tlv =
1177 kmemdup(pieces->dbg_dest_tlv,
1178 sizeof(*pieces->dbg_dest_tlv) +
1179 sizeof(pieces->dbg_dest_tlv->reg_ops[0]) *
1180 drv->fw.dbg_dest_reg_num, GFP_KERNEL);
1181
1182 if (!drv->fw.dbg_dest_tlv)
1183 goto out_free_fw;
1184 }
1185
1186 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_conf_tlv); i++) {
1187 if (pieces->dbg_conf_tlv[i]) {
1188 drv->fw.dbg_conf_tlv_len[i] =
1189 pieces->dbg_conf_tlv_len[i];
1190 drv->fw.dbg_conf_tlv[i] =
1191 kmemdup(pieces->dbg_conf_tlv[i],
1192 drv->fw.dbg_conf_tlv_len[i],
1193 GFP_KERNEL);
1194 if (!drv->fw.dbg_conf_tlv[i])
1195 goto out_free_fw;
1196 }
1197 }
1198
1086 /* Now that we can no longer fail, copy information */ 1199 /* Now that we can no longer fail, copy information */
1087 1200
1088 /* 1201 /*
@@ -1090,20 +1203,20 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1090 * for each event, which is of mode 1 (including timestamp) for all 1203 * for each event, which is of mode 1 (including timestamp) for all
1091 * new microcodes that include this information. 1204 * new microcodes that include this information.
1092 */ 1205 */
1093 fw->init_evtlog_ptr = pieces.init_evtlog_ptr; 1206 fw->init_evtlog_ptr = pieces->init_evtlog_ptr;
1094 if (pieces.init_evtlog_size) 1207 if (pieces->init_evtlog_size)
1095 fw->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; 1208 fw->init_evtlog_size = (pieces->init_evtlog_size - 16)/12;
1096 else 1209 else
1097 fw->init_evtlog_size = 1210 fw->init_evtlog_size =
1098 drv->cfg->base_params->max_event_log_size; 1211 drv->cfg->base_params->max_event_log_size;
1099 fw->init_errlog_ptr = pieces.init_errlog_ptr; 1212 fw->init_errlog_ptr = pieces->init_errlog_ptr;
1100 fw->inst_evtlog_ptr = pieces.inst_evtlog_ptr; 1213 fw->inst_evtlog_ptr = pieces->inst_evtlog_ptr;
1101 if (pieces.inst_evtlog_size) 1214 if (pieces->inst_evtlog_size)
1102 fw->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; 1215 fw->inst_evtlog_size = (pieces->inst_evtlog_size - 16)/12;
1103 else 1216 else
1104 fw->inst_evtlog_size = 1217 fw->inst_evtlog_size =
1105 drv->cfg->base_params->max_event_log_size; 1218 drv->cfg->base_params->max_event_log_size;
1106 fw->inst_errlog_ptr = pieces.inst_errlog_ptr; 1219 fw->inst_errlog_ptr = pieces->inst_errlog_ptr;
1107 1220
1108 /* 1221 /*
1109 * figure out the offset of chain noise reset and gain commands 1222 * figure out the offset of chain noise reset and gain commands
@@ -1162,10 +1275,55 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1162 op->name, err); 1275 op->name, err);
1163#endif 1276#endif
1164 } 1277 }
1278
1279 /*
1280 * We may have loaded the wrong FW file in 8000 HW family if it is an
1281 * A-step card, and if drv->trans->hw_rev wasn't properly read when
1282 * the FW file had been loaded. (This might happen in SDIO.) In such a
1283 * case - unload and reload the correct file.
1284 *
1285 * TODO:
1286 * Once there is only one supported step for 8000 family - delete this!
1287 */
1288 if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
1289 CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_A_STEP &&
1290 drv->trans->hw_rev != hw_rev) {
1291 char firmware_name[32];
1292
1293 /* Free previous FW resources */
1294 if (drv->op_mode)
1295 _iwl_op_mode_stop(drv);
1296 iwl_dealloc_ucode(drv);
1297
1298 /* Build name of correct-step FW */
1299 snprintf(firmware_name, sizeof(firmware_name),
1300 strrchr(drv->firmware_name, '-'));
1301 snprintf(drv->firmware_name, sizeof(drv->firmware_name),
1302 "%s%s", drv->cfg->fw_name_pre, firmware_name);
1303
1304 /* Clear data before loading correct FW */
1305 list_del(&drv->list);
1306
1307 /* Request correct FW file this time */
1308 IWL_DEBUG_INFO(drv, "attempting to load A-step FW %s\n",
1309 drv->firmware_name);
1310 err = request_firmware(&ucode_raw, drv->firmware_name,
1311 drv->trans->dev);
1312 if (err) {
1313 IWL_ERR(drv, "Failed swapping FW!\n");
1314 goto out_unbind;
1315 }
1316
1317 /* Redo callback function - this time with right FW */
1318 iwl_req_fw_callback(ucode_raw, context);
1319 }
1320
1321 kfree(pieces);
1165 return; 1322 return;
1166 1323
1167 try_again: 1324 try_again:
1168 /* try next, if any */ 1325 /* try next, if any */
1326 kfree(pieces);
1169 release_firmware(ucode_raw); 1327 release_firmware(ucode_raw);
1170 if (iwl_request_firmware(drv, false)) 1328 if (iwl_request_firmware(drv, false))
1171 goto out_unbind; 1329 goto out_unbind;
@@ -1176,6 +1334,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1176 iwl_dealloc_ucode(drv); 1334 iwl_dealloc_ucode(drv);
1177 release_firmware(ucode_raw); 1335 release_firmware(ucode_raw);
1178 out_unbind: 1336 out_unbind:
1337 kfree(pieces);
1179 complete(&drv->request_firmware_complete); 1338 complete(&drv->request_firmware_complete);
1180 device_release_driver(drv->trans->dev); 1339 device_release_driver(drv->trans->dev);
1181} 1340}