From d3561e0ecd75a595cb4a477fa4c65fdb51535364 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Thu, 13 Sep 2018 14:52:59 +0300 Subject: iwlwifi: wrt: add to dump number of lmacs, lmac1 and umac error id Add to the dump the number of lmacs, the error id of the umac and the error id of lmac1, if supported. In case the reason for the dump trigger is not an assert the error id is zero. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/intel/iwlwifi/fw/dbg.c') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 2a19b178c5e8..d4d6544f8833 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -828,7 +828,13 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt, sizeof(dump_info->dev_human_readable) - 1); strncpy(dump_info->bus_human_readable, fwrt->dev->bus->name, sizeof(dump_info->bus_human_readable) - 1); - dump_info->rt_status = cpu_to_le32(fwrt->dump.rt_status); + dump_info->num_of_lmacs = fwrt->smem_cfg.num_lmacs; + dump_info->lmac_err_id[0] = + cpu_to_le32(fwrt->dump.lmac_err_id[0]); + if (fwrt->smem_cfg.num_lmacs > 1) + dump_info->lmac_err_id[1] = + cpu_to_le32(fwrt->dump.lmac_err_id[1]); + dump_info->umac_err_id = cpu_to_le32(fwrt->dump.umac_err_id); dump_data = iwl_fw_error_next_data(dump_data); } -- cgit v1.2.3-55-g7522 From 7e08baeb3c6d57b333a08306875a5cd49b4d95b5 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Tue, 2 Oct 2018 14:13:48 +0300 Subject: iwlwifi: wrt: add 22000 device familiy prph dump support Add prph dump addresses to support prph dump in 22000 HW. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 168 ++++++++++++++++++++++------ 1 file changed, 131 insertions(+), 37 deletions(-) (limited to 'drivers/net/wireless/intel/iwlwifi/fw/dbg.c') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index d4d6544f8833..5f16879ab26a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -469,6 +469,93 @@ static const struct iwl_prph_range iwl_prph_dump_addr_9000[] = { { .start = 0x00a02400, .end = 0x00a02758 }, }; +static const struct iwl_prph_range iwl_prph_dump_addr_22000[] = { + { .start = 0x00a00000, .end = 0x00a00000 }, + { .start = 0x00a0000c, .end = 0x00a00024 }, + { .start = 0x00a0002c, .end = 0x00a00034 }, + { .start = 0x00a0003c, .end = 0x00a0003c }, + { .start = 0x00a00410, .end = 0x00a00418 }, + { .start = 0x00a00420, .end = 0x00a00420 }, + { .start = 0x00a00428, .end = 0x00a00428 }, + { .start = 0x00a00430, .end = 0x00a0043c }, + { .start = 0x00a00444, .end = 0x00a00444 }, + { .start = 0x00a00840, .end = 0x00a00840 }, + { .start = 0x00a00850, .end = 0x00a00858 }, + { .start = 0x00a01004, .end = 0x00a01008 }, + { .start = 0x00a01010, .end = 0x00a01010 }, + { .start = 0x00a01018, .end = 0x00a01018 }, + { .start = 0x00a01024, .end = 0x00a01024 }, + { .start = 0x00a0102c, .end = 0x00a01034 }, + { .start = 0x00a0103c, .end = 0x00a01040 }, + { .start = 0x00a01048, .end = 0x00a01050 }, + { .start = 0x00a01058, .end = 0x00a01058 }, + { .start = 0x00a01060, .end = 0x00a01070 }, + { .start = 0x00a0108c, .end = 0x00a0108c }, + { .start = 0x00a01c20, .end = 0x00a01c28 }, + { .start = 0x00a01d10, .end = 0x00a01d10 }, + { .start = 0x00a01e28, .end = 0x00a01e2c }, + { .start = 0x00a01e60, .end = 0x00a01e60 }, + { .start = 0x00a01e80, .end = 0x00a01e80 }, + { .start = 0x00a01ea0, .end = 0x00a01ea0 }, + { .start = 0x00a02000, .end = 0x00a0201c }, + { .start = 0x00a02024, .end = 0x00a02024 }, + { .start = 0x00a02040, .end = 0x00a02048 }, + { .start = 0x00a020c0, .end = 0x00a020e0 }, + { .start = 0x00a02400, .end = 0x00a02404 }, + { .start = 0x00a0240c, .end = 0x00a02414 }, + { .start = 0x00a0241c, .end = 0x00a0243c }, + { .start = 0x00a02448, .end = 0x00a024bc }, + { .start = 0x00a024c4, .end = 0x00a024cc }, + { .start = 0x00a02508, .end = 0x00a02508 }, + { .start = 0x00a02510, .end = 0x00a02514 }, + { .start = 0x00a0251c, .end = 0x00a0251c }, + { .start = 0x00a0252c, .end = 0x00a0255c }, + { .start = 0x00a02564, .end = 0x00a025a0 }, + { .start = 0x00a025a8, .end = 0x00a025b4 }, + { .start = 0x00a025c0, .end = 0x00a025c0 }, + { .start = 0x00a025e8, .end = 0x00a025f4 }, + { .start = 0x00a02c08, .end = 0x00a02c18 }, + { .start = 0x00a02c2c, .end = 0x00a02c38 }, + { .start = 0x00a02c68, .end = 0x00a02c78 }, + { .start = 0x00a03000, .end = 0x00a03000 }, + { .start = 0x00a03010, .end = 0x00a03014 }, + { .start = 0x00a0301c, .end = 0x00a0302c }, + { .start = 0x00a03034, .end = 0x00a03038 }, + { .start = 0x00a03040, .end = 0x00a03044 }, + { .start = 0x00a03060, .end = 0x00a03068 }, + { .start = 0x00a03070, .end = 0x00a03070 }, + { .start = 0x00a0307c, .end = 0x00a03084 }, + { .start = 0x00a0308c, .end = 0x00a03090 }, + { .start = 0x00a03098, .end = 0x00a03098 }, + { .start = 0x00a030a0, .end = 0x00a030a0 }, + { .start = 0x00a030a8, .end = 0x00a030b4 }, + { .start = 0x00a030bc, .end = 0x00a030c0 }, + { .start = 0x00a030c8, .end = 0x00a030f4 }, + { .start = 0x00a03100, .end = 0x00a0312c }, + { .start = 0x00a03c00, .end = 0x00a03c5c }, + { .start = 0x00a04400, .end = 0x00a04454 }, + { .start = 0x00a04460, .end = 0x00a04474 }, + { .start = 0x00a044c0, .end = 0x00a044ec }, + { .start = 0x00a04500, .end = 0x00a04504 }, + { .start = 0x00a04510, .end = 0x00a04538 }, + { .start = 0x00a04540, .end = 0x00a04548 }, + { .start = 0x00a04560, .end = 0x00a04560 }, + { .start = 0x00a04570, .end = 0x00a0457c }, + { .start = 0x00a04590, .end = 0x00a04590 }, + { .start = 0x00a04598, .end = 0x00a04598 }, + { .start = 0x00a045c0, .end = 0x00a045f4 }, + { .start = 0x00a0c000, .end = 0x00a0c018 }, + { .start = 0x00a0c020, .end = 0x00a0c028 }, + { .start = 0x00a0c038, .end = 0x00a0c094 }, + { .start = 0x00a0c0c0, .end = 0x00a0c104 }, + { .start = 0x00a0c10c, .end = 0x00a0c118 }, + { .start = 0x00a0c150, .end = 0x00a0c174 }, + { .start = 0x00a0c17c, .end = 0x00a0c188 }, + { .start = 0x00a0c190, .end = 0x00a0c198 }, + { .start = 0x00a0c1a0, .end = 0x00a0c1a8 }, + { .start = 0x00a0c1b0, .end = 0x00a0c1b8 }, +}; + static void iwl_read_prph_block(struct iwl_trans *trans, u32 start, u32 len_bytes, __le32 *data) { @@ -478,15 +565,20 @@ static void iwl_read_prph_block(struct iwl_trans *trans, u32 start, *data++ = cpu_to_le32(iwl_read_prph_no_grab(trans, start + i)); } -static void iwl_dump_prph(struct iwl_trans *trans, - struct iwl_fw_error_dump_data **data, +static void iwl_dump_prph(struct iwl_fw_runtime *fwrt, const struct iwl_prph_range *iwl_prph_dump_addr, - u32 range_len) + u32 range_len, void *ptr) { struct iwl_fw_error_dump_prph *prph; + struct iwl_trans *trans = fwrt->trans; + struct iwl_fw_error_dump_data **data = + (struct iwl_fw_error_dump_data **)ptr; unsigned long flags; u32 i; + if (!data) + return; + IWL_DEBUG_INFO(trans, "WRT PRPH dump\n"); if (!iwl_trans_grab_nic_access(trans, &flags)) @@ -552,37 +644,47 @@ static struct scatterlist *alloc_sgtable(int size) return table; } -static int iwl_fw_get_prph_len(struct iwl_fw_runtime *fwrt) +static void iwl_fw_get_prph_len(struct iwl_fw_runtime *fwrt, + const struct iwl_prph_range *iwl_prph_dump_addr, + u32 range_len, void *ptr) { - u32 prph_len = 0; - int i; + u32 *prph_len = (u32 *)ptr; + int i, num_bytes_in_chunk; + + if (!prph_len) + return; - for (i = 0; i < ARRAY_SIZE(iwl_prph_dump_addr_comm); - i++) { + for (i = 0; i < range_len; i++) { /* The range includes both boundaries */ - int num_bytes_in_chunk = - iwl_prph_dump_addr_comm[i].end - - iwl_prph_dump_addr_comm[i].start + 4; + num_bytes_in_chunk = + iwl_prph_dump_addr[i].end - + iwl_prph_dump_addr[i].start + 4; - prph_len += sizeof(struct iwl_fw_error_dump_data) + + *prph_len += sizeof(struct iwl_fw_error_dump_data) + sizeof(struct iwl_fw_error_dump_prph) + num_bytes_in_chunk; } +} - if (fwrt->trans->cfg->mq_rx_supported) { - for (i = 0; i < - ARRAY_SIZE(iwl_prph_dump_addr_9000); i++) { - /* The range includes both boundaries */ - int num_bytes_in_chunk = - iwl_prph_dump_addr_9000[i].end - - iwl_prph_dump_addr_9000[i].start + 4; - - prph_len += sizeof(struct iwl_fw_error_dump_data) + - sizeof(struct iwl_fw_error_dump_prph) + - num_bytes_in_chunk; +static void iwl_fw_prph_handler(struct iwl_fw_runtime *fwrt, void *ptr, + void (*handler)(struct iwl_fw_runtime *, + const struct iwl_prph_range *, + u32, void *)) +{ + u32 range_len; + + if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) { + range_len = ARRAY_SIZE(iwl_prph_dump_addr_22000); + handler(fwrt, iwl_prph_dump_addr_22000, range_len, ptr); + } else { + range_len = ARRAY_SIZE(iwl_prph_dump_addr_comm); + handler(fwrt, iwl_prph_dump_addr_comm, range_len, ptr); + + if (fwrt->trans->cfg->mq_rx_supported) { + range_len = ARRAY_SIZE(iwl_prph_dump_addr_9000); + handler(fwrt, iwl_prph_dump_addr_9000, range_len, ptr); } } - return prph_len; } static void iwl_fw_dump_mem(struct iwl_fw_runtime *fwrt, @@ -747,9 +849,9 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt, fifo_len += iwl_fw_txf_len(fwrt, mem_cfg); /* Make room for PRPH registers */ - if (!fwrt->trans->cfg->gen2 && - iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_PRPH)) - prph_len += iwl_fw_get_prph_len(fwrt); + if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_PRPH)) + iwl_fw_prph_handler(fwrt, &prph_len, + iwl_fw_get_prph_len); if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000 && iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_RADIO_REG)) @@ -941,16 +1043,8 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt, if (iwl_fw_dbg_is_paging_enabled(fwrt)) iwl_dump_paging(fwrt, &dump_data); - if (prph_len) { - iwl_dump_prph(fwrt->trans, &dump_data, - iwl_prph_dump_addr_comm, - ARRAY_SIZE(iwl_prph_dump_addr_comm)); - - if (fwrt->trans->cfg->mq_rx_supported) - iwl_dump_prph(fwrt->trans, &dump_data, - iwl_prph_dump_addr_9000, - ARRAY_SIZE(iwl_prph_dump_addr_9000)); - } + if (prph_len) + iwl_fw_prph_handler(fwrt, &dump_data, iwl_dump_prph); out: dump_file->file_len = cpu_to_le32(file_len); -- cgit v1.2.3-55-g7522 From 162b22c93e66530405d793a830f75da3fc48ed31 Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Sun, 21 Oct 2018 14:39:05 +0300 Subject: iwlwifi: tighten boundary checks The driver assumes certain sizes and lengths aren't crossed in some places. Make sure this indeed happens. Found by Klocwork. Signed-off-by: Liad Kaufman Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 2 ++ drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 24 ++++++++++++++++++----- drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 6 +++++- 3 files changed, 26 insertions(+), 6 deletions(-) (limited to 'drivers/net/wireless/intel/iwlwifi/fw/dbg.c') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 5f16879ab26a..56e99b5661f7 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -835,6 +835,8 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt, if (!fwrt->trans->cfg->dccm_offset || !fwrt->trans->cfg->dccm_len) { const struct fw_img *img; + if (fwrt->cur_fw_img >= IWL_UCODE_TYPE_MAX) + return NULL; img = &fwrt->fw->img[fwrt->cur_fw_img]; sram_ofs = img->sec[IWL_UCODE_SECTION_DATA].offset; sram_len = img->sec[IWL_UCODE_SECTION_DATA].len; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 2adef6e3e0ac..ac62eb8c4b36 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -1024,7 +1024,12 @@ static void iwl_mvm_tx_airtime(struct iwl_mvm *mvm, int airtime) { int mac = mvmsta->mac_id_n_color & FW_CTXT_ID_MSK; - struct iwl_mvm_tcm_mac *mdata = &mvm->tcm.data[mac]; + struct iwl_mvm_tcm_mac *mdata; + + if (mac >= NUM_MAC_INDEX_DRIVER) + return; + + mdata = &mvm->tcm.data[mac]; if (mvm->tcm.paused) return; @@ -1035,14 +1040,21 @@ static void iwl_mvm_tx_airtime(struct iwl_mvm *mvm, mdata->tx.airtime += airtime; } -static void iwl_mvm_tx_pkt_queued(struct iwl_mvm *mvm, - struct iwl_mvm_sta *mvmsta, int tid) +static int iwl_mvm_tx_pkt_queued(struct iwl_mvm *mvm, + struct iwl_mvm_sta *mvmsta, int tid) { u32 ac = tid_to_mac80211_ac[tid]; int mac = mvmsta->mac_id_n_color & FW_CTXT_ID_MSK; - struct iwl_mvm_tcm_mac *mdata = &mvm->tcm.data[mac]; + struct iwl_mvm_tcm_mac *mdata; + + if (mac >= NUM_MAC_INDEX_DRIVER) + return -EINVAL; + + mdata = &mvm->tcm.data[mac]; mdata->tx.pkts[ac]++; + + return 0; } /* @@ -1162,7 +1174,9 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, spin_unlock(&mvmsta->lock); - iwl_mvm_tx_pkt_queued(mvm, mvmsta, tid == IWL_MAX_TID_COUNT ? 0 : tid); + if (iwl_mvm_tx_pkt_queued(mvm, mvmsta, + tid == IWL_MAX_TID_COUNT ? 0 : tid)) + goto drop; return 0; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index 156ca1b1f621..af2791502b7d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c @@ -214,7 +214,11 @@ static int iwl_pcie_gen2_set_tb(struct iwl_trans *trans, { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int idx = iwl_pcie_gen2_get_num_tbs(trans, tfd); - struct iwl_tfh_tb *tb = &tfd->tbs[idx]; + struct iwl_tfh_tb *tb; + + if (WARN_ON(idx >= IWL_NUM_OF_TBS)) + return -EINVAL; + tb = &tfd->tbs[idx]; /* Each TFD can point to a maximum max_tbs Tx buffers */ if (le16_to_cpu(tfd->num_tbs) >= trans_pcie->max_tbs) { -- cgit v1.2.3-55-g7522 From acf42a957e341abcafd28d5e89a5e8bfffd67989 Mon Sep 17 00:00:00 2001 From: Mordechay Goodstein Date: Sun, 21 Oct 2018 18:48:13 +0300 Subject: iwlwifi: avoid access out of memory allocated The value in num_lmac can be bigger than mem_cfg->lmac array, warn in case it's bigger. Signed-off-by: Mordechay Goodstein Fixes: 68025d5f9bfe ("iwlwifi: dbg: refactor dump code to improve readability") Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/net/wireless/intel/iwlwifi/fw/dbg.c') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 56e99b5661f7..a97bf17da14d 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -748,6 +748,9 @@ static int iwl_fw_rxf_len(struct iwl_fw_runtime *fwrt, ADD_LEN(fifo_len, mem_cfg->rxfifo2_size, hdr_len); /* Count RXF1 sizes */ + if (WARN_ON(mem_cfg->num_lmacs > MAX_NUM_LMAC)) + mem_cfg->num_lmacs = MAX_NUM_LMAC; + for (i = 0; i < mem_cfg->num_lmacs; i++) ADD_LEN(fifo_len, mem_cfg->lmac[i].rxfifo1_size, hdr_len); @@ -766,6 +769,9 @@ static int iwl_fw_txf_len(struct iwl_fw_runtime *fwrt, goto dump_internal_txf; /* Count TXF sizes */ + if (WARN_ON(mem_cfg->num_lmacs > MAX_NUM_LMAC)) + mem_cfg->num_lmacs = MAX_NUM_LMAC; + for (i = 0; i < mem_cfg->num_lmacs; i++) { int j; -- cgit v1.2.3-55-g7522 From e6aeeb4f45178197c956a5795f49648db67607bd Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 29 Oct 2018 13:50:05 +0100 Subject: iwlwifi: mvm: clean up LDBG config command usage Clean up the LDBG config command to not be called "continuous recording", and while at it actually remove the continuous recording implementation completely since it was only used for store & forward architectures. This also fixes a bug at least in iwl_fw_dbg_buffer_allocation() because what's now "__le32 type" (matching the firmware) used to be "__le16 enable_recording", so the buffer allocation config sub-struct would erroneously have started at the wrong offset. In the other cases this didn't actually lead to a bug as other bytes in pad[] were all zeroes, so accessing the 16-bit value as a 32-bit value wouldn't make a difference (in little endian.) Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/debug.h | 33 ++++++++--------- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 12 +++---- drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 13 ++++--- drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 43 ----------------------- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 3 ++ 5 files changed, 29 insertions(+), 75 deletions(-) (limited to 'drivers/net/wireless/intel/iwlwifi/fw/dbg.c') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h index dc1fa377087a..988584973aba 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h @@ -335,29 +335,11 @@ struct iwl_dbg_mem_access_rsp { __le32 data[]; } __packed; /* DEBUG_(U|L)MAC_RD_WR_RSP_API_S_VER_1 */ -#define CONT_REC_COMMAND_SIZE 80 -#define ENABLE_CONT_RECORDING 0x15 -#define DISABLE_CONT_RECORDING 0x16 +#define LDBG_CFG_COMMAND_SIZE 80 #define BUFFER_ALLOCATION 0x27 #define START_DEBUG_RECORDING 0x29 #define STOP_DEBUG_RECORDING 0x2A -/* - * struct iwl_continuous_record_mode - recording mode - */ -struct iwl_continuous_record_mode { - __le16 enable_recording; -} __packed; - -/* - * struct iwl_continuous_record_cmd - enable/disable continuous recording - */ -struct iwl_continuous_record_cmd { - struct iwl_continuous_record_mode record_mode; - u8 pad[CONT_REC_COMMAND_SIZE - - sizeof(struct iwl_continuous_record_mode)]; -} __packed; - /* maximum fragments to be allocated per target of allocationId */ #define IWL_BUFFER_LOCATION_MAX_FRAGS 2 @@ -385,4 +367,17 @@ struct iwl_buffer_allocation_cmd { struct iwl_fragment_data fragments[IWL_BUFFER_LOCATION_MAX_FRAGS]; } __packed; /* BUFFER_ALLOCATION_CMD_API_S_VER_1 */ +/** + * struct iwl_ldbg_config_cmd - LDBG config command + * @type: configuration type + * @pad: reserved space for type-dependent data + */ +struct iwl_ldbg_config_cmd { + __le32 type; + union { + u8 pad[LDBG_CFG_COMMAND_SIZE - sizeof(__le32)]; + struct iwl_buffer_allocation_cmd buffer_allocation; + }; /* LDBG_CFG_BODY_API_U_VER_2 (partially) */ +} __packed; /* LDBG_CFG_CMD_API_S_VER_2 */ + #endif /* __iwl_fw_api_debug_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index a97bf17da14d..917aafe1a9db 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1678,20 +1678,20 @@ iwl_fw_dbg_buffer_allocation(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_allocation_tlv *alloc) { struct iwl_trans *trans = fwrt->trans; - struct iwl_continuous_record_cmd cont_rec = {}; - struct iwl_buffer_allocation_cmd *cmd = (void *)&cont_rec.pad[0]; + struct iwl_ldbg_config_cmd ldbg_cmd = { + .type = cpu_to_le32(BUFFER_ALLOCATION), + }; + struct iwl_buffer_allocation_cmd *cmd = &ldbg_cmd.buffer_allocation; struct iwl_host_cmd hcmd = { .id = LDBG_CONFIG_CMD, .flags = CMD_ASYNC, - .data[0] = &cont_rec, - .len[0] = sizeof(cont_rec), + .data[0] = &ldbg_cmd, + .len[0] = sizeof(ldbg_cmd), }; void *virtual_addr = NULL; u32 size = le32_to_cpu(alloc->size); dma_addr_t phys_addr; - cont_rec.record_mode.enable_recording = cpu_to_le16(BUFFER_ALLOCATION); - if (!trans->num_blocks && le32_to_cpu(alloc->buffer_location) != IWL_FW_INI_LOCATION_DRAM_PATH) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index 40dcc3deb257..7cd206e6fb9e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -271,18 +271,17 @@ _iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt, static int iwl_fw_dbg_start_stop_hcmd(struct iwl_fw_runtime *fwrt, bool start) { - struct iwl_continuous_record_cmd cont_rec = {}; + struct iwl_ldbg_config_cmd cmd = { + .type = start ? cpu_to_le32(START_DEBUG_RECORDING) : + cpu_to_le32(STOP_DEBUG_RECORDING), + }; struct iwl_host_cmd hcmd = { .id = LDBG_CONFIG_CMD, .flags = CMD_ASYNC, - .data[0] = &cont_rec, - .len[0] = sizeof(cont_rec), + .data[0] = &cmd, + .len[0] = sizeof(cmd), }; - cont_rec.record_mode.enable_recording = start ? - cpu_to_le16(START_DEBUG_RECORDING) : - cpu_to_le16(STOP_DEBUG_RECORDING); - return iwl_trans_send_cmd(fwrt->trans, &hcmd); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 52c361a6124c..514aaec6d59e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -1206,47 +1206,6 @@ static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file, return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } -/* - * Enable / Disable continuous recording. - * Cause the FW to start continuous recording, by sending the relevant hcmd. - * Enable: input of every integer larger than 0, ENABLE_CONT_RECORDING. - * Disable: for 0 as input, DISABLE_CONT_RECORDING. - */ -static ssize_t iwl_dbgfs_cont_recording_write(struct iwl_mvm *mvm, - char *buf, size_t count, - loff_t *ppos) -{ - struct iwl_trans *trans = mvm->trans; - const struct iwl_fw_dbg_dest_tlv_v1 *dest = trans->dbg_dest_tlv; - struct iwl_continuous_record_cmd cont_rec = {}; - int ret, rec_mode; - - if (!iwl_mvm_firmware_running(mvm)) - return -EIO; - - if (!dest) - return -EOPNOTSUPP; - - if (dest->monitor_mode != SMEM_MODE || - trans->cfg->device_family < IWL_DEVICE_FAMILY_8000) - return -EOPNOTSUPP; - - ret = kstrtoint(buf, 0, &rec_mode); - if (ret) - return ret; - - cont_rec.record_mode.enable_recording = rec_mode ? - cpu_to_le16(ENABLE_CONT_RECORDING) : - cpu_to_le16(DISABLE_CONT_RECORDING); - - mutex_lock(&mvm->mutex); - ret = iwl_mvm_send_cmd_pdu(mvm, LDBG_CONFIG_CMD, 0, - sizeof(cont_rec), &cont_rec); - mutex_unlock(&mvm->mutex); - - return ret ?: count; -} - static ssize_t iwl_dbgfs_fw_dbg_conf_write(struct iwl_mvm *mvm, char *buf, size_t count, loff_t *ppos) @@ -1800,7 +1759,6 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8); MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8); MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8); MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64); -MVM_DEBUGFS_WRITE_FILE_OPS(cont_recording, 8); MVM_DEBUGFS_WRITE_FILE_OPS(max_amsdu_len, 8); MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl, (IWL_RSS_INDIRECTION_TABLE_SIZE * 2)); @@ -2004,7 +1962,6 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, 0200); MVM_DEBUGFS_ADD_FILE(max_amsdu_len, mvm->debugfs_dir, 0200); MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, 0200); - MVM_DEBUGFS_ADD_FILE(cont_recording, mvm->debugfs_dir, 0200); MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, 0200); MVM_DEBUGFS_ADD_FILE(inject_packet, mvm->debugfs_dir, 0200); #ifdef CONFIG_ACPI diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index d257c143e624..ee2ef3f0042c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -737,6 +737,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, trans_cfg.rx_buf_size = rb_size_default; } + BUILD_BUG_ON(sizeof(struct iwl_ldbg_config_cmd) != + LDBG_CFG_COMMAND_SIZE); + trans->wide_cmd_header = true; trans_cfg.bc_table_dword = mvm->trans->cfg->device_family < IWL_DEVICE_FAMILY_22560; -- cgit v1.2.3-55-g7522 From 07a44b322397b1a5e8c96ceef8ce352fe79ac7ee Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Mon, 26 Nov 2018 11:19:00 +0200 Subject: iwlwifi: dbg_ini: allocate dram buffer with proper flags Use the same flags we use in the legacy buffer allocation. Missing __GFP_NOWARN will cause an unwanted warning incase we fail to allocate. Missing __GFP_ZERO will give a buffer initially filled with garbage which can make debug difficult in case our wrap count is zero. Signed-off-by: Shahar S Matityahu Fixes: d47902f9f71d ("iwlwifi: dbg: add apply point logic") Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/intel/iwlwifi/fw/dbg.c') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 917aafe1a9db..947f282c05a9 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1697,8 +1697,10 @@ iwl_fw_dbg_buffer_allocation(struct iwl_fw_runtime *fwrt, IWL_FW_INI_LOCATION_DRAM_PATH) return; - virtual_addr = dma_alloc_coherent(fwrt->trans->dev, size, - &phys_addr, GFP_KERNEL); + virtual_addr = + dma_alloc_coherent(fwrt->trans->dev, size, &phys_addr, + GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO | + __GFP_COMP); /* TODO: alloc fragments if needed */ if (!virtual_addr) -- cgit v1.2.3-55-g7522 From cd0fc658fbb77b07b9bcd2fa315acfda40e02539 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Mon, 26 Nov 2018 11:02:54 +0200 Subject: iwlwifi: dbg_ini: properly handle ini user trigger in case of a user trigger while ini is enable we change FW_DBG_TRIGGER_USER to IWL_FW_TRIGGER_ID_USER_TRIGGER in iwl_fw_dbg_collect and then again we attempt to do so in _iwl_fw_error_ini_dump which causes to abort the dump. Fix it by removing the second check in _iwl_fw_error_ini_dump. Signed-off-by: Shahar S Matityahu Fixes: 7a14c23dcdee ("iwlwifi: dbg: dump data according to the new ini TLVs") Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/net/wireless/intel/iwlwifi/fw/dbg.c') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 947f282c05a9..07dc2919b0b4 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1254,10 +1254,6 @@ _iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt, if (id == FW_DBG_TRIGGER_FW_ASSERT) id = IWL_FW_TRIGGER_ID_FW_ASSERT; - else if (id == FW_DBG_TRIGGER_USER) - id = IWL_FW_TRIGGER_ID_USER_TRIGGER; - else if (id < FW_DBG_TRIGGER_MAX) - return NULL; if (WARN_ON(id >= ARRAY_SIZE(fwrt->dump.active_trigs))) return NULL; -- cgit v1.2.3-55-g7522 From b2aea95c183360e3a3add84e349915b87f3680b2 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Mon, 26 Nov 2018 10:34:37 +0200 Subject: iwlwifi: dbg_ini: retrieve dump_delay value properly The driver uses ignore_consec instead of dump_delay. Fix it by using dump_delay as expected. Signed-off-by: Shahar S Matityahu Fixes: fe1b7d6c2888 ("iwlwifi: add support for triggering ini triggers") Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/intel/iwlwifi/fw/dbg.c') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 07dc2919b0b4..02ad87022e78 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1489,7 +1489,7 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt, if (WARN_ON(!fwrt->dump.active_trigs[id].active)) return -EINVAL; - delay = le32_to_cpu(fwrt->dump.active_trigs[id].conf->ignore_consec); + delay = le32_to_cpu(fwrt->dump.active_trigs[id].conf->dump_delay); occur = le32_to_cpu(fwrt->dump.active_trigs[id].conf->occurrences); if (!occur) return 0; -- cgit v1.2.3-55-g7522 From 55fbf0d21c443dc98a0c537d3db5a29be54c04de Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Mon, 26 Nov 2018 10:29:15 +0200 Subject: iwlwifi: dbg_ini: set dump mask BIT(n) instead of n The driver sets dump_mask value instead of BIT(value). fix it by updating dump_mask correctly. Signed-off-by: Shahar S Matityahu Fixes: 7a14c23dcdee ("iwlwifi: dbg: dump data according to the new ini TLVs") Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/intel/iwlwifi/fw/dbg.c') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 02ad87022e78..22efd94da6d3 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1216,13 +1216,13 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt, iwl_dump_prph_ini(fwrt->trans, data, reg); break; case IWL_FW_INI_REGION_DRAM_BUFFER: - *dump_mask |= IWL_FW_ERROR_DUMP_FW_MONITOR; + *dump_mask |= BIT(IWL_FW_ERROR_DUMP_FW_MONITOR); break; case IWL_FW_INI_REGION_PAGING: if (iwl_fw_dbg_is_paging_enabled(fwrt)) iwl_dump_paging(fwrt, data); else - *dump_mask |= IWL_FW_ERROR_DUMP_PAGING; + *dump_mask |= BIT(IWL_FW_ERROR_DUMP_PAGING); break; case IWL_FW_INI_REGION_TXF: iwl_fw_dump_txf(fwrt, data); -- cgit v1.2.3-55-g7522