xref: /freebsd/sys/dev/ixgbe/ixgbe_fw_logging.c (revision 6b58d10fc6d51ddcf5ee81628ead74d3dadb9bf6)
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