mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 07:31:29 +00:00
ice: enable FW logging
Once users have configured the FW logging then allow them to enable it by writing to the 'fwlog/enable' file. The file accepts a boolean value (0 or 1) where 1 means enable FW logging and 0 means disable FW logging. # echo <value> > /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/enable Where <value> is 0 or 1. The user can read the 'fwlog/enable' file to see whether logging is enabled or not. Reading the actual data is a separate patch. To see the current value then: # cat /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/enable Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com> Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel) Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
parent
96a9a9341c
commit
73671c3162
@ -2393,6 +2393,7 @@ enum ice_aqc_fw_logging_mod {
|
||||
};
|
||||
|
||||
/* Set FW Logging configuration (indirect 0xFF30)
|
||||
* Register for FW Logging (indirect 0xFF31)
|
||||
* Query FW Logging (indirect 0xFF32)
|
||||
*/
|
||||
struct ice_aqc_fw_log {
|
||||
@ -2401,6 +2402,7 @@ struct ice_aqc_fw_log {
|
||||
#define ICE_AQC_FW_LOG_CONF_AQ_EN BIT(1)
|
||||
#define ICE_AQC_FW_LOG_QUERY_REGISTERED BIT(2)
|
||||
#define ICE_AQC_FW_LOG_CONF_SET_VALID BIT(3)
|
||||
#define ICE_AQC_FW_LOG_AQ_REGISTER BIT(0)
|
||||
#define ICE_AQC_FW_LOG_AQ_QUERY BIT(2)
|
||||
|
||||
u8 rsp_flag;
|
||||
@ -2722,6 +2724,7 @@ enum ice_adminq_opc {
|
||||
|
||||
/* FW Logging Commands */
|
||||
ice_aqc_opc_fw_logs_config = 0xFF30,
|
||||
ice_aqc_opc_fw_logs_register = 0xFF31,
|
||||
ice_aqc_opc_fw_logs_query = 0xFF32,
|
||||
};
|
||||
|
||||
|
@ -281,6 +281,101 @@ static const struct file_operations ice_debugfs_nr_messages_fops = {
|
||||
.write = ice_debugfs_nr_messages_write,
|
||||
};
|
||||
|
||||
/**
|
||||
* ice_debugfs_enable_read - read from 'enable' file
|
||||
* @filp: the opened file
|
||||
* @buffer: where to write the data for the user to read
|
||||
* @count: the size of the user's buffer
|
||||
* @ppos: file position offset
|
||||
*/
|
||||
static ssize_t ice_debugfs_enable_read(struct file *filp,
|
||||
char __user *buffer, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct ice_pf *pf = filp->private_data;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
char buff[32] = {};
|
||||
|
||||
snprintf(buff, sizeof(buff), "%u\n",
|
||||
(u16)(hw->fwlog_cfg.options &
|
||||
ICE_FWLOG_OPTION_IS_REGISTERED) >> 3);
|
||||
|
||||
return simple_read_from_buffer(buffer, count, ppos, buff, strlen(buff));
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_debugfs_enable_write - write into 'enable' file
|
||||
* @filp: the opened file
|
||||
* @buf: where to find the user's data
|
||||
* @count: the length of the user's data
|
||||
* @ppos: file position offset
|
||||
*/
|
||||
static ssize_t
|
||||
ice_debugfs_enable_write(struct file *filp, const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ice_pf *pf = filp->private_data;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
char user_val[8], *cmd_buf;
|
||||
bool enable;
|
||||
ssize_t ret;
|
||||
|
||||
/* don't allow partial writes or invalid input */
|
||||
if (*ppos != 0 || count > 2)
|
||||
return -EINVAL;
|
||||
|
||||
cmd_buf = memdup_user(buf, count);
|
||||
if (IS_ERR(cmd_buf))
|
||||
return PTR_ERR(cmd_buf);
|
||||
|
||||
ret = sscanf(cmd_buf, "%s", user_val);
|
||||
if (ret != 1)
|
||||
return -EINVAL;
|
||||
|
||||
ret = kstrtobool(user_val, &enable);
|
||||
if (ret)
|
||||
goto enable_write_error;
|
||||
|
||||
if (enable)
|
||||
hw->fwlog_cfg.options |= ICE_FWLOG_OPTION_ARQ_ENA;
|
||||
else
|
||||
hw->fwlog_cfg.options &= ~ICE_FWLOG_OPTION_ARQ_ENA;
|
||||
|
||||
ret = ice_fwlog_set(hw, &hw->fwlog_cfg);
|
||||
if (ret)
|
||||
goto enable_write_error;
|
||||
|
||||
if (enable)
|
||||
ret = ice_fwlog_register(hw);
|
||||
else
|
||||
ret = ice_fwlog_unregister(hw);
|
||||
|
||||
if (ret)
|
||||
goto enable_write_error;
|
||||
|
||||
/* if we get here, nothing went wrong; return count since we didn't
|
||||
* really write anything
|
||||
*/
|
||||
ret = (ssize_t)count;
|
||||
|
||||
enable_write_error:
|
||||
/* This function always consumes all of the written input, or produces
|
||||
* an error. Check and enforce this. Otherwise, the write operation
|
||||
* won't complete properly.
|
||||
*/
|
||||
if (WARN_ON(ret != (ssize_t)count && ret >= 0))
|
||||
ret = -EIO;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations ice_debugfs_enable_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.read = ice_debugfs_enable_read,
|
||||
.write = ice_debugfs_enable_write,
|
||||
};
|
||||
|
||||
/**
|
||||
* ice_debugfs_fwlog_init - setup the debugfs directory
|
||||
* @pf: the ice that is starting up
|
||||
@ -332,6 +427,9 @@ void ice_debugfs_fwlog_init(struct ice_pf *pf)
|
||||
|
||||
pf->ice_debugfs_pf_fwlog_modules = fw_modules;
|
||||
|
||||
debugfs_create_file("enable", 0600, pf->ice_debugfs_pf_fwlog,
|
||||
pf, &ice_debugfs_enable_fops);
|
||||
|
||||
return;
|
||||
|
||||
err_create_module_files:
|
||||
|
@ -63,6 +63,11 @@ void ice_fwlog_deinit(struct ice_hw *hw)
|
||||
kfree(pf->ice_debugfs_pf_fwlog_modules);
|
||||
|
||||
pf->ice_debugfs_pf_fwlog_modules = NULL;
|
||||
|
||||
status = ice_fwlog_unregister(hw);
|
||||
if (status)
|
||||
dev_warn(ice_hw_to_dev(hw), "Unable to unregister FW logging, status: %d\n",
|
||||
status);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -197,6 +202,8 @@ static int ice_aq_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg)
|
||||
cfg->options |= ICE_FWLOG_OPTION_ARQ_ENA;
|
||||
if (cmd->cmd_flags & ICE_AQC_FW_LOG_CONF_UART_EN)
|
||||
cfg->options |= ICE_FWLOG_OPTION_UART_ENA;
|
||||
if (cmd->cmd_flags & ICE_AQC_FW_LOG_QUERY_REGISTERED)
|
||||
cfg->options |= ICE_FWLOG_OPTION_IS_REGISTERED;
|
||||
|
||||
fw_modules = (struct ice_aqc_fw_log_cfg_resp *)buf;
|
||||
|
||||
@ -226,6 +233,66 @@ int ice_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg)
|
||||
return ice_aq_fwlog_get(hw, cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_aq_fwlog_register - Register PF for firmware logging events (0xFF31)
|
||||
* @hw: pointer to the HW structure
|
||||
* @reg: true to register and false to unregister
|
||||
*/
|
||||
static int ice_aq_fwlog_register(struct ice_hw *hw, bool reg)
|
||||
{
|
||||
struct ice_aq_desc desc;
|
||||
|
||||
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logs_register);
|
||||
|
||||
if (reg)
|
||||
desc.params.fw_log.cmd_flags = ICE_AQC_FW_LOG_AQ_REGISTER;
|
||||
|
||||
return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_fwlog_register - Register the PF for firmware logging
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* After this call the PF will start to receive firmware logging based on the
|
||||
* configuration set in ice_fwlog_set.
|
||||
*/
|
||||
int ice_fwlog_register(struct ice_hw *hw)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (!ice_fwlog_supported(hw))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
status = ice_aq_fwlog_register(hw, true);
|
||||
if (status)
|
||||
ice_debug(hw, ICE_DBG_FW_LOG, "Failed to register for firmware logging events over ARQ\n");
|
||||
else
|
||||
hw->fwlog_cfg.options |= ICE_FWLOG_OPTION_IS_REGISTERED;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_fwlog_unregister - Unregister the PF from firmware logging
|
||||
* @hw: pointer to the HW structure
|
||||
*/
|
||||
int ice_fwlog_unregister(struct ice_hw *hw)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (!ice_fwlog_supported(hw))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
status = ice_aq_fwlog_register(hw, false);
|
||||
if (status)
|
||||
ice_debug(hw, ICE_DBG_FW_LOG, "Failed to unregister from firmware logging events over ARQ\n");
|
||||
else
|
||||
hw->fwlog_cfg.options &= ~ICE_FWLOG_OPTION_IS_REGISTERED;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_fwlog_set_supported - Set if FW logging is supported by FW
|
||||
* @hw: pointer to the HW struct
|
||||
|
@ -53,4 +53,6 @@ int ice_fwlog_init(struct ice_hw *hw);
|
||||
void ice_fwlog_deinit(struct ice_hw *hw);
|
||||
int ice_fwlog_set(struct ice_hw *hw, struct ice_fwlog_cfg *cfg);
|
||||
int ice_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg);
|
||||
int ice_fwlog_register(struct ice_hw *hw);
|
||||
int ice_fwlog_unregister(struct ice_hw *hw);
|
||||
#endif /* _ICE_FWLOG_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user