Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F152998900
D53973.id175192.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
37 KB
Referenced Files
None
Subscribers
None
D53973.id175192.diff
View Options
diff --git a/share/man/man4/ix.4 b/share/man/man4/ix.4
--- a/share/man/man4/ix.4
+++ b/share/man/man4/ix.4
@@ -138,7 +138,7 @@
driver supports the following
.Xr sysctl 8
variables:
-.Bl -tag -width "dev.ix.?.debug.dump.clusters"
+.Bl -tag -width "dev.ix.?.debug.fw_log.severity.<module>"
.It Va dev.ix.?.debug.dump.clusters
Specify a bitmask to select firmware event clusters
to be included in the debug dump.
@@ -160,6 +160,38 @@
and decoded by Intel Customer Support.
.Pp
This feature is only supported on E610.
+.It Va dev.ix.?.debug.fw_log.severity.<module>
+Specify firmware logging verbosity level for the specified module.
+Available levels include:
+.Pp
+.Bl -tag -compact
+.It 0
+none
+.It 1
+error
+.It 2
+warning
+.It 3
+normal
+.It 4
+verbose
+.El
+.Pp
+Supported modules: general, ctrl, link, link_topo, dnl, i2c, sdp, mdio,
+adminq, hdma, lldp, dcbx, dcb, xlr, nvm, auth, vpd, iosf, parser, sw,
+scheduler, txq, acl, post, watchdog, task_dispatch, mng, synce, health,
+tsdrv, pfreg, mdlver.
+.Pp
+This feature is only supported on E610 devices.
+.It Va dev.ix.?.debug.fw_log.register
+Specify 1 to apply per-device firmware logging configuration.
+.Pp
+This feature is only supported on E610 devices.
+.It Va dev.ix.?.debug.fw_log.on_load
+Enable firmware logging during driver initialization when set via
+.Xr kenv 1 .
+.Pp
+This feature is only supported on E610 devices.
.El
.Sh DIAGNOSTICS
.Bl -diag
diff --git a/sys/conf/files b/sys/conf/files
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2315,6 +2315,8 @@
compile-with "${NORMAL_C} -I$S/dev/ixgbe"
dev/ixgbe/ixgbe_common.c optional ix inet | ixv inet \
compile-with "${NORMAL_C} -I$S/dev/ixgbe"
+dev/ixgbe/ixgbe_fw_logging.c optional ix inet | ixv inet \
+ compile-with "${NORMAL_C} -I$S/dev/ixgbe"
dev/ixgbe/ixgbe_mbx.c optional ix inet | ixv inet \
compile-with "${NORMAL_C} -I$S/dev/ixgbe"
dev/ixgbe/ixgbe_vf.c optional ix inet | ixv inet \
diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c
--- a/sys/dev/ixgbe/if_ix.c
+++ b/sys/dev/ixgbe/if_ix.c
@@ -1122,10 +1122,13 @@
break;
}
- /* Check the FW API version */
- if (hw->mac.type == ixgbe_mac_E610 && ixgbe_check_fw_api_version(sc)) {
- error = EIO;
- goto err_pci;
+ /* Check the FW API version and enable FW logging support for E610 */
+ if (hw->mac.type == ixgbe_mac_E610) {
+ if (ixgbe_check_fw_api_version(sc)) {
+ error = EIO;
+ goto err_pci;
+ }
+ ixgbe_fwlog_set_support_ena(hw);
}
/* Most of the iflib initialization... */
@@ -3399,6 +3402,9 @@
if (sc->feat_en & IXGBE_FEATURE_DBG_DUMP)
ixgbe_add_debug_dump_sysctls(sc);
+
+ if (sc->feat_en & IXGBE_FEATURE_FW_LOGGING)
+ ixgbe_add_fw_logging_tunables(sc, sc->debug_sysctls);
} /* ixgbe_add_debug_sysctls */
/************************************************************************
@@ -4495,6 +4501,10 @@
sc->task_requests |= IXGBE_REQUEST_TASK_LSC;
break;
+ case ixgbe_aci_opc_fw_logs_event:
+ ixgbe_fwlog_event_dump(&sc->hw, &event.desc, event.msg_buf);
+ break;
+
case ixgbe_aci_opc_temp_tca_event:
if (hw->adapter_stopped == FALSE)
ixgbe_if_stop(ctx);
@@ -5731,6 +5741,7 @@
case ixgbe_mac_E610:
sc->feat_cap |= IXGBE_FEATURE_RECOVERY_MODE;
sc->feat_cap |= IXGBE_FEATURE_DBG_DUMP;
+ sc->feat_cap |= IXGBE_FEATURE_FW_LOGGING;
error = ixgbe_get_caps(&sc->hw);
if (error == 0 && sc->hw.func_caps.common_cap.eee_support != 0)
sc->feat_cap |= IXGBE_FEATURE_EEE;
@@ -5758,6 +5769,9 @@
/* FW Debug Dump */
if (sc->feat_cap & IXGBE_FEATURE_DBG_DUMP)
sc->feat_en |= IXGBE_FEATURE_DBG_DUMP;
+ /* FW Logging */
+ if (sc->feat_cap & IXGBE_FEATURE_FW_LOGGING)
+ sc->feat_en |= IXGBE_FEATURE_FW_LOGGING;
/* Enabled via global sysctl... */
/* Flow Director */
diff --git a/sys/dev/ixgbe/ixgbe.h b/sys/dev/ixgbe/ixgbe.h
--- a/sys/dev/ixgbe/ixgbe.h
+++ b/sys/dev/ixgbe/ixgbe.h
@@ -607,6 +607,11 @@
void ixgbe_free_receive_structures(struct ixgbe_softc *);
int ixgbe_get_regs(SYSCTL_HANDLER_ARGS);
+void ixgbe_add_fw_logging_tunables(struct ixgbe_softc *sc,
+ struct sysctl_oid *parent);
+
+#define IXGBE_STR_BUF_LEN 32
+
#include "ixgbe_bypass.h"
#include "ixgbe_fdir.h"
#include "ixgbe_rss.h"
diff --git a/sys/dev/ixgbe/ixgbe_e610.h b/sys/dev/ixgbe/ixgbe_e610.h
--- a/sys/dev/ixgbe/ixgbe_e610.h
+++ b/sys/dev/ixgbe/ixgbe_e610.h
@@ -169,6 +169,19 @@
s32 ixgbe_aci_set_health_status_config(struct ixgbe_hw *hw, u8 event_source);
+s32 ixgbe_fwlog_init(struct ixgbe_hw *hw, struct ixgbe_fwlog_cfg *cfg);
+bool ixgbe_fwlog_supported(struct ixgbe_hw *hw);
+s32 ixgbe_fwlog_set(struct ixgbe_hw *hw, struct ixgbe_fwlog_cfg *cfg);
+s32 ixgbe_fwlog_update_modules(struct ixgbe_hw *hw,
+ struct ixgbe_fwlog_module_entry *entries,
+ u16 num_entries);
+s32 ixgbe_fwlog_register(struct ixgbe_hw *hw);
+s32 ixgbe_fwlog_unregister(struct ixgbe_hw *hw);
+void ixgbe_fwlog_set_support_ena(struct ixgbe_hw *hw);
+s32 ixgbe_fwlog_get(struct ixgbe_hw *hw, struct ixgbe_fwlog_cfg *cfg);
+void ixgbe_fwlog_event_dump(struct ixgbe_hw *hw,
+ struct ixgbe_aci_desc *desc, void *buf);
+
/* E610 operations */
s32 ixgbe_init_ops_E610(struct ixgbe_hw *hw);
s32 ixgbe_reset_hw_E610(struct ixgbe_hw *hw);
diff --git a/sys/dev/ixgbe/ixgbe_e610.c b/sys/dev/ixgbe/ixgbe_e610.c
--- a/sys/dev/ixgbe/ixgbe_e610.c
+++ b/sys/dev/ixgbe/ixgbe_e610.c
@@ -3829,6 +3829,492 @@
}
}
+/**
+ * ixgbe_fwlog_cache_cfg - Cache FW logging config
+ * @hw: pointer to the HW structure
+ * @cfg: config to cache
+ *
+ * Cache FW logging config.
+ */
+static void ixgbe_fwlog_cache_cfg(struct ixgbe_hw *hw,
+ struct ixgbe_fwlog_cfg *cfg)
+{
+ hw->fwlog_cfg = *cfg;
+}
+
+/**
+ * ixgbe_fwlog_valid_module_entries - validate all the module entry IDs and
+ * log levels
+ * @hw: pointer to the HW structure
+ * @entries: entries to validate
+ * @num_entries: number of entries to validate
+ *
+ * Checks if all the module entry IDs and log levels are valid.
+ *
+ * Return: true if all the module entry IDs and log levels are valid,
+ * otherwise false.
+ */
+static bool ixgbe_fwlog_valid_module_entries(struct ixgbe_hw *hw,
+ struct ixgbe_fwlog_module_entry *entries,
+ u16 num_entries)
+{
+ u16 i;
+
+ UNREFERENCED_1PARAMETER(hw);
+
+ if (!entries) {
+ return false;
+ }
+
+ if (!num_entries) {
+ return false;
+ }
+
+ for (i = 0; i < num_entries; i++) {
+ struct ixgbe_fwlog_module_entry *entry = &entries[i];
+
+ if (entry->module_id >= IXGBE_ACI_FW_LOG_ID_MAX) {
+ return false;
+ }
+
+ if (entry->log_level >= IXGBE_FWLOG_LEVEL_INVALID) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/**
+ * ixgbe_fwlog_valid_cfg - validate configuration
+ * @hw: pointer to the HW structure
+ * @cfg: config to validate
+ *
+ * Validate the entire configuration.
+ *
+ * Return: true if the entire configuration is valid, otherwise false.
+ */
+static bool ixgbe_fwlog_valid_cfg(struct ixgbe_hw *hw,
+ struct ixgbe_fwlog_cfg *cfg)
+{
+ if (!cfg) {
+ return false;
+ }
+
+ if (cfg->log_resolution < IXGBE_ACI_FW_LOG_MIN_RESOLUTION ||
+ cfg->log_resolution > IXGBE_ACI_FW_LOG_MAX_RESOLUTION) {
+ return false;
+ }
+
+ if (!ixgbe_fwlog_valid_module_entries(hw, cfg->module_entries,
+ IXGBE_ACI_FW_LOG_ID_MAX))
+ return false;
+
+ return true;
+}
+
+/**
+ * ixgbe_fwlog_init - Initialize cached structures for tracking FW logging
+ * @hw: pointer to the HW structure
+ * @cfg: config used to initialize the cached structures
+ *
+ * Initialize cached structures for tracking FW logging
+ * Called on driver initialization and before calling
+ * ixgbe_init_hw(). Firmware logging will be configured based on these settings
+ * and also the PF will be registered on init.
+ *
+ * Return: the exit code of the operation.
+ */
+s32 ixgbe_fwlog_init(struct ixgbe_hw *hw, struct ixgbe_fwlog_cfg *cfg)
+{
+ if (!ixgbe_fwlog_valid_cfg(hw, cfg))
+ return IXGBE_ERR_PARAM;
+
+ ixgbe_fwlog_cache_cfg(hw, cfg);
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_aci_fwlog_set - Set FW logging configuration
+ * @hw: pointer to the HW structure
+ * @entries: entries to configure
+ * @num_entries: number of @entries
+ * @options: options from ixgbe_fwlog_cfg->options structure
+ * @log_resolution: logging resolution
+ *
+ * Set FW logging configuration using ACI command (0xFF30).
+ *
+ * Return: the exit code of the operation.
+ */
+static s32 ixgbe_aci_fwlog_set(struct ixgbe_hw *hw,
+ struct ixgbe_fwlog_module_entry *entries,
+ u16 num_entries, u16 options, u16 log_resolution)
+{
+ struct ixgbe_aci_cmd_fw_log_cfg_resp fw_modules[IXGBE_ACI_FW_LOG_ID_MAX];
+ struct ixgbe_aci_cmd_fw_log *cmd;
+ struct ixgbe_aci_desc desc;
+ s32 status;
+ u16 i;
+
+ if (num_entries > IXGBE_ACI_FW_LOG_ID_MAX)
+ return IXGBE_ERR_PARAM;
+
+ for (i = 0; i < num_entries; i++) {
+ fw_modules[i].module_identifier =
+ IXGBE_CPU_TO_LE16(entries[i].module_id);
+ fw_modules[i].log_level = entries[i].log_level;
+ }
+
+ ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_fw_logs_config);
+ desc.flags |= IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_RD);
+
+ cmd = &desc.params.fw_log;
+
+ cmd->cmd_flags = IXGBE_ACI_FW_LOG_CONF_SET_VALID;
+ cmd->ops.cfg.log_resolution = IXGBE_CPU_TO_LE16(log_resolution);
+ cmd->ops.cfg.mdl_cnt = IXGBE_CPU_TO_LE16(num_entries);
+
+ if (options & IXGBE_FWLOG_OPTION_ARQ_ENA)
+ cmd->cmd_flags |= IXGBE_ACI_FW_LOG_CONF_AQ_EN;
+ if (options & IXGBE_FWLOG_OPTION_UART_ENA)
+ cmd->cmd_flags |= IXGBE_ACI_FW_LOG_CONF_UART_EN;
+
+ status = ixgbe_aci_send_cmd(hw, &desc, fw_modules,
+ sizeof(*fw_modules) * num_entries);
+
+ return status;
+}
+
+/**
+ * ixgbe_fwlog_supported - Cached for whether FW supports FW logging or not
+ * @hw: pointer to the HW structure
+ *
+ * This will always return false if called before ixgbe_init_hw(), so it must be
+ * called after ixgbe_init_hw().
+ *
+ * Return: true if FW supports FW logging.
+ * If this function is called before ixgbe_init_hw(), return false.
+ */
+bool ixgbe_fwlog_supported(struct ixgbe_hw *hw)
+{
+ return hw->fwlog_support_ena;
+}
+
+/**
+ * ixgbe_fwlog_set - Set the firmware logging settings
+ * @hw: pointer to the HW structure
+ * @cfg: config used to set firmware logging
+ *
+ * Call this function whenever the driver needs to set the firmware
+ * logging configuration. It can be called on initialization, reset, or during
+ * runtime.
+ *
+ * If the PF wishes to receive FW logging then it must register via
+ * ixgbe_fwlog_register. Note, that ixgbe_fwlog_register does not need to
+ * be called for init.
+ *
+ * Return: the exit code of the operation.
+ */
+s32 ixgbe_fwlog_set(struct ixgbe_hw *hw, struct ixgbe_fwlog_cfg *cfg)
+{
+ s32 status;
+
+ if (!ixgbe_fwlog_supported(hw))
+ return IXGBE_ERR_NOT_SUPPORTED;
+
+ if (!ixgbe_fwlog_valid_cfg(hw, cfg))
+ return IXGBE_ERR_PARAM;
+
+ status = ixgbe_aci_fwlog_set(hw, cfg->module_entries,
+ IXGBE_ACI_FW_LOG_ID_MAX, cfg->options,
+ cfg->log_resolution);
+ if (!status)
+ ixgbe_fwlog_cache_cfg(hw, cfg);
+
+ return status;
+}
+
+/**
+ * ixgbe_fwlog_update_cached_entries - Update module entries in cached
+ * FW logging config
+ * @hw: pointer to the HW structure
+ * @entries: entries to cache
+ * @num_entries: number of @entries
+ *
+ * Update module entries in cached FW logging config.
+ */
+static void ixgbe_fwlog_update_cached_entries(struct ixgbe_hw *hw,
+ struct ixgbe_fwlog_module_entry *entries,
+ u16 num_entries)
+{
+ u16 i;
+
+ for (i = 0; i < num_entries; i++) {
+ struct ixgbe_fwlog_module_entry *updated = &entries[i];
+ u16 j;
+
+ for (j = 0; j < IXGBE_ACI_FW_LOG_ID_MAX; j++) {
+ struct ixgbe_fwlog_module_entry *cached =
+ &hw->fwlog_cfg.module_entries[j];
+
+ if (cached->module_id == updated->module_id) {
+ cached->log_level = updated->log_level;
+ break;
+ }
+ }
+ }
+}
+
+/**
+ * ixgbe_fwlog_update_modules - Update the log level 1 or more
+ * FW logging modules
+ * @hw: pointer to the HW structure
+ * @entries: array of ixgbe_fwlog_module_entry(s)
+ * @num_entries: number of entries
+ *
+ * Update the log level of 1 or more FW logging modules via module ID.
+ *
+ * Only the entries passed in will be affected. All other firmware logging
+ * settings will be unaffected.
+ *
+ * Return: the exit code of the operation.
+ */
+s32 ixgbe_fwlog_update_modules(struct ixgbe_hw *hw,
+ struct ixgbe_fwlog_module_entry *entries,
+ u16 num_entries)
+{
+ struct ixgbe_fwlog_cfg cfg;
+ s32 status;
+
+ if (!ixgbe_fwlog_supported(hw))
+ return IXGBE_ERR_NOT_SUPPORTED;
+
+ if (num_entries > IXGBE_ACI_FW_LOG_ID_MAX)
+ return IXGBE_ERR_PARAM;
+
+ if (!ixgbe_fwlog_valid_module_entries(hw, entries, num_entries))
+ return IXGBE_ERR_PARAM;
+
+ status = ixgbe_fwlog_get(hw, &cfg);
+ if (status)
+ goto status_out;
+
+ status = ixgbe_aci_fwlog_set(hw, entries, num_entries, cfg.options,
+ cfg.log_resolution);
+ if (!status)
+ ixgbe_fwlog_update_cached_entries(hw, entries, num_entries);
+
+status_out:
+ return status;
+}
+
+/**
+ * ixgbe_aci_fwlog_register - Register PF for firmware logging events.
+ * @hw: pointer to the HW structure
+ * @reg: true to register and false to unregister
+ *
+ * Register a PF for firmware logging events using ACI command (0xFF31).
+ *
+ * Return: the exit code of the operation.
+ */
+static s32 ixgbe_aci_fwlog_register(struct ixgbe_hw *hw, bool reg)
+{
+ struct ixgbe_aci_desc desc;
+
+ ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_fw_logs_register);
+
+ if (reg)
+ desc.params.fw_log.cmd_flags = IXGBE_ACI_FW_LOG_AQ_REGISTER;
+
+ return ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
+}
+
+/**
+ * ixgbe_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 ixgbe_fwlog_set.
+ *
+ * Return: the exit code of the operation.
+ */
+s32 ixgbe_fwlog_register(struct ixgbe_hw *hw)
+{
+ s32 status;
+
+ if (!ixgbe_fwlog_supported(hw))
+ return IXGBE_ERR_NOT_SUPPORTED;
+
+ status = ixgbe_aci_fwlog_register(hw, true);
+
+ if (!status)
+ hw->fwlog_cfg.options |= IXGBE_FWLOG_OPTION_IS_REGISTERED;
+
+ return status;
+}
+
+/**
+ * ixgbe_fwlog_unregister - Unregister the PF from firmware logging
+ * @hw: pointer to the HW structure
+ *
+ * Make an attempt to unregister the PF from firmware logging.
+ *
+ * Return: the exit code of the operation.
+ */
+s32 ixgbe_fwlog_unregister(struct ixgbe_hw *hw)
+{
+ s32 status;
+
+ if (!ixgbe_fwlog_supported(hw))
+ return IXGBE_ERR_NOT_SUPPORTED;
+
+ status = ixgbe_aci_fwlog_register(hw, false);
+ if (!status)
+ hw->fwlog_cfg.options &= ~IXGBE_FWLOG_OPTION_IS_REGISTERED;
+
+ return status;
+}
+
+/**
+ * ixgbe_aci_fwlog_get - Get the current firmware logging configuration
+ * @hw: pointer to the HW structure
+ * @cfg: firmware logging configuration to populate
+ *
+ * Make an attempt to get the current firmware logging
+ * configuration using ACI command (0xFF32).
+ *
+ * Return: the exit code of the operation.
+ */
+static s32 ixgbe_aci_fwlog_get(struct ixgbe_hw *hw, struct ixgbe_fwlog_cfg *cfg)
+{
+ struct ixgbe_aci_cmd_fw_log_cfg_resp *fw_modules;
+ struct ixgbe_aci_cmd_fw_log *cmd;
+ struct ixgbe_aci_desc desc;
+ u16 i, module_id_cnt;
+ u8 *buf = NULL;
+ s32 status;
+
+ memset(cfg, 0, sizeof(*cfg));
+
+ ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_fw_logs_query);
+ cmd = &desc.params.fw_log;
+
+ cmd->cmd_flags = IXGBE_ACI_FW_LOG_AQ_QUERY;
+
+ buf = (u8 *)ixgbe_malloc(hw, IXGBE_ACI_MAX_BUFFER_SIZE);
+ if (!buf)
+ return IXGBE_ERR_OUT_OF_MEM;
+
+ status = ixgbe_aci_send_cmd(hw, &desc, buf, IXGBE_ACI_MAX_BUFFER_SIZE);
+ if (status) {
+ goto status_out;
+ }
+
+ module_id_cnt = IXGBE_LE16_TO_CPU(cmd->ops.cfg.mdl_cnt);
+ if (module_id_cnt > IXGBE_ACI_FW_LOG_ID_MAX) {
+ module_id_cnt = IXGBE_ACI_FW_LOG_ID_MAX;
+ }
+
+ cfg->log_resolution = (u8)IXGBE_LE16_TO_CPU(cmd->ops.cfg.log_resolution);
+ if (cmd->cmd_flags & IXGBE_ACI_FW_LOG_CONF_AQ_EN)
+ cfg->options |= IXGBE_FWLOG_OPTION_ARQ_ENA;
+ if (cmd->cmd_flags & IXGBE_ACI_FW_LOG_CONF_UART_EN)
+ cfg->options |= IXGBE_FWLOG_OPTION_UART_ENA;
+ if (cmd->cmd_flags & IXGBE_ACI_FW_LOG_QUERY_REGISTERED)
+ cfg->options |= IXGBE_FWLOG_OPTION_IS_REGISTERED;
+
+ fw_modules = (struct ixgbe_aci_cmd_fw_log_cfg_resp *)buf;
+
+ for (i = 0; i < module_id_cnt; i++) {
+ struct ixgbe_aci_cmd_fw_log_cfg_resp *fw_module = &fw_modules[i];
+
+ cfg->module_entries[i].module_id =
+ IXGBE_LE16_TO_CPU(fw_module->module_identifier);
+ cfg->module_entries[i].log_level = fw_module->log_level;
+ }
+
+status_out:
+ if (buf)
+ ixgbe_free(hw, buf);
+ return status;
+}
+
+/**
+ * ixgbe_fwlog_set_support_ena - Set if FW logging is supported by FW
+ * @hw: pointer to the HW struct
+ *
+ * If FW returns success to the ixgbe_aci_fwlog_get call then it supports FW
+ * logging, else it doesn't. Set the fwlog_support_ena flag accordingly.
+ *
+ * This function is only meant to be called during driver init to determine if
+ * the FW support FW logging.
+ *
+ * Return: the exit code of the operation.
+ */
+void ixgbe_fwlog_set_support_ena(struct ixgbe_hw *hw)
+{
+ struct ixgbe_fwlog_cfg cfg;
+ s32 status;
+
+ hw->fwlog_support_ena = false;
+
+ /* don't call ixgbe_fwlog_get() because that would overwrite the cached
+ * configuration from the call to ixgbe_fwlog_init(), which is expected
+ * to be called prior to this function
+ */
+ status = ixgbe_aci_fwlog_get(hw, &cfg);
+ if (!status)
+ hw->fwlog_support_ena = true;
+}
+
+/**
+ * ixgbe_fwlog_get - Get the firmware logging settings
+ * @hw: pointer to the HW structure
+ * @cfg: config to populate based on current firmware logging settings
+ *
+ * Get the current firmware logging settings.
+ *
+ * Return: the exit code of the operation.
+ */
+s32 ixgbe_fwlog_get(struct ixgbe_hw *hw, struct ixgbe_fwlog_cfg *cfg)
+{
+ s32 status;
+
+ if (!ixgbe_fwlog_supported(hw))
+ return IXGBE_ERR_NOT_SUPPORTED;
+
+ if (!cfg)
+ return IXGBE_ERR_PARAM;
+
+ status = ixgbe_aci_fwlog_get(hw, cfg);
+ if (status)
+ return status;
+
+ ixgbe_fwlog_cache_cfg(hw, cfg);
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_fwlog_event_dump - Dump the event received over the Admin Receive Queue
+ * @hw: pointer to the HW structure
+ * @desc: Admin Receive Queue descriptor
+ * @buf: buffer that contains the FW log event data
+ *
+ * If the driver receives the ixgbe_aci_opc_fw_logs_event on the Admin Receive
+ * Queue, then it should call this function to dump the FW log data.
+ */
+void ixgbe_fwlog_event_dump(struct ixgbe_hw *hw,
+ struct ixgbe_aci_desc *desc, void *buf)
+{
+ if (!ixgbe_fwlog_supported(hw))
+ return;
+
+ ixgbe_info_fwlog(hw, 32, 1, (u8 *)buf,
+ IXGBE_LE16_TO_CPU(desc->datalen));
+}
+
/**
* ixgbe_aci_set_health_status_config - Configure FW health events
* @hw: pointer to the HW struct
diff --git a/sys/dev/ixgbe/ixgbe_features.h b/sys/dev/ixgbe/ixgbe_features.h
--- a/sys/dev/ixgbe/ixgbe_features.h
+++ b/sys/dev/ixgbe/ixgbe_features.h
@@ -58,6 +58,7 @@
#define IXGBE_FEATURE_NEEDS_CTXD (u32)(1 << 13)
#define IXGBE_FEATURE_RECOVERY_MODE (u32)(1 << 15)
#define IXGBE_FEATURE_DBG_DUMP (u32)(1 << 16)
+#define IXGBE_FEATURE_FW_LOGGING (u32)(1 << 17)
/* Check for OS support. Undefine features if not included in the OS */
#ifndef PCI_IOV
diff --git a/sys/dev/ixgbe/ixgbe_fw_logging.c b/sys/dev/ixgbe/ixgbe_fw_logging.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/ixgbe/ixgbe_fw_logging.c
@@ -0,0 +1,467 @@
+/**
+ * @file ixgbe_fw_logging.c
+ * @brief firmware logging sysctls
+ *
+ * Contains sysctls to enable and configure firmware logging debug support.
+ */
+
+ #include "ixgbe.h"
+
+ /**
+ * ixgbe_reconfig_fw_log - Re-program firmware logging configuration
+ * @sc: private softc structure
+ * @cfg: firmware log configuration to latch
+ *
+ * If the adminq is currently active, ask firmware to update the logging
+ * configuration. If the adminq is currently down, then do nothing. In this
+ * case, ixgbe_init_hw() will re-configure firmware logging as soon as it brings
+ * up the adminq.
+ */
+ static int
+ ixgbe_reconfig_fw_log(struct ixgbe_softc *sc, struct ixgbe_fwlog_cfg *cfg)
+ {
+ int status;
+
+ ixgbe_fwlog_init(&sc->hw, cfg);
+
+ if (!ixgbe_fwlog_supported(&sc->hw))
+ return (0);
+
+ status = ixgbe_fwlog_set(&sc->hw, cfg);
+ if (status != IXGBE_SUCCESS) {
+ DEBUGOUT1("Failed to reconfigure firmware logging, status %d\n",
+ status);
+ return (ENODEV);
+ }
+
+ return (0);
+ }
+
+ /**
+ * ixgbe_sysctl_fwlog_set_cfg_options - Sysctl for setting fwlog cfg options
+ * @oidp: sysctl oid structure
+ * @arg1: private softc structure
+ * @arg2: option to adjust
+ * @req: sysctl request pointer
+ *
+ * On read: displays whether firmware logging was reported during attachment
+ * On write: enables/disables firmware logging during attach phase
+ *
+ * This has no effect on the legacy (V1) version of firmware logging.
+ */
+ static int
+ ixgbe_sysctl_fwlog_set_cfg_options(SYSCTL_HANDLER_ARGS)
+ {
+ struct ixgbe_softc *sc = (struct ixgbe_softc *)arg1;
+ struct ixgbe_fwlog_cfg *cfg = &sc->hw.fwlog_cfg;
+ int error;
+ u16 option = (u16)arg2;
+ bool enabled;
+
+ enabled = !!(cfg->options & option);
+
+ error = sysctl_handle_bool(oidp, &enabled, 0, req);
+ if ((error) || (req->newptr == NULL))
+ return (error);
+
+ if (enabled)
+ cfg->options |= option;
+ else
+ cfg->options &= ~option;
+
+ return ixgbe_reconfig_fw_log(sc, cfg);
+ }
+
+ /**
+ * ixgbe_sysctl_fwlog_log_resolution - Sysctl for setting log message resolution
+ * @oidp: sysctl oid structure
+ * @arg1: private softc structure
+ * @arg2: __unused__
+ * @req: sysctl request pointer
+ *
+ * On read: displays message queue limit before posting
+ * On write: sets message queue limit before posting
+ *
+ * This has no effect on the legacy (V1) version of firmware logging.
+ */
+ static int
+ ixgbe_sysctl_fwlog_log_resolution(SYSCTL_HANDLER_ARGS)
+ {
+ struct ixgbe_softc *sc = (struct ixgbe_softc *)arg1;
+ struct ixgbe_fwlog_cfg *cfg = &sc->hw.fwlog_cfg;
+ int error;
+ u8 resolution;
+
+ UNREFERENCED_PARAMETER(arg2);
+
+ resolution = cfg->log_resolution;
+
+ error = sysctl_handle_8(oidp, &resolution, 0, req);
+ if ((error) || (req->newptr == NULL))
+ return (error);
+
+ if ((resolution < IXGBE_ACI_FW_LOG_MIN_RESOLUTION) ||
+ (resolution > IXGBE_ACI_FW_LOG_MAX_RESOLUTION)) {
+ DEBUGOUT("Log resolution out-of-bounds\n");
+ return (EINVAL);
+ }
+
+ cfg->log_resolution = resolution;
+
+ return ixgbe_reconfig_fw_log(sc, cfg);
+ }
+
+ /**
+ * ixgbe_sysctl_fwlog_register - Sysctl for (de)registering firmware logs
+ * @oidp: sysctl oid structure
+ * @arg1: private softc structure
+ * @arg2: __unused__
+ * @req: sysctl request pointer
+ *
+ * On read: displays whether firmware logging is registered
+ * On write: (de)registers firmware logging.
+ */
+ static int
+ ixgbe_sysctl_fwlog_register(SYSCTL_HANDLER_ARGS)
+ {
+ struct ixgbe_softc *sc = (struct ixgbe_softc *)arg1;
+ struct ixgbe_fwlog_cfg *cfg = &sc->hw.fwlog_cfg;
+ int status;
+ int error;
+ u8 enabled;
+
+ UNREFERENCED_PARAMETER(arg2);
+
+ if (cfg->options & IXGBE_FWLOG_OPTION_IS_REGISTERED)
+ enabled = true;
+ else
+ enabled = false;
+
+ error = sysctl_handle_bool(oidp, &enabled, 0, req);
+ if ((error) || (req->newptr == NULL))
+ return (error);
+
+ if (enabled) {
+ status = ixgbe_fwlog_register(&sc->hw);
+ if (status == IXGBE_SUCCESS)
+ sc->feat_en |= IXGBE_FEATURE_FW_LOGGING;
+ } else {
+ status = ixgbe_fwlog_unregister(&sc->hw);
+ if (status == IXGBE_SUCCESS)
+ sc->feat_en &= ~IXGBE_FEATURE_FW_LOGGING;
+ }
+
+ if (status != IXGBE_SUCCESS)
+ return (EIO);
+
+ return (0);
+ }
+
+ /**
+ * ixgbe_log_sev_str - Convert log level to a string
+ * @log_level: the log level to convert
+ *
+ * Convert the u8 log level of a FW logging module into a readable
+ * string for outputting in a sysctl.
+ */
+ struct ixgbe_str_buf {
+ char str[IXGBE_STR_BUF_LEN];
+ };
+
+ static struct ixgbe_str_buf
+ _ixgbe_log_sev_str(u8 log_level)
+ {
+ struct ixgbe_str_buf buf = { .str = "" };
+ const char *str = NULL;
+
+ switch (log_level) {
+ case IXGBE_FWLOG_LEVEL_NONE:
+ str = "none";
+ break;
+ case IXGBE_FWLOG_LEVEL_ERROR:
+ str = "error";
+ break;
+ case IXGBE_FWLOG_LEVEL_WARNING:
+ str = "warning";
+ break;
+ case IXGBE_FWLOG_LEVEL_NORMAL:
+ str = "normal";
+ break;
+ case IXGBE_FWLOG_LEVEL_VERBOSE:
+ str = "verbose";
+ break;
+ default:
+ break;
+ }
+
+ if (str)
+ snprintf(buf.str, IXGBE_STR_BUF_LEN, "%s", str);
+ else
+ snprintf(buf.str, IXGBE_STR_BUF_LEN, "%u", log_level);
+
+ return buf;
+ }
+
+ #define ixgbe_log_sev_str(log_level) _ixgbe_log_sev_str(log_level).str
+
+ /**
+ * ixgbe_sysctl_fwlog_module_log_severity - Add tunables for a FW logging module
+ * @oidp: sysctl oid structure
+ * @arg1: private softc structure
+ * @arg2: index to logging module
+ * @req: sysctl request pointer
+ */
+ static int
+ ixgbe_sysctl_fwlog_module_log_severity(SYSCTL_HANDLER_ARGS)
+ {
+ struct ixgbe_softc *sc = (struct ixgbe_softc *)arg1;
+ struct ixgbe_fwlog_cfg *cfg = &sc->hw.fwlog_cfg;
+ struct sbuf *sbuf;
+ char *sev_str_end;
+ enum ixgbe_aci_fw_logging_mod module = (enum ixgbe_aci_fw_logging_mod)arg2;
+ int error, ll_num;
+ u8 log_level;
+ char sev_str[16];
+ bool sev_set = false;
+
+ log_level = cfg->module_entries[module].log_level;
+ sbuf = sbuf_new(NULL, sev_str, sizeof(sev_str), SBUF_FIXEDLEN);
+ sbuf_printf(sbuf, "%d<%s>", log_level, ixgbe_log_sev_str(log_level));
+ sbuf_finish(sbuf);
+ sbuf_delete(sbuf);
+
+ error = sysctl_handle_string(oidp, sev_str, sizeof(sev_str), req);
+ if ((error) || (req->newptr == NULL))
+ return (error);
+
+ if (strcasecmp(ixgbe_log_sev_str(IXGBE_FWLOG_LEVEL_VERBOSE), sev_str) == 0) {
+ log_level = IXGBE_FWLOG_LEVEL_VERBOSE;
+ sev_set = true;
+ } else if (strcasecmp(ixgbe_log_sev_str(IXGBE_FWLOG_LEVEL_NORMAL), sev_str) == 0) {
+ log_level = IXGBE_FWLOG_LEVEL_NORMAL;
+ sev_set = true;
+ } else if (strcasecmp(ixgbe_log_sev_str(IXGBE_FWLOG_LEVEL_WARNING), sev_str) == 0) {
+ log_level = IXGBE_FWLOG_LEVEL_WARNING;
+ sev_set = true;
+ } else if (strcasecmp(ixgbe_log_sev_str(IXGBE_FWLOG_LEVEL_ERROR), sev_str) == 0) {
+ log_level = IXGBE_FWLOG_LEVEL_ERROR;
+ sev_set = true;
+ } else if (strcasecmp(ixgbe_log_sev_str(IXGBE_FWLOG_LEVEL_NONE), sev_str) == 0) {
+ log_level = IXGBE_FWLOG_LEVEL_NONE;
+ sev_set = true;
+ }
+
+ if (!sev_set) {
+ ll_num = strtol(sev_str, &sev_str_end, 0);
+ if (sev_str_end == sev_str)
+ ll_num = -1;
+ if ((ll_num >= IXGBE_FWLOG_LEVEL_NONE) &&
+ (ll_num < IXGBE_FWLOG_LEVEL_INVALID))
+ log_level = ll_num;
+ else {
+ DEBUGOUT2("%s: \"%s\" is not a valid log level\n",
+ __func__, sev_str);
+ return (EINVAL);
+ }
+ }
+
+ cfg->module_entries[module].log_level = log_level;
+
+ return ixgbe_reconfig_fw_log(sc, cfg);
+ }
+
+ #define IXGBE_SYSCTL_HELP_FWLOG_LOG_RESOLUTION \
+ "\nControl firmware message limit to send per ARQ event" \
+ "\t\nMin: 1" \
+ "\t\nMax: 128"
+
+ #define IXGBE_SYSCTL_HELP_FWLOG_ARQ_ENA \
+ "\nControl whether to enable/disable reporting to admin Rx queue" \
+ "\n1 - Enable firmware reporting via ARQ" \
+ "\n0 - Disable firmware reporting via ARQ"
+
+ #define IXGBE_SYSCTL_HELP_FWLOG_UART_ENA \
+ "\nControl whether to enable/disable reporting to UART" \
+ "\n1 - Enable firmware reporting via UART" \
+ "\n0 - Disable firmware reporting via UART"
+
+ #define IXGBE_SYSCTL_HELP_FWLOG_ENABLE_ON_LOAD \
+ "\nControl whether to enable logging during the attach phase" \
+ "\n1 - Enable firmware logging during attach phase" \
+ "\n0 - Disable firmware logging during attach phase"
+
+ #define IXGBE_SYSCTL_HELP_FWLOG_REGISTER \
+ "\nControl whether to enable/disable firmware logging" \
+ "\n1 - Enable firmware logging" \
+ "\n0 - Disable firmware logging"
+
+ #define IXGBE_SYSCTL_HELP_FWLOG_MODULE_SEVERITY \
+ "\nControl the level of log output messages for this module" \
+ "\n\tverbose <4> - Verbose messages + (Error|Warning|Normal)" \
+ "\n\tnormal <3> - Normal messages + (Error|Warning)" \
+ "\n\twarning <2> - Warning messages + (Error)" \
+ "\n\terror <1> - Error messages" \
+ "\n\tnone <0> - Disables all logging for this module"
+
+ /**
+ * ixgbe_fw_module_str - Convert a FW logging module to a string name
+ * @module: the module to convert
+ *
+ * Given a FW logging module id, convert it to a shorthand human readable
+ * name, for generating sysctl tunables.
+ */
+ static const char *
+ ixgbe_fw_module_str(enum ixgbe_aci_fw_logging_mod module)
+ {
+ switch (module) {
+ case IXGBE_ACI_FW_LOG_ID_GENERAL:
+ return "general";
+ case IXGBE_ACI_FW_LOG_ID_CTRL:
+ return "ctrl";
+ case IXGBE_ACI_FW_LOG_ID_LINK:
+ return "link";
+ case IXGBE_ACI_FW_LOG_ID_LINK_TOPO:
+ return "link_topo";
+ case IXGBE_ACI_FW_LOG_ID_DNL:
+ return "dnl";
+ case IXGBE_ACI_FW_LOG_ID_I2C:
+ return "i2c";
+ case IXGBE_ACI_FW_LOG_ID_SDP:
+ return "sdp";
+ case IXGBE_ACI_FW_LOG_ID_MDIO:
+ return "mdio";
+ case IXGBE_ACI_FW_LOG_ID_ADMINQ:
+ return "adminq";
+ case IXGBE_ACI_FW_LOG_ID_HDMA:
+ return "hdma";
+ case IXGBE_ACI_FW_LOG_ID_LLDP:
+ return "lldp";
+ case IXGBE_ACI_FW_LOG_ID_DCBX:
+ return "dcbx";
+ case IXGBE_ACI_FW_LOG_ID_DCB:
+ return "dcb";
+ case IXGBE_ACI_FW_LOG_ID_XLR:
+ return "xlr";
+ case IXGBE_ACI_FW_LOG_ID_NVM:
+ return "nvm";
+ case IXGBE_ACI_FW_LOG_ID_AUTH:
+ return "auth";
+ case IXGBE_ACI_FW_LOG_ID_VPD:
+ return "vpd";
+ case IXGBE_ACI_FW_LOG_ID_IOSF:
+ return "iosf";
+ case IXGBE_ACI_FW_LOG_ID_PARSER:
+ return "parser";
+ case IXGBE_ACI_FW_LOG_ID_SW:
+ return "sw";
+ case IXGBE_ACI_FW_LOG_ID_SCHEDULER:
+ return "scheduler";
+ case IXGBE_ACI_FW_LOG_ID_TXQ:
+ return "txq";
+ case IXGBE_ACI_FW_LOG_ID_ACL:
+ return "acl";
+ case IXGBE_ACI_FW_LOG_ID_POST:
+ return "post";
+ case IXGBE_ACI_FW_LOG_ID_WATCHDOG:
+ return "watchdog";
+ case IXGBE_ACI_FW_LOG_ID_TASK_DISPATCH:
+ return "task_dispatch";
+ case IXGBE_ACI_FW_LOG_ID_MNG:
+ return "mng";
+ case IXGBE_ACI_FW_LOG_ID_SYNCE:
+ return "synce";
+ case IXGBE_ACI_FW_LOG_ID_HEALTH:
+ return "health";
+ case IXGBE_ACI_FW_LOG_ID_TSDRV:
+ return "tsdrv";
+ case IXGBE_ACI_FW_LOG_ID_PFREG:
+ return "pfreg";
+ case IXGBE_ACI_FW_LOG_ID_MDLVER:
+ return "mdlver";
+ case IXGBE_ACI_FW_LOG_ID_MAX:
+ return "unknown";
+ }
+
+ /* The compiler generates errors on unhandled enum values if we omit
+ * the default case.
+ */
+ return "unknown";
+ }
+
+ /**
+ * ixgbe_add_fw_logging_tunables - Add tunables to configure FW logging events
+ * @sc: private softc structure
+ * @parent: parent node to add the tunables under
+ *
+ * Add tunables for configuring the firmware logging support. This includes
+ * a control to enable the logging, and controls for each module to configure
+ * which events to receive.
+ */
+ void
+ ixgbe_add_fw_logging_tunables(struct ixgbe_softc *sc, struct sysctl_oid *parent)
+ {
+ struct sysctl_oid_list *parent_list, *fwlog_list, *module_list;
+ struct sysctl_oid *fwlog_node, *module_node;
+ struct sysctl_ctx_list *ctx;
+ struct ixgbe_hw *hw = &sc->hw;
+ struct ixgbe_fwlog_cfg *cfg;
+ device_t dev = sc->dev;
+ enum ixgbe_aci_fw_logging_mod module;
+ u16 i;
+
+ cfg = &hw->fwlog_cfg;
+ ctx = device_get_sysctl_ctx(dev);
+ parent_list = SYSCTL_CHILDREN(parent);
+
+ fwlog_node = SYSCTL_ADD_NODE(ctx, parent_list, OID_AUTO, "fw_log",
+ CTLFLAG_RD, NULL,
+ "Firmware Logging");
+ fwlog_list = SYSCTL_CHILDREN(fwlog_node);
+
+ cfg->log_resolution = 10;
+ SYSCTL_ADD_PROC(ctx, fwlog_list, OID_AUTO, "log_resolution",
+ CTLTYPE_U8 | CTLFLAG_RWTUN, sc,
+ 0, ixgbe_sysctl_fwlog_log_resolution,
+ "CU", IXGBE_SYSCTL_HELP_FWLOG_LOG_RESOLUTION);
+
+ cfg->options |= IXGBE_FWLOG_OPTION_ARQ_ENA;
+ SYSCTL_ADD_PROC(ctx, fwlog_list, OID_AUTO, "arq_en",
+ CTLTYPE_U8 | CTLFLAG_RWTUN, sc,
+ IXGBE_FWLOG_OPTION_ARQ_ENA, ixgbe_sysctl_fwlog_set_cfg_options,
+ "CU", IXGBE_SYSCTL_HELP_FWLOG_ARQ_ENA);
+
+ SYSCTL_ADD_PROC(ctx, fwlog_list, OID_AUTO, "uart_en",
+ CTLTYPE_U8 | CTLFLAG_RWTUN, sc,
+ IXGBE_FWLOG_OPTION_UART_ENA, ixgbe_sysctl_fwlog_set_cfg_options,
+ "CU", IXGBE_SYSCTL_HELP_FWLOG_UART_ENA);
+
+ SYSCTL_ADD_PROC(ctx, fwlog_list, OID_AUTO, "on_load",
+ CTLTYPE_U8 | CTLFLAG_RWTUN, sc,
+ IXGBE_FWLOG_OPTION_REGISTER_ON_INIT, ixgbe_sysctl_fwlog_set_cfg_options,
+ "CU", IXGBE_SYSCTL_HELP_FWLOG_ENABLE_ON_LOAD);
+
+ SYSCTL_ADD_PROC(ctx, fwlog_list, OID_AUTO, "register",
+ CTLTYPE_U8 | CTLFLAG_RWTUN, sc,
+ 0, ixgbe_sysctl_fwlog_register,
+ "CU", IXGBE_SYSCTL_HELP_FWLOG_REGISTER);
+
+ module_node = SYSCTL_ADD_NODE(ctx, fwlog_list, OID_AUTO, "severity",
+ CTLFLAG_RD, NULL,
+ "Level of log output");
+
+ module_list = SYSCTL_CHILDREN(module_node);
+
+ for (i = 0; i < IXGBE_ACI_FW_LOG_ID_MAX; i++) {
+ /* Setup some defaults */
+ cfg->module_entries[i].module_id = i;
+ cfg->module_entries[i].log_level = IXGBE_FWLOG_LEVEL_NONE;
+ module = (enum ixgbe_aci_fw_logging_mod)i;
+
+ SYSCTL_ADD_PROC(ctx, module_list,
+ OID_AUTO, ixgbe_fw_module_str(module),
+ CTLTYPE_STRING | CTLFLAG_RWTUN, sc,
+ module, ixgbe_sysctl_fwlog_module_log_severity,
+ "A", IXGBE_SYSCTL_HELP_FWLOG_MODULE_SEVERITY);
+ }
+ }
+
\ No newline at end of file
diff --git a/sys/dev/ixgbe/ixgbe_osdep.h b/sys/dev/ixgbe/ixgbe_osdep.h
--- a/sys/dev/ixgbe/ixgbe_osdep.h
+++ b/sys/dev/ixgbe/ixgbe_osdep.h
@@ -253,4 +253,7 @@
free(addr, M_DEVBUF);
}
+void ixgbe_info_fwlog(struct ixgbe_hw *hw, uint32_t rowsize,
+ uint32_t groupsize, uint8_t *buf, size_t len);
+
#endif /* _IXGBE_OSDEP_H_ */
diff --git a/sys/dev/ixgbe/ixgbe_osdep.c b/sys/dev/ixgbe/ixgbe_osdep.c
--- a/sys/dev/ixgbe/ixgbe_osdep.c
+++ b/sys/dev/ixgbe/ixgbe_osdep.c
@@ -140,3 +140,39 @@
if (mtx_initialized(&lock->mutex))
mtx_destroy(&lock->mutex);
}
+
+/**
+ * ixgbe_info_fwlog - Format and print an array of values to the console
+ * @hw: private hardware structure
+ * @rowsize: preferred number of rows to use
+ * @groupsize: preferred size in bytes to print each chunk
+ * @buf: the array buffer to print
+ * @len: size of the array buffer
+ *
+ * Format the given array as a series of uint8_t values with hexadecimal
+ * notation and log the contents to the console log. This variation is
+ * specific to firmware logging.
+ *
+ * TODO: Currently only supports a group size of 1, due to the way hexdump is
+ * implemented.
+ */
+void
+ixgbe_info_fwlog(struct ixgbe_hw *hw, uint32_t rowsize, uint32_t __unused groupsize,
+ uint8_t *buf, size_t len)
+{
+ device_t dev = ((struct ixgbe_softc *)hw->back)->dev;
+ char prettyname[20];
+
+ if (!ixgbe_fwlog_supported(hw))
+ return;
+
+ /* Format the device header to a string */
+ snprintf(prettyname, sizeof(prettyname), "%s: FWLOG: ",
+ device_get_nameunit(dev));
+
+ /* Make sure the row-size isn't too large */
+ if (rowsize > 0xFF)
+ rowsize = 0xFF;
+
+ hexdump(buf, len, prettyname, HD_OMIT_CHARS | rowsize);
+}
diff --git a/sys/modules/ix/Makefile b/sys/modules/ix/Makefile
--- a/sys/modules/ix/Makefile
+++ b/sys/modules/ix/Makefile
@@ -8,6 +8,7 @@
SRCS += ixgbe_common.c ixgbe_api.c ixgbe_phy.c ixgbe_mbx.c ixgbe_vf.c
SRCS += ixgbe_dcb.c ixgbe_dcb_82598.c ixgbe_dcb_82599.c
SRCS += ixgbe_82598.c ixgbe_82599.c ixgbe_x540.c ixgbe_x550.c ixgbe_e610.c
+SRCS += ixgbe_fw_logging.c
CFLAGS+= -I${SRCTOP}/sys/dev/ixgbe
.include <bsd.kmod.mk>
diff --git a/sys/modules/ixv/Makefile b/sys/modules/ixv/Makefile
--- a/sys/modules/ixv/Makefile
+++ b/sys/modules/ixv/Makefile
@@ -8,6 +8,7 @@
SRCS += ixgbe_common.c ixgbe_api.c ixgbe_phy.c ixgbe_mbx.c ixgbe_vf.c
SRCS += ixgbe_dcb.c ixgbe_dcb_82598.c ixgbe_dcb_82599.c
SRCS += ixgbe_82598.c ixgbe_82599.c ixgbe_x540.c ixgbe_x550.c ixgbe_e610.c
+SRCS += ixgbe_fw_logging.c
CFLAGS+= -I${SRCTOP}/sys/dev/ixgbe
.include <bsd.kmod.mk>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Apr 19, 1:32 PM (8 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31773516
Default Alt Text
D53973.id175192.diff (37 KB)
Attached To
Mode
D53973: ix(4): Add support for firmware logging for E610 adapters
Attached
Detach File
Event Timeline
Log In to Comment