linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31
@ 2019-08-31  9:48 Luca Coelho
  2019-08-31  9:48 ` [PATCH 01/19] iwlwifi: stop passing bogus gfp flags arguments to dma_alloc_coherent Luca Coelho
                   ` (18 more replies)
  0 siblings, 19 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Luca Coelho <luciano.coelho@intel.com>

Hi,

Here's the third set of patches intended for v5.4.  It's the usual
development, new features, cleanups and bugfixes.

The changes are:

* New FW channel-switch support;
* Debug infrastructure work continues;
* Support new ACPI value for per-platform antenna gain;
* Some work on new FW scan APIs;
* A few clean-ups;
* Other small fixes and improvements;

As usual, I'm pushing this to a pending branch, for kbuild bot, and
will send a pull-request later.

Please review.

Cheers,
Luca.


Christoph Hellwig (1):
  iwlwifi: stop passing bogus gfp flags arguments to dma_alloc_coherent

Emmanuel Grumbach (1):
  iwlwifi: mvm: simplify the channel switch flow for newer firmware

Gil Adam (1):
  iwlwifi: support per-platform antenna gain

Johannes Berg (1):
  iwlwifi: api: fix FTM struct documentation

Luca Coelho (4):
  iwlwifi: mvm: remove check for lq_sta in __iwl_mvm_rs_tx_status()
  iwlwifi: bump FW API to 50 for 22000 series
  iwlwifi: remove duplicate FW string definitions
  iwlwifi: remove unnecessary IWL_DEVICE_AX200_COMMON definition

Shahar S Matityahu (9):
  iwlwifi: dbg_ini: use function to check if ini dbg mode is on
  iwlwifi: dbg_ini: verify debug TLVs at allocation phase
  iwlwifi: dbg_ini: remove debug flow TLV
  iwlwifi: dbg: align wrt log prints to the same format
  iwlwifi: dbg_ini: separate cfg and dump flows to different modules
  iwlwifi: dbg_ini: use linked list for dump TLVs during dump creation
  iwlwifi: dbg_ini: move tx fifo data into fw runtime
  iwlwifi: dbg_ini: make a single ops struct for paging collect
  iwlwifi: dbg_ini: use regions ops array instead of switch case in dump
    flow

Tova Mussai (2):
  iwlwifi: allocate bigger nvm data in case of UHB
  iwlwifi: mvm: look for the first supported channel when add/remove phy
    ctxt

 .../net/wireless/intel/iwlwifi/cfg/22000.c    |   13 +-
 drivers/net/wireless/intel/iwlwifi/fw/acpi.h  |   12 +
 .../wireless/intel/iwlwifi/fw/api/dbg-tlv.h   |   11 -
 .../wireless/intel/iwlwifi/fw/api/location.h  |    4 +-
 .../net/wireless/intel/iwlwifi/fw/api/phy.h   |    7 +
 .../net/wireless/intel/iwlwifi/fw/api/power.h |   12 +
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   | 1003 +++++------------
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h   |   12 +-
 .../wireless/intel/iwlwifi/fw/error-dump.h    |   22 +
 drivers/net/wireless/intel/iwlwifi/fw/file.h  |    4 +-
 .../net/wireless/intel/iwlwifi/fw/runtime.h   |   18 +-
 .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c  |  580 +++++++++-
 .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h  |    8 +-
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c  |    3 +-
 .../wireless/intel/iwlwifi/iwl-nvm-parse.c    |    6 +-
 .../net/wireless/intel/iwlwifi/iwl-trans.h    |   27 +-
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c   |    3 +
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   |  142 ++-
 .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c |    6 +-
 .../net/wireless/intel/iwlwifi/mvm/mac80211.c |   83 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |    3 +
 .../net/wireless/intel/iwlwifi/mvm/phy-ctxt.c |   11 +-
 drivers/net/wireless/intel/iwlwifi/mvm/rs.c   |    6 +-
 drivers/net/wireless/intel/iwlwifi/mvm/scan.c |    2 +-
 .../intel/iwlwifi/pcie/ctxt-info-gen3.c       |    2 +-
 .../wireless/intel/iwlwifi/pcie/internal.h    |    2 +-
 .../net/wireless/intel/iwlwifi/pcie/trans.c   |    7 +-
 27 files changed, 1121 insertions(+), 888 deletions(-)

-- 
2.23.0.rc1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 01/19] iwlwifi: stop passing bogus gfp flags arguments to dma_alloc_coherent
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 02/19] iwlwifi: mvm: simplify the channel switch flow for newer firmware Luca Coelho
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Christoph Hellwig <hch@lst.de>

dma_alloc_coherent is not just the page allocator.  The only valid
arguments to pass are either GFP_ATOMIC or GFP_ATOMIC with possible
modifiers of __GFP_NORETRY or __GFP_NOWARN.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c     | 3 +--
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 1aa880936121..f52427ec60e9 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -2485,8 +2485,7 @@ iwl_fw_dbg_buffer_allocation(struct iwl_fw_runtime *fwrt, u32 size)
 
 	virtual_addr =
 		dma_alloc_coherent(fwrt->trans->dev, size, &phys_addr,
-				   GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO |
-				   __GFP_COMP);
+				   GFP_KERNEL | __GFP_NOWARN);
 
 	/* TODO: alloc fragments if needed */
 	if (!virtual_addr)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 0972ef064514..48a209708852 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -215,8 +215,7 @@ static void iwl_pcie_alloc_fw_monitor_block(struct iwl_trans *trans,
 	for (power = max_power; power >= min_power; power--) {
 		size = BIT(power);
 		cpu_addr = dma_alloc_coherent(trans->dev, size, &phys,
-					      GFP_KERNEL | __GFP_NOWARN |
-					      __GFP_ZERO | __GFP_COMP);
+					      GFP_KERNEL | __GFP_NOWARN);
 		if (!cpu_addr)
 			continue;
 
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 02/19] iwlwifi: mvm: simplify the channel switch flow for newer firmware
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
  2019-08-31  9:48 ` [PATCH 01/19] iwlwifi: stop passing bogus gfp flags arguments to dma_alloc_coherent Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 03/19] iwlwifi: mvm: remove check for lq_sta in __iwl_mvm_rs_tx_status() Luca Coelho
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

Any firmware that supports the new channel switch flow is
able to close / re-open the queues when needed. It takes
into account the channel switch mode etc...
Don't open / close the queues or enable / disable beacon
abort before and after the channel switch in case the
firmware is able to do this by itself.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c |  4 +-
 .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 81 ++++++++++++-------
 2 files changed, 54 insertions(+), 31 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index cb22d447fcb8..8c9777424316 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -1567,7 +1567,9 @@ void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm,
 		RCU_INIT_POINTER(mvm->csa_vif, NULL);
 		return;
 	case NL80211_IFTYPE_STATION:
-		iwl_mvm_csa_client_absent(mvm, vif);
+		if (!fw_has_capa(&mvm->fw->ucode_capa,
+				 IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
+			iwl_mvm_csa_client_absent(mvm, vif);
 		cancel_delayed_work(&mvmvif->csa_work);
 		ieee80211_chswitch_done(vif, true);
 		break;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index e49558fb8aa3..e3699df89572 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -1326,15 +1326,20 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
 			goto out_unlock;
 		}
 
-		iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
+		if (!fw_has_capa(&mvm->fw->ucode_capa,
+				 IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
+			iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
 
 		iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
 
-		ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0);
-		if (ret)
-			goto out_unlock;
+		if (!fw_has_capa(&mvm->fw->ucode_capa,
+				 IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) {
+			ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0);
+			if (ret)
+				goto out_unlock;
 
-		iwl_mvm_stop_session_protection(mvm, vif);
+			iwl_mvm_stop_session_protection(mvm, vif);
+		}
 	}
 
 	mvmvif->ps_disabled = false;
@@ -4411,6 +4416,42 @@ static int iwl_mvm_schedule_client_csa(struct iwl_mvm *mvm,
 				    0, sizeof(cmd), &cmd);
 }
 
+static int iwl_mvm_old_pre_chan_sw_sta(struct iwl_mvm *mvm,
+				       struct ieee80211_vif *vif,
+				       struct ieee80211_channel_switch *chsw)
+{
+	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+	u32 apply_time;
+
+	/* Schedule the time event to a bit before beacon 1,
+	 * to make sure we're in the new channel when the
+	 * GO/AP arrives. In case count <= 1 immediately schedule the
+	 * TE (this might result with some packet loss or connection
+	 * loss).
+	 */
+	if (chsw->count <= 1)
+		apply_time = 0;
+	else
+		apply_time = chsw->device_timestamp +
+			((vif->bss_conf.beacon_int * (chsw->count - 1) -
+			  IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
+
+	if (chsw->block_tx)
+		iwl_mvm_csa_client_absent(mvm, vif);
+
+	if (mvmvif->bf_data.bf_enabled) {
+		int ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
+
+		if (ret)
+			return ret;
+	}
+
+	iwl_mvm_schedule_csa_period(mvm, vif, vif->bss_conf.beacon_int,
+				    apply_time);
+
+	return 0;
+}
+
 #define IWL_MAX_CSA_BLOCK_TX 1500
 static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
 				      struct ieee80211_vif *vif,
@@ -4419,7 +4460,6 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 	struct ieee80211_vif *csa_vif;
 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
-	u32 apply_time;
 	int ret;
 
 	mutex_lock(&mvm->mutex);
@@ -4463,21 +4503,7 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
 
 		break;
 	case NL80211_IFTYPE_STATION:
-		/* Schedule the time event to a bit before beacon 1,
-		 * to make sure we're in the new channel when the
-		 * GO/AP arrives. In case count <= 1 immediately schedule the
-		 * TE (this might result with some packet loss or connection
-		 * loss).
-		 */
-		if (chsw->count <= 1)
-			apply_time = 0;
-		else
-			apply_time = chsw->device_timestamp +
-				((vif->bss_conf.beacon_int * (chsw->count - 1) -
-				  IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
-
 		if (chsw->block_tx) {
-			iwl_mvm_csa_client_absent(mvm, vif);
 			/*
 			 * In case of undetermined / long time with immediate
 			 * quiet monitor status to gracefully disconnect
@@ -4489,19 +4515,14 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
 						      msecs_to_jiffies(IWL_MAX_CSA_BLOCK_TX));
 		}
 
-		if (mvmvif->bf_data.bf_enabled) {
-			ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
+		if (!fw_has_capa(&mvm->fw->ucode_capa,
+				 IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) {
+			ret = iwl_mvm_old_pre_chan_sw_sta(mvm, vif, chsw);
 			if (ret)
 				goto out_unlock;
-		}
-
-		if (fw_has_capa(&mvm->fw->ucode_capa,
-				IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
+		} else {
 			iwl_mvm_schedule_client_csa(mvm, vif, chsw);
-		else
-			iwl_mvm_schedule_csa_period(mvm, vif,
-						    vif->bss_conf.beacon_int,
-						    apply_time);
+		}
 
 		mvmvif->csa_count = chsw->count;
 		mvmvif->csa_misbehave = false;
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 03/19] iwlwifi: mvm: remove check for lq_sta in __iwl_mvm_rs_tx_status()
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
  2019-08-31  9:48 ` [PATCH 01/19] iwlwifi: stop passing bogus gfp flags arguments to dma_alloc_coherent Luca Coelho
  2019-08-31  9:48 ` [PATCH 02/19] iwlwifi: mvm: simplify the channel switch flow for newer firmware Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 04/19] iwlwifi: support per-platform antenna gain Luca Coelho
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Luca Coelho <luciano.coelho@intel.com>

The check is not necessary anymore, because now the struct is not
allocated separately, but is part of the mvmsta struct.  Remove the
check, since it's dead code.

Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
index e4415e58fa78..fcd1b15d2fa0 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -3079,11 +3079,7 @@ static void __iwl_mvm_rs_tx_status(struct iwl_mvm *mvm,
 	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 	struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv;
 
-	/* Treat uninitialized rate scaling data same as non-existing. */
-	if (!lq_sta) {
-		IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n");
-		return;
-	} else if (!lq_sta->pers.drv) {
+	if (!lq_sta->pers.drv) {
 		IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n");
 		return;
 	}
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 04/19] iwlwifi: support per-platform antenna gain
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
                   ` (2 preceding siblings ...)
  2019-08-31  9:48 ` [PATCH 03/19] iwlwifi: mvm: remove check for lq_sta in __iwl_mvm_rs_tx_status() Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 05/19] iwlwifi: api: fix FTM struct documentation Luca Coelho
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Gil Adam <gil.adam@intel.com>

TX power limits as defined in the OTP assume the worst case scenario
in terms of the platform's atenna gain, but most platforms are below
that value so they can use more TX power without passing the regulatory
limit. If the platform indicates in the BIOS that it indeed has lower
gain, and the geographic location allows it, higher TX power can be
used. The driver reads the PPAG (Per-Platform Antenna Gain) data from
BIOS (if it exists), validates it and sends the appropriate command to
the FW. This flow happens once at FW init, in case of suspend/resume
there is no need to read again from BIOS as we save those values during
init, so just send the PPAG command again to FW.

Signed-off-by: Gil Adam <gil.adam@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/acpi.h  |  12 ++
 .../net/wireless/intel/iwlwifi/fw/api/phy.h   |   7 +
 .../net/wireless/intel/iwlwifi/fw/api/power.h |  12 ++
 drivers/net/wireless/intel/iwlwifi/fw/file.h  |   1 +
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c   |   3 +
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   | 121 ++++++++++++++++++
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |   3 +
 7 files changed, 159 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
index 991a23450999..6cb2d1f5efea 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
@@ -68,6 +68,7 @@
 #define ACPI_WRDD_METHOD	"WRDD"
 #define ACPI_SPLC_METHOD	"SPLC"
 #define ACPI_ECKV_METHOD	"ECKV"
+#define ACPI_PPAG_METHOD	"PPAG"
 
 #define ACPI_WIFI_DOMAIN	(0x07)
 
@@ -92,6 +93,17 @@
 #define ACPI_WGDS_NUM_BANDS		2
 #define ACPI_WGDS_TABLE_SIZE		3
 
+#define ACPI_PPAG_NUM_CHAINS		2
+#define ACPI_PPAG_NUM_SUB_BANDS		5
+#define ACPI_PPAG_WIFI_DATA_SIZE	((ACPI_PPAG_NUM_CHAINS * \
+					ACPI_PPAG_NUM_SUB_BANDS) + 3)
+
+/* PPAG gain value bounds in 1/8 dBm */
+#define ACPI_PPAG_MIN_LB -16
+#define ACPI_PPAG_MAX_LB 24
+#define ACPI_PPAG_MIN_HB -16
+#define ACPI_PPAG_MAX_HB 40
+
 #ifdef CONFIG_ACPI
 
 void *iwl_acpi_get_object(struct device *dev, acpi_string method);
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h b/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h
index 9cc59e00bd95..8991ddffbf5e 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h
@@ -8,6 +8,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2019 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,6 +31,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2019 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -89,6 +91,11 @@ enum iwl_phy_ops_subcmd_ids {
 	 */
 	GEO_TX_POWER_LIMIT = 0x05,
 
+	/**
+	 * @PER_PLATFORM_ANT_GAIN_CMD: &struct iwl_ppag_table_cmd
+	 */
+	PER_PLATFORM_ANT_GAIN_CMD = 0x07,
+
 	/**
 	 * @CT_KILL_NOTIFICATION: &struct ct_kill_notif
 	 */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
index f195db398bed..6e1b9b21904e 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
@@ -449,6 +449,18 @@ struct iwl_geo_tx_power_profiles_resp {
 	__le32 profile_idx;
 } __packed; /* GEO_TX_POWER_LIMIT_RESP */
 
+/**
+ * struct iwl_ppag_table_cmd - struct for PER_PLATFORM_ANT_GAIN_CMD cmd.
+ * @enabled: 1 if PPAG is enabled, 0 otherwise
+ * @gain: table of antenna gain values per chain and sub-band
+ * @reserved: reserved
+ */
+struct iwl_ppag_table_cmd {
+	__le32 enabled;
+	s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS];
+	s8 reserved[2];
+} __packed; /* PER_PLATFORM_ANT_GAIN_CMD */
+
 /**
  * struct iwl_beacon_filter_cmd
  * REPLY_BEACON_FILTERING_CMD = 0xd2 (command)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index 3d567240ef11..73cd41480c2f 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -446,6 +446,7 @@ enum iwl_ucode_tlv_capa {
 	IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS		= (__force iwl_ucode_tlv_capa_t)48,
 	IWL_UCODE_TLV_CAPA_CS_MODIFY			= (__force iwl_ucode_tlv_capa_t)49,
 	IWL_UCODE_TLV_CAPA_SET_LTR_GEN2			= (__force iwl_ucode_tlv_capa_t)50,
+	IWL_UCODE_TLV_CAPA_SET_PPAG			= (__force iwl_ucode_tlv_capa_t)52,
 
 	/* set 2 */
 	IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE		= (__force iwl_ucode_tlv_capa_t)64,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 6f7345b121a6..2bf5b83e116c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -1965,6 +1965,9 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
 	 */
 	iwl_mvm_update_changed_regdom(mvm);
 
+	/* Re-configure PPAG settings */
+	iwl_mvm_ppag_send_cmd(mvm);
+
 	if (!unified_image)
 		/*  Re-configure default SAR profile */
 		iwl_mvm_sar_select_profile(mvm, 1, 1);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 0f6925a51435..af46723f790f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -1002,6 +1002,113 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
 	return iwl_mvm_send_cmd_pdu(mvm, cmd_wide_id, 0, sizeof(cmd), &cmd);
 }
 
+static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm)
+{
+	union acpi_object *wifi_pkg, *data, *enabled;
+	int i, j, ret, tbl_rev;
+	int idx = 2;
+
+	mvm->ppag_table.enabled = cpu_to_le32(0);
+	data = iwl_acpi_get_object(mvm->dev, ACPI_PPAG_METHOD);
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data,
+					 ACPI_PPAG_WIFI_DATA_SIZE, &tbl_rev);
+
+	if (IS_ERR(wifi_pkg) || tbl_rev != 0) {
+		ret = PTR_ERR(wifi_pkg);
+		goto out_free;
+	}
+
+	enabled = &wifi_pkg->package.elements[1];
+	if (enabled->type != ACPI_TYPE_INTEGER ||
+	    (enabled->integer.value != 0 && enabled->integer.value != 1)) {
+		ret = -EINVAL;
+		goto out_free;
+	}
+
+	mvm->ppag_table.enabled = cpu_to_le32(enabled->integer.value);
+	if (!mvm->ppag_table.enabled) {
+		ret = 0;
+		goto out_free;
+	}
+
+	/*
+	 * read, verify gain values and save them into the PPAG table.
+	 * first sub-band (j=0) corresponds to Low-Band (2.4GHz), and the
+	 * following sub-bands to High-Band (5GHz).
+	 */
+	for (i = 0; i < ACPI_PPAG_NUM_CHAINS; i++) {
+		for (j = 0; j < ACPI_PPAG_NUM_SUB_BANDS; j++) {
+			union acpi_object *ent;
+
+			ent = &wifi_pkg->package.elements[idx++];
+			if (ent->type != ACPI_TYPE_INTEGER ||
+			    (j == 0 && ent->integer.value > ACPI_PPAG_MAX_LB) ||
+			    (j == 0 && ent->integer.value < ACPI_PPAG_MIN_LB) ||
+			    (j != 0 && ent->integer.value > ACPI_PPAG_MAX_HB) ||
+			    (j != 0 && ent->integer.value < ACPI_PPAG_MIN_HB)) {
+				mvm->ppag_table.enabled = cpu_to_le32(0);
+				ret = -EINVAL;
+				goto out_free;
+			}
+			mvm->ppag_table.gain[i][j] = ent->integer.value;
+		}
+	}
+	ret = 0;
+out_free:
+	kfree(data);
+	return ret;
+}
+
+int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm)
+{
+	int i, j, ret;
+
+	if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_PPAG)) {
+		IWL_DEBUG_RADIO(mvm,
+				"PPAG capability not supported by FW, command not sent.\n");
+		return 0;
+	}
+
+	IWL_DEBUG_RADIO(mvm, "Sending PER_PLATFORM_ANT_GAIN_CMD\n");
+	IWL_DEBUG_RADIO(mvm, "PPAG is %s\n",
+			mvm->ppag_table.enabled ? "enabled" : "disabled");
+
+	for (i = 0; i < ACPI_PPAG_NUM_CHAINS; i++) {
+		for (j = 0; j < ACPI_PPAG_NUM_SUB_BANDS; j++) {
+			IWL_DEBUG_RADIO(mvm,
+					"PPAG table: chain[%d] band[%d]: gain = %d\n",
+					i, j, mvm->ppag_table.gain[i][j]);
+		}
+	}
+
+	ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(PHY_OPS_GROUP,
+						PER_PLATFORM_ANT_GAIN_CMD),
+				   0, sizeof(mvm->ppag_table),
+				   &mvm->ppag_table);
+	if (ret < 0)
+		IWL_ERR(mvm, "failed to send PER_PLATFORM_ANT_GAIN_CMD (%d)\n",
+			ret);
+
+	return ret;
+}
+
+static int iwl_mvm_ppag_init(struct iwl_mvm *mvm)
+{
+	int ret;
+
+	ret = iwl_mvm_get_ppag_table(mvm);
+	if (ret < 0) {
+		IWL_DEBUG_RADIO(mvm,
+				"PPAG BIOS table invalid or unavailable. (%d)\n",
+				ret);
+		return 0;
+	}
+	return iwl_mvm_ppag_send_cmd(mvm);
+}
+
 #else /* CONFIG_ACPI */
 static int iwl_mvm_sar_get_wrds_table(struct iwl_mvm *mvm)
 {
@@ -1033,6 +1140,16 @@ int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
 {
 	return -ENOENT;
 }
+
+int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm)
+{
+	return -ENOENT;
+}
+
+static int iwl_mvm_ppag_init(struct iwl_mvm *mvm)
+{
+	return -ENOENT;
+}
 #endif /* CONFIG_ACPI */
 
 void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
@@ -1325,6 +1442,10 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
 	if (iwl_acpi_get_eckv(mvm->dev, &mvm->ext_clock_valid))
 		IWL_DEBUG_INFO(mvm, "ECKV table doesn't exist in BIOS\n");
 
+	ret = iwl_mvm_ppag_init(mvm);
+	if (ret)
+		goto error;
+
 	ret = iwl_mvm_sar_init(mvm);
 	if (ret == 0) {
 		ret = iwl_mvm_sar_geo_init(mvm);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 79bbdf8121cc..0ea0f72880af 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1136,6 +1136,8 @@ struct iwl_mvm {
 	struct iwl_mvm_sar_profile sar_profiles[ACPI_SAR_PROFILE_NUM];
 	struct iwl_mvm_geo_profile geo_profiles[ACPI_NUM_GEO_PROFILES];
 	u32 geo_rev;
+	struct iwl_ppag_table_cmd ppag_table;
+	u32 ppag_rev;
 #endif
 };
 
@@ -2050,6 +2052,7 @@ void iwl_mvm_event_frame_timeout_callback(struct iwl_mvm *mvm,
 
 int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b);
 int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm);
+int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm);
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw,
 			     struct ieee80211_vif *vif,
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 05/19] iwlwifi: api: fix FTM struct documentation
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
                   ` (3 preceding siblings ...)
  2019-08-31  9:48 ` [PATCH 04/19] iwlwifi: support per-platform antenna gain Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 06/19] iwlwifi: bump FW API to 50 for 22000 series Luca Coelho
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Johannes Berg <johannes.berg@intel.com>

The real name is struct iwl_tof_range_req_ext_cmd, fix that.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/api/location.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
index ec864c7b497f..7a0fe5adefa5 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
@@ -82,7 +82,7 @@ enum iwl_location_subcmd_ids {
 	TOF_RANGE_ABORT_CMD = 0x2,
 	/**
 	 * @TOF_RANGE_REQ_EXT_CMD: TOF extended ranging config,
-	 *	uses &struct iwl_tof_range_request_ext_cmd
+	 *	uses &struct iwl_tof_range_req_ext_cmd
 	 */
 	TOF_RANGE_REQ_EXT_CMD = 0x3,
 	/**
@@ -292,7 +292,7 @@ struct iwl_tof_responder_dyn_config_cmd {
 } __packed; /* TOF_RESPONDER_DYN_CONFIG_CMD_API_S_VER_2 */
 
 /**
- * struct iwl_tof_range_request_ext_cmd - extended range req for WLS
+ * struct iwl_tof_range_req_ext_cmd - extended range req for WLS
  * @tsf_timer_offset_msec: the recommended time offset (mSec) from the AP's TSF
  * @reserved: reserved
  * @min_delta_ftm: Minimal time between two consecutive measurements,
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 06/19] iwlwifi: bump FW API to 50 for 22000 series
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
                   ` (4 preceding siblings ...)
  2019-08-31  9:48 ` [PATCH 05/19] iwlwifi: api: fix FTM struct documentation Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 07/19] iwlwifi: remove duplicate FW string definitions Luca Coelho
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Luca Coelho <luciano.coelho@intel.com>

Start supporting API version 50 for 22000 series.

Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index f057835d2155..cd230b9b896b 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -56,7 +56,7 @@
 #include "iwl-config.h"
 
 /* Highest firmware API version supported */
-#define IWL_22000_UCODE_API_MAX	49
+#define IWL_22000_UCODE_API_MAX	50
 
 /* Lowest firmware API version supported */
 #define IWL_22000_UCODE_API_MIN	39
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 07/19] iwlwifi: remove duplicate FW string definitions
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
                   ` (5 preceding siblings ...)
  2019-08-31  9:48 ` [PATCH 06/19] iwlwifi: bump FW API to 50 for 22000 series Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 08/19] iwlwifi: dbg_ini: use function to check if ini dbg mode is on Luca Coelho
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Luca Coelho <luciano.coelho@intel.com>

The string we define as IWL_22000_HR_B_F0_FW_PRE is duplicate with
IWL_22000_QU_B_HR_B_FW_PRE.  Remove the former to avoid confusion.

Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index cd230b9b896b..af52a26bcaca 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -76,7 +76,6 @@
 #define IWL_22000_HR_FW_PRE		"iwlwifi-Qu-a0-hr-a0-"
 #define IWL_22000_HR_CDB_FW_PRE		"iwlwifi-QuIcp-z0-hrcdb-a0-"
 #define IWL_22000_HR_A_F0_FW_PRE	"iwlwifi-QuQnj-f0-hr-a0-"
-#define IWL_22000_HR_B_F0_FW_PRE	"iwlwifi-Qu-b0-hr-b0-"
 #define IWL_22000_QU_B_HR_B_FW_PRE	"iwlwifi-Qu-b0-hr-b0-"
 #define IWL_22000_HR_B_FW_PRE		"iwlwifi-QuQnj-b0-hr-b0-"
 #define IWL_22000_HR_A0_FW_PRE		"iwlwifi-QuQnj-a0-hr-a0-"
@@ -99,8 +98,6 @@
 	IWL_22000_JF_FW_PRE __stringify(api) ".ucode"
 #define IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(api) \
 	IWL_22000_HR_A_F0_FW_PRE __stringify(api) ".ucode"
-#define IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(api) \
-	IWL_22000_HR_B_F0_FW_PRE __stringify(api) ".ucode"
 #define IWL_22000_QU_B_HR_B_MODULE_FIRMWARE(api) \
 	IWL_22000_QU_B_HR_B_FW_PRE __stringify(api) ".ucode"
 #define IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(api)	\
@@ -639,7 +636,6 @@ const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0 = {
 MODULE_FIRMWARE(IWL_22000_HR_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL_22000_JF_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 08/19] iwlwifi: dbg_ini: use function to check if ini dbg mode is on
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
                   ` (6 preceding siblings ...)
  2019-08-31  9:48 ` [PATCH 07/19] iwlwifi: remove duplicate FW string definitions Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 09/19] iwlwifi: dbg_ini: verify debug TLVs at allocation phase Luca Coelho
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Shahar S Matityahu <shahar.s.matityahu@intel.com>

use iwl_trans_dbg_ini_valid function instead of a boolean value check if
dbg_ini mode is on. It is needed for a future patch.

Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c              | 4 ++--
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h              | 9 +++++----
 drivers/net/wireless/intel/iwlwifi/iwl-trans.h           | 5 +++++
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c              | 2 +-
 drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c | 2 +-
 drivers/net/wireless/intel/iwlwifi/pcie/internal.h       | 2 +-
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c          | 2 +-
 7 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index f52427ec60e9..3679ba89ea9d 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -2101,7 +2101,7 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
 	u32 trig_type = le32_to_cpu(desc->trig_desc.type);
 	int ret;
 
-	if (fwrt->trans->dbg.ini_valid) {
+	if (iwl_trans_dbg_ini_valid(fwrt->trans)) {
 		ret = iwl_fw_dbg_ini_collect(fwrt, trig_type);
 		if (!ret)
 			iwl_fw_free_dump_desc(fwrt);
@@ -2381,7 +2381,7 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx)
 	}
 
 	IWL_DEBUG_FW_INFO(fwrt, "WRT: data collection start\n");
-	if (fwrt->trans->dbg.ini_valid)
+	if (iwl_trans_dbg_ini_valid(fwrt->trans))
 		iwl_fw_error_ini_dump(fwrt, wk_idx);
 	else
 		iwl_fw_error_dump(fwrt);
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index 461331703ea6..8faea2571788 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -202,7 +202,7 @@ _iwl_fw_dbg_trigger_on(struct iwl_fw_runtime *fwrt,
 {
 	struct iwl_fw_dbg_trigger_tlv *trig;
 
-	if (fwrt->trans->dbg.ini_valid)
+	if (iwl_trans_dbg_ini_valid(fwrt->trans))
 		return NULL;
 
 	if (!iwl_fw_dbg_trigger_enabled(fwrt->fw, id))
@@ -229,8 +229,9 @@ iwl_fw_ini_trigger_on(struct iwl_fw_runtime *fwrt,
 	struct iwl_fw_ini_trigger *trig;
 	u32 usec;
 
-	if (!fwrt->trans->dbg.ini_valid || id == IWL_FW_TRIGGER_ID_INVALID ||
-	    id >= IWL_FW_TRIGGER_ID_NUM || !fwrt->dump.active_trigs[id].active)
+	if (!iwl_trans_dbg_ini_valid(fwrt->trans) ||
+	    id == IWL_FW_TRIGGER_ID_INVALID || id >= IWL_FW_TRIGGER_ID_NUM ||
+	    !fwrt->dump.active_trigs[id].active)
 		return false;
 
 	trig = fwrt->dump.active_trigs[id].trig;
@@ -394,7 +395,7 @@ static inline void iwl_fw_umac_set_alive_err_table(struct iwl_trans *trans,
 
 static inline void iwl_fw_error_collect(struct iwl_fw_runtime *fwrt)
 {
-	if (fwrt->trans->dbg.ini_valid && fwrt->trans->dbg.hw_error) {
+	if (iwl_trans_dbg_ini_valid(fwrt->trans) && fwrt->trans->dbg.hw_error) {
 		_iwl_fw_dbg_ini_collect(fwrt, IWL_FW_TRIGGER_ID_FW_HW_ERROR);
 		fwrt->trans->dbg.hw_error = false;
 	} else {
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index 0fa4b100f109..731ffb4a33af 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -1216,6 +1216,11 @@ static inline void iwl_trans_sync_nmi(struct iwl_trans *trans)
 		trans->ops->sync_nmi(trans);
 }
 
+static inline bool iwl_trans_dbg_ini_valid(struct iwl_trans *trans)
+{
+	return trans->dbg.ini_valid;
+}
+
 /*****************************************************
  * transport helper functions
  *****************************************************/
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index af46723f790f..d2baea22cba2 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -1304,7 +1304,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
 	if (ret)
 		IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
 
-	if (!mvm->trans->dbg.ini_valid) {
+	if (!iwl_trans_dbg_ini_valid(mvm->trans)) {
 		mvm->fwrt.dump.conf = FW_DBG_INVALID;
 		/* if we have a destination, assume EARLY START */
 		if (mvm->fw->dbg.dest_tlv)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
index 5e86783d616b..9b27c955b8dc 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
@@ -96,7 +96,7 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
 		cpu_to_le64(trans_pcie->rxq->bd_dma);
 
 	/* Configure debug, for integration */
-	if (!trans->dbg.ini_valid)
+	if (!iwl_trans_dbg_ini_valid(trans))
 		iwl_pcie_alloc_fw_monitor(trans, 0);
 	if (trans->dbg.num_blocks) {
 		prph_sc_ctrl->hwm_cfg.hwm_base_addr =
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index 95f78d8b4ae5..906e1da3923d 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -1044,7 +1044,7 @@ static inline void __iwl_trans_pcie_set_bit(struct iwl_trans *trans,
 
 static inline bool iwl_pcie_dbg_on(struct iwl_trans *trans)
 {
-	return (trans->dbg.dest_tlv || trans->dbg.ini_valid);
+	return (trans->dbg.dest_tlv || iwl_trans_dbg_ini_valid(trans));
 }
 
 void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 48a209708852..41ecd1ede04b 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -896,7 +896,7 @@ void iwl_pcie_apply_destination(struct iwl_trans *trans)
 	const struct iwl_fw_dbg_dest_tlv_v1 *dest = trans->dbg.dest_tlv;
 	int i;
 
-	if (trans->dbg.ini_valid) {
+	if (iwl_trans_dbg_ini_valid(trans)) {
 		if (!trans->dbg.num_blocks)
 			return;
 
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 09/19] iwlwifi: dbg_ini: verify debug TLVs at allocation phase
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
                   ` (7 preceding siblings ...)
  2019-08-31  9:48 ` [PATCH 08/19] iwlwifi: dbg_ini: use function to check if ini dbg mode is on Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 10/19] iwlwifi: dbg_ini: remove debug flow TLV Luca Coelho
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Shahar S Matityahu <shahar.s.matityahu@intel.com>

Reimplement debug TLV allocation flow. The driver will check the
validity of the debug TLVs prior allocating space for them.
Any malformed or unsupported TLV will be skipped.
The TLV specific checks will be added in later patches.

Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   |  15 +-
 .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c  | 151 +++++++++++++-----
 .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h  |   4 +-
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c  |   2 +-
 .../net/wireless/intel/iwlwifi/iwl-trans.h    |  24 ++-
 5 files changed, 139 insertions(+), 57 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 3679ba89ea9d..6e5a3289e04a 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -1739,7 +1739,7 @@ static void iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,
 	dump->version = cpu_to_le32(IWL_INI_DUMP_VER);
 	dump->trigger_id = trigger->trigger_id;
 	dump->is_external_cfg =
-		cpu_to_le32(fwrt->trans->dbg.external_ini_loaded);
+		cpu_to_le32(fwrt->trans->dbg.external_ini_cfg);
 
 	dump->ver_type = cpu_to_le32(fwrt->dump.fw_ver.type);
 	dump->ver_subtype = cpu_to_le32(fwrt->dump.fw_ver.subtype);
@@ -2855,17 +2855,22 @@ static void iwl_fw_dbg_ini_reset_cfg(struct iwl_fw_runtime *fwrt)
 void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
 			    enum iwl_fw_ini_apply_point apply_point)
 {
-	void *data = &fwrt->trans->dbg.apply_points[apply_point];
+	void *data;
 
 	IWL_DEBUG_FW(fwrt, "WRT: enabling apply point %d\n", apply_point);
 
 	if (apply_point == IWL_FW_INI_APPLY_EARLY)
 		iwl_fw_dbg_ini_reset_cfg(fwrt);
 
-	_iwl_fw_dbg_apply_point(fwrt, data, apply_point, false);
+	if (fwrt->trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) {
+		data = &fwrt->trans->dbg.apply_points[apply_point];
+		_iwl_fw_dbg_apply_point(fwrt, data, apply_point, false);
+	}
 
-	data = &fwrt->trans->dbg.apply_points_ext[apply_point];
-	_iwl_fw_dbg_apply_point(fwrt, data, apply_point, true);
+	if (fwrt->trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) {
+		data = &fwrt->trans->dbg.apply_points_ext[apply_point];
+		_iwl_fw_dbg_apply_point(fwrt, data, apply_point, true);
+	}
 }
 IWL_EXPORT_SYMBOL(iwl_fw_dbg_apply_point);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
index 7c1e76ee7ede..5b1644a70ace 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
@@ -63,46 +63,124 @@
 #include "iwl-trans.h"
 #include "iwl-dbg-tlv.h"
 
-void iwl_dbg_tlv_copy(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
-		      bool ext)
+/**
+ * enum iwl_dbg_tlv_type - debug TLV types
+ * @IWL_DBG_TLV_TYPE_DEBUG_INFO: debug info TLV
+ * @IWL_DBG_TLV_TYPE_BUF_ALLOC: buffer allocation TLV
+ * @IWL_DBG_TLV_TYPE_HCMD: host command TLV
+ * @IWL_DBG_TLV_TYPE_REGION: region TLV
+ * @IWL_DBG_TLV_TYPE_TRIGGER: trigger TLV
+ * @IWL_DBG_TLV_TYPE_NUM: number of debug TLVs
+ */
+enum iwl_dbg_tlv_type {
+	IWL_DBG_TLV_TYPE_DEBUG_INFO =
+		IWL_UCODE_TLV_TYPE_DEBUG_INFO - IWL_UCODE_TLV_DEBUG_BASE,
+	IWL_DBG_TLV_TYPE_BUF_ALLOC,
+	IWL_DBG_TLV_TYPE_HCMD,
+	IWL_DBG_TLV_TYPE_REGION,
+	IWL_DBG_TLV_TYPE_TRIGGER,
+	IWL_DBG_TLV_TYPE_NUM,
+};
+
+/**
+ * struct iwl_dbg_tlv_ver_data -  debug TLV version struct
+ * @min_ver: min version supported
+ * @max_ver: max version supported
+ */
+struct iwl_dbg_tlv_ver_data {
+	int min_ver;
+	int max_ver;
+};
+
+static const struct iwl_dbg_tlv_ver_data
+dbg_ver_table[IWL_DBG_TLV_TYPE_NUM] = {
+	[IWL_DBG_TLV_TYPE_DEBUG_INFO]	= {.min_ver = 1, .max_ver = 1,},
+	[IWL_DBG_TLV_TYPE_BUF_ALLOC]	= {.min_ver = 1, .max_ver = 1,},
+	[IWL_DBG_TLV_TYPE_HCMD]		= {.min_ver = 1, .max_ver = 1,},
+	[IWL_DBG_TLV_TYPE_REGION]	= {.min_ver = 1, .max_ver = 1,},
+	[IWL_DBG_TLV_TYPE_TRIGGER]	= {.min_ver = 1, .max_ver = 1,},
+};
+
+static int iwl_dbg_tlv_copy(struct iwl_ucode_tlv *tlv, struct list_head *list)
 {
-	struct iwl_apply_point_data *dbg_cfg, *tlv_copy;
-	struct iwl_fw_ini_header *header = (void *)&tlv->data[0];
-	u32 tlv_type = le32_to_cpu(tlv->type);
+	struct iwl_apply_point_data *tlv_copy;
 	u32 len = le32_to_cpu(tlv->length);
-	u32 apply_point = le32_to_cpu(header->apply_point);
 
-	if (le32_to_cpu(header->tlv_version) != 1)
-		return;
+	tlv_copy = kzalloc(sizeof(*tlv_copy) + len, GFP_KERNEL);
+	if (!tlv_copy)
+		return -ENOMEM;
 
-	if (WARN_ONCE(apply_point >= IWL_FW_INI_APPLY_NUM,
-		      "Invalid apply point %d\n", apply_point))
-		return;
+	INIT_LIST_HEAD(&tlv_copy->list);
+	memcpy(&tlv_copy->tlv, tlv, sizeof(*tlv) + len);
+
+	if (!list->next)
+		INIT_LIST_HEAD(list);
+
+	list_add_tail(&tlv_copy->list, list);
+
+	return 0;
+}
+
+static bool iwl_dbg_tlv_ver_support(struct iwl_ucode_tlv *tlv)
+{
+	struct iwl_fw_ini_header *hdr = (void *)&tlv->data[0];
+	u32 type = le32_to_cpu(tlv->type);
+	u32 tlv_idx = type - IWL_UCODE_TLV_DEBUG_BASE;
+	u32 ver = le32_to_cpu(hdr->tlv_version);
+
+	if (ver < dbg_ver_table[tlv_idx].min_ver ||
+	    ver > dbg_ver_table[tlv_idx].max_ver)
+		return false;
+
+	return true;
+}
+
+void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
+		       bool ext)
+{
+	struct iwl_fw_ini_header *hdr = (void *)&tlv->data[0];
+	u32 type = le32_to_cpu(tlv->type);
+	u32 pnt = le32_to_cpu(hdr->apply_point);
+	u32 tlv_idx = type - IWL_UCODE_TLV_DEBUG_BASE;
+	enum iwl_ini_cfg_state *cfg_state = ext ?
+		&trans->dbg.external_ini_cfg : &trans->dbg.internal_ini_cfg;
+	struct list_head *dbg_cfg_list = ext ?
+		&trans->dbg.apply_points_ext[pnt].list :
+		&trans->dbg.apply_points[pnt].list;
 
 	IWL_DEBUG_FW(trans, "WRT: read TLV 0x%x, apply point %d\n",
-		     tlv_type, apply_point);
+		     type, pnt);
 
-	if (ext)
-		dbg_cfg = &trans->dbg.apply_points_ext[apply_point];
-	else
-		dbg_cfg = &trans->dbg.apply_points[apply_point];
+	if (tlv_idx >= IWL_DBG_TLV_TYPE_NUM) {
+		IWL_ERR(trans, "WRT: Unsupported TLV 0x%x\n", type);
+		goto out_err;
+	}
 
-	tlv_copy = kzalloc(sizeof(*tlv_copy) + len, GFP_KERNEL);
-	if (!tlv_copy) {
-		IWL_ERR(trans, "WRT: No memory for TLV 0x%x, apply point %d\n",
-			tlv_type, apply_point);
-		return;
+	if (pnt >= IWL_FW_INI_APPLY_NUM) {
+		IWL_ERR(trans, "WRT: Invalid apply point %d\n", pnt);
+		goto out_err;
 	}
 
-	INIT_LIST_HEAD(&tlv_copy->list);
-	memcpy(&tlv_copy->tlv, tlv, sizeof(*tlv) + len);
+	if (!iwl_dbg_tlv_ver_support(tlv)) {
+		IWL_ERR(trans, "WRT: Unsupported TLV 0x%x version %u\n", type,
+			le32_to_cpu(hdr->tlv_version));
+		goto out_err;
+	}
 
-	if (!dbg_cfg->list.next)
-		INIT_LIST_HEAD(&dbg_cfg->list);
+	if (iwl_dbg_tlv_copy(tlv, dbg_cfg_list)) {
+		IWL_ERR(trans,
+			"WRT: Failed to allocate TLV 0x%x, apply point %d\n",
+			type, pnt);
+		goto out_err;
+	}
+
+	if (*cfg_state == IWL_INI_CFG_STATE_NOT_LOADED)
+		*cfg_state = IWL_INI_CFG_STATE_LOADED;
 
-	list_add_tail(&tlv_copy->list, &dbg_cfg->list);
+	return;
 
-	trans->dbg.ini_valid = true;
+out_err:
+	*cfg_state = IWL_INI_CFG_STATE_CORRUPTED;
 }
 
 static void iwl_dbg_tlv_free_list(struct list_head *list)
@@ -138,7 +216,6 @@ static int iwl_dbg_tlv_parse_bin(struct iwl_trans *trans, const u8 *data,
 				 size_t len)
 {
 	struct iwl_ucode_tlv *tlv;
-	enum iwl_ucode_tlv_type tlv_type;
 	u32 tlv_len;
 
 	while (len >= sizeof(*tlv)) {
@@ -146,7 +223,6 @@ static int iwl_dbg_tlv_parse_bin(struct iwl_trans *trans, const u8 *data,
 		tlv = (void *)data;
 
 		tlv_len = le32_to_cpu(tlv->length);
-		tlv_type = le32_to_cpu(tlv->type);
 
 		if (len < tlv_len) {
 			IWL_ERR(trans, "invalid TLV len: %zd/%u\n",
@@ -156,19 +232,7 @@ static int iwl_dbg_tlv_parse_bin(struct iwl_trans *trans, const u8 *data,
 		len -= ALIGN(tlv_len, 4);
 		data += sizeof(*tlv) + ALIGN(tlv_len, 4);
 
-		switch (tlv_type) {
-		case IWL_UCODE_TLV_TYPE_DEBUG_INFO:
-		case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION:
-		case IWL_UCODE_TLV_TYPE_HCMD:
-		case IWL_UCODE_TLV_TYPE_REGIONS:
-		case IWL_UCODE_TLV_TYPE_TRIGGERS:
-		case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
-			iwl_dbg_tlv_copy(trans, tlv, true);
-			break;
-		default:
-			WARN_ONCE(1, "Invalid TLV %x\n", tlv_type);
-			break;
-		}
+		iwl_dbg_tlv_alloc(trans, tlv, true);
 	}
 
 	return 0;
@@ -179,7 +243,7 @@ void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans)
 	const struct firmware *fw;
 	int res;
 
-	if (trans->dbg.external_ini_loaded || !iwlwifi_mod_params.enable_ini)
+	if (!iwlwifi_mod_params.enable_ini)
 		return;
 
 	res = request_firmware(&fw, "iwl-dbg-tlv.ini", dev);
@@ -188,6 +252,5 @@ void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans)
 
 	iwl_dbg_tlv_parse_bin(trans, fw->data, fw->size);
 
-	trans->dbg.external_ini_loaded = true;
 	release_firmware(fw);
 }
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
index 72552de801d4..3a60590d274d 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
@@ -77,7 +77,7 @@ struct iwl_apply_point_data {
 struct iwl_trans;
 void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans);
 void iwl_dbg_tlv_free(struct iwl_trans *trans);
-void iwl_dbg_tlv_copy(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
-		      bool ext);
+void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
+		       bool ext);
 
 #endif /* __iwl_dbg_tlv_h__*/
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 3792b421746e..1351f7fe5ae2 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -1153,7 +1153,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
 		case IWL_UCODE_TLV_TYPE_TRIGGERS:
 		case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
 			if (iwlwifi_mod_params.enable_ini)
-				iwl_dbg_tlv_copy(drv->trans, tlv, false);
+				iwl_dbg_tlv_alloc(drv->trans, tlv, false);
 			break;
 		case IWL_UCODE_TLV_CMD_VERSIONS:
 			if (tlv_len % sizeof(struct iwl_fw_cmd_version)) {
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index 731ffb4a33af..09ed0dd163eb 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -650,6 +650,19 @@ enum iwl_plat_pm_mode {
 	IWL_PLAT_PM_MODE_D3,
 };
 
+/**
+ * enum iwl_ini_cfg_state
+ * @IWL_INI_CFG_STATE_NOT_LOADED: no debug cfg was given
+ * @IWL_INI_CFG_STATE_LOADED: debug cfg was found and loaded
+ * @IWL_INI_CFG_STATE_CORRUPTED: debug cfg was found and some of the TLVs
+ *	are corrupted. The rest of the debug TLVs will still be used
+ */
+enum iwl_ini_cfg_state {
+	IWL_INI_CFG_STATE_NOT_LOADED,
+	IWL_INI_CFG_STATE_LOADED,
+	IWL_INI_CFG_STATE_CORRUPTED,
+};
+
 /* Max time to wait for nmi interrupt */
 #define IWL_TRANS_NMI_TIMEOUT (HZ / 4)
 
@@ -691,8 +704,8 @@ struct iwl_self_init_dram {
  * @umac_error_event_table: addr of umac error table
  * @error_event_table_tlv_status: bitmap that indicates what error table
  *	pointers was recevied via TLV. uses enum &iwl_error_event_table_status
- * @external_ini_loaded: indicates if an external ini cfg was given
- * @ini_valid: indicates if debug ini mode is on
+ * @internal_ini_cfg: internal debug cfg state. Uses &enum iwl_ini_cfg_state
+ * @external_ini_cfg: external debug cfg state. Uses &enum iwl_ini_cfg_state
  * @num_blocks: number of blocks in fw_mon
  * @fw_mon: address of the buffers for firmware monitor
  * @is_alloc: bit i is set if buffer i was allocated
@@ -711,8 +724,8 @@ struct iwl_trans_debug {
 	u32 umac_error_event_table;
 	unsigned int error_event_table_tlv_status;
 
-	bool external_ini_loaded;
-	bool ini_valid;
+	enum iwl_ini_cfg_state internal_ini_cfg;
+	enum iwl_ini_cfg_state external_ini_cfg;
 
 	struct iwl_apply_point_data apply_points[IWL_FW_INI_APPLY_NUM];
 	struct iwl_apply_point_data apply_points_ext[IWL_FW_INI_APPLY_NUM];
@@ -1218,7 +1231,8 @@ static inline void iwl_trans_sync_nmi(struct iwl_trans *trans)
 
 static inline bool iwl_trans_dbg_ini_valid(struct iwl_trans *trans)
 {
-	return trans->dbg.ini_valid;
+	return trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED ||
+		trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED;
 }
 
 /*****************************************************
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 10/19] iwlwifi: dbg_ini: remove debug flow TLV
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
                   ` (8 preceding siblings ...)
  2019-08-31  9:48 ` [PATCH 09/19] iwlwifi: dbg_ini: verify debug TLVs at allocation phase Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 11/19] iwlwifi: dbg: align wrt log prints to the same format Luca Coelho
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Shahar S Matityahu <shahar.s.matityahu@intel.com>

Debug flow TLV was removed from the FW. Remove the TLV from the driver
as well.

Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h | 11 -----------
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c         |  2 --
 drivers/net/wireless/intel/iwlwifi/fw/file.h        |  3 +--
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c        |  1 -
 4 files changed, 1 insertion(+), 16 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
index e02e289d29b1..798e61d4d683 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
@@ -140,17 +140,6 @@ struct iwl_fw_ini_hcmd_tlv {
 	struct iwl_fw_ini_hcmd hcmd;
 } __packed; /* FW_DEBUG_TLV_HCMD_API_S_VER_1 */
 
-/**
- * struct iwl_fw_ini_debug_flow_tlv - (IWL_UCODE_TLV_TYPE_DEBUG_FLOW)
- *
- * @header: header
- * @debug_flow_cfg: &enum iwl_fw_ini_debug_flow
- */
-struct iwl_fw_ini_debug_flow_tlv {
-	struct iwl_fw_ini_header header;
-	__le32 debug_flow_cfg;
-} __packed; /* FW_DEBUG_TLV_FLOW_TLV_S_VER_1 */
-
 #define IWL_FW_INI_MAX_REGION_ID	64
 #define IWL_FW_INI_MAX_NAME		32
 
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 6e5a3289e04a..2d37628694d2 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -2820,8 +2820,6 @@ static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
 		case IWL_UCODE_TLV_TYPE_TRIGGERS:
 			iwl_fw_dbg_update_triggers(fwrt, ini_tlv, ext, pnt);
 			break;
-		case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
-			break;
 		default:
 			WARN_ONCE(1,
 				  "WRT: ext=%d. Invalid TLV 0x%x for apply point\n",
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index 73cd41480c2f..00db39427be7 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -157,8 +157,7 @@ enum iwl_ucode_tlv_type {
 	IWL_UCODE_TLV_TYPE_HCMD			= IWL_UCODE_TLV_DEBUG_BASE + 2,
 	IWL_UCODE_TLV_TYPE_REGIONS		= IWL_UCODE_TLV_DEBUG_BASE + 3,
 	IWL_UCODE_TLV_TYPE_TRIGGERS		= IWL_UCODE_TLV_DEBUG_BASE + 4,
-	IWL_UCODE_TLV_TYPE_DEBUG_FLOW		= IWL_UCODE_TLV_DEBUG_BASE + 5,
-	IWL_UCODE_TLV_DEBUG_MAX = IWL_UCODE_TLV_TYPE_DEBUG_FLOW,
+	IWL_UCODE_TLV_DEBUG_MAX = IWL_UCODE_TLV_TYPE_TRIGGERS,
 
 	/* TLVs 0x1000-0x2000 are for internal driver usage */
 	IWL_UCODE_TLV_FW_DBG_DUMP_LST	= 0x1000,
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 1351f7fe5ae2..ae61ad129f06 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -1151,7 +1151,6 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
 		case IWL_UCODE_TLV_TYPE_HCMD:
 		case IWL_UCODE_TLV_TYPE_REGIONS:
 		case IWL_UCODE_TLV_TYPE_TRIGGERS:
-		case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
 			if (iwlwifi_mod_params.enable_ini)
 				iwl_dbg_tlv_alloc(drv->trans, tlv, false);
 			break;
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 11/19] iwlwifi: dbg: align wrt log prints to the same format
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
                   ` (9 preceding siblings ...)
  2019-08-31  9:48 ` [PATCH 10/19] iwlwifi: dbg_ini: remove debug flow TLV Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 12/19] iwlwifi: remove unnecessary IWL_DEVICE_AX200_COMMON definition Luca Coelho
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Shahar S Matityahu <shahar.s.matityahu@intel.com>

Align wrt log prints to the driver coding style
Remove the ext field from the log and print it at the beginning of the
apply point.

Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   | 87 +++++++++----------
 .../net/wireless/intel/iwlwifi/pcie/trans.c   |  2 +-
 2 files changed, 42 insertions(+), 47 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 2d37628694d2..2a4c2e772d1b 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -1688,7 +1688,7 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
 	if (!size)
 		return;
 
-	IWL_DEBUG_FW(fwrt, "WRT: collecting region: id=%d, type=%d\n",
+	IWL_DEBUG_FW(fwrt, "WRT: Collecting region: id=%d, type=%d\n",
 		     le32_to_cpu(reg->region_id), type);
 
 	num_of_ranges = ops->get_num_of_ranges(fwrt, reg);
@@ -1705,7 +1705,7 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
 	range = ops->fill_mem_hdr(fwrt, reg, header);
 	if (!range) {
 		IWL_ERR(fwrt,
-			"WRT: failed to fill region header: id=%d, type=%d\n",
+			"WRT: Failed to fill region header: id=%d, type=%d\n",
 			le32_to_cpu(reg->region_id), type);
 		memset(*data, 0, size);
 		return;
@@ -1716,7 +1716,7 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
 
 		if (range_size < 0) {
 			IWL_ERR(fwrt,
-				"WRT: failed to dump region: id=%d, type=%d\n",
+				"WRT: Failed to dump region: id=%d, type=%d\n",
 				le32_to_cpu(reg->region_id), type);
 			memset(*data, 0, size);
 			return;
@@ -1805,7 +1805,7 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
 		reg = fwrt->dump.active_regs[reg_id];
 		if (!reg) {
 			IWL_WARN(fwrt,
-				 "WRT: unassigned region id %d, skipping\n",
+				 "WRT: Unassigned region id %d, skipping\n",
 				 reg_id);
 			continue;
 		}
@@ -2223,7 +2223,7 @@ int _iwl_fw_dbg_ini_collect(struct iwl_fw_runtime *fwrt,
 	active->trig->occurrences = cpu_to_le32(--occur);
 
 	if (le32_to_cpu(active->trig->force_restart)) {
-		IWL_WARN(fwrt, "WRT: force restart: trigger %d fired.\n", id);
+		IWL_WARN(fwrt, "WRT: Force restart: trigger %d fired.\n", id);
 		iwl_force_nmi(fwrt->trans);
 		return 0;
 	}
@@ -2243,7 +2243,7 @@ int _iwl_fw_dbg_ini_collect(struct iwl_fw_runtime *fwrt,
 
 	fwrt->dump.wks[idx].ini_trig_id = id;
 
-	IWL_WARN(fwrt, "WRT: collecting data: ini trigger %d fired.\n", id);
+	IWL_WARN(fwrt, "WRT: Collecting data: ini trigger %d fired.\n", id);
 
 	schedule_delayed_work(&fwrt->dump.wks[idx].wk, usecs_to_jiffies(delay));
 
@@ -2380,12 +2380,12 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx)
 		goto out;
 	}
 
-	IWL_DEBUG_FW_INFO(fwrt, "WRT: data collection start\n");
+	IWL_DEBUG_FW_INFO(fwrt, "WRT: Data collection start\n");
 	if (iwl_trans_dbg_ini_valid(fwrt->trans))
 		iwl_fw_error_ini_dump(fwrt, wk_idx);
 	else
 		iwl_fw_error_dump(fwrt);
-	IWL_DEBUG_FW_INFO(fwrt, "WRT: data collection done\n");
+	IWL_DEBUG_FW_INFO(fwrt, "WRT: Data collection done\n");
 
 	iwl_fw_dbg_stop_restart_recording(fwrt, &params, false);
 
@@ -2538,7 +2538,7 @@ static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt,
 	}
 
 	if (buf_location == IWL_FW_INI_LOCATION_SRAM_PATH) {
-		IWL_DEBUG_FW(trans, "WRT: applying SMEM buffer destination\n");
+		IWL_DEBUG_FW(trans, "WRT: Applying SMEM buffer destination\n");
 		/* set sram monitor by enabling bit 7 */
 		iwl_set_bit(fwrt->trans, CSR_HW_IF_CONFIG_REG,
 			    CSR_HW_IF_CONFIG_REG_BIT_MONITOR_SRAM);
@@ -2561,7 +2561,7 @@ static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt,
 		return;
 
 	IWL_DEBUG_FW(trans,
-		     "WRT: applying DRAM buffer[%d] destination\n", block_idx);
+		     "WRT: Applying DRAM buffer[%d] destination\n", block_idx);
 
 	cmd->num_frags = cpu_to_le32(1);
 	cmd->fragments[0].address =
@@ -2574,8 +2574,7 @@ static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt,
 }
 
 static void iwl_fw_dbg_send_hcmd(struct iwl_fw_runtime *fwrt,
-				 struct iwl_ucode_tlv *tlv,
-				 bool ext)
+				 struct iwl_ucode_tlv *tlv)
 {
 	struct iwl_fw_ini_hcmd_tlv *hcmd_tlv = (void *)&tlv->data[0];
 	struct iwl_fw_ini_hcmd *data = &hcmd_tlv->hcmd;
@@ -2591,45 +2590,41 @@ static void iwl_fw_dbg_send_hcmd(struct iwl_fw_runtime *fwrt,
 	if (le32_to_cpu(hcmd_tlv->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON)
 		return;
 
-	IWL_DEBUG_FW(fwrt,
-		     "WRT: ext=%d. Sending host command id=0x%x, group=0x%x\n",
-		     ext, data->id, data->group);
+	IWL_DEBUG_FW(fwrt, "WRT: Sending host command id=0x%x, group=0x%x\n",
+		     data->id, data->group);
 
 	iwl_trans_send_cmd(fwrt->trans, &hcmd);
 }
 
 static void iwl_fw_dbg_update_regions(struct iwl_fw_runtime *fwrt,
 				      struct iwl_fw_ini_region_tlv *tlv,
-				      bool ext, enum iwl_fw_ini_apply_point pnt)
+				      enum iwl_fw_ini_apply_point pnt)
 {
 	void *iter = (void *)tlv->region_config;
 	int i, size = le32_to_cpu(tlv->num_regions);
 	const char *err_st =
-		"WRT: ext=%d. Invalid region %s %d for apply point %d\n";
+		"WRT: Invalid region %s %d for apply point %d\n";
 
 	for (i = 0; i < size; i++) {
 		struct iwl_fw_ini_region_cfg *reg = iter, **active;
 		int id = le32_to_cpu(reg->region_id);
 		u32 type = le32_to_cpu(reg->region_type);
 
-		if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_regs), err_st, ext,
-			 "id", id, pnt))
+		if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_regs), err_st, "id",
+			 id, pnt))
 			break;
 
 		if (WARN(type == 0 || type >= IWL_FW_INI_REGION_NUM, err_st,
-			 ext, "type", type, pnt))
+			 "type", type, pnt))
 			break;
 
 		active = &fwrt->dump.active_regs[id];
 
 		if (*active)
-			IWL_WARN(fwrt->trans,
-				 "WRT: ext=%d. Region id %d override\n",
-				 ext, id);
+			IWL_WARN(fwrt->trans, "WRT: Region id %d override\n",
+				 id);
 
-		IWL_DEBUG_FW(fwrt,
-			     "WRT: ext=%d. Activating region id %d\n",
-			     ext, id);
+		IWL_DEBUG_FW(fwrt, "WRT: Activating region id %d\n", id);
 
 		*active = reg;
 
@@ -2676,7 +2671,6 @@ static int iwl_fw_dbg_trig_realloc(struct iwl_fw_runtime *fwrt,
 
 static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt,
 				       struct iwl_fw_ini_trigger_tlv *tlv,
-				       bool ext,
 				       enum iwl_fw_ini_apply_point apply_point)
 {
 	int i, size = le32_to_cpu(tlv->num_triggers);
@@ -2690,8 +2684,8 @@ static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt,
 			sizeof(__le32);
 
 		if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_trigs),
-			 "WRT: ext=%d. Invalid trigger id %d for apply point %d\n",
-			 ext, id, apply_point))
+			 "WRT: Invalid trigger id %d for apply point %d\n", id,
+			 apply_point))
 			break;
 
 		active = &fwrt->dump.active_trigs[id];
@@ -2699,9 +2693,7 @@ static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt,
 		if (!active->active) {
 			size_t trig_size = sizeof(*trig) + trig_regs_size;
 
-			IWL_DEBUG_FW(fwrt,
-				     "WRT: ext=%d. Activating trigger %d\n",
-				     ext, id);
+			IWL_DEBUG_FW(fwrt, "WRT: Activating trigger %d\n", id);
 
 			if (iwl_fw_dbg_trig_realloc(fwrt, active, id,
 						    trig_size))
@@ -2722,14 +2714,14 @@ static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt,
 
 			if (region_override) {
 				IWL_DEBUG_FW(fwrt,
-					     "WRT: ext=%d. Trigger %d regions override\n",
-					     ext, id);
+					     "WRT: Trigger %d regions override\n",
+					     id);
 
 				mem_to_add -= active_regs * sizeof(__le32);
 			} else {
 				IWL_DEBUG_FW(fwrt,
-					     "WRT: ext=%d. Trigger %d regions appending\n",
-					     ext, id);
+					     "WRT: Trigger %d regions appending\n",
+					     id);
 
 				offset += active_regs;
 				new_regs += active_regs;
@@ -2741,8 +2733,8 @@ static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt,
 
 			if (conf_override) {
 				IWL_DEBUG_FW(fwrt,
-					     "WRT: ext=%d. Trigger %d configuration override\n",
-					     ext, id);
+					     "WRT: Trigger %d configuration override\n",
+					     id);
 
 				memcpy(active->trig, trig, sizeof(*trig));
 			}
@@ -2812,18 +2804,17 @@ static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
 					ext, pnt);
 				break;
 			}
-			iwl_fw_dbg_send_hcmd(fwrt, tlv, ext);
+			iwl_fw_dbg_send_hcmd(fwrt, tlv);
 			break;
 		case IWL_UCODE_TLV_TYPE_REGIONS:
-			iwl_fw_dbg_update_regions(fwrt, ini_tlv, ext, pnt);
+			iwl_fw_dbg_update_regions(fwrt, ini_tlv, pnt);
 			break;
 		case IWL_UCODE_TLV_TYPE_TRIGGERS:
-			iwl_fw_dbg_update_triggers(fwrt, ini_tlv, ext, pnt);
+			iwl_fw_dbg_update_triggers(fwrt, ini_tlv, pnt);
 			break;
 		default:
-			WARN_ONCE(1,
-				  "WRT: ext=%d. Invalid TLV 0x%x for apply point\n",
-				  ext, type);
+			WARN_ONCE(1, "WRT: Invalid TLV 0x%x for apply point\n",
+				  type);
 			break;
 		}
 	}
@@ -2855,17 +2846,21 @@ void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
 {
 	void *data;
 
-	IWL_DEBUG_FW(fwrt, "WRT: enabling apply point %d\n", apply_point);
-
 	if (apply_point == IWL_FW_INI_APPLY_EARLY)
 		iwl_fw_dbg_ini_reset_cfg(fwrt);
 
 	if (fwrt->trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) {
+		IWL_DEBUG_FW(fwrt,
+			     "WRT: Enabling internal configuration apply point %d\n",
+			     apply_point);
 		data = &fwrt->trans->dbg.apply_points[apply_point];
 		_iwl_fw_dbg_apply_point(fwrt, data, apply_point, false);
 	}
 
 	if (fwrt->trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) {
+		IWL_DEBUG_FW(fwrt,
+			     "WRT: Enabling external configuration apply point %d\n",
+			     apply_point);
 		data = &fwrt->trans->dbg.apply_points_ext[apply_point];
 		_iwl_fw_dbg_apply_point(fwrt, data, apply_point, true);
 	}
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 41ecd1ede04b..90b3e26ee979 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -901,7 +901,7 @@ void iwl_pcie_apply_destination(struct iwl_trans *trans)
 			return;
 
 		IWL_DEBUG_FW(trans,
-			     "WRT: applying DRAM buffer[0] destination\n");
+			     "WRT: Applying DRAM buffer[0] destination\n");
 		iwl_write_umac_prph(trans, MON_BUFF_BASE_ADDR_VER2,
 				    trans->dbg.fw_mon[0].physical >>
 				    MON_BUFF_SHIFT_VER2);
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 12/19] iwlwifi: remove unnecessary IWL_DEVICE_AX200_COMMON definition
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
                   ` (10 preceding siblings ...)
  2019-08-31  9:48 ` [PATCH 11/19] iwlwifi: dbg: align wrt log prints to the same format Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 13/19] iwlwifi: allocate bigger nvm data in case of UHB Luca Coelho
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Luca Coelho <luciano.coelho@intel.com>

Remove the IWL_DEVICE_AX200_COMMON definition, since it's only used
once and relies mostly on IWL_DEVICE_22000_COMMON anyway.

Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index af52a26bcaca..894c1e4cc582 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -188,10 +188,6 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
 	.fw_mon_smem_cycle_cnt_ptr_addr = 0xa0c174,			\
 	.fw_mon_smem_cycle_cnt_ptr_msk = 0xfffff
 
-#define IWL_DEVICE_AX200_COMMON						\
-	IWL_DEVICE_22000_COMMON,					\
-	.umac_prph_offset = 0x300000
-
 #define IWL_DEVICE_22500						\
 	IWL_DEVICE_22000_COMMON,					\
 	.device_family = IWL_DEVICE_FAMILY_22000,			\
@@ -206,7 +202,8 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
 	.csr = &iwl_csr_v2
 
 #define IWL_DEVICE_AX210						\
-	IWL_DEVICE_AX200_COMMON,					\
+	IWL_DEVICE_22000_COMMON,					\
+	.umac_prph_offset = 0x300000,					\
 	.device_family = IWL_DEVICE_FAMILY_AX210,			\
 	.base_params = &iwl_22560_base_params,				\
 	.csr = &iwl_csr_v1,						\
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 13/19] iwlwifi: allocate bigger nvm data in case of UHB
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
                   ` (11 preceding siblings ...)
  2019-08-31  9:48 ` [PATCH 12/19] iwlwifi: remove unnecessary IWL_DEVICE_AX200_COMMON definition Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 14/19] iwlwifi: mvm: look for the first supported channel when add/remove phy ctxt Luca Coelho
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Tova Mussai <tova.mussai@intel.com>

In case of Ultra-high-band (UHB), need to allocate nvm data structure in
size of UHB channels array.

Signed-off-by: Tova Mussai <tova.mussai@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index fd386bfbd5df..6d95941f56a7 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -942,7 +942,11 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
 	u16 lar_config;
 	const __le16 *ch_section;
 
-	if (cfg->nvm_type != IWL_NVM_EXT)
+	if (cfg->uhb_supported)
+		data = kzalloc(struct_size(data, channels,
+					   IWL_NVM_NUM_CHANNELS_UHB),
+					   GFP_KERNEL);
+	else if (cfg->nvm_type != IWL_NVM_EXT)
 		data = kzalloc(struct_size(data, channels,
 					   IWL_NVM_NUM_CHANNELS),
 					   GFP_KERNEL);
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 14/19] iwlwifi: mvm: look for the first supported channel when add/remove phy ctxt
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
                   ` (12 preceding siblings ...)
  2019-08-31  9:48 ` [PATCH 13/19] iwlwifi: allocate bigger nvm data in case of UHB Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 15/19] iwlwifi: dbg_ini: separate cfg and dump flows to different modules Luca Coelho
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Tova Mussai <tova.mussai@intel.com>

Can't rely that band 2.4 is always supported by the NIC and use the
first channel in this band for the phy ctxt.
Instead, look for the first channel in the first band that is supported

Signed-off-by: Tova Mussai <tova.mussai@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c       | 11 ++++++++++-
 drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c | 11 ++++++++++-
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index d2baea22cba2..a6e360194e00 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -1282,6 +1282,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
 	int ret, i;
 	struct ieee80211_channel *chan;
 	struct cfg80211_chan_def chandef;
+	struct ieee80211_supported_band *sband = NULL;
 
 	lockdep_assert_held(&mvm->mutex);
 
@@ -1371,7 +1372,15 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
 		goto error;
 
 	/* Add all the PHY contexts */
-	chan = &mvm->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[0];
+	i = 0;
+	while (!sband && i < NUM_NL80211_BANDS)
+		sband = mvm->hw->wiphy->bands[i++];
+
+	if (WARN_ON_ONCE(!sband))
+		goto error;
+
+	chan = &sband->channels[0];
+
 	cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
 	for (i = 0; i < NUM_PHY_CTX; i++) {
 		/*
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
index 86e40bae57e3..0243dbe8ac49 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
@@ -289,8 +289,17 @@ void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
 	if (ctxt->ref == 0) {
 		struct ieee80211_channel *chan;
 		struct cfg80211_chan_def chandef;
+		struct ieee80211_supported_band *sband = NULL;
+		enum nl80211_band band = NL80211_BAND_2GHZ;
+
+		while (!sband && band < NUM_NL80211_BANDS)
+			sband = mvm->hw->wiphy->bands[band++];
+
+		if (WARN_ON(!sband))
+			return;
+
+		chan = &sband->channels[0];
 
-		chan = &mvm->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[0];
 		cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
 		iwl_mvm_phy_ctxt_changed(mvm, ctxt, &chandef, 1, 1);
 	}
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 15/19] iwlwifi: dbg_ini: separate cfg and dump flows to different modules
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
                   ` (13 preceding siblings ...)
  2019-08-31  9:48 ` [PATCH 14/19] iwlwifi: mvm: look for the first supported channel when add/remove phy ctxt Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 16/19] iwlwifi: dbg_ini: use linked list for dump TLVs during dump creation Luca Coelho
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Shahar S Matityahu <shahar.s.matityahu@intel.com>

separate configuration flows and dump collection flows.
make ini configuration flows be in iwl-dbg-tlv.c and dump related flows
in dbg.c to better reflect their logical difference.

Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   | 429 ------------------
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h   |   3 -
 .../net/wireless/intel/iwlwifi/fw/runtime.h   |   1 -
 .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c  | 429 ++++++++++++++++++
 .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h  |   4 +
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   |   8 +-
 .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c |   2 +-
 .../net/wireless/intel/iwlwifi/mvm/mac80211.c |   2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/scan.c |   2 +-
 9 files changed, 440 insertions(+), 440 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 2a4c2e772d1b..3320acc8a52f 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -2438,435 +2438,6 @@ void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt)
 }
 IWL_EXPORT_SYMBOL(iwl_fw_dbg_read_d3_debug_data);
 
-static void iwl_fw_dbg_info_apply(struct iwl_fw_runtime *fwrt,
-				  struct iwl_fw_ini_debug_info_tlv *dbg_info,
-				  bool ext, enum iwl_fw_ini_apply_point pnt)
-{
-	u32 img_name_len = le32_to_cpu(dbg_info->img_name_len);
-	u32 dbg_cfg_name_len = le32_to_cpu(dbg_info->dbg_cfg_name_len);
-
-	if (img_name_len != IWL_FW_INI_MAX_IMG_NAME_LEN) {
-		IWL_WARN(fwrt,
-			 "WRT: ext=%d. Invalid image name length %d, expected %d\n",
-			 ext, img_name_len,
-			 IWL_FW_INI_MAX_IMG_NAME_LEN);
-		return;
-	}
-
-	if (dbg_cfg_name_len != IWL_FW_INI_MAX_DBG_CFG_NAME_LEN) {
-		IWL_WARN(fwrt,
-			 "WRT: ext=%d. Invalid debug cfg name length %d, expected %d\n",
-			 ext, dbg_cfg_name_len,
-			 IWL_FW_INI_MAX_DBG_CFG_NAME_LEN);
-		return;
-	}
-
-	if (ext) {
-		memcpy(fwrt->dump.external_dbg_cfg_name, dbg_info->dbg_cfg_name,
-		       sizeof(fwrt->dump.external_dbg_cfg_name));
-	} else {
-		memcpy(fwrt->dump.img_name, dbg_info->img_name,
-		       sizeof(fwrt->dump.img_name));
-		memcpy(fwrt->dump.internal_dbg_cfg_name, dbg_info->dbg_cfg_name,
-		       sizeof(fwrt->dump.internal_dbg_cfg_name));
-	}
-}
-
-static void
-iwl_fw_dbg_buffer_allocation(struct iwl_fw_runtime *fwrt, u32 size)
-{
-	struct iwl_trans *trans = fwrt->trans;
-	void *virtual_addr = NULL;
-	dma_addr_t phys_addr;
-
-	if (WARN_ON_ONCE(trans->dbg.num_blocks ==
-			 ARRAY_SIZE(trans->dbg.fw_mon)))
-		return;
-
-	virtual_addr =
-		dma_alloc_coherent(fwrt->trans->dev, size, &phys_addr,
-				   GFP_KERNEL | __GFP_NOWARN);
-
-	/* TODO: alloc fragments if needed */
-	if (!virtual_addr)
-		IWL_ERR(fwrt, "Failed to allocate debug memory\n");
-
-	IWL_DEBUG_FW(trans,
-		     "Allocated DRAM buffer[%d], size=0x%x\n",
-		     trans->dbg.num_blocks, size);
-
-	trans->dbg.fw_mon[trans->dbg.num_blocks].block = virtual_addr;
-	trans->dbg.fw_mon[trans->dbg.num_blocks].physical = phys_addr;
-	trans->dbg.fw_mon[trans->dbg.num_blocks].size = size;
-	trans->dbg.num_blocks++;
-}
-
-static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt,
-				    struct iwl_fw_ini_allocation_tlv *alloc,
-				    enum iwl_fw_ini_apply_point pnt)
-{
-	struct iwl_trans *trans = fwrt->trans;
-	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] = &ldbg_cmd,
-		.len[0] = sizeof(ldbg_cmd),
-	};
-	int block_idx = trans->dbg.num_blocks;
-	u32 buf_location = le32_to_cpu(alloc->buffer_location);
-	u32 alloc_id = le32_to_cpu(alloc->allocation_id);
-
-	if (alloc_id <= IWL_FW_INI_ALLOCATION_INVALID ||
-	    alloc_id >= IWL_FW_INI_ALLOCATION_NUM) {
-		IWL_ERR(fwrt, "WRT: Invalid allocation id %d\n", alloc_id);
-		return;
-	}
-
-	if (fwrt->trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID)
-		fwrt->trans->dbg.ini_dest = buf_location;
-
-	if (buf_location != fwrt->trans->dbg.ini_dest) {
-		WARN(fwrt,
-		     "WRT: attempt to override buffer location on apply point %d\n",
-		     pnt);
-
-		return;
-	}
-
-	if (buf_location == IWL_FW_INI_LOCATION_SRAM_PATH) {
-		IWL_DEBUG_FW(trans, "WRT: Applying SMEM buffer destination\n");
-		/* set sram monitor by enabling bit 7 */
-		iwl_set_bit(fwrt->trans, CSR_HW_IF_CONFIG_REG,
-			    CSR_HW_IF_CONFIG_REG_BIT_MONITOR_SRAM);
-
-		return;
-	}
-
-	if (buf_location != IWL_FW_INI_LOCATION_DRAM_PATH)
-		return;
-
-	if (!(BIT(alloc_id) & fwrt->trans->dbg.is_alloc)) {
-		iwl_fw_dbg_buffer_allocation(fwrt, le32_to_cpu(alloc->size));
-		if (block_idx == trans->dbg.num_blocks)
-			return;
-		fwrt->trans->dbg.is_alloc |= BIT(alloc_id);
-	}
-
-	/* First block is assigned via registers / context info */
-	if (trans->dbg.num_blocks == 1)
-		return;
-
-	IWL_DEBUG_FW(trans,
-		     "WRT: Applying DRAM buffer[%d] destination\n", block_idx);
-
-	cmd->num_frags = cpu_to_le32(1);
-	cmd->fragments[0].address =
-		cpu_to_le64(trans->dbg.fw_mon[block_idx].physical);
-	cmd->fragments[0].size = alloc->size;
-	cmd->allocation_id = alloc->allocation_id;
-	cmd->buffer_location = alloc->buffer_location;
-
-	iwl_trans_send_cmd(trans, &hcmd);
-}
-
-static void iwl_fw_dbg_send_hcmd(struct iwl_fw_runtime *fwrt,
-				 struct iwl_ucode_tlv *tlv)
-{
-	struct iwl_fw_ini_hcmd_tlv *hcmd_tlv = (void *)&tlv->data[0];
-	struct iwl_fw_ini_hcmd *data = &hcmd_tlv->hcmd;
-	u16 len = le32_to_cpu(tlv->length) - sizeof(*hcmd_tlv);
-
-	struct iwl_host_cmd hcmd = {
-		.id = WIDE_ID(data->group, data->id),
-		.len = { len, },
-		.data = { data->data, },
-	};
-
-	/* currently the driver supports always on domain only */
-	if (le32_to_cpu(hcmd_tlv->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON)
-		return;
-
-	IWL_DEBUG_FW(fwrt, "WRT: Sending host command id=0x%x, group=0x%x\n",
-		     data->id, data->group);
-
-	iwl_trans_send_cmd(fwrt->trans, &hcmd);
-}
-
-static void iwl_fw_dbg_update_regions(struct iwl_fw_runtime *fwrt,
-				      struct iwl_fw_ini_region_tlv *tlv,
-				      enum iwl_fw_ini_apply_point pnt)
-{
-	void *iter = (void *)tlv->region_config;
-	int i, size = le32_to_cpu(tlv->num_regions);
-	const char *err_st =
-		"WRT: Invalid region %s %d for apply point %d\n";
-
-	for (i = 0; i < size; i++) {
-		struct iwl_fw_ini_region_cfg *reg = iter, **active;
-		int id = le32_to_cpu(reg->region_id);
-		u32 type = le32_to_cpu(reg->region_type);
-
-		if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_regs), err_st, "id",
-			 id, pnt))
-			break;
-
-		if (WARN(type == 0 || type >= IWL_FW_INI_REGION_NUM, err_st,
-			 "type", type, pnt))
-			break;
-
-		active = &fwrt->dump.active_regs[id];
-
-		if (*active)
-			IWL_WARN(fwrt->trans, "WRT: Region id %d override\n",
-				 id);
-
-		IWL_DEBUG_FW(fwrt, "WRT: Activating region id %d\n", id);
-
-		*active = reg;
-
-		if (type == IWL_FW_INI_REGION_TXF ||
-		    type == IWL_FW_INI_REGION_RXF)
-			iter += le32_to_cpu(reg->fifos.num_of_registers) *
-				sizeof(__le32);
-		else if (type == IWL_FW_INI_REGION_DEVICE_MEMORY ||
-			 type == IWL_FW_INI_REGION_PERIPHERY_MAC ||
-			 type == IWL_FW_INI_REGION_PERIPHERY_PHY ||
-			 type == IWL_FW_INI_REGION_PERIPHERY_AUX ||
-			 type == IWL_FW_INI_REGION_INTERNAL_BUFFER ||
-			 type == IWL_FW_INI_REGION_PAGING ||
-			 type == IWL_FW_INI_REGION_CSR ||
-			 type == IWL_FW_INI_REGION_LMAC_ERROR_TABLE ||
-			 type == IWL_FW_INI_REGION_UMAC_ERROR_TABLE)
-			iter += le32_to_cpu(reg->internal.num_of_ranges) *
-				sizeof(__le32);
-
-		iter += sizeof(*reg);
-	}
-}
-
-static int iwl_fw_dbg_trig_realloc(struct iwl_fw_runtime *fwrt,
-				   struct iwl_fw_ini_active_triggers *active,
-				   u32 id, int size)
-{
-	void *ptr;
-
-	if (size <= active->size)
-		return 0;
-
-	ptr = krealloc(active->trig, size, GFP_KERNEL);
-	if (!ptr) {
-		IWL_ERR(fwrt, "WRT: Failed to allocate memory for trigger %d\n",
-			id);
-		return -ENOMEM;
-	}
-	active->trig = ptr;
-	active->size = size;
-
-	return 0;
-}
-
-static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt,
-				       struct iwl_fw_ini_trigger_tlv *tlv,
-				       enum iwl_fw_ini_apply_point apply_point)
-{
-	int i, size = le32_to_cpu(tlv->num_triggers);
-	void *iter = (void *)tlv->trigger_config;
-
-	for (i = 0; i < size; i++) {
-		struct iwl_fw_ini_trigger *trig = iter;
-		struct iwl_fw_ini_active_triggers *active;
-		int id = le32_to_cpu(trig->trigger_id);
-		u32 trig_regs_size = le32_to_cpu(trig->num_regions) *
-			sizeof(__le32);
-
-		if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_trigs),
-			 "WRT: Invalid trigger id %d for apply point %d\n", id,
-			 apply_point))
-			break;
-
-		active = &fwrt->dump.active_trigs[id];
-
-		if (!active->active) {
-			size_t trig_size = sizeof(*trig) + trig_regs_size;
-
-			IWL_DEBUG_FW(fwrt, "WRT: Activating trigger %d\n", id);
-
-			if (iwl_fw_dbg_trig_realloc(fwrt, active, id,
-						    trig_size))
-				goto next;
-
-			memcpy(active->trig, trig, trig_size);
-
-		} else {
-			u32 conf_override =
-				!(le32_to_cpu(trig->override_trig) & 0xff);
-			u32 region_override =
-				!(le32_to_cpu(trig->override_trig) & 0xff00);
-			u32 offset = 0;
-			u32 active_regs =
-				le32_to_cpu(active->trig->num_regions);
-			u32 new_regs = le32_to_cpu(trig->num_regions);
-			int mem_to_add = trig_regs_size;
-
-			if (region_override) {
-				IWL_DEBUG_FW(fwrt,
-					     "WRT: Trigger %d regions override\n",
-					     id);
-
-				mem_to_add -= active_regs * sizeof(__le32);
-			} else {
-				IWL_DEBUG_FW(fwrt,
-					     "WRT: Trigger %d regions appending\n",
-					     id);
-
-				offset += active_regs;
-				new_regs += active_regs;
-			}
-
-			if (iwl_fw_dbg_trig_realloc(fwrt, active, id,
-						    active->size + mem_to_add))
-				goto next;
-
-			if (conf_override) {
-				IWL_DEBUG_FW(fwrt,
-					     "WRT: Trigger %d configuration override\n",
-					     id);
-
-				memcpy(active->trig, trig, sizeof(*trig));
-			}
-
-			memcpy(active->trig->data + offset, trig->data,
-			       trig_regs_size);
-			active->trig->num_regions = cpu_to_le32(new_regs);
-		}
-
-		/* Since zero means infinity - just set to -1 */
-		if (!le32_to_cpu(active->trig->occurrences))
-			active->trig->occurrences = cpu_to_le32(-1);
-
-		active->active = true;
-
-		if (id == IWL_FW_TRIGGER_ID_PERIODIC_TRIGGER) {
-			u32 collect_interval = le32_to_cpu(trig->trigger_data);
-
-			/* the minimum allowed interval is 50ms */
-			if (collect_interval < 50) {
-				collect_interval = 50;
-				trig->trigger_data =
-					cpu_to_le32(collect_interval);
-			}
-
-			mod_timer(&fwrt->dump.periodic_trig,
-				  jiffies + msecs_to_jiffies(collect_interval));
-		}
-next:
-		iter += sizeof(*trig) + trig_regs_size;
-
-	}
-}
-
-static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
-				    struct iwl_apply_point_data *data,
-				    enum iwl_fw_ini_apply_point pnt,
-				    bool ext)
-{
-	struct iwl_apply_point_data *iter;
-
-	if (!data->list.next)
-		return;
-
-	list_for_each_entry(iter, &data->list, list) {
-		struct iwl_ucode_tlv *tlv = &iter->tlv;
-		void *ini_tlv = (void *)tlv->data;
-		u32 type = le32_to_cpu(tlv->type);
-
-		switch (type) {
-		case IWL_UCODE_TLV_TYPE_DEBUG_INFO:
-			iwl_fw_dbg_info_apply(fwrt, ini_tlv, ext, pnt);
-			break;
-		case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION:
-			if (pnt != IWL_FW_INI_APPLY_EARLY) {
-				IWL_ERR(fwrt,
-					"WRT: ext=%d. Invalid apply point %d for buffer allocation\n",
-					ext, pnt);
-				break;
-			}
-			iwl_fw_dbg_buffer_apply(fwrt, ini_tlv, pnt);
-			break;
-		case IWL_UCODE_TLV_TYPE_HCMD:
-			if (pnt < IWL_FW_INI_APPLY_AFTER_ALIVE) {
-				IWL_ERR(fwrt,
-					"WRT: ext=%d. Invalid apply point %d for host command\n",
-					ext, pnt);
-				break;
-			}
-			iwl_fw_dbg_send_hcmd(fwrt, tlv);
-			break;
-		case IWL_UCODE_TLV_TYPE_REGIONS:
-			iwl_fw_dbg_update_regions(fwrt, ini_tlv, pnt);
-			break;
-		case IWL_UCODE_TLV_TYPE_TRIGGERS:
-			iwl_fw_dbg_update_triggers(fwrt, ini_tlv, pnt);
-			break;
-		default:
-			WARN_ONCE(1, "WRT: Invalid TLV 0x%x for apply point\n",
-				  type);
-			break;
-		}
-	}
-}
-
-static void iwl_fw_dbg_ini_reset_cfg(struct iwl_fw_runtime *fwrt)
-{
-	int i;
-
-	for (i = 0; i < IWL_FW_INI_MAX_REGION_ID; i++)
-		fwrt->dump.active_regs[i] = NULL;
-
-	/* disable the triggers, used in recovery flow */
-	for (i = 0; i < IWL_FW_TRIGGER_ID_NUM; i++)
-		fwrt->dump.active_trigs[i].active = false;
-
-	memset(fwrt->dump.img_name, 0,
-	       sizeof(fwrt->dump.img_name));
-	memset(fwrt->dump.internal_dbg_cfg_name, 0,
-	       sizeof(fwrt->dump.internal_dbg_cfg_name));
-	memset(fwrt->dump.external_dbg_cfg_name, 0,
-	       sizeof(fwrt->dump.external_dbg_cfg_name));
-
-	fwrt->trans->dbg.ini_dest = IWL_FW_INI_LOCATION_INVALID;
-}
-
-void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
-			    enum iwl_fw_ini_apply_point apply_point)
-{
-	void *data;
-
-	if (apply_point == IWL_FW_INI_APPLY_EARLY)
-		iwl_fw_dbg_ini_reset_cfg(fwrt);
-
-	if (fwrt->trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) {
-		IWL_DEBUG_FW(fwrt,
-			     "WRT: Enabling internal configuration apply point %d\n",
-			     apply_point);
-		data = &fwrt->trans->dbg.apply_points[apply_point];
-		_iwl_fw_dbg_apply_point(fwrt, data, apply_point, false);
-	}
-
-	if (fwrt->trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) {
-		IWL_DEBUG_FW(fwrt,
-			     "WRT: Enabling external configuration apply point %d\n",
-			     apply_point);
-		data = &fwrt->trans->dbg.apply_points_ext[apply_point];
-		_iwl_fw_dbg_apply_point(fwrt, data, apply_point, true);
-	}
-}
-IWL_EXPORT_SYMBOL(iwl_fw_dbg_apply_point);
-
 void iwl_fw_dbg_stop_sync(struct iwl_fw_runtime *fwrt)
 {
 	int i;
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index 8faea2571788..deb84ba3dc7e 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -368,9 +368,6 @@ static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {}
 
 #endif /* CONFIG_IWLWIFI_DEBUGFS */
 
-void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
-			    enum iwl_fw_ini_apply_point apply_point);
-
 void iwl_fw_dbg_stop_sync(struct iwl_fw_runtime *fwrt);
 
 static inline void iwl_fw_lmac1_set_alive_err_table(struct iwl_trans *trans,
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
index 406ef73992c1..0a4e13e4cc2c 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
@@ -64,7 +64,6 @@
 #include "iwl-trans.h"
 #include "img.h"
 #include "fw/api/debug.h"
-#include "fw/api/dbg-tlv.h"
 #include "fw/api/paging.h"
 #include "iwl-eeprom-parse.h"
 
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
index 5b1644a70ace..b4fba73b5b23 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
@@ -60,8 +60,11 @@
  *****************************************************************************/
 
 #include <linux/firmware.h>
+#include "iwl-drv.h"
 #include "iwl-trans.h"
 #include "iwl-dbg-tlv.h"
+#include "fw/dbg.h"
+#include "fw/runtime.h"
 
 /**
  * enum iwl_dbg_tlv_type - debug TLV types
@@ -254,3 +257,429 @@ void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans)
 
 	release_firmware(fw);
 }
+
+static void
+iwl_dbg_tlv_apply_debug_info(struct iwl_fw_runtime *fwrt,
+			     struct iwl_fw_ini_debug_info_tlv *dbg_info,
+			     bool ext, enum iwl_fw_ini_apply_point pnt)
+{
+	u32 img_name_len = le32_to_cpu(dbg_info->img_name_len);
+	u32 dbg_cfg_name_len = le32_to_cpu(dbg_info->dbg_cfg_name_len);
+	const char err_str[] =
+		"WRT: Invalid %s name length %d, expected %d\n";
+
+	if (img_name_len != IWL_FW_INI_MAX_IMG_NAME_LEN) {
+		IWL_WARN(fwrt, err_str, "image", img_name_len,
+			 IWL_FW_INI_MAX_IMG_NAME_LEN);
+		return;
+	}
+
+	if (dbg_cfg_name_len != IWL_FW_INI_MAX_DBG_CFG_NAME_LEN) {
+		IWL_WARN(fwrt, err_str, "debug cfg", dbg_cfg_name_len,
+			 IWL_FW_INI_MAX_DBG_CFG_NAME_LEN);
+		return;
+	}
+
+	if (ext) {
+		memcpy(fwrt->dump.external_dbg_cfg_name, dbg_info->dbg_cfg_name,
+		       sizeof(fwrt->dump.external_dbg_cfg_name));
+	} else {
+		memcpy(fwrt->dump.img_name, dbg_info->img_name,
+		       sizeof(fwrt->dump.img_name));
+		memcpy(fwrt->dump.internal_dbg_cfg_name, dbg_info->dbg_cfg_name,
+		       sizeof(fwrt->dump.internal_dbg_cfg_name));
+	}
+}
+
+static void iwl_dbg_tlv_alloc_buffer(struct iwl_fw_runtime *fwrt, u32 size)
+{
+	struct iwl_trans *trans = fwrt->trans;
+	void *virtual_addr = NULL;
+	dma_addr_t phys_addr;
+
+	if (WARN_ON_ONCE(trans->dbg.num_blocks ==
+			 ARRAY_SIZE(trans->dbg.fw_mon)))
+		return;
+
+	virtual_addr =
+		dma_alloc_coherent(fwrt->trans->dev, size, &phys_addr,
+				   GFP_KERNEL | __GFP_NOWARN);
+
+	/* TODO: alloc fragments if needed */
+	if (!virtual_addr)
+		IWL_ERR(fwrt, "Failed to allocate debug memory\n");
+
+	IWL_DEBUG_FW(trans,
+		     "Allocated DRAM buffer[%d], size=0x%x\n",
+		     trans->dbg.num_blocks, size);
+
+	trans->dbg.fw_mon[trans->dbg.num_blocks].block = virtual_addr;
+	trans->dbg.fw_mon[trans->dbg.num_blocks].physical = phys_addr;
+	trans->dbg.fw_mon[trans->dbg.num_blocks].size = size;
+	trans->dbg.num_blocks++;
+}
+
+static void iwl_dbg_tlv_apply_buffer(struct iwl_fw_runtime *fwrt,
+				     struct iwl_fw_ini_allocation_tlv *alloc,
+				     enum iwl_fw_ini_apply_point pnt)
+{
+	struct iwl_trans *trans = fwrt->trans;
+	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] = &ldbg_cmd,
+		.len[0] = sizeof(ldbg_cmd),
+	};
+	int block_idx = trans->dbg.num_blocks;
+	u32 buf_location = le32_to_cpu(alloc->buffer_location);
+	u32 alloc_id = le32_to_cpu(alloc->allocation_id);
+
+	if (alloc_id <= IWL_FW_INI_ALLOCATION_INVALID ||
+	    alloc_id >= IWL_FW_INI_ALLOCATION_NUM) {
+		IWL_ERR(fwrt, "WRT: Invalid allocation id %d\n", alloc_id);
+		return;
+	}
+
+	if (fwrt->trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID)
+		fwrt->trans->dbg.ini_dest = buf_location;
+
+	if (buf_location != fwrt->trans->dbg.ini_dest) {
+		WARN(fwrt,
+		     "WRT: attempt to override buffer location on apply point %d\n",
+		     pnt);
+
+		return;
+	}
+
+	if (buf_location == IWL_FW_INI_LOCATION_SRAM_PATH) {
+		IWL_DEBUG_FW(trans, "WRT: Applying SMEM buffer destination\n");
+		/* set sram monitor by enabling bit 7 */
+		iwl_set_bit(fwrt->trans, CSR_HW_IF_CONFIG_REG,
+			    CSR_HW_IF_CONFIG_REG_BIT_MONITOR_SRAM);
+
+		return;
+	}
+
+	if (buf_location != IWL_FW_INI_LOCATION_DRAM_PATH)
+		return;
+
+	if (!(BIT(alloc_id) & fwrt->trans->dbg.is_alloc)) {
+		iwl_dbg_tlv_alloc_buffer(fwrt, le32_to_cpu(alloc->size));
+		if (block_idx == trans->dbg.num_blocks)
+			return;
+		fwrt->trans->dbg.is_alloc |= BIT(alloc_id);
+	}
+
+	/* First block is assigned via registers / context info */
+	if (trans->dbg.num_blocks == 1)
+		return;
+
+	IWL_DEBUG_FW(trans,
+		     "WRT: Applying DRAM buffer[%d] destination\n", block_idx);
+
+	cmd->num_frags = cpu_to_le32(1);
+	cmd->fragments[0].address =
+		cpu_to_le64(trans->dbg.fw_mon[block_idx].physical);
+	cmd->fragments[0].size = alloc->size;
+	cmd->allocation_id = alloc->allocation_id;
+	cmd->buffer_location = alloc->buffer_location;
+
+	iwl_trans_send_cmd(trans, &hcmd);
+}
+
+static void iwl_dbg_tlv_apply_hcmd(struct iwl_fw_runtime *fwrt,
+				   struct iwl_ucode_tlv *tlv)
+{
+	struct iwl_fw_ini_hcmd_tlv *hcmd_tlv = (void *)&tlv->data[0];
+	struct iwl_fw_ini_hcmd *data = &hcmd_tlv->hcmd;
+	u16 len = le32_to_cpu(tlv->length) - sizeof(*hcmd_tlv);
+
+	struct iwl_host_cmd hcmd = {
+		.id = WIDE_ID(data->group, data->id),
+		.len = { len, },
+		.data = { data->data, },
+	};
+
+	/* currently the driver supports always on domain only */
+	if (le32_to_cpu(hcmd_tlv->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON)
+		return;
+
+	IWL_DEBUG_FW(fwrt, "WRT: Sending host command id=0x%x, group=0x%x\n",
+		     data->id, data->group);
+
+	iwl_trans_send_cmd(fwrt->trans, &hcmd);
+}
+
+static void iwl_dbg_tlv_apply_region(struct iwl_fw_runtime *fwrt,
+				     struct iwl_fw_ini_region_tlv *tlv,
+				     enum iwl_fw_ini_apply_point pnt)
+{
+	void *iter = (void *)tlv->region_config;
+	int i, size = le32_to_cpu(tlv->num_regions);
+	const char *err_st =
+		"WRT: Invalid region %s %d for apply point %d\n";
+
+	for (i = 0; i < size; i++) {
+		struct iwl_fw_ini_region_cfg *reg = iter, **active;
+		int id = le32_to_cpu(reg->region_id);
+		u32 type = le32_to_cpu(reg->region_type);
+
+		if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_regs), err_st, "id",
+			 id, pnt))
+			break;
+
+		if (WARN(type == 0 || type >= IWL_FW_INI_REGION_NUM, err_st,
+			 "type", type, pnt))
+			break;
+
+		active = &fwrt->dump.active_regs[id];
+
+		if (*active)
+			IWL_WARN(fwrt->trans, "WRT: Region id %d override\n",
+				 id);
+
+		IWL_DEBUG_FW(fwrt, "WRT: Activating region id %d\n", id);
+
+		*active = reg;
+
+		if (type == IWL_FW_INI_REGION_TXF ||
+		    type == IWL_FW_INI_REGION_RXF)
+			iter += le32_to_cpu(reg->fifos.num_of_registers) *
+				sizeof(__le32);
+		else if (type == IWL_FW_INI_REGION_DEVICE_MEMORY ||
+			 type == IWL_FW_INI_REGION_PERIPHERY_MAC ||
+			 type == IWL_FW_INI_REGION_PERIPHERY_PHY ||
+			 type == IWL_FW_INI_REGION_PERIPHERY_AUX ||
+			 type == IWL_FW_INI_REGION_INTERNAL_BUFFER ||
+			 type == IWL_FW_INI_REGION_PAGING ||
+			 type == IWL_FW_INI_REGION_CSR ||
+			 type == IWL_FW_INI_REGION_LMAC_ERROR_TABLE ||
+			 type == IWL_FW_INI_REGION_UMAC_ERROR_TABLE)
+			iter += le32_to_cpu(reg->internal.num_of_ranges) *
+				sizeof(__le32);
+
+		iter += sizeof(*reg);
+	}
+}
+
+static int iwl_dbg_tlv_trig_realloc(struct iwl_fw_runtime *fwrt,
+				    struct iwl_fw_ini_active_triggers *active,
+				    u32 id, int size)
+{
+	void *ptr;
+
+	if (size <= active->size)
+		return 0;
+
+	ptr = krealloc(active->trig, size, GFP_KERNEL);
+	if (!ptr) {
+		IWL_ERR(fwrt, "WRT: Failed to allocate memory for trigger %d\n",
+			id);
+		return -ENOMEM;
+	}
+	active->trig = ptr;
+	active->size = size;
+
+	return 0;
+}
+
+static void iwl_dbg_tlv_apply_trigger(struct iwl_fw_runtime *fwrt,
+				      struct iwl_fw_ini_trigger_tlv *tlv,
+				      enum iwl_fw_ini_apply_point apply_point)
+{
+	int i, size = le32_to_cpu(tlv->num_triggers);
+	void *iter = (void *)tlv->trigger_config;
+
+	for (i = 0; i < size; i++) {
+		struct iwl_fw_ini_trigger *trig = iter;
+		struct iwl_fw_ini_active_triggers *active;
+		int id = le32_to_cpu(trig->trigger_id);
+		u32 trig_regs_size = le32_to_cpu(trig->num_regions) *
+			sizeof(__le32);
+
+		if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_trigs),
+			 "WRT: Invalid trigger id %d for apply point %d\n", id,
+			 apply_point))
+			break;
+
+		active = &fwrt->dump.active_trigs[id];
+
+		if (!active->active) {
+			size_t trig_size = sizeof(*trig) + trig_regs_size;
+
+			IWL_DEBUG_FW(fwrt, "WRT: Activating trigger %d\n", id);
+
+			if (iwl_dbg_tlv_trig_realloc(fwrt, active, id,
+						     trig_size))
+				goto next;
+
+			memcpy(active->trig, trig, trig_size);
+
+		} else {
+			u32 conf_override =
+				!(le32_to_cpu(trig->override_trig) & 0xff);
+			u32 region_override =
+				!(le32_to_cpu(trig->override_trig) & 0xff00);
+			u32 offset = 0;
+			u32 active_regs =
+				le32_to_cpu(active->trig->num_regions);
+			u32 new_regs = le32_to_cpu(trig->num_regions);
+			int mem_to_add = trig_regs_size;
+
+			if (region_override) {
+				IWL_DEBUG_FW(fwrt,
+					     "WRT: Trigger %d regions override\n",
+					     id);
+
+				mem_to_add -= active_regs * sizeof(__le32);
+			} else {
+				IWL_DEBUG_FW(fwrt,
+					     "WRT: Trigger %d regions appending\n",
+					     id);
+
+				offset += active_regs;
+				new_regs += active_regs;
+			}
+
+			if (iwl_dbg_tlv_trig_realloc(fwrt, active, id,
+						     active->size + mem_to_add))
+				goto next;
+
+			if (conf_override) {
+				IWL_DEBUG_FW(fwrt,
+					     "WRT: Trigger %d configuration override\n",
+					     id);
+
+				memcpy(active->trig, trig, sizeof(*trig));
+			}
+
+			memcpy(active->trig->data + offset, trig->data,
+			       trig_regs_size);
+			active->trig->num_regions = cpu_to_le32(new_regs);
+		}
+
+		/* Since zero means infinity - just set to -1 */
+		if (!le32_to_cpu(active->trig->occurrences))
+			active->trig->occurrences = cpu_to_le32(-1);
+
+		active->active = true;
+
+		if (id == IWL_FW_TRIGGER_ID_PERIODIC_TRIGGER) {
+			u32 collect_interval = le32_to_cpu(trig->trigger_data);
+
+			/* the minimum allowed interval is 50ms */
+			if (collect_interval < 50) {
+				collect_interval = 50;
+				trig->trigger_data =
+					cpu_to_le32(collect_interval);
+			}
+
+			mod_timer(&fwrt->dump.periodic_trig,
+				  jiffies + msecs_to_jiffies(collect_interval));
+		}
+next:
+		iter += sizeof(*trig) + trig_regs_size;
+	}
+}
+
+static void _iwl_dbg_tlv_apply_point(struct iwl_fw_runtime *fwrt,
+				     struct iwl_apply_point_data *data,
+				     enum iwl_fw_ini_apply_point pnt,
+				     bool ext)
+{
+	struct iwl_apply_point_data *iter;
+
+	if (!data->list.next)
+		return;
+
+	list_for_each_entry(iter, &data->list, list) {
+		struct iwl_ucode_tlv *tlv = &iter->tlv;
+		void *ini_tlv = (void *)tlv->data;
+		u32 type = le32_to_cpu(tlv->type);
+		const char invalid_ap_str[] =
+			"WRT: Invalid apply point %d for %s\n";
+
+		switch (type) {
+		case IWL_UCODE_TLV_TYPE_DEBUG_INFO:
+			iwl_dbg_tlv_apply_debug_info(fwrt, ini_tlv, ext, pnt);
+			break;
+		case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION:
+			if (pnt != IWL_FW_INI_APPLY_EARLY) {
+				IWL_ERR(fwrt, invalid_ap_str, pnt,
+					"buffer allocation");
+				break;
+			}
+			iwl_dbg_tlv_apply_buffer(fwrt, ini_tlv, pnt);
+			break;
+		case IWL_UCODE_TLV_TYPE_HCMD:
+			if (pnt < IWL_FW_INI_APPLY_AFTER_ALIVE) {
+				IWL_ERR(fwrt, invalid_ap_str, pnt,
+					"host command");
+				break;
+			}
+			iwl_dbg_tlv_apply_hcmd(fwrt, tlv);
+			break;
+		case IWL_UCODE_TLV_TYPE_REGIONS:
+			iwl_dbg_tlv_apply_region(fwrt, ini_tlv, pnt);
+			break;
+		case IWL_UCODE_TLV_TYPE_TRIGGERS:
+			iwl_dbg_tlv_apply_trigger(fwrt, ini_tlv, pnt);
+			break;
+		default:
+			WARN_ONCE(1, "WRT: Invalid TLV 0x%x for apply point\n",
+				  type);
+			break;
+		}
+	}
+}
+
+static void iwl_dbg_tlv_reset_cfg(struct iwl_fw_runtime *fwrt)
+{
+	int i;
+
+	for (i = 0; i < IWL_FW_INI_MAX_REGION_ID; i++)
+		fwrt->dump.active_regs[i] = NULL;
+
+	/* disable the triggers, used in recovery flow */
+	for (i = 0; i < IWL_FW_TRIGGER_ID_NUM; i++)
+		fwrt->dump.active_trigs[i].active = false;
+
+	memset(fwrt->dump.img_name, 0,
+	       sizeof(fwrt->dump.img_name));
+	memset(fwrt->dump.internal_dbg_cfg_name, 0,
+	       sizeof(fwrt->dump.internal_dbg_cfg_name));
+	memset(fwrt->dump.external_dbg_cfg_name, 0,
+	       sizeof(fwrt->dump.external_dbg_cfg_name));
+
+	fwrt->trans->dbg.ini_dest = IWL_FW_INI_LOCATION_INVALID;
+}
+
+void iwl_dbg_tlv_apply_point(struct iwl_fw_runtime *fwrt,
+			     enum iwl_fw_ini_apply_point apply_point)
+{
+	void *data;
+
+	if (apply_point == IWL_FW_INI_APPLY_EARLY)
+		iwl_dbg_tlv_reset_cfg(fwrt);
+
+	if (fwrt->trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) {
+		IWL_DEBUG_FW(fwrt,
+			     "WRT: Enabling internal configuration apply point %d\n",
+			     apply_point);
+		data = &fwrt->trans->dbg.apply_points[apply_point];
+		_iwl_dbg_tlv_apply_point(fwrt, data, apply_point, false);
+	}
+
+	if (fwrt->trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) {
+		IWL_DEBUG_FW(fwrt,
+			     "WRT: Enabling external configuration apply point %d\n",
+			     apply_point);
+		data = &fwrt->trans->dbg.apply_points_ext[apply_point];
+		_iwl_dbg_tlv_apply_point(fwrt, data, apply_point, true);
+	}
+}
+IWL_EXPORT_SYMBOL(iwl_dbg_tlv_apply_point);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
index 3a60590d274d..93496945d313 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
@@ -75,9 +75,13 @@ struct iwl_apply_point_data {
 };
 
 struct iwl_trans;
+struct iwl_fw_runtime;
+
 void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans);
 void iwl_dbg_tlv_free(struct iwl_trans *trans);
 void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
 		       bool ext);
+void iwl_dbg_tlv_apply_point(struct iwl_fw_runtime *fwrt,
+			     enum iwl_fw_ini_apply_point apply_point);
 
 #endif /* __iwl_dbg_tlv_h__*/
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index a6e360194e00..f09f24089fe7 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -430,7 +430,7 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
 				   iwl_wait_init_complete,
 				   NULL);
 
-	iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY);
+	iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY);
 
 	/* Will also start the device */
 	ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR);
@@ -438,7 +438,7 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
 		IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret);
 		goto error;
 	}
-	iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE);
+	iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE);
 
 	/* Send init config command to mark that we are sending NVM access
 	 * commands
@@ -1263,7 +1263,7 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm)
 	if (ret)
 		return ret;
 
-	iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY);
+	iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY);
 
 	mvm->rfkill_safe_init_done = false;
 	ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR);
@@ -1272,7 +1272,7 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm)
 
 	mvm->rfkill_safe_init_done = true;
 
-	iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE);
+	iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE);
 
 	return iwl_init_paging(&mvm->fwrt, mvm->fwrt.cur_fw_img);
 }
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index 8c9777424316..5ea7f8571dd9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -1420,7 +1420,7 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
 	    rx_missed_bcon >= stop_trig_missed_bcon)
 		iwl_fw_dbg_collect_trig(&mvm->fwrt, trigger, NULL);
 
-	iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_MISSED_BEACONS);
+	iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_MISSED_BEACONS);
 
 out:
 	rcu_read_unlock();
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index e3699df89572..07763f97d5c5 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -1106,7 +1106,7 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm)
 	}
 	ret = iwl_mvm_up(mvm);
 
-	iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_POST_INIT);
+	iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_POST_INIT);
 
 	if (ret && test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
 		/* Something went wrong - we need to finish some cleanup
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index afa44345f37b..892db3dcdc27 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -1940,7 +1940,7 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
 
 	mvm->scan_uid_status[uid] = 0;
 
-	iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_SCAN_COMPLETE);
+	iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_SCAN_COMPLETE);
 }
 
 void iwl_mvm_rx_umac_scan_iter_complete_notif(struct iwl_mvm *mvm,
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 16/19] iwlwifi: dbg_ini: use linked list for dump TLVs during dump creation
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
                   ` (14 preceding siblings ...)
  2019-08-31  9:48 ` [PATCH 15/19] iwlwifi: dbg_ini: separate cfg and dump flows to different modules Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 17/19] iwlwifi: dbg_ini: move tx fifo data into fw runtime Luca Coelho
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Shahar S Matityahu <shahar.s.matityahu@intel.com>

Avoid iterating over dump TLVs twice for size calculation by using
linked list to store the dump TLVs.

Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   | 288 ++++++++----------
 .../wireless/intel/iwlwifi/fw/error-dump.h    |  22 ++
 2 files changed, 152 insertions(+), 158 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 3320acc8a52f..73af6e6a54c3 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -1664,38 +1664,50 @@ struct iwl_dump_ini_mem_ops {
 };
 
 /**
- * iwl_dump_ini_mem - copy a memory region into the dump
- * @fwrt: fw runtime struct.
- * @data: dump memory data.
- * @reg: region to copy to the dump.
- * @ops: memory dump operations.
+ * iwl_dump_ini_mem
+ *
+ * Creates a dump tlv and copy a memory region into it.
+ * Returns the size of the current dump tlv or 0 if failed
+ *
+ * @fwrt: fw runtime struct
+ * @list: list to add the dump tlv to
+ * @reg: memory region
+ * @ops: memory dump operations
  */
-static void
-iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
-		 struct iwl_fw_error_dump_data **data,
-		 struct iwl_fw_ini_region_cfg *reg,
-		 struct iwl_dump_ini_mem_ops *ops)
+static u32 iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, struct list_head *list,
+			    struct iwl_fw_ini_region_cfg *reg,
+			    struct iwl_dump_ini_mem_ops *ops)
 {
-	struct iwl_fw_ini_error_dump_header *header = (void *)(*data)->data;
+	struct iwl_fw_ini_dump_entry *entry;
+	struct iwl_fw_error_dump_data *tlv;
+	struct iwl_fw_ini_error_dump_header *header;
 	u32 num_of_ranges, i, type = le32_to_cpu(reg->region_type), size;
 	void *range;
 
 	if (WARN_ON(!ops || !ops->get_num_of_ranges || !ops->get_size ||
 		    !ops->fill_mem_hdr || !ops->fill_range))
-		return;
+		return 0;
 
 	size = ops->get_size(fwrt, reg);
 	if (!size)
-		return;
+		return 0;
+
+	entry = kmalloc(sizeof(*entry) + sizeof(*tlv) + size, GFP_KERNEL);
+	if (!entry)
+		return 0;
+
+	entry->size = sizeof(*tlv) + size;
+
+	tlv = (void *)entry->data;
+	tlv->type = cpu_to_le32(type);
+	tlv->len = cpu_to_le32(size);
 
 	IWL_DEBUG_FW(fwrt, "WRT: Collecting region: id=%d, type=%d\n",
 		     le32_to_cpu(reg->region_id), type);
 
 	num_of_ranges = ops->get_num_of_ranges(fwrt, reg);
 
-	(*data)->type = cpu_to_le32(type);
-	(*data)->len = cpu_to_le32(size);
-
+	header = (void *)tlv->data;
 	header->region_id = reg->region_id;
 	header->num_of_ranges = cpu_to_le32(num_of_ranges);
 	header->name_len = cpu_to_le32(min_t(int, IWL_FW_INI_MAX_NAME,
@@ -1707,8 +1719,7 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
 		IWL_ERR(fwrt,
 			"WRT: Failed to fill region header: id=%d, type=%d\n",
 			le32_to_cpu(reg->region_id), type);
-		memset(*data, 0, size);
-		return;
+		goto out_err;
 	}
 
 	for (i = 0; i < num_of_ranges; i++) {
@@ -1718,23 +1729,42 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
 			IWL_ERR(fwrt,
 				"WRT: Failed to dump region: id=%d, type=%d\n",
 				le32_to_cpu(reg->region_id), type);
-			memset(*data, 0, size);
-			return;
+			goto out_err;
 		}
 		range = range + range_size;
 	}
-	*data = iwl_fw_error_next_data(*data);
+
+	list_add_tail(&entry->list, list);
+
+	return entry->size;
+
+out_err:
+	kfree(entry);
+
+	return 0;
 }
 
-static void iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,
-			      struct iwl_fw_ini_trigger *trigger,
-			      struct iwl_fw_error_dump_data **data)
+static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,
+			     struct iwl_fw_ini_trigger *trigger,
+			     struct list_head *list)
 {
-	struct iwl_fw_ini_dump_info *dump = (void *)(*data)->data;
+	struct iwl_fw_ini_dump_entry *entry;
+	struct iwl_fw_error_dump_data *tlv;
+	struct iwl_fw_ini_dump_info *dump;
 	u32 reg_ids_size = le32_to_cpu(trigger->num_regions) * sizeof(__le32);
+	u32 size = sizeof(*tlv) + sizeof(*dump) + reg_ids_size;
+
+	entry = kmalloc(sizeof(*entry) + size, GFP_KERNEL);
+	if (!entry)
+		return 0;
 
-	(*data)->type = cpu_to_le32(IWL_INI_DUMP_INFO_TYPE);
-	(*data)->len = cpu_to_le32(sizeof(*dump) + reg_ids_size);
+	entry->size = size;
+
+	tlv = (void *)entry->data;
+	tlv->type = cpu_to_le32(IWL_INI_DUMP_INFO_TYPE);
+	tlv->len = cpu_to_le32(sizeof(*dump) + reg_ids_size);
+
+	dump = (void *)tlv->data;
 
 	dump->version = cpu_to_le32(IWL_INI_DUMP_VER);
 	dump->trigger_id = trigger->trigger_id;
@@ -1773,31 +1803,31 @@ static void iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,
 	dump->external_dbg_cfg_name_len =
 		cpu_to_le32(sizeof(dump->external_dbg_cfg_name));
 
-	/* dump info size is allocated in iwl_fw_ini_get_trigger_len.
-	 * The driver allocates (sizeof(*dump) + reg_ids_size) so it is safe to
-	 * use reg_ids_size
-	 */
 	memcpy(dump->external_dbg_cfg_name, fwrt->dump.external_dbg_cfg_name,
 	       sizeof(dump->external_dbg_cfg_name));
 
 	dump->regions_num = trigger->num_regions;
 	memcpy(dump->region_ids, trigger->data, reg_ids_size);
 
-	*data = iwl_fw_error_next_data(*data);
+	/* add dump info TLV to the beginning of the list since it needs to be
+	 * the first TLV in the dump
+	 */
+	list_add(&entry->list, list);
+
+	return entry->size;
 }
 
-static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
-				      struct iwl_fw_ini_trigger *trigger)
+static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt,
+				struct iwl_fw_ini_trigger *trigger,
+				struct list_head *list)
 {
-	int i, ret_size = 0, hdr_len = sizeof(struct iwl_fw_error_dump_data);
-	u32 size;
-
-	if (!trigger || !trigger->num_regions)
-		return 0;
+	int i;
+	u32 size = 0;
 
 	for (i = 0; i < le32_to_cpu(trigger->num_regions); i++) {
 		u32 reg_id = le32_to_cpu(trigger->data[i]);
 		struct iwl_fw_ini_region_cfg *reg;
+		struct iwl_dump_ini_mem_ops ops;
 
 		if (WARN_ON(reg_id >= ARRAY_SIZE(fwrt->dump.active_regs)))
 			continue;
@@ -1810,89 +1840,6 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
 			continue;
 		}
 
-		/* currently the driver supports always on domain only */
-		if (le32_to_cpu(reg->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON)
-			continue;
-
-		switch (le32_to_cpu(reg->region_type)) {
-		case IWL_FW_INI_REGION_DEVICE_MEMORY:
-		case IWL_FW_INI_REGION_PERIPHERY_MAC:
-		case IWL_FW_INI_REGION_PERIPHERY_PHY:
-		case IWL_FW_INI_REGION_PERIPHERY_AUX:
-		case IWL_FW_INI_REGION_CSR:
-		case IWL_FW_INI_REGION_LMAC_ERROR_TABLE:
-		case IWL_FW_INI_REGION_UMAC_ERROR_TABLE:
-			size = iwl_dump_ini_mem_get_size(fwrt, reg);
-			if (size)
-				ret_size += hdr_len + size;
-			break;
-		case IWL_FW_INI_REGION_TXF:
-			size = iwl_dump_ini_txf_get_size(fwrt, reg);
-			if (size)
-				ret_size += hdr_len + size;
-			break;
-		case IWL_FW_INI_REGION_RXF:
-			size = iwl_dump_ini_rxf_get_size(fwrt, reg);
-			if (size)
-				ret_size += hdr_len + size;
-			break;
-		case IWL_FW_INI_REGION_PAGING:
-			if (iwl_fw_dbg_is_paging_enabled(fwrt))
-				size = iwl_dump_ini_paging_get_size(fwrt, reg);
-			else
-				size = iwl_dump_ini_paging_gen2_get_size(fwrt,
-									 reg);
-			if (size)
-				ret_size += hdr_len + size;
-			break;
-		case IWL_FW_INI_REGION_DRAM_BUFFER:
-			if (!fwrt->trans->dbg.num_blocks)
-				break;
-			size = iwl_dump_ini_mon_dram_get_size(fwrt, reg);
-			if (size)
-				ret_size += hdr_len + size;
-			break;
-		case IWL_FW_INI_REGION_INTERNAL_BUFFER:
-			size = iwl_dump_ini_mon_smem_get_size(fwrt, reg);
-			if (size)
-				ret_size += hdr_len + size;
-			break;
-		case IWL_FW_INI_REGION_DRAM_IMR:
-			/* Undefined yet */
-		default:
-			break;
-		}
-	}
-
-	/* add dump info size */
-	if (ret_size)
-		ret_size += hdr_len + sizeof(struct iwl_fw_ini_dump_info) +
-			(le32_to_cpu(trigger->num_regions) * sizeof(__le32));
-
-	return ret_size;
-}
-
-static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
-				    struct iwl_fw_ini_trigger *trigger,
-				    struct iwl_fw_error_dump_data **data)
-{
-	int i, num = le32_to_cpu(trigger->num_regions);
-
-	iwl_dump_ini_info(fwrt, trigger, data);
-
-	for (i = 0; i < num; i++) {
-		u32 reg_id = le32_to_cpu(trigger->data[i]);
-		struct iwl_fw_ini_region_cfg *reg;
-		struct iwl_dump_ini_mem_ops ops;
-
-		if (reg_id >= ARRAY_SIZE(fwrt->dump.active_regs))
-			continue;
-
-		reg = fwrt->dump.active_regs[reg_id];
-		/* Don't warn, get_trigger_len already warned */
-		if (!reg)
-			continue;
-
 		/* currently the driver supports always on domain only */
 		if (le32_to_cpu(reg->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON)
 			continue;
@@ -1905,28 +1852,28 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
 			ops.get_size = iwl_dump_ini_mem_get_size;
 			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
 			ops.fill_range = iwl_dump_ini_dev_mem_iter;
-			iwl_dump_ini_mem(fwrt, data, reg, &ops);
+			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
 			break;
 		case IWL_FW_INI_REGION_PERIPHERY_MAC:
 			ops.get_num_of_ranges =	iwl_dump_ini_mem_ranges;
 			ops.get_size = iwl_dump_ini_mem_get_size;
 			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
 			ops.fill_range = iwl_dump_ini_prph_iter;
-			iwl_dump_ini_mem(fwrt, data, reg, &ops);
+			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
 			break;
 		case IWL_FW_INI_REGION_DRAM_BUFFER:
 			ops.get_num_of_ranges = iwl_dump_ini_mon_dram_ranges;
 			ops.get_size = iwl_dump_ini_mon_dram_get_size;
 			ops.fill_mem_hdr = iwl_dump_ini_mon_dram_fill_header;
 			ops.fill_range = iwl_dump_ini_mon_dram_iter;
-			iwl_dump_ini_mem(fwrt, data, reg, &ops);
+			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
 			break;
 		case IWL_FW_INI_REGION_INTERNAL_BUFFER:
 			ops.get_num_of_ranges = iwl_dump_ini_mem_ranges;
 			ops.get_size = iwl_dump_ini_mon_smem_get_size;
 			ops.fill_mem_hdr = iwl_dump_ini_mon_smem_fill_header;
 			ops.fill_range = iwl_dump_ini_dev_mem_iter;
-			iwl_dump_ini_mem(fwrt, data, reg, &ops);
+			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
 			break;
 		case IWL_FW_INI_REGION_PAGING:
 			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
@@ -1942,8 +1889,7 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
 					iwl_dump_ini_paging_gen2_get_size;
 				ops.fill_range = iwl_dump_ini_paging_gen2_iter;
 			}
-
-			iwl_dump_ini_mem(fwrt, data, reg, &ops);
+			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
 			break;
 		case IWL_FW_INI_REGION_TXF: {
 			struct iwl_ini_txf_iter_data iter = { .init = true };
@@ -1954,7 +1900,7 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
 			ops.get_size = iwl_dump_ini_txf_get_size;
 			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
 			ops.fill_range = iwl_dump_ini_txf_iter;
-			iwl_dump_ini_mem(fwrt, data, reg, &ops);
+			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
 			fwrt->dump.fifo_iter = fifo_iter;
 			break;
 		}
@@ -1963,14 +1909,14 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
 			ops.get_size = iwl_dump_ini_rxf_get_size;
 			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
 			ops.fill_range = iwl_dump_ini_rxf_iter;
-			iwl_dump_ini_mem(fwrt, data, reg, &ops);
+			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
 			break;
 		case IWL_FW_INI_REGION_CSR:
 			ops.get_num_of_ranges =	iwl_dump_ini_mem_ranges;
 			ops.get_size = iwl_dump_ini_mem_get_size;
 			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
 			ops.fill_range = iwl_dump_ini_csr_iter;
-			iwl_dump_ini_mem(fwrt, data, reg, &ops);
+			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
 			break;
 		case IWL_FW_INI_REGION_PERIPHERY_PHY:
 		case IWL_FW_INI_REGION_PERIPHERY_AUX:
@@ -1980,39 +1926,48 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
 			break;
 		}
 	}
+
+	if (size)
+		size += iwl_dump_ini_info(fwrt, trigger, list);
+
+	return size;
 }
 
-static struct iwl_fw_error_dump_file *
-iwl_fw_error_ini_dump_file(struct iwl_fw_runtime *fwrt,
-			   enum iwl_fw_ini_trigger_id trig_id)
+static u32 iwl_dump_ini_file_gen(struct iwl_fw_runtime *fwrt,
+				 enum iwl_fw_ini_trigger_id trig_id,
+				 struct list_head *list)
 {
-	int size;
-	struct iwl_fw_error_dump_data *dump_data;
-	struct iwl_fw_error_dump_file *dump_file;
+	struct iwl_fw_ini_dump_entry *entry;
+	struct iwl_fw_ini_dump_file_hdr *hdr;
 	struct iwl_fw_ini_trigger *trigger;
+	u32 size;
 
 	if (!iwl_fw_ini_trigger_on(fwrt, trig_id))
-		return NULL;
+		return 0;
 
 	trigger = fwrt->dump.active_trigs[trig_id].trig;
+	if (!trigger || !le32_to_cpu(trigger->num_regions))
+		return 0;
 
-	size = iwl_fw_ini_get_trigger_len(fwrt, trigger);
-	if (!size)
-		return NULL;
+	entry = kmalloc(sizeof(*entry) + sizeof(*hdr), GFP_KERNEL);
+	if (!entry)
+		return 0;
 
-	size += sizeof(*dump_file);
+	entry->size = sizeof(*hdr);
 
-	dump_file = vzalloc(size);
-	if (!dump_file)
-		return NULL;
+	size = iwl_dump_ini_trigger(fwrt, trigger, list);
+	if (!size) {
+		kfree(entry);
+		return 0;
+	}
 
-	dump_file->barker = cpu_to_le32(IWL_FW_INI_ERROR_DUMP_BARKER);
-	dump_data = (void *)dump_file->data;
-	dump_file->file_len = cpu_to_le32(size);
+	hdr = (void *)entry->data;
+	hdr->barker = cpu_to_le32(IWL_FW_INI_ERROR_DUMP_BARKER);
+	hdr->file_len = cpu_to_le32(size + entry->size);
 
-	iwl_fw_ini_dump_trigger(fwrt, trigger, &dump_data);
+	list_add(&entry->list, list);
 
-	return dump_file;
+	return le32_to_cpu(hdr->file_len);
 }
 
 static void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
@@ -2061,27 +2016,44 @@ static void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
 	iwl_fw_free_dump_desc(fwrt);
 }
 
+static void iwl_dump_ini_list_free(struct list_head *list)
+{
+	while (!list_empty(list)) {
+		struct iwl_fw_ini_dump_entry *entry =
+			list_entry(list->next, typeof(*entry), list);
+
+		list_del(&entry->list);
+		kfree(entry);
+	}
+}
+
 static void iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt, u8 wk_idx)
 {
 	enum iwl_fw_ini_trigger_id trig_id = fwrt->dump.wks[wk_idx].ini_trig_id;
-	struct iwl_fw_error_dump_file *dump_file;
+	struct list_head dump_list = LIST_HEAD_INIT(dump_list);
 	struct scatterlist *sg_dump_data;
 	u32 file_len;
 
-	dump_file = iwl_fw_error_ini_dump_file(fwrt, trig_id);
-	if (!dump_file)
+	file_len = iwl_dump_ini_file_gen(fwrt, trig_id, &dump_list);
+	if (!file_len)
 		goto out;
 
-	file_len = le32_to_cpu(dump_file->file_len);
-
 	sg_dump_data = alloc_sgtable(file_len);
 	if (sg_dump_data) {
-		sg_pcopy_from_buffer(sg_dump_data, sg_nents(sg_dump_data),
-				     dump_file, file_len, 0);
+		struct iwl_fw_ini_dump_entry *entry;
+		int sg_entries = sg_nents(sg_dump_data);
+		u32 offs = 0;
+
+		list_for_each_entry(entry, &dump_list, list) {
+			sg_pcopy_from_buffer(sg_dump_data, sg_entries,
+					     entry->data, entry->size, offs);
+			offs += entry->size;
+		}
 		dev_coredumpsg(fwrt->trans->dev, sg_dump_data, file_len,
 			       GFP_KERNEL);
 	}
-	vfree(dump_file);
+	iwl_dump_ini_list_free(&dump_list);
+
 out:
 	fwrt->dump.wks[wk_idx].ini_trig_id = IWL_FW_TRIGGER_ID_INVALID;
 }
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
index 00a45ea85b69..9529e5925ad5 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
@@ -287,6 +287,28 @@ struct iwl_fw_error_dump_mem {
 /* Use bit 31 as dump info type to avoid colliding with region types */
 #define IWL_INI_DUMP_INFO_TYPE BIT(31)
 
+/**
+ * struct iwl_fw_ini_dump_entry
+ * @list: list of dump entries
+ * @size: size of the data
+ * @data: entry data
+ */
+struct iwl_fw_ini_dump_entry {
+	struct list_head list;
+	u32 size;
+	u8 data[];
+} __packed;
+
+/**
+ * struct iwl_fw_error_dump_file - header of dump file
+ * @barker: must be %IWL_FW_INI_ERROR_DUMP_BARKER
+ * @file_len: the length of all the file including the header
+ */
+struct iwl_fw_ini_dump_file_hdr {
+	__le32 barker;
+	__le32 file_len;
+} __packed;
+
 /**
  * struct iwl_fw_ini_fifo_hdr - fifo range header
  * @fifo_num: the fifo number. In case of umac rx fifo, set BIT(31) to
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 17/19] iwlwifi: dbg_ini: move tx fifo data into fw runtime
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
                   ` (15 preceding siblings ...)
  2019-08-31  9:48 ` [PATCH 16/19] iwlwifi: dbg_ini: use linked list for dump TLVs during dump creation Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 18/19] iwlwifi: dbg_ini: make a single ops struct for paging collect Luca Coelho
  2019-08-31  9:48 ` [PATCH 19/19] iwlwifi: dbg_ini: use regions ops array instead of switch case in dump flow Luca Coelho
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Shahar S Matityahu <shahar.s.matityahu@intel.com>

Needed for future changes.

Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   | 53 +++++--------------
 .../net/wireless/intel/iwlwifi/fw/runtime.h   | 17 +++++-
 2 files changed, 28 insertions(+), 42 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 73af6e6a54c3..77eeca3eb3bf 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -1166,35 +1166,23 @@ iwl_dump_ini_mon_dram_iter(struct iwl_fw_runtime *fwrt,
 	return sizeof(*range) + le32_to_cpu(range->range_data_size);
 }
 
-struct iwl_ini_txf_iter_data {
-	int fifo;
-	int lmac;
-	u32 fifo_size;
-	bool internal_txf;
-	bool init;
-};
-
 static bool iwl_ini_txf_iter(struct iwl_fw_runtime *fwrt,
-			     struct iwl_fw_ini_region_cfg *reg)
+			     struct iwl_fw_ini_region_cfg *reg, int idx)
 {
-	struct iwl_ini_txf_iter_data *iter = fwrt->dump.fifo_iter;
+	struct iwl_txf_iter_data *iter = &fwrt->dump.txf_iter_data;
 	struct iwl_fwrt_shared_mem_cfg *cfg = &fwrt->smem_cfg;
 	int txf_num = cfg->num_txfifo_entries;
 	int int_txf_num = ARRAY_SIZE(cfg->internal_txfifo_size);
 	u32 lmac_bitmap = le32_to_cpu(reg->fifos.fid1);
 
-	if (!iter)
-		return false;
-
-	if (iter->init) {
+	if (!idx) {
 		if (le32_to_cpu(reg->offset) &&
 		    WARN_ONCE(cfg->num_lmacs == 1,
 			      "Invalid lmac offset: 0x%x\n",
 			      le32_to_cpu(reg->offset)))
 			return false;
 
-		iter->init = false;
-		iter->internal_txf = false;
+		iter->internal_txf = 0;
 		iter->fifo_size = 0;
 		iter->fifo = -1;
 		if (le32_to_cpu(reg->offset))
@@ -1211,7 +1199,7 @@ static bool iwl_ini_txf_iter(struct iwl_fw_runtime *fwrt,
 				return true;
 		}
 
-	iter->internal_txf = true;
+	iter->internal_txf = 1;
 
 	if (!fw_has_capa(&fwrt->fw->ucode_capa,
 			 IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG))
@@ -1232,7 +1220,7 @@ static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt,
 				 void *range_ptr, int idx)
 {
 	struct iwl_fw_ini_error_dump_range *range = range_ptr;
-	struct iwl_ini_txf_iter_data *iter;
+	struct iwl_txf_iter_data *iter = &fwrt->dump.txf_iter_data;
 	struct iwl_fw_ini_error_dump_register *reg_dump = (void *)range->data;
 	u32 offs = le32_to_cpu(reg->offset), addr;
 	u32 registers_size =
@@ -1241,14 +1229,12 @@ static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt,
 	unsigned long flags;
 	int i;
 
-	if (!iwl_ini_txf_iter(fwrt, reg))
+	if (!iwl_ini_txf_iter(fwrt, reg, idx))
 		return -EIO;
 
 	if (!iwl_trans_grab_nic_access(fwrt->trans, &flags))
 		return -EBUSY;
 
-	iter = fwrt->dump.fifo_iter;
-
 	range->fifo_hdr.fifo_num = cpu_to_le32(iter->fifo);
 	range->fifo_hdr.num_of_registers = reg->fifos.num_of_registers;
 	range->range_data_size = cpu_to_le32(iter->fifo_size + registers_size);
@@ -1520,16 +1506,11 @@ static u32 iwl_dump_ini_mon_dram_ranges(struct iwl_fw_runtime *fwrt,
 static u32 iwl_dump_ini_txf_ranges(struct iwl_fw_runtime *fwrt,
 				   struct iwl_fw_ini_region_cfg *reg)
 {
-	struct iwl_ini_txf_iter_data iter = { .init = true };
-	void *fifo_iter = fwrt->dump.fifo_iter;
 	u32 num_of_fifos = 0;
 
-	fwrt->dump.fifo_iter = &iter;
-	while (iwl_ini_txf_iter(fwrt, reg))
+	while (iwl_ini_txf_iter(fwrt, reg, num_of_fifos))
 		num_of_fifos++;
 
-	fwrt->dump.fifo_iter = fifo_iter;
-
 	return num_of_fifos;
 }
 
@@ -1602,25 +1583,21 @@ static u32 iwl_dump_ini_mon_smem_get_size(struct iwl_fw_runtime *fwrt,
 static u32 iwl_dump_ini_txf_get_size(struct iwl_fw_runtime *fwrt,
 				     struct iwl_fw_ini_region_cfg *reg)
 {
-	struct iwl_ini_txf_iter_data iter = { .init = true };
-	void *fifo_iter = fwrt->dump.fifo_iter;
+	struct iwl_txf_iter_data *iter = &fwrt->dump.txf_iter_data;
 	u32 size = 0;
 	u32 fifo_hdr = sizeof(struct iwl_fw_ini_error_dump_range) +
 		le32_to_cpu(reg->fifos.num_of_registers) *
 		sizeof(struct iwl_fw_ini_error_dump_register);
 
-	fwrt->dump.fifo_iter = &iter;
-	while (iwl_ini_txf_iter(fwrt, reg)) {
+	while (iwl_ini_txf_iter(fwrt, reg, size)) {
 		size += fifo_hdr;
 		if (!reg->fifos.header_only)
-			size += iter.fifo_size;
+			size += iter->fifo_size;
 	}
 
 	if (size)
 		size += sizeof(struct iwl_fw_ini_error_dump);
 
-	fwrt->dump.fifo_iter = fifo_iter;
-
 	return size;
 }
 
@@ -1891,19 +1868,13 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt,
 			}
 			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
 			break;
-		case IWL_FW_INI_REGION_TXF: {
-			struct iwl_ini_txf_iter_data iter = { .init = true };
-			void *fifo_iter = fwrt->dump.fifo_iter;
-
-			fwrt->dump.fifo_iter = &iter;
+		case IWL_FW_INI_REGION_TXF:
 			ops.get_num_of_ranges = iwl_dump_ini_txf_ranges;
 			ops.get_size = iwl_dump_ini_txf_get_size;
 			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
 			ops.fill_range = iwl_dump_ini_txf_iter;
 			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
-			fwrt->dump.fifo_iter = fifo_iter;
 			break;
-		}
 		case IWL_FW_INI_REGION_RXF:
 			ops.get_num_of_ranges = iwl_dump_ini_rxf_ranges;
 			ops.get_size = iwl_dump_ini_rxf_get_size;
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
index 0a4e13e4cc2c..40b92509085d 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
@@ -90,6 +90,20 @@ struct iwl_fwrt_shared_mem_cfg {
 
 #define IWL_FW_RUNTIME_DUMP_WK_NUM 5
 
+/**
+ * struct iwl_txf_iter_data - Tx fifo iterator data struct
+ * @fifo: fifo number
+ * @lmac: lmac number
+ * @fifo_size: fifo size
+ * @internal_txf: non zero if fifo is  internal Tx fifo
+ */
+struct iwl_txf_iter_data {
+	int fifo;
+	int lmac;
+	u32 fifo_size;
+	u8 internal_txf;
+};
+
 /**
  * struct iwl_fw_runtime - runtime data for firmware
  * @fw: firmware image
@@ -143,7 +157,8 @@ struct iwl_fw_runtime {
 		struct iwl_fw_ini_active_triggers active_trigs[IWL_FW_TRIGGER_ID_NUM];
 		u32 lmac_err_id[MAX_NUM_LMAC];
 		u32 umac_err_id;
-		void *fifo_iter;
+
+		struct iwl_txf_iter_data txf_iter_data;
 		struct timer_list periodic_trig;
 
 		u8 img_name[IWL_FW_INI_MAX_IMG_NAME_LEN];
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 18/19] iwlwifi: dbg_ini: make a single ops struct for paging collect
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
                   ` (16 preceding siblings ...)
  2019-08-31  9:48 ` [PATCH 17/19] iwlwifi: dbg_ini: move tx fifo data into fw runtime Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  2019-08-31  9:48 ` [PATCH 19/19] iwlwifi: dbg_ini: use regions ops array instead of switch case in dump flow Luca Coelho
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Shahar S Matityahu <shahar.s.matityahu@intel.com>

Needed for future changes.

Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 92 +++++++++------------
 1 file changed, 39 insertions(+), 53 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 77eeca3eb3bf..0c7035033f27 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -1106,25 +1106,9 @@ static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt,
 	return sizeof(*range) + le32_to_cpu(range->range_data_size);
 }
 
-static int
-iwl_dump_ini_paging_gen2_iter(struct iwl_fw_runtime *fwrt,
-			      struct iwl_fw_ini_region_cfg *reg,
-			      void *range_ptr, int idx)
-{
-	struct iwl_fw_ini_error_dump_range *range = range_ptr;
-	u32 page_size = fwrt->trans->init_dram.paging[idx].size;
-
-	range->page_num = cpu_to_le32(idx);
-	range->range_data_size = cpu_to_le32(page_size);
-	memcpy(range->data, fwrt->trans->init_dram.paging[idx].block,
-	       page_size);
-
-	return sizeof(*range) + le32_to_cpu(range->range_data_size);
-}
-
-static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt,
-				    struct iwl_fw_ini_region_cfg *reg,
-				    void *range_ptr, int idx)
+static int _iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt,
+				     struct iwl_fw_ini_region_cfg *reg,
+				     void *range_ptr, int idx)
 {
 	/* increase idx by 1 since the pages are from 1 to
 	 * fwrt->num_of_paging_blk + 1
@@ -1145,6 +1129,27 @@ static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt,
 	return sizeof(*range) + le32_to_cpu(range->range_data_size);
 }
 
+static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt,
+				    struct iwl_fw_ini_region_cfg *reg,
+				    void *range_ptr, int idx)
+{
+	struct iwl_fw_ini_error_dump_range *range;
+	u32 page_size;
+
+	if (!fwrt->trans->cfg->gen2)
+		return _iwl_dump_ini_paging_iter(fwrt, reg, range_ptr, idx);
+
+	range = range_ptr;
+	page_size = fwrt->trans->init_dram.paging[idx].size;
+
+	range->page_num = cpu_to_le32(idx);
+	range->range_data_size = cpu_to_le32(page_size);
+	memcpy(range->data, fwrt->trans->init_dram.paging[idx].block,
+	       page_size);
+
+	return sizeof(*range) + le32_to_cpu(range->range_data_size);
+}
+
 static int
 iwl_dump_ini_mon_dram_iter(struct iwl_fw_runtime *fwrt,
 			   struct iwl_fw_ini_region_cfg *reg, void *range_ptr,
@@ -1485,15 +1490,12 @@ static u32 iwl_dump_ini_mem_ranges(struct iwl_fw_runtime *fwrt,
 	return le32_to_cpu(reg->internal.num_of_ranges);
 }
 
-static u32 iwl_dump_ini_paging_gen2_ranges(struct iwl_fw_runtime *fwrt,
-					   struct iwl_fw_ini_region_cfg *reg)
-{
-	return fwrt->trans->init_dram.paging_cnt;
-}
-
 static u32 iwl_dump_ini_paging_ranges(struct iwl_fw_runtime *fwrt,
 				      struct iwl_fw_ini_region_cfg *reg)
 {
+	if (fwrt->trans->cfg->gen2)
+		return fwrt->trans->init_dram.paging_cnt;
+
 	return fwrt->num_of_paging_blk;
 }
 
@@ -1532,20 +1534,6 @@ static u32 iwl_dump_ini_mem_get_size(struct iwl_fw_runtime *fwrt,
 		 le32_to_cpu(reg->internal.range_data_size));
 }
 
-static u32 iwl_dump_ini_paging_gen2_get_size(struct iwl_fw_runtime *fwrt,
-					     struct iwl_fw_ini_region_cfg *reg)
-{
-	int i;
-	u32 range_header_len = sizeof(struct iwl_fw_ini_error_dump_range);
-	u32 size = sizeof(struct iwl_fw_ini_error_dump);
-
-	for (i = 0; i < iwl_dump_ini_paging_gen2_ranges(fwrt, reg); i++)
-		size += range_header_len +
-			fwrt->trans->init_dram.paging[i].size;
-
-	return size;
-}
-
 static u32 iwl_dump_ini_paging_get_size(struct iwl_fw_runtime *fwrt,
 					struct iwl_fw_ini_region_cfg *reg)
 {
@@ -1553,8 +1541,15 @@ static u32 iwl_dump_ini_paging_get_size(struct iwl_fw_runtime *fwrt,
 	u32 range_header_len = sizeof(struct iwl_fw_ini_error_dump_range);
 	u32 size = sizeof(struct iwl_fw_ini_error_dump);
 
-	for (i = 1; i <= iwl_dump_ini_paging_ranges(fwrt, reg); i++)
-		size += range_header_len + fwrt->fw_paging_db[i].fw_paging_size;
+	if (fwrt->trans->cfg->gen2) {
+		for (i = 0; i < iwl_dump_ini_paging_ranges(fwrt, reg); i++)
+			size += range_header_len +
+				fwrt->trans->init_dram.paging[i].size;
+	} else {
+		for (i = 1; i <= iwl_dump_ini_paging_ranges(fwrt, reg); i++)
+			size += range_header_len +
+				fwrt->fw_paging_db[i].fw_paging_size;
+	}
 
 	return size;
 }
@@ -1854,18 +1849,9 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt,
 			break;
 		case IWL_FW_INI_REGION_PAGING:
 			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
-			if (iwl_fw_dbg_is_paging_enabled(fwrt)) {
-				ops.get_num_of_ranges =
-					iwl_dump_ini_paging_ranges;
-				ops.get_size = iwl_dump_ini_paging_get_size;
-				ops.fill_range = iwl_dump_ini_paging_iter;
-			} else {
-				ops.get_num_of_ranges =
-					iwl_dump_ini_paging_gen2_ranges;
-				ops.get_size =
-					iwl_dump_ini_paging_gen2_get_size;
-				ops.fill_range = iwl_dump_ini_paging_gen2_iter;
-			}
+			ops.get_num_of_ranges = iwl_dump_ini_paging_ranges;
+			ops.get_size = iwl_dump_ini_paging_get_size;
+			ops.fill_range = iwl_dump_ini_paging_iter;
 			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
 			break;
 		case IWL_FW_INI_REGION_TXF:
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 19/19] iwlwifi: dbg_ini: use regions ops array instead of switch case in dump flow
  2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
                   ` (17 preceding siblings ...)
  2019-08-31  9:48 ` [PATCH 18/19] iwlwifi: dbg_ini: make a single ops struct for paging collect Luca Coelho
@ 2019-08-31  9:48 ` Luca Coelho
  18 siblings, 0 replies; 20+ messages in thread
From: Luca Coelho @ 2019-08-31  9:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

From: Shahar S Matityahu <shahar.s.matityahu@intel.com>

Make a static regions ops array and use it instead of switch case when
determining what op to use to collect a region.

Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 150 +++++++++++---------
 1 file changed, 79 insertions(+), 71 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 0c7035033f27..04afaec2d80e 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -1648,7 +1648,7 @@ struct iwl_dump_ini_mem_ops {
  */
 static u32 iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, struct list_head *list,
 			    struct iwl_fw_ini_region_cfg *reg,
-			    struct iwl_dump_ini_mem_ops *ops)
+			    const struct iwl_dump_ini_mem_ops *ops)
 {
 	struct iwl_fw_ini_dump_entry *entry;
 	struct iwl_fw_error_dump_data *tlv;
@@ -1656,8 +1656,8 @@ static u32 iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, struct list_head *list,
 	u32 num_of_ranges, i, type = le32_to_cpu(reg->region_type), size;
 	void *range;
 
-	if (WARN_ON(!ops || !ops->get_num_of_ranges || !ops->get_size ||
-		    !ops->fill_mem_hdr || !ops->fill_range))
+	if (!ops->get_num_of_ranges || !ops->get_size || !ops->fill_mem_hdr ||
+	    !ops->fill_range)
 		return 0;
 
 	size = ops->get_size(fwrt, reg);
@@ -1789,6 +1789,75 @@ static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,
 	return entry->size;
 }
 
+static const struct iwl_dump_ini_mem_ops iwl_dump_ini_region_ops[] = {
+	[IWL_FW_INI_REGION_INVALID] = {},
+	[IWL_FW_INI_REGION_DEVICE_MEMORY] = {
+		.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_dev_mem_iter,
+	},
+	[IWL_FW_INI_REGION_PERIPHERY_MAC] = {
+		.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,
+	},
+	[IWL_FW_INI_REGION_PERIPHERY_PHY] = {},
+	[IWL_FW_INI_REGION_PERIPHERY_AUX] = {},
+	[IWL_FW_INI_REGION_DRAM_BUFFER] = {
+		.get_num_of_ranges = iwl_dump_ini_mon_dram_ranges,
+		.get_size = iwl_dump_ini_mon_dram_get_size,
+		.fill_mem_hdr = iwl_dump_ini_mon_dram_fill_header,
+		.fill_range = iwl_dump_ini_mon_dram_iter,
+	},
+	[IWL_FW_INI_REGION_DRAM_IMR] = {},
+	[IWL_FW_INI_REGION_INTERNAL_BUFFER] = {
+		.get_num_of_ranges = iwl_dump_ini_mem_ranges,
+		.get_size = iwl_dump_ini_mon_smem_get_size,
+		.fill_mem_hdr = iwl_dump_ini_mon_smem_fill_header,
+		.fill_range = iwl_dump_ini_dev_mem_iter,
+	},
+	[IWL_FW_INI_REGION_TXF] = {
+		.get_num_of_ranges = iwl_dump_ini_txf_ranges,
+		.get_size = iwl_dump_ini_txf_get_size,
+		.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
+		.fill_range = iwl_dump_ini_txf_iter,
+	},
+	[IWL_FW_INI_REGION_RXF] = {
+		.get_num_of_ranges = iwl_dump_ini_rxf_ranges,
+		.get_size = iwl_dump_ini_rxf_get_size,
+		.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
+		.fill_range = iwl_dump_ini_rxf_iter,
+	},
+	[IWL_FW_INI_REGION_PAGING] = {
+		.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
+		.get_num_of_ranges = iwl_dump_ini_paging_ranges,
+		.get_size = iwl_dump_ini_paging_get_size,
+		.fill_range = iwl_dump_ini_paging_iter,
+	},
+	[IWL_FW_INI_REGION_CSR] = {
+		.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_csr_iter,
+	},
+	[IWL_FW_INI_REGION_NOTIFICATION] = {},
+	[IWL_FW_INI_REGION_DHC] = {},
+	[IWL_FW_INI_REGION_LMAC_ERROR_TABLE] = {
+		.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_dev_mem_iter,
+	},
+	[IWL_FW_INI_REGION_UMAC_ERROR_TABLE] = {
+		.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_dev_mem_iter,
+	},
+};
+
 static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt,
 				struct iwl_fw_ini_trigger *trigger,
 				struct list_head *list)
@@ -1797,9 +1866,8 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt,
 	u32 size = 0;
 
 	for (i = 0; i < le32_to_cpu(trigger->num_regions); i++) {
-		u32 reg_id = le32_to_cpu(trigger->data[i]);
+		u32 reg_id = le32_to_cpu(trigger->data[i]), reg_type;
 		struct iwl_fw_ini_region_cfg *reg;
-		struct iwl_dump_ini_mem_ops ops;
 
 		if (WARN_ON(reg_id >= ARRAY_SIZE(fwrt->dump.active_regs)))
 			continue;
@@ -1816,72 +1884,12 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt,
 		if (le32_to_cpu(reg->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON)
 			continue;
 
-		switch (le32_to_cpu(reg->region_type)) {
-		case IWL_FW_INI_REGION_DEVICE_MEMORY:
-		case IWL_FW_INI_REGION_LMAC_ERROR_TABLE:
-		case IWL_FW_INI_REGION_UMAC_ERROR_TABLE:
-			ops.get_num_of_ranges = iwl_dump_ini_mem_ranges;
-			ops.get_size = iwl_dump_ini_mem_get_size;
-			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
-			ops.fill_range = iwl_dump_ini_dev_mem_iter;
-			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
-			break;
-		case IWL_FW_INI_REGION_PERIPHERY_MAC:
-			ops.get_num_of_ranges =	iwl_dump_ini_mem_ranges;
-			ops.get_size = iwl_dump_ini_mem_get_size;
-			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
-			ops.fill_range = iwl_dump_ini_prph_iter;
-			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
-			break;
-		case IWL_FW_INI_REGION_DRAM_BUFFER:
-			ops.get_num_of_ranges = iwl_dump_ini_mon_dram_ranges;
-			ops.get_size = iwl_dump_ini_mon_dram_get_size;
-			ops.fill_mem_hdr = iwl_dump_ini_mon_dram_fill_header;
-			ops.fill_range = iwl_dump_ini_mon_dram_iter;
-			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
-			break;
-		case IWL_FW_INI_REGION_INTERNAL_BUFFER:
-			ops.get_num_of_ranges = iwl_dump_ini_mem_ranges;
-			ops.get_size = iwl_dump_ini_mon_smem_get_size;
-			ops.fill_mem_hdr = iwl_dump_ini_mon_smem_fill_header;
-			ops.fill_range = iwl_dump_ini_dev_mem_iter;
-			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
-			break;
-		case IWL_FW_INI_REGION_PAGING:
-			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
-			ops.get_num_of_ranges = iwl_dump_ini_paging_ranges;
-			ops.get_size = iwl_dump_ini_paging_get_size;
-			ops.fill_range = iwl_dump_ini_paging_iter;
-			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
-			break;
-		case IWL_FW_INI_REGION_TXF:
-			ops.get_num_of_ranges = iwl_dump_ini_txf_ranges;
-			ops.get_size = iwl_dump_ini_txf_get_size;
-			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
-			ops.fill_range = iwl_dump_ini_txf_iter;
-			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
-			break;
-		case IWL_FW_INI_REGION_RXF:
-			ops.get_num_of_ranges = iwl_dump_ini_rxf_ranges;
-			ops.get_size = iwl_dump_ini_rxf_get_size;
-			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
-			ops.fill_range = iwl_dump_ini_rxf_iter;
-			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
-			break;
-		case IWL_FW_INI_REGION_CSR:
-			ops.get_num_of_ranges =	iwl_dump_ini_mem_ranges;
-			ops.get_size = iwl_dump_ini_mem_get_size;
-			ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
-			ops.fill_range = iwl_dump_ini_csr_iter;
-			size += iwl_dump_ini_mem(fwrt, list, reg, &ops);
-			break;
-		case IWL_FW_INI_REGION_PERIPHERY_PHY:
-		case IWL_FW_INI_REGION_PERIPHERY_AUX:
-		case IWL_FW_INI_REGION_DRAM_IMR:
-			/* This is undefined yet */
-		default:
-			break;
-		}
+		reg_type = le32_to_cpu(reg->region_type);
+		if (reg_type >= ARRAY_SIZE(iwl_dump_ini_region_ops))
+			continue;
+
+		size += iwl_dump_ini_mem(fwrt, list, reg,
+					 &iwl_dump_ini_region_ops[reg_type]);
 	}
 
 	if (size)
-- 
2.23.0.rc1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2019-08-31  9:53 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-31  9:48 [PATCH 00/19] iwlwifi: updates intended for v5.4 2019-08-31 Luca Coelho
2019-08-31  9:48 ` [PATCH 01/19] iwlwifi: stop passing bogus gfp flags arguments to dma_alloc_coherent Luca Coelho
2019-08-31  9:48 ` [PATCH 02/19] iwlwifi: mvm: simplify the channel switch flow for newer firmware Luca Coelho
2019-08-31  9:48 ` [PATCH 03/19] iwlwifi: mvm: remove check for lq_sta in __iwl_mvm_rs_tx_status() Luca Coelho
2019-08-31  9:48 ` [PATCH 04/19] iwlwifi: support per-platform antenna gain Luca Coelho
2019-08-31  9:48 ` [PATCH 05/19] iwlwifi: api: fix FTM struct documentation Luca Coelho
2019-08-31  9:48 ` [PATCH 06/19] iwlwifi: bump FW API to 50 for 22000 series Luca Coelho
2019-08-31  9:48 ` [PATCH 07/19] iwlwifi: remove duplicate FW string definitions Luca Coelho
2019-08-31  9:48 ` [PATCH 08/19] iwlwifi: dbg_ini: use function to check if ini dbg mode is on Luca Coelho
2019-08-31  9:48 ` [PATCH 09/19] iwlwifi: dbg_ini: verify debug TLVs at allocation phase Luca Coelho
2019-08-31  9:48 ` [PATCH 10/19] iwlwifi: dbg_ini: remove debug flow TLV Luca Coelho
2019-08-31  9:48 ` [PATCH 11/19] iwlwifi: dbg: align wrt log prints to the same format Luca Coelho
2019-08-31  9:48 ` [PATCH 12/19] iwlwifi: remove unnecessary IWL_DEVICE_AX200_COMMON definition Luca Coelho
2019-08-31  9:48 ` [PATCH 13/19] iwlwifi: allocate bigger nvm data in case of UHB Luca Coelho
2019-08-31  9:48 ` [PATCH 14/19] iwlwifi: mvm: look for the first supported channel when add/remove phy ctxt Luca Coelho
2019-08-31  9:48 ` [PATCH 15/19] iwlwifi: dbg_ini: separate cfg and dump flows to different modules Luca Coelho
2019-08-31  9:48 ` [PATCH 16/19] iwlwifi: dbg_ini: use linked list for dump TLVs during dump creation Luca Coelho
2019-08-31  9:48 ` [PATCH 17/19] iwlwifi: dbg_ini: move tx fifo data into fw runtime Luca Coelho
2019-08-31  9:48 ` [PATCH 18/19] iwlwifi: dbg_ini: make a single ops struct for paging collect Luca Coelho
2019-08-31  9:48 ` [PATCH 19/19] iwlwifi: dbg_ini: use regions ops array instead of switch case in dump flow Luca Coelho

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).