@@ -591,6 +591,8 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
char buildstr[25];
u32 build;
int num_of_cpus;
+ bool usniffer_images = false;
+ bool usniffer_req = false;
if (len < sizeof(*ucode)) {
IWL_ERR(drv, "uCode has invalid length: %zd\n", len);
@@ -908,6 +910,9 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
break;
}
+ if (conf->usniffer)
+ usniffer_req = true;
+
IWL_INFO(drv, "Found debug configuration: %d\n",
conf->id);
@@ -915,12 +920,24 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
pieces->dbg_conf_tlv_len[conf->id] = tlv_len;
break;
}
+ case IWL_UCODE_TLV_SEC_RT_USNIFFER:
+ usniffer_images = true;
+ iwl_store_ucode_sec(pieces, tlv_data,
+ IWL_UCODE_REGULAR_USNIFFER,
+ tlv_len);
+ break;
default:
IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
break;
}
}
+ if (usniffer_req && !usniffer_images) {
+ IWL_ERR(drv,
+ "user selected to work with usniffer but usniffer image isn't available in ucode package\n");
+ return -EINVAL;
+ }
+
if (len) {
IWL_ERR(drv, "invalid TLV after parsing: %zd\n", len);
iwl_print_hex_dump(drv, IWL_DL_FW, (u8 *)data, len);
@@ -131,6 +131,7 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_API_CHANGES_SET = 29,
IWL_UCODE_TLV_ENABLED_CAPABILITIES = 30,
IWL_UCODE_TLV_N_SCAN_CHANNELS = 31,
+ IWL_UCODE_TLV_SEC_RT_USNIFFER = 34,
IWL_UCODE_TLV_FW_DBG_DEST = 38,
IWL_UCODE_TLV_FW_DBG_CONF = 39,
};
@@ -77,11 +77,13 @@
* @IWL_UCODE_REGULAR: Normal runtime ucode
* @IWL_UCODE_INIT: Initial ucode
* @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode
+ * @IWL_UCODE_REGULAR_USNIFFER: Normal runtime ucode when using usniffer image
*/
enum iwl_ucode_type {
IWL_UCODE_REGULAR,
IWL_UCODE_INIT,
IWL_UCODE_WOWLAN,
+ IWL_UCODE_REGULAR_USNIFFER,
IWL_UCODE_TYPE_MAX,
};
@@ -231,4 +233,15 @@ iwl_fw_dbg_conf_enabled(const struct iwl_fw *fw, u8 id)
return trigger->enabled;
}
+static inline bool
+iwl_fw_dbg_conf_usniffer(const struct iwl_fw *fw, u8 id)
+{
+ const struct iwl_fw_dbg_conf_tlv *conf_tlv = fw->dbg_conf_tlv[id];
+
+ if (!conf_tlv)
+ return false;
+
+ return conf_tlv->usniffer;
+}
+
#endif /* __iwl_fw_h__ */
@@ -186,7 +186,12 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
static const u8 alive_cmd[] = { MVM_ALIVE };
struct iwl_sf_region st_fwrd_space;
- fw = iwl_get_ucode_image(mvm, ucode_type);
+ if (ucode_type == IWL_UCODE_REGULAR &&
+ iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_CUSTOM) &&
+ iwl_fw_dbg_conf_enabled(mvm->fw, FW_DBG_CUSTOM))
+ fw = iwl_get_ucode_image(mvm, IWL_UCODE_REGULAR_USNIFFER);
+ else
+ fw = iwl_get_ucode_image(mvm, ucode_type);
if (WARN_ON(!fw))
return -EINVAL;
mvm->cur_ucode = ucode_type;