[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