iwlwifi: add debug print for parsing firmware TLV
When parsing TLV during loading firmware, if encounter any TLV error, log the error message to help debugging. Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
This commit is contained in:
parent
c04f9f2203
commit
ad8d8333b1
|
@ -1806,12 +1806,21 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
|
||||||
const u8 *data;
|
const u8 *data;
|
||||||
int wanted_alternative = iwlagn_wanted_ucode_alternative, tmp;
|
int wanted_alternative = iwlagn_wanted_ucode_alternative, tmp;
|
||||||
u64 alternatives;
|
u64 alternatives;
|
||||||
|
u32 tlv_len;
|
||||||
|
enum iwl_ucode_tlv_type tlv_type;
|
||||||
|
const u8 *tlv_data;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (len < sizeof(*ucode))
|
if (len < sizeof(*ucode)) {
|
||||||
|
IWL_ERR(priv, "uCode has invalid length: %zd\n", len);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC))
|
if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) {
|
||||||
|
IWL_ERR(priv, "invalid uCode magic: 0X%x\n",
|
||||||
|
le32_to_cpu(ucode->magic));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check which alternatives are present, and "downgrade"
|
* Check which alternatives are present, and "downgrade"
|
||||||
|
@ -1836,11 +1845,9 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
|
||||||
|
|
||||||
len -= sizeof(*ucode);
|
len -= sizeof(*ucode);
|
||||||
|
|
||||||
while (len >= sizeof(*tlv)) {
|
while (len >= sizeof(*tlv) && !ret) {
|
||||||
u32 tlv_len;
|
|
||||||
enum iwl_ucode_tlv_type tlv_type;
|
|
||||||
u16 tlv_alt;
|
u16 tlv_alt;
|
||||||
const u8 *tlv_data;
|
u32 fixed_tlv_size = 4;
|
||||||
|
|
||||||
len -= sizeof(*tlv);
|
len -= sizeof(*tlv);
|
||||||
tlv = (void *)data;
|
tlv = (void *)data;
|
||||||
|
@ -1850,8 +1857,11 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
|
||||||
tlv_alt = le16_to_cpu(tlv->alternative);
|
tlv_alt = le16_to_cpu(tlv->alternative);
|
||||||
tlv_data = tlv->data;
|
tlv_data = tlv->data;
|
||||||
|
|
||||||
if (len < tlv_len)
|
if (len < tlv_len) {
|
||||||
|
IWL_ERR(priv, "invalid TLV len: %zd/%u\n",
|
||||||
|
len, tlv_len);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
}
|
||||||
len -= ALIGN(tlv_len, 4);
|
len -= ALIGN(tlv_len, 4);
|
||||||
data += sizeof(*tlv) + ALIGN(tlv_len, 4);
|
data += sizeof(*tlv) + ALIGN(tlv_len, 4);
|
||||||
|
|
||||||
|
@ -1885,56 +1895,71 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
|
||||||
pieces->boot_size = tlv_len;
|
pieces->boot_size = tlv_len;
|
||||||
break;
|
break;
|
||||||
case IWL_UCODE_TLV_PROBE_MAX_LEN:
|
case IWL_UCODE_TLV_PROBE_MAX_LEN:
|
||||||
if (tlv_len != 4)
|
if (tlv_len != fixed_tlv_size)
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
else
|
||||||
capa->max_probe_length =
|
capa->max_probe_length =
|
||||||
le32_to_cpup((__le32 *)tlv_data);
|
le32_to_cpup((__le32 *)tlv_data);
|
||||||
break;
|
break;
|
||||||
case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
|
case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
|
||||||
if (tlv_len != 4)
|
if (tlv_len != fixed_tlv_size)
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
else
|
||||||
pieces->init_evtlog_ptr =
|
pieces->init_evtlog_ptr =
|
||||||
le32_to_cpup((__le32 *)tlv_data);
|
le32_to_cpup((__le32 *)tlv_data);
|
||||||
break;
|
break;
|
||||||
case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
|
case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
|
||||||
if (tlv_len != 4)
|
if (tlv_len != fixed_tlv_size)
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
else
|
||||||
pieces->init_evtlog_size =
|
pieces->init_evtlog_size =
|
||||||
le32_to_cpup((__le32 *)tlv_data);
|
le32_to_cpup((__le32 *)tlv_data);
|
||||||
break;
|
break;
|
||||||
case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
|
case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
|
||||||
if (tlv_len != 4)
|
if (tlv_len != fixed_tlv_size)
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
else
|
||||||
pieces->init_errlog_ptr =
|
pieces->init_errlog_ptr =
|
||||||
le32_to_cpup((__le32 *)tlv_data);
|
le32_to_cpup((__le32 *)tlv_data);
|
||||||
break;
|
break;
|
||||||
case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
|
case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
|
||||||
if (tlv_len != 4)
|
if (tlv_len != fixed_tlv_size)
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
else
|
||||||
pieces->inst_evtlog_ptr =
|
pieces->inst_evtlog_ptr =
|
||||||
le32_to_cpup((__le32 *)tlv_data);
|
le32_to_cpup((__le32 *)tlv_data);
|
||||||
break;
|
break;
|
||||||
case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
|
case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
|
||||||
if (tlv_len != 4)
|
if (tlv_len != fixed_tlv_size)
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
else
|
||||||
pieces->inst_evtlog_size =
|
pieces->inst_evtlog_size =
|
||||||
le32_to_cpup((__le32 *)tlv_data);
|
le32_to_cpup((__le32 *)tlv_data);
|
||||||
break;
|
break;
|
||||||
case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
|
case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
|
||||||
if (tlv_len != 4)
|
if (tlv_len != fixed_tlv_size)
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
else
|
||||||
pieces->inst_errlog_ptr =
|
pieces->inst_errlog_ptr =
|
||||||
le32_to_cpup((__le32 *)tlv_data);
|
le32_to_cpup((__le32 *)tlv_data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
IWL_WARN(priv, "unknown TLV: %d\n", tlv_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len)
|
if (len) {
|
||||||
return -EINVAL;
|
IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len);
|
||||||
|
iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len);
|
||||||
|
ret = -EINVAL;
|
||||||
|
} else if (ret) {
|
||||||
|
IWL_ERR(priv, "TLV %d has invalid size: %u\n",
|
||||||
|
tlv_type, tlv_len);
|
||||||
|
iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)tlv_data, tlv_len);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue