[Intel-wired-lan] [PATCH net-next v11 3/5] ice: add ability to set FW log configuration

Paul M Stillwell Jr paul.m.stillwell.jr at intel.com
Mon Mar 13 23:18:39 UTC 2023


The FW log has several configuration options to control what gets output
and how often it gets output. Allow the user to set the log level,
events, and how often the FW generates messages with data in them
(resolution).

The command to set the configuration looks like:

update fwlog_cfg <fwlog_level> <fwlog_events> <fwlog_resolution>

where
fwlog_level is a value from 0-4 as described below
    Each level includes the messages from the previous/lower level
	0 - no logging
	1 - error logging
	2 - warning logging
	3 - normal logging
	4 - verbose logging

fwlog_events is a value from 0-32 that represents the module to receive
events for. The values are sent as a hex value where each bit represents
a specific module. The module values are:
	0 (0x00) - General
	1 (0x01) - Control (Resets + Autoload)
	2 (0x02) - Link Management
	3 (0x03) - Link Topology Detection
	4 (0x04) - DNL
	5 (0x05) - I2C
	6 (0x06) - SDP
	7 (0x07) - MDIO
	8 (0x08) - Admin Queue
	9 (0x09) - HDMA
	10 (0x0A) - LLDP
	11 (0x0B) - DCBX
	12 (0x0C) - DCB
	13 (0x0D) - XLR
	14 (0x0E) - NVM
	15 (0x0F) - Authentication
	16 (0x10) - VPD
	17 (0x11) - IOSF
	18 (0x12) - Parser
	19 (0x13) - Switch
	20 (0x14) - Scheduler
	21 (0x15) - Tx Queue Management
	22 (0x16) - Unsupported
	23 (0x17) - Post
	24 (0x18) - Watchdog
	25 (0x19) - Task Dispatcher
	26 (0x1A) - Manageability
	27 (0x1B) - Synce
	28 (0x1C) - Health
	29 (0x1D) - Time Sync
	30 (0x1E) - PF Registration
	31 (0x1F) - Module Version

fwlog_resolution is the number of log messages to included
in a single ARQ event. The range is 1-128 (1 means push every log
message, 128 means push only when the max AQ command buffer is full).
The suggested value is 10.

An example command to update the FW log configuration is:

echo update fwlog_cfg 4 0x82414821 50 > /sys/kernel/debug/ice/0000\:18\:00.0/fwlog

The above command would set the log level to 4 (Verbose) for the
following modules
        0 (0x00) - General
        5 (0x05) - I2C
        11 (0x0B) - DCBX
        14 (0x0E) - NVM
        16 (0x10) - VPD
        22 (0x16) - Unsupported
        25 (0x19) - Task Dispatcher
        31 (0x1F) - Module Version

The setting of the configuration does NOT enable FW logging, that is a
separate command. There are effectively 2 configurations at this point:
the one that is currently running and the staged configuration.

To allow the user to see what is going on the 'dump fwlog_cfg' command
now shows the 'Running' config and the 'Staged' config. This allows the
user to be able to compare the currently running configuration with
what will be enabled when the user executes the command to enable the
staged configuration.

Co-developed-by: Brett Creeley <brett.creeley at intel.com>
Signed-off-by: Brett Creeley <brett.creeley at intel.com>
Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr at intel.com>
---
v11:
- changed 'events' variable to be u32 instead of unsigned long since
  the FW expects a 32-bit value. This caused some changes to a few
  functions that pass 'events' and changed the parsing in debugfs.
  Also fixed an issue with i386 cross compile where BIT_ULL() was
  being used incorrectly and causing compiler issues on i386 because
  the value was larger than the variable.

v10 at:
https://lore.kernel.org/intel-wired-lan/20230308235102.170-4-paul.m.stillwell.jr@intel.com/
---
 drivers/net/ethernet/intel/ice/ice.h          |  2 +-
 .../net/ethernet/intel/ice/ice_adminq_cmd.h   |  3 ++
 drivers/net/ethernet/intel/ice/ice_debugfs.c  | 35 ++++++++++++++++++
 drivers/net/ethernet/intel/ice/ice_main.c     | 37 +++++++++++++++++++
 4 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
index 5b44e400b740..8269f033e84d 100644
--- a/drivers/net/ethernet/intel/ice/ice.h
+++ b/drivers/net/ethernet/intel/ice/ice.h
@@ -879,7 +879,7 @@ void ice_debugfs_init(void);
 void ice_debugfs_exit(void);
 int
 ice_pf_fwlog_update_modules(struct ice_pf *pf, u8 log_level,
-			    unsigned long events);
+			    u32 events);
 #else
 static inline void ice_debugfs_fwlog_init(struct ice_pf *pf) { }
 static inline void ice_debugfs_init(void) { }
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
index 80e5376ca064..558a17d38918 100644
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
@@ -2092,6 +2092,9 @@ struct ice_aqc_fw_log {
 		} sync;
 		struct {
 			__le16 log_resolution;
+#define ICE_AQC_FW_LOG_MIN_RESOLUTION		(1)
+#define ICE_AQC_FW_LOG_MAX_RESOLUTION		(128)
+
 			__le16 mdl_cnt;
 		} cfg;
 	} ops;
diff --git a/drivers/net/ethernet/intel/ice/ice_debugfs.c b/drivers/net/ethernet/intel/ice/ice_debugfs.c
index 1319ec3e97b1..cb1b578e929e 100644
--- a/drivers/net/ethernet/intel/ice/ice_debugfs.c
+++ b/drivers/net/ethernet/intel/ice/ice_debugfs.c
@@ -146,6 +146,8 @@ static void ice_fwlog_dump_cfg(struct ice_hw *hw)
 
 	dev_info(dev, "Running FWLOG Configuration:\n");
 	ice_print_fwlog_config(hw, cfg);
+	dev_info(dev, "Staged FWLOG Configuration:\n");
+	ice_print_fwlog_config(hw, &hw->fwlog_cfg);
 
 	kfree(cfg);
 }
@@ -199,10 +201,43 @@ ice_debugfs_command_write(struct file *filp, const char __user *buf,
 	if (argc == 2 && !strncmp(argv[0], "dump", 4) &&
 	    !strncmp(argv[1], "fwlog_cfg", 9)) {
 		ice_fwlog_dump_cfg(&pf->hw);
+	} else if (argc == 5 && !strncmp(argv[0], "update", 6) &&
+		   !strncmp(argv[1], "fwlog_cfg", 9)) {
+		struct ice_hw *hw = &pf->hw;
+		u8 log_level, resolution;
+		u32 events;
+
+		ret = kstrtou8(argv[2], 0, &log_level);
+		if (ret)
+			goto command_write_error;
+
+		ret = kstrtouint(argv[3], 0, &events);
+		if (ret)
+			goto command_write_error;
+
+		ret = kstrtou8(argv[4], 0, &resolution);
+		if (ret)
+			goto command_write_error;
+
+		if (resolution < ICE_AQC_FW_LOG_MIN_RESOLUTION ||
+		    resolution > ICE_AQC_FW_LOG_MAX_RESOLUTION) {
+			dev_err(dev, "Invalid FW log resolution %d, value must be between %d - %d\n",
+				resolution, ICE_AQC_FW_LOG_MIN_RESOLUTION,
+				ICE_AQC_FW_LOG_MAX_RESOLUTION);
+			ret = -EINVAL;
+			goto command_write_error;
+		}
+
+		ret = ice_pf_fwlog_update_modules(pf, log_level, events);
+		if (ret)
+			goto command_write_error;
+
+		hw->fwlog_cfg.log_resolution = resolution;
 	} else {
 		dev_info(dev, "unknown or invalid command '%s'\n", cmd_buf);
 		dev_info(dev, "available commands\n");
 		dev_info(dev, "\t dump fwlog_cfg\n");
+		dev_info(dev, "\t update fwlog_cfg <fwlog_level> <fwlog_events> <fwlog_resolution>");
 		ret = -EINVAL;
 		goto command_write_error;
 	}
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 47b95a1185f6..a5ce84d84843 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -4552,6 +4552,43 @@ static void ice_print_wake_reason(struct ice_pf *pf)
 	dev_info(ice_pf_to_dev(pf), "Wake reason: %s", wake_str);
 }
 
+/**
+ * ice_pf_fwlog_update_modules - update 1 or more modules via debugfs
+ * @pf: pointer to the PF struct
+ * @log_level: log_level to use for the @events
+ * @events: events to update
+ */
+int ice_pf_fwlog_update_modules(struct ice_pf *pf, u8 log_level,
+				u32 events)
+{
+	struct ice_fwlog_module_entry *entries;
+	struct ice_hw *hw = &pf->hw;
+	u16 max_bits;
+	int i;
+
+	if (log_level >= ICE_FWLOG_LEVEL_INVALID) {
+		dev_err(ice_pf_to_dev(pf), "Invalid FW log level %u, all level(s) >= %u are invalid\n",
+			log_level, ICE_FWLOG_LEVEL_INVALID);
+		return -EINVAL;
+	}
+
+	entries = (struct ice_fwlog_module_entry *)hw->fwlog_cfg.module_entries;
+
+	max_bits = min_t(u32, BITS_PER_TYPE(u32),
+			 ICE_AQC_FW_LOG_ID_MAX);
+
+	/* look for the set bits in events. the driver can't use any of the
+	 * built in bitops because they all need an unsigned long type which
+	 * events is not
+	 */
+	for (i = 0; i < max_bits; i++) {
+		if (BIT(i) & events)
+			entries[i].log_level = log_level;
+	}
+
+	return 0;
+}
+
 /**
  * ice_register_netdev - register netdev
  * @vsi: pointer to the VSI struct
-- 
2.35.1



More information about the Intel-wired-lan mailing list