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

Paul M Stillwell Jr paul.m.stillwell.jr at intel.com
Wed Mar 8 23:51:00 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>
---
 .../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 +++++++++++++++++++
 3 files changed, 75 insertions(+)

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..7cc1621fb237 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;
+		unsigned long events;
+
+		ret = kstrtou8(argv[2], 0, &log_level);
+		if (ret)
+			goto command_write_error;
+
+		ret = kstrtoul(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..ee13518e3c65 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,
+				unsigned long events)
+{
+	struct ice_fwlog_module_entry *entries;
+	struct ice_hw *hw = &pf->hw;
+	u16 module_id, max_bits;
+
+	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;
+	}
+
+	if (events >= BIT_ULL(ICE_AQC_FW_LOG_ID_MAX)) {
+		dev_err(ice_pf_to_dev(pf), "Invalid FW log events 0x%lx, all FW log event bits >= 0x%llx are invalid\n",
+			events, BIT_ULL(ICE_AQC_FW_LOG_ID_MAX));
+		return -EINVAL;
+	}
+
+	entries = (struct ice_fwlog_module_entry *)hw->fwlog_cfg.module_entries;
+
+	max_bits = min_t(u16, BITS_PER_TYPE(unsigned long),
+			 ICE_AQC_FW_LOG_ID_MAX);
+
+	for_each_set_bit(module_id, &events, max_bits) {
+		entries[module_id].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