1*6b58d10fSBhosale, Yogesh /** 2*6b58d10fSBhosale, Yogesh * @file ixgbe_fw_logging.c 3*6b58d10fSBhosale, Yogesh * @brief firmware logging sysctls 4*6b58d10fSBhosale, Yogesh * 5*6b58d10fSBhosale, Yogesh * Contains sysctls to enable and configure firmware logging debug support. 6*6b58d10fSBhosale, Yogesh */ 7*6b58d10fSBhosale, Yogesh 8*6b58d10fSBhosale, Yogesh #include "ixgbe.h" 9*6b58d10fSBhosale, Yogesh 10*6b58d10fSBhosale, Yogesh /** 11*6b58d10fSBhosale, Yogesh * ixgbe_reconfig_fw_log - Re-program firmware logging configuration 12*6b58d10fSBhosale, Yogesh * @sc: private softc structure 13*6b58d10fSBhosale, Yogesh * @cfg: firmware log configuration to latch 14*6b58d10fSBhosale, Yogesh * 15*6b58d10fSBhosale, Yogesh * If the adminq is currently active, ask firmware to update the logging 16*6b58d10fSBhosale, Yogesh * configuration. If the adminq is currently down, then do nothing. In this 17*6b58d10fSBhosale, Yogesh * case, ixgbe_init_hw() will re-configure firmware logging as soon as it brings 18*6b58d10fSBhosale, Yogesh * up the adminq. 19*6b58d10fSBhosale, Yogesh */ 20*6b58d10fSBhosale, Yogesh static int ixgbe_reconfig_fw_log(struct ixgbe_softc * sc,struct ixgbe_fwlog_cfg * cfg)21*6b58d10fSBhosale, Yogesh ixgbe_reconfig_fw_log(struct ixgbe_softc *sc, struct ixgbe_fwlog_cfg *cfg) 22*6b58d10fSBhosale, Yogesh { 23*6b58d10fSBhosale, Yogesh int status; 24*6b58d10fSBhosale, Yogesh 25*6b58d10fSBhosale, Yogesh ixgbe_fwlog_init(&sc->hw, cfg); 26*6b58d10fSBhosale, Yogesh 27*6b58d10fSBhosale, Yogesh if (!ixgbe_fwlog_supported(&sc->hw)) 28*6b58d10fSBhosale, Yogesh return (0); 29*6b58d10fSBhosale, Yogesh 30*6b58d10fSBhosale, Yogesh status = ixgbe_fwlog_set(&sc->hw, cfg); 31*6b58d10fSBhosale, Yogesh if (status != IXGBE_SUCCESS) { 32*6b58d10fSBhosale, Yogesh DEBUGOUT1("Failed to reconfigure firmware logging, status %d\n", 33*6b58d10fSBhosale, Yogesh status); 34*6b58d10fSBhosale, Yogesh return (ENODEV); 35*6b58d10fSBhosale, Yogesh } 36*6b58d10fSBhosale, Yogesh 37*6b58d10fSBhosale, Yogesh return (0); 38*6b58d10fSBhosale, Yogesh } 39*6b58d10fSBhosale, Yogesh 40*6b58d10fSBhosale, Yogesh /** 41*6b58d10fSBhosale, Yogesh * ixgbe_sysctl_fwlog_set_cfg_options - Sysctl for setting fwlog cfg options 42*6b58d10fSBhosale, Yogesh * @oidp: sysctl oid structure 43*6b58d10fSBhosale, Yogesh * @arg1: private softc structure 44*6b58d10fSBhosale, Yogesh * @arg2: option to adjust 45*6b58d10fSBhosale, Yogesh * @req: sysctl request pointer 46*6b58d10fSBhosale, Yogesh * 47*6b58d10fSBhosale, Yogesh * On read: displays whether firmware logging was reported during attachment 48*6b58d10fSBhosale, Yogesh * On write: enables/disables firmware logging during attach phase 49*6b58d10fSBhosale, Yogesh * 50*6b58d10fSBhosale, Yogesh * This has no effect on the legacy (V1) version of firmware logging. 51*6b58d10fSBhosale, Yogesh */ 52*6b58d10fSBhosale, Yogesh static int ixgbe_sysctl_fwlog_set_cfg_options(SYSCTL_HANDLER_ARGS)53*6b58d10fSBhosale, Yogesh ixgbe_sysctl_fwlog_set_cfg_options(SYSCTL_HANDLER_ARGS) 54*6b58d10fSBhosale, Yogesh { 55*6b58d10fSBhosale, Yogesh struct ixgbe_softc *sc = (struct ixgbe_softc *)arg1; 56*6b58d10fSBhosale, Yogesh struct ixgbe_fwlog_cfg *cfg = &sc->hw.fwlog_cfg; 57*6b58d10fSBhosale, Yogesh int error; 58*6b58d10fSBhosale, Yogesh u16 option = (u16)arg2; 59*6b58d10fSBhosale, Yogesh bool enabled; 60*6b58d10fSBhosale, Yogesh 61*6b58d10fSBhosale, Yogesh enabled = !!(cfg->options & option); 62*6b58d10fSBhosale, Yogesh 63*6b58d10fSBhosale, Yogesh error = sysctl_handle_bool(oidp, &enabled, 0, req); 64*6b58d10fSBhosale, Yogesh if ((error) || (req->newptr == NULL)) 65*6b58d10fSBhosale, Yogesh return (error); 66*6b58d10fSBhosale, Yogesh 67*6b58d10fSBhosale, Yogesh if (enabled) 68*6b58d10fSBhosale, Yogesh cfg->options |= option; 69*6b58d10fSBhosale, Yogesh else 70*6b58d10fSBhosale, Yogesh cfg->options &= ~option; 71*6b58d10fSBhosale, Yogesh 72*6b58d10fSBhosale, Yogesh return ixgbe_reconfig_fw_log(sc, cfg); 73*6b58d10fSBhosale, Yogesh } 74*6b58d10fSBhosale, Yogesh 75*6b58d10fSBhosale, Yogesh /** 76*6b58d10fSBhosale, Yogesh * ixgbe_sysctl_fwlog_log_resolution - Sysctl for setting log message resolution 77*6b58d10fSBhosale, Yogesh * @oidp: sysctl oid structure 78*6b58d10fSBhosale, Yogesh * @arg1: private softc structure 79*6b58d10fSBhosale, Yogesh * @arg2: __unused__ 80*6b58d10fSBhosale, Yogesh * @req: sysctl request pointer 81*6b58d10fSBhosale, Yogesh * 82*6b58d10fSBhosale, Yogesh * On read: displays message queue limit before posting 83*6b58d10fSBhosale, Yogesh * On write: sets message queue limit before posting 84*6b58d10fSBhosale, Yogesh * 85*6b58d10fSBhosale, Yogesh * This has no effect on the legacy (V1) version of firmware logging. 86*6b58d10fSBhosale, Yogesh */ 87*6b58d10fSBhosale, Yogesh static int ixgbe_sysctl_fwlog_log_resolution(SYSCTL_HANDLER_ARGS)88*6b58d10fSBhosale, Yogesh ixgbe_sysctl_fwlog_log_resolution(SYSCTL_HANDLER_ARGS) 89*6b58d10fSBhosale, Yogesh { 90*6b58d10fSBhosale, Yogesh struct ixgbe_softc *sc = (struct ixgbe_softc *)arg1; 91*6b58d10fSBhosale, Yogesh struct ixgbe_fwlog_cfg *cfg = &sc->hw.fwlog_cfg; 92*6b58d10fSBhosale, Yogesh int error; 93*6b58d10fSBhosale, Yogesh u8 resolution; 94*6b58d10fSBhosale, Yogesh 95*6b58d10fSBhosale, Yogesh UNREFERENCED_PARAMETER(arg2); 96*6b58d10fSBhosale, Yogesh 97*6b58d10fSBhosale, Yogesh resolution = cfg->log_resolution; 98*6b58d10fSBhosale, Yogesh 99*6b58d10fSBhosale, Yogesh error = sysctl_handle_8(oidp, &resolution, 0, req); 100*6b58d10fSBhosale, Yogesh if ((error) || (req->newptr == NULL)) 101*6b58d10fSBhosale, Yogesh return (error); 102*6b58d10fSBhosale, Yogesh 103*6b58d10fSBhosale, Yogesh if ((resolution < IXGBE_ACI_FW_LOG_MIN_RESOLUTION) || 104*6b58d10fSBhosale, Yogesh (resolution > IXGBE_ACI_FW_LOG_MAX_RESOLUTION)) { 105*6b58d10fSBhosale, Yogesh DEBUGOUT("Log resolution out-of-bounds\n"); 106*6b58d10fSBhosale, Yogesh return (EINVAL); 107*6b58d10fSBhosale, Yogesh } 108*6b58d10fSBhosale, Yogesh 109*6b58d10fSBhosale, Yogesh cfg->log_resolution = resolution; 110*6b58d10fSBhosale, Yogesh 111*6b58d10fSBhosale, Yogesh return ixgbe_reconfig_fw_log(sc, cfg); 112*6b58d10fSBhosale, Yogesh } 113*6b58d10fSBhosale, Yogesh 114*6b58d10fSBhosale, Yogesh /** 115*6b58d10fSBhosale, Yogesh * ixgbe_sysctl_fwlog_register - Sysctl for (de)registering firmware logs 116*6b58d10fSBhosale, Yogesh * @oidp: sysctl oid structure 117*6b58d10fSBhosale, Yogesh * @arg1: private softc structure 118*6b58d10fSBhosale, Yogesh * @arg2: __unused__ 119*6b58d10fSBhosale, Yogesh * @req: sysctl request pointer 120*6b58d10fSBhosale, Yogesh * 121*6b58d10fSBhosale, Yogesh * On read: displays whether firmware logging is registered 122*6b58d10fSBhosale, Yogesh * On write: (de)registers firmware logging. 123*6b58d10fSBhosale, Yogesh */ 124*6b58d10fSBhosale, Yogesh static int ixgbe_sysctl_fwlog_register(SYSCTL_HANDLER_ARGS)125*6b58d10fSBhosale, Yogesh ixgbe_sysctl_fwlog_register(SYSCTL_HANDLER_ARGS) 126*6b58d10fSBhosale, Yogesh { 127*6b58d10fSBhosale, Yogesh struct ixgbe_softc *sc = (struct ixgbe_softc *)arg1; 128*6b58d10fSBhosale, Yogesh struct ixgbe_fwlog_cfg *cfg = &sc->hw.fwlog_cfg; 129*6b58d10fSBhosale, Yogesh int status; 130*6b58d10fSBhosale, Yogesh int error; 131*6b58d10fSBhosale, Yogesh u8 enabled; 132*6b58d10fSBhosale, Yogesh 133*6b58d10fSBhosale, Yogesh UNREFERENCED_PARAMETER(arg2); 134*6b58d10fSBhosale, Yogesh 135*6b58d10fSBhosale, Yogesh if (cfg->options & IXGBE_FWLOG_OPTION_IS_REGISTERED) 136*6b58d10fSBhosale, Yogesh enabled = true; 137*6b58d10fSBhosale, Yogesh else 138*6b58d10fSBhosale, Yogesh enabled = false; 139*6b58d10fSBhosale, Yogesh 140*6b58d10fSBhosale, Yogesh error = sysctl_handle_bool(oidp, &enabled, 0, req); 141*6b58d10fSBhosale, Yogesh if ((error) || (req->newptr == NULL)) 142*6b58d10fSBhosale, Yogesh return (error); 143*6b58d10fSBhosale, Yogesh 144*6b58d10fSBhosale, Yogesh if (enabled) { 145*6b58d10fSBhosale, Yogesh status = ixgbe_fwlog_register(&sc->hw); 146*6b58d10fSBhosale, Yogesh if (status == IXGBE_SUCCESS) 147*6b58d10fSBhosale, Yogesh sc->feat_en |= IXGBE_FEATURE_FW_LOGGING; 148*6b58d10fSBhosale, Yogesh } else { 149*6b58d10fSBhosale, Yogesh status = ixgbe_fwlog_unregister(&sc->hw); 150*6b58d10fSBhosale, Yogesh if (status == IXGBE_SUCCESS) 151*6b58d10fSBhosale, Yogesh sc->feat_en &= ~IXGBE_FEATURE_FW_LOGGING; 152*6b58d10fSBhosale, Yogesh } 153*6b58d10fSBhosale, Yogesh 154*6b58d10fSBhosale, Yogesh if (status != IXGBE_SUCCESS) 155*6b58d10fSBhosale, Yogesh return (EIO); 156*6b58d10fSBhosale, Yogesh 157*6b58d10fSBhosale, Yogesh return (0); 158*6b58d10fSBhosale, Yogesh } 159*6b58d10fSBhosale, Yogesh 160*6b58d10fSBhosale, Yogesh /** 161*6b58d10fSBhosale, Yogesh * ixgbe_log_sev_str - Convert log level to a string 162*6b58d10fSBhosale, Yogesh * @log_level: the log level to convert 163*6b58d10fSBhosale, Yogesh * 164*6b58d10fSBhosale, Yogesh * Convert the u8 log level of a FW logging module into a readable 165*6b58d10fSBhosale, Yogesh * string for outputting in a sysctl. 166*6b58d10fSBhosale, Yogesh */ 167*6b58d10fSBhosale, Yogesh struct ixgbe_str_buf { 168*6b58d10fSBhosale, Yogesh char str[IXGBE_STR_BUF_LEN]; 169*6b58d10fSBhosale, Yogesh }; 170*6b58d10fSBhosale, Yogesh 171*6b58d10fSBhosale, Yogesh static struct ixgbe_str_buf _ixgbe_log_sev_str(u8 log_level)172*6b58d10fSBhosale, Yogesh _ixgbe_log_sev_str(u8 log_level) 173*6b58d10fSBhosale, Yogesh { 174*6b58d10fSBhosale, Yogesh struct ixgbe_str_buf buf = { .str = "" }; 175*6b58d10fSBhosale, Yogesh const char *str = NULL; 176*6b58d10fSBhosale, Yogesh 177*6b58d10fSBhosale, Yogesh switch (log_level) { 178*6b58d10fSBhosale, Yogesh case IXGBE_FWLOG_LEVEL_NONE: 179*6b58d10fSBhosale, Yogesh str = "none"; 180*6b58d10fSBhosale, Yogesh break; 181*6b58d10fSBhosale, Yogesh case IXGBE_FWLOG_LEVEL_ERROR: 182*6b58d10fSBhosale, Yogesh str = "error"; 183*6b58d10fSBhosale, Yogesh break; 184*6b58d10fSBhosale, Yogesh case IXGBE_FWLOG_LEVEL_WARNING: 185*6b58d10fSBhosale, Yogesh str = "warning"; 186*6b58d10fSBhosale, Yogesh break; 187*6b58d10fSBhosale, Yogesh case IXGBE_FWLOG_LEVEL_NORMAL: 188*6b58d10fSBhosale, Yogesh str = "normal"; 189*6b58d10fSBhosale, Yogesh break; 190*6b58d10fSBhosale, Yogesh case IXGBE_FWLOG_LEVEL_VERBOSE: 191*6b58d10fSBhosale, Yogesh str = "verbose"; 192*6b58d10fSBhosale, Yogesh break; 193*6b58d10fSBhosale, Yogesh default: 194*6b58d10fSBhosale, Yogesh break; 195*6b58d10fSBhosale, Yogesh } 196*6b58d10fSBhosale, Yogesh 197*6b58d10fSBhosale, Yogesh if (str) 198*6b58d10fSBhosale, Yogesh snprintf(buf.str, IXGBE_STR_BUF_LEN, "%s", str); 199*6b58d10fSBhosale, Yogesh else 200*6b58d10fSBhosale, Yogesh snprintf(buf.str, IXGBE_STR_BUF_LEN, "%u", log_level); 201*6b58d10fSBhosale, Yogesh 202*6b58d10fSBhosale, Yogesh return buf; 203*6b58d10fSBhosale, Yogesh } 204*6b58d10fSBhosale, Yogesh 205*6b58d10fSBhosale, Yogesh #define ixgbe_log_sev_str(log_level) _ixgbe_log_sev_str(log_level).str 206*6b58d10fSBhosale, Yogesh 207*6b58d10fSBhosale, Yogesh /** 208*6b58d10fSBhosale, Yogesh * ixgbe_sysctl_fwlog_module_log_severity - Add tunables for a FW logging module 209*6b58d10fSBhosale, Yogesh * @oidp: sysctl oid structure 210*6b58d10fSBhosale, Yogesh * @arg1: private softc structure 211*6b58d10fSBhosale, Yogesh * @arg2: index to logging module 212*6b58d10fSBhosale, Yogesh * @req: sysctl request pointer 213*6b58d10fSBhosale, Yogesh */ 214*6b58d10fSBhosale, Yogesh static int ixgbe_sysctl_fwlog_module_log_severity(SYSCTL_HANDLER_ARGS)215*6b58d10fSBhosale, Yogesh ixgbe_sysctl_fwlog_module_log_severity(SYSCTL_HANDLER_ARGS) 216*6b58d10fSBhosale, Yogesh { 217*6b58d10fSBhosale, Yogesh struct ixgbe_softc *sc = (struct ixgbe_softc *)arg1; 218*6b58d10fSBhosale, Yogesh struct ixgbe_fwlog_cfg *cfg = &sc->hw.fwlog_cfg; 219*6b58d10fSBhosale, Yogesh struct sbuf *sbuf; 220*6b58d10fSBhosale, Yogesh char *sev_str_end; 221*6b58d10fSBhosale, Yogesh enum ixgbe_aci_fw_logging_mod module = (enum ixgbe_aci_fw_logging_mod)arg2; 222*6b58d10fSBhosale, Yogesh int error, ll_num; 223*6b58d10fSBhosale, Yogesh u8 log_level; 224*6b58d10fSBhosale, Yogesh char sev_str[16]; 225*6b58d10fSBhosale, Yogesh bool sev_set = false; 226*6b58d10fSBhosale, Yogesh 227*6b58d10fSBhosale, Yogesh log_level = cfg->module_entries[module].log_level; 228*6b58d10fSBhosale, Yogesh sbuf = sbuf_new(NULL, sev_str, sizeof(sev_str), SBUF_FIXEDLEN); 229*6b58d10fSBhosale, Yogesh sbuf_printf(sbuf, "%d<%s>", log_level, ixgbe_log_sev_str(log_level)); 230*6b58d10fSBhosale, Yogesh sbuf_finish(sbuf); 231*6b58d10fSBhosale, Yogesh sbuf_delete(sbuf); 232*6b58d10fSBhosale, Yogesh 233*6b58d10fSBhosale, Yogesh error = sysctl_handle_string(oidp, sev_str, sizeof(sev_str), req); 234*6b58d10fSBhosale, Yogesh if ((error) || (req->newptr == NULL)) 235*6b58d10fSBhosale, Yogesh return (error); 236*6b58d10fSBhosale, Yogesh 237*6b58d10fSBhosale, Yogesh if (strcasecmp(ixgbe_log_sev_str(IXGBE_FWLOG_LEVEL_VERBOSE), sev_str) == 0) { 238*6b58d10fSBhosale, Yogesh log_level = IXGBE_FWLOG_LEVEL_VERBOSE; 239*6b58d10fSBhosale, Yogesh sev_set = true; 240*6b58d10fSBhosale, Yogesh } else if (strcasecmp(ixgbe_log_sev_str(IXGBE_FWLOG_LEVEL_NORMAL), sev_str) == 0) { 241*6b58d10fSBhosale, Yogesh log_level = IXGBE_FWLOG_LEVEL_NORMAL; 242*6b58d10fSBhosale, Yogesh sev_set = true; 243*6b58d10fSBhosale, Yogesh } else if (strcasecmp(ixgbe_log_sev_str(IXGBE_FWLOG_LEVEL_WARNING), sev_str) == 0) { 244*6b58d10fSBhosale, Yogesh log_level = IXGBE_FWLOG_LEVEL_WARNING; 245*6b58d10fSBhosale, Yogesh sev_set = true; 246*6b58d10fSBhosale, Yogesh } else if (strcasecmp(ixgbe_log_sev_str(IXGBE_FWLOG_LEVEL_ERROR), sev_str) == 0) { 247*6b58d10fSBhosale, Yogesh log_level = IXGBE_FWLOG_LEVEL_ERROR; 248*6b58d10fSBhosale, Yogesh sev_set = true; 249*6b58d10fSBhosale, Yogesh } else if (strcasecmp(ixgbe_log_sev_str(IXGBE_FWLOG_LEVEL_NONE), sev_str) == 0) { 250*6b58d10fSBhosale, Yogesh log_level = IXGBE_FWLOG_LEVEL_NONE; 251*6b58d10fSBhosale, Yogesh sev_set = true; 252*6b58d10fSBhosale, Yogesh } 253*6b58d10fSBhosale, Yogesh 254*6b58d10fSBhosale, Yogesh if (!sev_set) { 255*6b58d10fSBhosale, Yogesh ll_num = strtol(sev_str, &sev_str_end, 0); 256*6b58d10fSBhosale, Yogesh if (sev_str_end == sev_str) 257*6b58d10fSBhosale, Yogesh ll_num = -1; 258*6b58d10fSBhosale, Yogesh if ((ll_num >= IXGBE_FWLOG_LEVEL_NONE) && 259*6b58d10fSBhosale, Yogesh (ll_num < IXGBE_FWLOG_LEVEL_INVALID)) 260*6b58d10fSBhosale, Yogesh log_level = ll_num; 261*6b58d10fSBhosale, Yogesh else { 262*6b58d10fSBhosale, Yogesh DEBUGOUT2("%s: \"%s\" is not a valid log level\n", 263*6b58d10fSBhosale, Yogesh __func__, sev_str); 264*6b58d10fSBhosale, Yogesh return (EINVAL); 265*6b58d10fSBhosale, Yogesh } 266*6b58d10fSBhosale, Yogesh } 267*6b58d10fSBhosale, Yogesh 268*6b58d10fSBhosale, Yogesh cfg->module_entries[module].log_level = log_level; 269*6b58d10fSBhosale, Yogesh 270*6b58d10fSBhosale, Yogesh return ixgbe_reconfig_fw_log(sc, cfg); 271*6b58d10fSBhosale, Yogesh } 272*6b58d10fSBhosale, Yogesh 273*6b58d10fSBhosale, Yogesh #define IXGBE_SYSCTL_HELP_FWLOG_LOG_RESOLUTION \ 274*6b58d10fSBhosale, Yogesh "\nControl firmware message limit to send per ARQ event" \ 275*6b58d10fSBhosale, Yogesh "\t\nMin: 1" \ 276*6b58d10fSBhosale, Yogesh "\t\nMax: 128" 277*6b58d10fSBhosale, Yogesh 278*6b58d10fSBhosale, Yogesh #define IXGBE_SYSCTL_HELP_FWLOG_ARQ_ENA \ 279*6b58d10fSBhosale, Yogesh "\nControl whether to enable/disable reporting to admin Rx queue" \ 280*6b58d10fSBhosale, Yogesh "\n1 - Enable firmware reporting via ARQ" \ 281*6b58d10fSBhosale, Yogesh "\n0 - Disable firmware reporting via ARQ" 282*6b58d10fSBhosale, Yogesh 283*6b58d10fSBhosale, Yogesh #define IXGBE_SYSCTL_HELP_FWLOG_UART_ENA \ 284*6b58d10fSBhosale, Yogesh "\nControl whether to enable/disable reporting to UART" \ 285*6b58d10fSBhosale, Yogesh "\n1 - Enable firmware reporting via UART" \ 286*6b58d10fSBhosale, Yogesh "\n0 - Disable firmware reporting via UART" 287*6b58d10fSBhosale, Yogesh 288*6b58d10fSBhosale, Yogesh #define IXGBE_SYSCTL_HELP_FWLOG_ENABLE_ON_LOAD \ 289*6b58d10fSBhosale, Yogesh "\nControl whether to enable logging during the attach phase" \ 290*6b58d10fSBhosale, Yogesh "\n1 - Enable firmware logging during attach phase" \ 291*6b58d10fSBhosale, Yogesh "\n0 - Disable firmware logging during attach phase" 292*6b58d10fSBhosale, Yogesh 293*6b58d10fSBhosale, Yogesh #define IXGBE_SYSCTL_HELP_FWLOG_REGISTER \ 294*6b58d10fSBhosale, Yogesh "\nControl whether to enable/disable firmware logging" \ 295*6b58d10fSBhosale, Yogesh "\n1 - Enable firmware logging" \ 296*6b58d10fSBhosale, Yogesh "\n0 - Disable firmware logging" 297*6b58d10fSBhosale, Yogesh 298*6b58d10fSBhosale, Yogesh #define IXGBE_SYSCTL_HELP_FWLOG_MODULE_SEVERITY \ 299*6b58d10fSBhosale, Yogesh "\nControl the level of log output messages for this module" \ 300*6b58d10fSBhosale, Yogesh "\n\tverbose <4> - Verbose messages + (Error|Warning|Normal)" \ 301*6b58d10fSBhosale, Yogesh "\n\tnormal <3> - Normal messages + (Error|Warning)" \ 302*6b58d10fSBhosale, Yogesh "\n\twarning <2> - Warning messages + (Error)" \ 303*6b58d10fSBhosale, Yogesh "\n\terror <1> - Error messages" \ 304*6b58d10fSBhosale, Yogesh "\n\tnone <0> - Disables all logging for this module" 305*6b58d10fSBhosale, Yogesh 306*6b58d10fSBhosale, Yogesh /** 307*6b58d10fSBhosale, Yogesh * ixgbe_fw_module_str - Convert a FW logging module to a string name 308*6b58d10fSBhosale, Yogesh * @module: the module to convert 309*6b58d10fSBhosale, Yogesh * 310*6b58d10fSBhosale, Yogesh * Given a FW logging module id, convert it to a shorthand human readable 311*6b58d10fSBhosale, Yogesh * name, for generating sysctl tunables. 312*6b58d10fSBhosale, Yogesh */ 313*6b58d10fSBhosale, Yogesh static const char * ixgbe_fw_module_str(enum ixgbe_aci_fw_logging_mod module)314*6b58d10fSBhosale, Yogesh ixgbe_fw_module_str(enum ixgbe_aci_fw_logging_mod module) 315*6b58d10fSBhosale, Yogesh { 316*6b58d10fSBhosale, Yogesh switch (module) { 317*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_GENERAL: 318*6b58d10fSBhosale, Yogesh return "general"; 319*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_CTRL: 320*6b58d10fSBhosale, Yogesh return "ctrl"; 321*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_LINK: 322*6b58d10fSBhosale, Yogesh return "link"; 323*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_LINK_TOPO: 324*6b58d10fSBhosale, Yogesh return "link_topo"; 325*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_DNL: 326*6b58d10fSBhosale, Yogesh return "dnl"; 327*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_I2C: 328*6b58d10fSBhosale, Yogesh return "i2c"; 329*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_SDP: 330*6b58d10fSBhosale, Yogesh return "sdp"; 331*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_MDIO: 332*6b58d10fSBhosale, Yogesh return "mdio"; 333*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_ADMINQ: 334*6b58d10fSBhosale, Yogesh return "adminq"; 335*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_HDMA: 336*6b58d10fSBhosale, Yogesh return "hdma"; 337*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_LLDP: 338*6b58d10fSBhosale, Yogesh return "lldp"; 339*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_DCBX: 340*6b58d10fSBhosale, Yogesh return "dcbx"; 341*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_DCB: 342*6b58d10fSBhosale, Yogesh return "dcb"; 343*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_XLR: 344*6b58d10fSBhosale, Yogesh return "xlr"; 345*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_NVM: 346*6b58d10fSBhosale, Yogesh return "nvm"; 347*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_AUTH: 348*6b58d10fSBhosale, Yogesh return "auth"; 349*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_VPD: 350*6b58d10fSBhosale, Yogesh return "vpd"; 351*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_IOSF: 352*6b58d10fSBhosale, Yogesh return "iosf"; 353*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_PARSER: 354*6b58d10fSBhosale, Yogesh return "parser"; 355*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_SW: 356*6b58d10fSBhosale, Yogesh return "sw"; 357*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_SCHEDULER: 358*6b58d10fSBhosale, Yogesh return "scheduler"; 359*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_TXQ: 360*6b58d10fSBhosale, Yogesh return "txq"; 361*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_ACL: 362*6b58d10fSBhosale, Yogesh return "acl"; 363*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_POST: 364*6b58d10fSBhosale, Yogesh return "post"; 365*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_WATCHDOG: 366*6b58d10fSBhosale, Yogesh return "watchdog"; 367*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_TASK_DISPATCH: 368*6b58d10fSBhosale, Yogesh return "task_dispatch"; 369*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_MNG: 370*6b58d10fSBhosale, Yogesh return "mng"; 371*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_SYNCE: 372*6b58d10fSBhosale, Yogesh return "synce"; 373*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_HEALTH: 374*6b58d10fSBhosale, Yogesh return "health"; 375*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_TSDRV: 376*6b58d10fSBhosale, Yogesh return "tsdrv"; 377*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_PFREG: 378*6b58d10fSBhosale, Yogesh return "pfreg"; 379*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_MDLVER: 380*6b58d10fSBhosale, Yogesh return "mdlver"; 381*6b58d10fSBhosale, Yogesh case IXGBE_ACI_FW_LOG_ID_MAX: 382*6b58d10fSBhosale, Yogesh return "unknown"; 383*6b58d10fSBhosale, Yogesh } 384*6b58d10fSBhosale, Yogesh 385*6b58d10fSBhosale, Yogesh /* The compiler generates errors on unhandled enum values if we omit 386*6b58d10fSBhosale, Yogesh * the default case. 387*6b58d10fSBhosale, Yogesh */ 388*6b58d10fSBhosale, Yogesh return "unknown"; 389*6b58d10fSBhosale, Yogesh } 390*6b58d10fSBhosale, Yogesh 391*6b58d10fSBhosale, Yogesh /** 392*6b58d10fSBhosale, Yogesh * ixgbe_add_fw_logging_tunables - Add tunables to configure FW logging events 393*6b58d10fSBhosale, Yogesh * @sc: private softc structure 394*6b58d10fSBhosale, Yogesh * @parent: parent node to add the tunables under 395*6b58d10fSBhosale, Yogesh * 396*6b58d10fSBhosale, Yogesh * Add tunables for configuring the firmware logging support. This includes 397*6b58d10fSBhosale, Yogesh * a control to enable the logging, and controls for each module to configure 398*6b58d10fSBhosale, Yogesh * which events to receive. 399*6b58d10fSBhosale, Yogesh */ 400*6b58d10fSBhosale, Yogesh void ixgbe_add_fw_logging_tunables(struct ixgbe_softc * sc,struct sysctl_oid * parent)401*6b58d10fSBhosale, Yogesh ixgbe_add_fw_logging_tunables(struct ixgbe_softc *sc, struct sysctl_oid *parent) 402*6b58d10fSBhosale, Yogesh { 403*6b58d10fSBhosale, Yogesh struct sysctl_oid_list *parent_list, *fwlog_list, *module_list; 404*6b58d10fSBhosale, Yogesh struct sysctl_oid *fwlog_node, *module_node; 405*6b58d10fSBhosale, Yogesh struct sysctl_ctx_list *ctx; 406*6b58d10fSBhosale, Yogesh struct ixgbe_hw *hw = &sc->hw; 407*6b58d10fSBhosale, Yogesh struct ixgbe_fwlog_cfg *cfg; 408*6b58d10fSBhosale, Yogesh device_t dev = sc->dev; 409*6b58d10fSBhosale, Yogesh enum ixgbe_aci_fw_logging_mod module; 410*6b58d10fSBhosale, Yogesh u16 i; 411*6b58d10fSBhosale, Yogesh 412*6b58d10fSBhosale, Yogesh cfg = &hw->fwlog_cfg; 413*6b58d10fSBhosale, Yogesh ctx = device_get_sysctl_ctx(dev); 414*6b58d10fSBhosale, Yogesh parent_list = SYSCTL_CHILDREN(parent); 415*6b58d10fSBhosale, Yogesh 416*6b58d10fSBhosale, Yogesh fwlog_node = SYSCTL_ADD_NODE(ctx, parent_list, OID_AUTO, "fw_log", 417*6b58d10fSBhosale, Yogesh CTLFLAG_RD, NULL, 418*6b58d10fSBhosale, Yogesh "Firmware Logging"); 419*6b58d10fSBhosale, Yogesh fwlog_list = SYSCTL_CHILDREN(fwlog_node); 420*6b58d10fSBhosale, Yogesh 421*6b58d10fSBhosale, Yogesh cfg->log_resolution = 10; 422*6b58d10fSBhosale, Yogesh SYSCTL_ADD_PROC(ctx, fwlog_list, OID_AUTO, "log_resolution", 423*6b58d10fSBhosale, Yogesh CTLTYPE_U8 | CTLFLAG_RWTUN, sc, 424*6b58d10fSBhosale, Yogesh 0, ixgbe_sysctl_fwlog_log_resolution, 425*6b58d10fSBhosale, Yogesh "CU", IXGBE_SYSCTL_HELP_FWLOG_LOG_RESOLUTION); 426*6b58d10fSBhosale, Yogesh 427*6b58d10fSBhosale, Yogesh cfg->options |= IXGBE_FWLOG_OPTION_ARQ_ENA; 428*6b58d10fSBhosale, Yogesh SYSCTL_ADD_PROC(ctx, fwlog_list, OID_AUTO, "arq_en", 429*6b58d10fSBhosale, Yogesh CTLTYPE_U8 | CTLFLAG_RWTUN, sc, 430*6b58d10fSBhosale, Yogesh IXGBE_FWLOG_OPTION_ARQ_ENA, ixgbe_sysctl_fwlog_set_cfg_options, 431*6b58d10fSBhosale, Yogesh "CU", IXGBE_SYSCTL_HELP_FWLOG_ARQ_ENA); 432*6b58d10fSBhosale, Yogesh 433*6b58d10fSBhosale, Yogesh SYSCTL_ADD_PROC(ctx, fwlog_list, OID_AUTO, "uart_en", 434*6b58d10fSBhosale, Yogesh CTLTYPE_U8 | CTLFLAG_RWTUN, sc, 435*6b58d10fSBhosale, Yogesh IXGBE_FWLOG_OPTION_UART_ENA, ixgbe_sysctl_fwlog_set_cfg_options, 436*6b58d10fSBhosale, Yogesh "CU", IXGBE_SYSCTL_HELP_FWLOG_UART_ENA); 437*6b58d10fSBhosale, Yogesh 438*6b58d10fSBhosale, Yogesh SYSCTL_ADD_PROC(ctx, fwlog_list, OID_AUTO, "on_load", 439*6b58d10fSBhosale, Yogesh CTLTYPE_U8 | CTLFLAG_RWTUN, sc, 440*6b58d10fSBhosale, Yogesh IXGBE_FWLOG_OPTION_REGISTER_ON_INIT, ixgbe_sysctl_fwlog_set_cfg_options, 441*6b58d10fSBhosale, Yogesh "CU", IXGBE_SYSCTL_HELP_FWLOG_ENABLE_ON_LOAD); 442*6b58d10fSBhosale, Yogesh 443*6b58d10fSBhosale, Yogesh SYSCTL_ADD_PROC(ctx, fwlog_list, OID_AUTO, "register", 444*6b58d10fSBhosale, Yogesh CTLTYPE_U8 | CTLFLAG_RWTUN, sc, 445*6b58d10fSBhosale, Yogesh 0, ixgbe_sysctl_fwlog_register, 446*6b58d10fSBhosale, Yogesh "CU", IXGBE_SYSCTL_HELP_FWLOG_REGISTER); 447*6b58d10fSBhosale, Yogesh 448*6b58d10fSBhosale, Yogesh module_node = SYSCTL_ADD_NODE(ctx, fwlog_list, OID_AUTO, "severity", 449*6b58d10fSBhosale, Yogesh CTLFLAG_RD, NULL, 450*6b58d10fSBhosale, Yogesh "Level of log output"); 451*6b58d10fSBhosale, Yogesh 452*6b58d10fSBhosale, Yogesh module_list = SYSCTL_CHILDREN(module_node); 453*6b58d10fSBhosale, Yogesh 454*6b58d10fSBhosale, Yogesh for (i = 0; i < IXGBE_ACI_FW_LOG_ID_MAX; i++) { 455*6b58d10fSBhosale, Yogesh /* Setup some defaults */ 456*6b58d10fSBhosale, Yogesh cfg->module_entries[i].module_id = i; 457*6b58d10fSBhosale, Yogesh cfg->module_entries[i].log_level = IXGBE_FWLOG_LEVEL_NONE; 458*6b58d10fSBhosale, Yogesh module = (enum ixgbe_aci_fw_logging_mod)i; 459*6b58d10fSBhosale, Yogesh 460*6b58d10fSBhosale, Yogesh SYSCTL_ADD_PROC(ctx, module_list, 461*6b58d10fSBhosale, Yogesh OID_AUTO, ixgbe_fw_module_str(module), 462*6b58d10fSBhosale, Yogesh CTLTYPE_STRING | CTLFLAG_RWTUN, sc, 463*6b58d10fSBhosale, Yogesh module, ixgbe_sysctl_fwlog_module_log_severity, 464*6b58d10fSBhosale, Yogesh "A", IXGBE_SYSCTL_HELP_FWLOG_MODULE_SEVERITY); 465*6b58d10fSBhosale, Yogesh } 466*6b58d10fSBhosale, Yogesh } 467*6b58d10fSBhosale, Yogesh