mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02: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
					
				
					 4 changed files with 170 additions and 0 deletions
				
			
		| 
						 | 
					@ -2393,6 +2393,7 @@ enum ice_aqc_fw_logging_mod {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Set FW Logging configuration (indirect 0xFF30)
 | 
					/* Set FW Logging configuration (indirect 0xFF30)
 | 
				
			||||||
 | 
					 * Register for FW Logging (indirect 0xFF31)
 | 
				
			||||||
 * Query FW Logging (indirect 0xFF32)
 | 
					 * Query FW Logging (indirect 0xFF32)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct ice_aqc_fw_log {
 | 
					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_CONF_AQ_EN	BIT(1)
 | 
				
			||||||
#define ICE_AQC_FW_LOG_QUERY_REGISTERED	BIT(2)
 | 
					#define ICE_AQC_FW_LOG_QUERY_REGISTERED	BIT(2)
 | 
				
			||||||
#define ICE_AQC_FW_LOG_CONF_SET_VALID	BIT(3)
 | 
					#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)
 | 
					#define ICE_AQC_FW_LOG_AQ_QUERY		BIT(2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	u8 rsp_flag;
 | 
						u8 rsp_flag;
 | 
				
			||||||
| 
						 | 
					@ -2722,6 +2724,7 @@ enum ice_adminq_opc {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* FW Logging Commands */
 | 
						/* FW Logging Commands */
 | 
				
			||||||
	ice_aqc_opc_fw_logs_config			= 0xFF30,
 | 
						ice_aqc_opc_fw_logs_config			= 0xFF30,
 | 
				
			||||||
 | 
						ice_aqc_opc_fw_logs_register			= 0xFF31,
 | 
				
			||||||
	ice_aqc_opc_fw_logs_query			= 0xFF32,
 | 
						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,
 | 
						.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
 | 
					 * ice_debugfs_fwlog_init - setup the debugfs directory
 | 
				
			||||||
 * @pf: the ice that is starting up
 | 
					 * @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;
 | 
						pf->ice_debugfs_pf_fwlog_modules = fw_modules;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						debugfs_create_file("enable", 0600, pf->ice_debugfs_pf_fwlog,
 | 
				
			||||||
 | 
								    pf, &ice_debugfs_enable_fops);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
err_create_module_files:
 | 
					err_create_module_files:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,6 +63,11 @@ void ice_fwlog_deinit(struct ice_hw *hw)
 | 
				
			||||||
	kfree(pf->ice_debugfs_pf_fwlog_modules);
 | 
						kfree(pf->ice_debugfs_pf_fwlog_modules);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pf->ice_debugfs_pf_fwlog_modules = NULL;
 | 
						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;
 | 
							cfg->options |= ICE_FWLOG_OPTION_ARQ_ENA;
 | 
				
			||||||
	if (cmd->cmd_flags & ICE_AQC_FW_LOG_CONF_UART_EN)
 | 
						if (cmd->cmd_flags & ICE_AQC_FW_LOG_CONF_UART_EN)
 | 
				
			||||||
		cfg->options |= ICE_FWLOG_OPTION_UART_ENA;
 | 
							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;
 | 
						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);
 | 
						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
 | 
					 * ice_fwlog_set_supported - Set if FW logging is supported by FW
 | 
				
			||||||
 * @hw: pointer to the HW struct
 | 
					 * @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);
 | 
					void ice_fwlog_deinit(struct ice_hw *hw);
 | 
				
			||||||
int ice_fwlog_set(struct ice_hw *hw, struct ice_fwlog_cfg *cfg);
 | 
					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_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_ */
 | 
					#endif /* _ICE_FWLOG_H_ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue