The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ice/ice_fw_logging.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* SPDX-License-Identifier: BSD-3-Clause */
    2 /*  Copyright (c) 2021, Intel Corporation
    3  *  All rights reserved.
    4  *
    5  *  Redistribution and use in source and binary forms, with or without
    6  *  modification, are permitted provided that the following conditions are met:
    7  *
    8  *   1. Redistributions of source code must retain the above copyright notice,
    9  *      this list of conditions and the following disclaimer.
   10  *
   11  *   2. Redistributions in binary form must reproduce the above copyright
   12  *      notice, this list of conditions and the following disclaimer in the
   13  *      documentation and/or other materials provided with the distribution.
   14  *
   15  *   3. Neither the name of the Intel Corporation nor the names of its
   16  *      contributors may be used to endorse or promote products derived from
   17  *      this software without specific prior written permission.
   18  *
   19  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   20  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   23  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  *  POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 /*$FreeBSD$*/
   32 
   33 /**
   34  * @file ice_fw_logging.c
   35  * @brief firmware logging sysctls
   36  *
   37  * Contains sysctls to enable and configure firmware logging debug support.
   38  */
   39 
   40 #include "ice_lib.h"
   41 #include "ice_iflib.h"
   42 #include <sys/queue.h>
   43 #include <sys/sdt.h>
   44 
   45 /*
   46  * SDT provider for DTrace probes related to firmware logging events
   47  */
   48 SDT_PROVIDER_DEFINE(ice_fwlog);
   49 
   50 /*
   51  * SDT DTrace probe fired when a firmware log message is received over the
   52  * AdminQ. It passes the buffer of the firwmare log message along with its
   53  * length in bytes to the DTrace framework.
   54  */
   55 SDT_PROBE_DEFINE2(ice_fwlog, , , message, "uint8_t *", "int");
   56 
   57 /*
   58  * Helper function prototypes
   59  */
   60 static int ice_reconfig_fw_log(struct ice_softc *sc, struct ice_fwlog_cfg *cfg);
   61 
   62 /*
   63  * dynamic sysctl handlers
   64  */
   65 static int ice_sysctl_fwlog_set_cfg_options(SYSCTL_HANDLER_ARGS);
   66 static int ice_sysctl_fwlog_log_resolution(SYSCTL_HANDLER_ARGS);
   67 static int ice_sysctl_fwlog_register(SYSCTL_HANDLER_ARGS);
   68 static int ice_sysctl_fwlog_module_log_severity(SYSCTL_HANDLER_ARGS);
   69 
   70 /**
   71  * ice_reconfig_fw_log - Re-program firmware logging configuration
   72  * @sc: private softc structure
   73  * @cfg: firmware log configuration to latch
   74  *
   75  * If the adminq is currently active, ask firmware to update the logging
   76  * configuration. If the adminq is currently down, then do nothing. In this
   77  * case, ice_init_hw() will re-configure firmware logging as soon as it brings
   78  * up the adminq.
   79  */
   80 static int
   81 ice_reconfig_fw_log(struct ice_softc *sc, struct ice_fwlog_cfg *cfg)
   82 {
   83         enum ice_status status;
   84 
   85         ice_fwlog_init(&sc->hw, cfg);
   86 
   87         if (!ice_check_sq_alive(&sc->hw, &sc->hw.adminq))
   88                 return (0);
   89 
   90         if (!ice_fwlog_supported(&sc->hw))
   91                 return (0);
   92 
   93         status = ice_fwlog_set(&sc->hw, cfg);
   94         if (status) {
   95                 device_printf(sc->dev,
   96                     "Failed to reconfigure firmware logging, err %s aq_err %s\n",
   97                     ice_status_str(status),
   98                     ice_aq_str(sc->hw.adminq.sq_last_status));
   99                 return (ENODEV);
  100         }
  101 
  102         return (0);
  103 }
  104 
  105 #define ICE_SYSCTL_HELP_FWLOG_LOG_RESOLUTION                            \
  106 "\nControl firmware message limit to send per ARQ event"                \
  107 "\t\nMin: 1"                                                            \
  108 "\t\nMax: 128"
  109 
  110 #define ICE_SYSCTL_HELP_FWLOG_ARQ_ENA                                   \
  111 "\nControl whether to enable/disable reporing to admin Rx queue"        \
  112 "\n0 - Enable firmware reporting via ARQ"                               \
  113 "\n1 - Disable firmware reporting via ARQ"
  114 
  115 #define ICE_SYSCTL_HELP_FWLOG_UART_ENA                                  \
  116 "\nControl whether to enable/disable reporing to UART"                  \
  117 "\n0 - Enable firmware reporting via UART"                              \
  118 "\n1 - Disable firmware reporting via UART"
  119 
  120 #define ICE_SYSCTL_HELP_FWLOG_ENABLE_ON_LOAD                            \
  121 "\nControl whether to enable logging during the attach phase"           \
  122 "\n0 - Enable firmware logging during attach phase"                     \
  123 "\n1 - Disable firmware logging during attach phase"
  124 
  125 #define ICE_SYSCTL_HELP_FWLOG_REGISTER                                  \
  126 "\nControl whether to enable/disable firmware logging"                  \
  127 "\n0 - Enable firmware logging"                                         \
  128 "\n1 - Disable firmware logging"
  129 
  130 #define ICE_SYSCTL_HELP_FWLOG_MODULE_SEVERITY                           \
  131 "\nControl the level of log output messages for this module"            \
  132 "\n\tverbose <4> - Verbose messages + (Error|Warning|Normal)"           \
  133 "\n\tnormal  <3> - Normal messages  + (Error|Warning)"                  \
  134 "\n\twarning <2> - Warning messages + (Error)"                          \
  135 "\n\terror   <1> - Error messages"                                      \
  136 "\n\tnone    <0> - Disables all logging for this module"
  137 
  138 /**
  139  * ice_sysctl_fwlog_set_cfg_options - Sysctl for setting fwlog cfg options
  140  * @oidp: sysctl oid structure
  141  * @arg1: private softc structure
  142  * @arg2: option to adjust
  143  * @req: sysctl request pointer
  144  *
  145  * On read: displays whether firmware logging was reported during attachment
  146  * On write: enables/disables firmware logging during attach phase
  147  *
  148  * This has no effect on the legacy (V1) version of firmware logging.
  149  */
  150 static int
  151 ice_sysctl_fwlog_set_cfg_options(SYSCTL_HANDLER_ARGS)
  152 {
  153         struct ice_softc *sc = (struct ice_softc *)arg1;
  154         struct ice_fwlog_cfg *cfg = &sc->hw.fwlog_cfg;
  155         int error;
  156         u16 option = (u16)arg2;
  157         bool enabled;
  158 
  159         enabled = !!(cfg->options & option);
  160 
  161         error = sysctl_handle_bool(oidp, &enabled, 0, req);
  162         if ((error) || (req->newptr == NULL))
  163                 return (error);
  164 
  165         if (enabled)
  166                 cfg->options |= option;
  167         else
  168                 cfg->options &= ~option;
  169 
  170         return ice_reconfig_fw_log(sc, cfg);
  171 }
  172 
  173 /**
  174  * ice_sysctl_fwlog_log_resolution - Sysctl for setting log message resolution
  175  * @oidp: sysctl oid structure
  176  * @arg1: private softc structure
  177  * @arg2: __unused__
  178  * @req: sysctl request pointer
  179  *
  180  * On read: displays message queue limit before posting
  181  * On write: sets message queue limit before posting
  182  *
  183  * This has no effect on the legacy (V1) version of firmware logging.
  184  */
  185 static int
  186 ice_sysctl_fwlog_log_resolution(SYSCTL_HANDLER_ARGS)
  187 {
  188         struct ice_softc *sc = (struct ice_softc *)arg1;
  189         struct ice_fwlog_cfg *cfg = &sc->hw.fwlog_cfg;
  190         int error;
  191         u8 resolution;
  192 
  193         UNREFERENCED_PARAMETER(arg2);
  194 
  195         resolution = cfg->log_resolution;
  196 
  197         error = sysctl_handle_8(oidp, &resolution, 0, req);
  198         if ((error) || (req->newptr == NULL))
  199                 return (error);
  200 
  201         if ((resolution < ICE_AQC_FW_LOG_MIN_RESOLUTION) ||
  202             (resolution > ICE_AQC_FW_LOG_MAX_RESOLUTION)) {
  203                 device_printf(sc->dev, "Log resolution out-of-bounds\n");
  204                 return (EINVAL);
  205         }
  206 
  207         cfg->log_resolution = resolution;
  208 
  209         return ice_reconfig_fw_log(sc, cfg);
  210 }
  211 
  212 /**
  213  * ice_sysctl_fwlog_register - Sysctl for (de)registering firmware logs
  214  * @oidp: sysctl oid structure
  215  * @arg1: private softc structure
  216  * @arg2: __unused__
  217  * @req: sysctl request pointer
  218  *
  219  * On read: displays whether firmware logging is registered
  220  * On write: (de)registers firmware logging.
  221  */
  222 static int
  223 ice_sysctl_fwlog_register(SYSCTL_HANDLER_ARGS)
  224 {
  225         struct ice_softc *sc = (struct ice_softc *)arg1;
  226         struct ice_fwlog_cfg *cfg = &sc->hw.fwlog_cfg;
  227         enum ice_status status;
  228         int error;
  229         u8 enabled;
  230 
  231         UNREFERENCED_PARAMETER(arg2);
  232 
  233         if (ice_test_state(&sc->state, ICE_STATE_ATTACHING)) {
  234                 device_printf(sc->dev, "Registering FW Logging via kenv is supported with the on_load option\n");
  235                 return (EIO);
  236         }
  237 
  238         if (cfg->options & ICE_FWLOG_OPTION_IS_REGISTERED)
  239                 enabled = true;
  240         else
  241                 enabled = false;
  242 
  243         error = sysctl_handle_bool(oidp, &enabled, 0, req);
  244         if ((error) || (req->newptr == NULL))
  245                 return (error);
  246 
  247         if (!ice_check_sq_alive(&sc->hw, &sc->hw.adminq))
  248                 return (0);
  249 
  250         if (enabled) {
  251                 status = ice_fwlog_register(&sc->hw);
  252                 if (!status)
  253                         ice_set_bit(ICE_FEATURE_FW_LOGGING, sc->feat_en);
  254         } else {
  255                 status = ice_fwlog_unregister(&sc->hw);
  256                 if (!status)
  257                         ice_clear_bit(ICE_FEATURE_FW_LOGGING, sc->feat_en);
  258         }
  259 
  260         if (status)
  261                 return (EIO);
  262 
  263         return (0);
  264 }
  265 
  266 /**
  267  * ice_sysctl_fwlog_module_log_severity - Add tunables for a FW logging module
  268  * @oidp: sysctl oid structure
  269  * @arg1: private softc structure
  270  * @arg2: index to logging module
  271  * @req: sysctl request pointer
  272  */
  273 static int
  274 ice_sysctl_fwlog_module_log_severity(SYSCTL_HANDLER_ARGS)
  275 {
  276         struct ice_softc *sc = (struct ice_softc *)arg1;
  277         struct ice_fwlog_cfg *cfg = &sc->hw.fwlog_cfg;
  278         struct sbuf *sbuf;
  279         char *sev_str_end;
  280         enum ice_aqc_fw_logging_mod module = (enum ice_aqc_fw_logging_mod)arg2;
  281         int error, ll_num;
  282         u8 log_level;
  283         char sev_str[16];
  284         bool sev_set = false;
  285 
  286         log_level = cfg->module_entries[module].log_level;
  287         sbuf = sbuf_new(NULL, sev_str, sizeof(sev_str), SBUF_FIXEDLEN);
  288         sbuf_printf(sbuf, "%d<%s>", log_level, ice_log_sev_str(log_level));
  289         sbuf_finish(sbuf);
  290         sbuf_delete(sbuf);
  291 
  292         error = sysctl_handle_string(oidp, sev_str, sizeof(sev_str), req);
  293         if ((error) || (req->newptr == NULL))
  294                 return (error);
  295 
  296         if (strcasecmp(ice_log_sev_str(ICE_FWLOG_LEVEL_VERBOSE), sev_str) == 0) {
  297                 log_level = ICE_FWLOG_LEVEL_VERBOSE;
  298                 sev_set = true;
  299         } else if (strcasecmp(ice_log_sev_str(ICE_FWLOG_LEVEL_NORMAL), sev_str) == 0) {
  300                 log_level = ICE_FWLOG_LEVEL_NORMAL;
  301                 sev_set = true;
  302         } else if (strcasecmp(ice_log_sev_str(ICE_FWLOG_LEVEL_WARNING), sev_str) == 0) {
  303                 log_level = ICE_FWLOG_LEVEL_WARNING;
  304                 sev_set = true;
  305         } else if (strcasecmp(ice_log_sev_str(ICE_FWLOG_LEVEL_ERROR), sev_str) == 0) {
  306                 log_level = ICE_FWLOG_LEVEL_ERROR;
  307                 sev_set = true;
  308         } else if (strcasecmp(ice_log_sev_str(ICE_FWLOG_LEVEL_NONE), sev_str) == 0) {
  309                 log_level = ICE_FWLOG_LEVEL_NONE;
  310                 sev_set = true;
  311         }
  312 
  313         if (!sev_set) {
  314                 ll_num = strtol(sev_str, &sev_str_end, 0);
  315                 if (sev_str_end == sev_str)
  316                         ll_num = -1;
  317                 if ((ll_num >= ICE_FWLOG_LEVEL_NONE) &&
  318                     (ll_num < ICE_FWLOG_LEVEL_INVALID))
  319                         log_level = ll_num;
  320                 else {
  321                         device_printf(sc->dev,
  322                             "%s: \"%s\" is not a valid log level\n",
  323                             __func__, sev_str);
  324                         return (EINVAL);
  325                 }
  326         }
  327 
  328         cfg->module_entries[module].log_level = log_level;
  329 
  330         return ice_reconfig_fw_log(sc, cfg);
  331 }
  332 
  333 /**
  334  * ice_add_fw_logging_tunables - Add tunables to configure FW logging events
  335  * @sc: private softc structure
  336  * @parent: parent node to add the tunables under
  337  *
  338  * Add tunables for configuring the firmware logging support. This includes
  339  * a control to enable the logging, and controls for each module to configure
  340  * which events to receive.
  341  */
  342 void
  343 ice_add_fw_logging_tunables(struct ice_softc *sc, struct sysctl_oid *parent)
  344 {
  345         struct sysctl_oid_list *parent_list, *fwlog_list, *module_list;
  346         struct sysctl_oid *fwlog_node, *module_node;
  347         struct sysctl_ctx_list *ctx;
  348         struct ice_hw *hw = &sc->hw;
  349         struct ice_fwlog_cfg *cfg;
  350         device_t dev = sc->dev;
  351         enum ice_aqc_fw_logging_mod module;
  352         u16 i;
  353 
  354         cfg = &hw->fwlog_cfg;
  355         ctx = device_get_sysctl_ctx(dev);
  356         parent_list = SYSCTL_CHILDREN(parent);
  357 
  358         fwlog_node = SYSCTL_ADD_NODE(ctx, parent_list, OID_AUTO, "fw_log",
  359                                      ICE_CTLFLAG_DEBUG | CTLFLAG_RD, NULL,
  360                                      "Firmware Logging");
  361         fwlog_list = SYSCTL_CHILDREN(fwlog_node);
  362 
  363         cfg->log_resolution = 10;
  364         SYSCTL_ADD_PROC(ctx, fwlog_list, OID_AUTO, "log_resolution",
  365             ICE_CTLFLAG_DEBUG | CTLTYPE_U8 | CTLFLAG_RWTUN, sc,
  366             0, ice_sysctl_fwlog_log_resolution,
  367             "CU", ICE_SYSCTL_HELP_FWLOG_LOG_RESOLUTION);
  368 
  369         cfg->options |= ICE_FWLOG_OPTION_ARQ_ENA;
  370         SYSCTL_ADD_PROC(ctx, fwlog_list, OID_AUTO, "arq_en",
  371             ICE_CTLFLAG_DEBUG | CTLTYPE_U8 | CTLFLAG_RWTUN, sc,
  372             ICE_FWLOG_OPTION_ARQ_ENA, ice_sysctl_fwlog_set_cfg_options,
  373             "CU", ICE_SYSCTL_HELP_FWLOG_ARQ_ENA);
  374 
  375         SYSCTL_ADD_PROC(ctx, fwlog_list, OID_AUTO, "uart_en",
  376             ICE_CTLFLAG_DEBUG | CTLTYPE_U8 | CTLFLAG_RWTUN, sc,
  377             ICE_FWLOG_OPTION_UART_ENA, ice_sysctl_fwlog_set_cfg_options,
  378             "CU", ICE_SYSCTL_HELP_FWLOG_UART_ENA);
  379 
  380         SYSCTL_ADD_PROC(ctx, fwlog_list, OID_AUTO, "on_load",
  381             ICE_CTLFLAG_DEBUG | CTLTYPE_U8 | CTLFLAG_RWTUN, sc,
  382             ICE_FWLOG_OPTION_REGISTER_ON_INIT, ice_sysctl_fwlog_set_cfg_options,
  383             "CU", ICE_SYSCTL_HELP_FWLOG_ENABLE_ON_LOAD);
  384 
  385         SYSCTL_ADD_PROC(ctx, fwlog_list, OID_AUTO, "register",
  386             ICE_CTLFLAG_DEBUG | CTLTYPE_U8 | CTLFLAG_RWTUN, sc,
  387             0, ice_sysctl_fwlog_register,
  388             "CU", ICE_SYSCTL_HELP_FWLOG_REGISTER);
  389 
  390         module_node = SYSCTL_ADD_NODE(ctx, fwlog_list, OID_AUTO, "severity",
  391                                       ICE_CTLFLAG_DEBUG | CTLFLAG_RD, NULL,
  392                                       "Level of log output");
  393 
  394         module_list = SYSCTL_CHILDREN(module_node);
  395 
  396         for (i = 0; i < ICE_AQC_FW_LOG_ID_MAX; i++) {
  397                 /* Setup some defaults */
  398                 cfg->module_entries[i].module_id = i;
  399                 cfg->module_entries[i].log_level = ICE_FWLOG_LEVEL_NONE;
  400                 module = (enum ice_aqc_fw_logging_mod)i;
  401 
  402                 SYSCTL_ADD_PROC(ctx, module_list,
  403                     OID_AUTO, ice_fw_module_str(module),
  404                     ICE_CTLFLAG_DEBUG | CTLTYPE_STRING | CTLFLAG_RWTUN, sc,
  405                     module, ice_sysctl_fwlog_module_log_severity,
  406                     "A", ICE_SYSCTL_HELP_FWLOG_MODULE_SEVERITY);
  407         }
  408 }
  409 
  410 /**
  411  * ice_handle_fw_log_event - Handle a firmware logging event from the AdminQ
  412  * @sc: pointer to private softc structure
  413  * @desc: the AdminQ descriptor for this firmware event
  414  * @buf: pointer to the buffer accompanying the AQ message
  415  */
  416 void
  417 ice_handle_fw_log_event(struct ice_softc *sc, struct ice_aq_desc *desc,
  418                         void *buf)
  419 {
  420         /* Trigger a DTrace probe event for this firmware message */
  421         SDT_PROBE2(ice_fwlog, , , message, (const u8 *)buf, desc->datalen);
  422 
  423         /* Possibly dump the firmware message to the console, if enabled */
  424         ice_fwlog_event_dump(&sc->hw, desc, buf);
  425 }

Cache object: 088dd353d791d8fdbee65fa77016c50c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.