iwlwifi: yoyo: add the ability to dump phy periphery
This enables analyzing phy/HW bugs. Signed-off-by: Mordechay Goodstein <mordechay.goodstein@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Link: https://lore.kernel.org/r/iwlwifi.20201209231351.53bce4f8353d.Ia6944582bd2c748387aaef96755d8919c5d25dc1@changeid Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
This commit is contained in:
parent
2f8cfcc43d
commit
b34872bc83
|
@ -1066,9 +1066,10 @@ struct iwl_dump_ini_region_data {
|
|||
struct iwl_fwrt_dump_data *dump_data;
|
||||
};
|
||||
|
||||
static int iwl_dump_ini_prph_iter(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_dump_ini_region_data *reg_data,
|
||||
void *range_ptr, int idx)
|
||||
static int
|
||||
iwl_dump_ini_prph_mac_iter(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_dump_ini_region_data *reg_data,
|
||||
void *range_ptr, int idx)
|
||||
{
|
||||
struct iwl_fw_ini_region_tlv *reg = (void *)reg_data->reg_tlv->data;
|
||||
struct iwl_fw_ini_error_dump_range *range = range_ptr;
|
||||
|
@ -1090,6 +1091,58 @@ static int iwl_dump_ini_prph_iter(struct iwl_fw_runtime *fwrt,
|
|||
return sizeof(*range) + le32_to_cpu(range->range_data_size);
|
||||
}
|
||||
|
||||
static int
|
||||
iwl_dump_ini_prph_phy_iter(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_dump_ini_region_data *reg_data,
|
||||
void *range_ptr, int idx)
|
||||
{
|
||||
struct iwl_fw_ini_region_tlv *reg = (void *)reg_data->reg_tlv->data;
|
||||
struct iwl_fw_ini_error_dump_range *range = range_ptr;
|
||||
__le32 *val = range->data;
|
||||
u32 indirect_wr_addr = WMAL_INDRCT_RD_CMD1;
|
||||
u32 indirect_rd_addr = WMAL_MRSPF_1;
|
||||
u32 prph_val;
|
||||
u32 addr = le32_to_cpu(reg->addrs[idx]);
|
||||
u32 dphy_state;
|
||||
u32 dphy_addr;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
range->internal_base_addr = cpu_to_le32(addr);
|
||||
range->range_data_size = reg->dev_addr.size;
|
||||
|
||||
if (fwrt->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
|
||||
indirect_wr_addr = WMAL_INDRCT_CMD1;
|
||||
|
||||
indirect_wr_addr += le32_to_cpu(reg->dev_addr.offset);
|
||||
indirect_rd_addr += le32_to_cpu(reg->dev_addr.offset);
|
||||
|
||||
if (!iwl_trans_grab_nic_access(fwrt->trans, &flags))
|
||||
return -EBUSY;
|
||||
|
||||
dphy_addr = (reg->dev_addr.offset) ? WFPM_LMAC2_PS_CTL_RW :
|
||||
WFPM_LMAC1_PS_CTL_RW;
|
||||
dphy_state = iwl_read_umac_prph_no_grab(fwrt->trans, dphy_addr);
|
||||
|
||||
for (i = 0; i < le32_to_cpu(reg->dev_addr.size); i += 4) {
|
||||
if (dphy_state == HBUS_TIMEOUT ||
|
||||
(dphy_state & WFPM_PS_CTL_RW_PHYRF_PD_FSM_CURSTATE_MSK) !=
|
||||
WFPM_PHYRF_STATE_ON) {
|
||||
*val++ = cpu_to_le32(WFPM_DPHY_OFF);
|
||||
continue;
|
||||
}
|
||||
|
||||
iwl_write_prph_no_grab(fwrt->trans, indirect_wr_addr,
|
||||
WMAL_INDRCT_CMD(addr + i));
|
||||
prph_val = iwl_read_prph_no_grab(fwrt->trans,
|
||||
indirect_rd_addr);
|
||||
*val++ = cpu_to_le32(prph_val);
|
||||
}
|
||||
|
||||
iwl_trans_release_nic_access(fwrt->trans, &flags);
|
||||
return sizeof(*range) + le32_to_cpu(range->range_data_size);
|
||||
}
|
||||
|
||||
static int iwl_dump_ini_csr_iter(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_dump_ini_region_data *reg_data,
|
||||
void *range_ptr, int idx)
|
||||
|
@ -2152,9 +2205,14 @@ static const struct iwl_dump_ini_mem_ops iwl_dump_ini_region_ops[] = {
|
|||
.get_num_of_ranges = iwl_dump_ini_mem_ranges,
|
||||
.get_size = iwl_dump_ini_mem_get_size,
|
||||
.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
|
||||
.fill_range = iwl_dump_ini_prph_iter,
|
||||
.fill_range = iwl_dump_ini_prph_mac_iter,
|
||||
},
|
||||
[IWL_FW_INI_REGION_PERIPHERY_PHY] = {
|
||||
.get_num_of_ranges = iwl_dump_ini_mem_ranges,
|
||||
.get_size = iwl_dump_ini_mem_get_size,
|
||||
.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
|
||||
.fill_range = iwl_dump_ini_prph_phy_iter,
|
||||
},
|
||||
[IWL_FW_INI_REGION_PERIPHERY_PHY] = {},
|
||||
[IWL_FW_INI_REGION_PERIPHERY_AUX] = {},
|
||||
[IWL_FW_INI_REGION_PAGING] = {
|
||||
.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
|
||||
|
@ -2188,6 +2246,7 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt,
|
|||
struct list_head *list)
|
||||
{
|
||||
struct iwl_fw_ini_trigger_tlv *trigger = dump_data->trig;
|
||||
enum iwl_fw_ini_time_point tp_id = le32_to_cpu(trigger->time_point);
|
||||
struct iwl_dump_ini_region_data reg_data = {
|
||||
.dump_data = dump_data,
|
||||
};
|
||||
|
@ -2218,6 +2277,14 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt,
|
|||
if (reg_type >= ARRAY_SIZE(iwl_dump_ini_region_ops))
|
||||
continue;
|
||||
|
||||
if (reg_type == IWL_FW_INI_REGION_PERIPHERY_PHY &&
|
||||
tp_id != IWL_FW_INI_TIME_POINT_FW_ASSERT) {
|
||||
IWL_WARN(fwrt,
|
||||
"WRT: trying to collect phy prph at time point: %d, skipping\n",
|
||||
tp_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
size += iwl_dump_ini_mem(fwrt, list, ®_data,
|
||||
&iwl_dump_ini_region_ops[reg_type]);
|
||||
}
|
||||
|
|
|
@ -473,4 +473,22 @@ enum {
|
|||
|
||||
#define IWL_D3_SLEEP_STATUS_SUSPEND 0xD3
|
||||
#define IWL_D3_SLEEP_STATUS_RESUME 0xD0
|
||||
|
||||
#define WMAL_INDRCT_RD_CMD1_OPMOD_POS 28
|
||||
#define WMAL_INDRCT_RD_CMD1_BYTE_ADDRESS_MSK 0xFFFFF
|
||||
#define WMAL_CMD_READ_BURST_ACCESS 2
|
||||
#define WMAL_MRSPF_1 0xADFC20
|
||||
#define WMAL_INDRCT_RD_CMD1 0xADFD44
|
||||
#define WMAL_INDRCT_CMD1 0xADFC14
|
||||
#define WMAL_INDRCT_CMD(addr) \
|
||||
((WMAL_CMD_READ_BURST_ACCESS << WMAL_INDRCT_RD_CMD1_OPMOD_POS) | \
|
||||
((addr) & WMAL_INDRCT_RD_CMD1_BYTE_ADDRESS_MSK))
|
||||
|
||||
#define WFPM_LMAC1_PS_CTL_RW 0xA03380
|
||||
#define WFPM_LMAC2_PS_CTL_RW 0xA033C0
|
||||
#define WFPM_PS_CTL_RW_PHYRF_PD_FSM_CURSTATE_MSK 0x0000000F
|
||||
#define WFPM_PHYRF_STATE_ON 5
|
||||
#define HBUS_TIMEOUT 0xA5A5A5A1
|
||||
#define WFPM_DPHY_OFF 0xDF10FF
|
||||
|
||||
#endif /* __iwl_prph_h__ */
|
||||
|
|
Loading…
Reference in New Issue