1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2022, Intel Corporation. */
4 #include <linux/vmalloc.h>
6 #include "ice_common.h"
9 bool ice_fwlog_ring_full(struct ice_fwlog_ring *rings)
16 if (head < tail && (tail - head == (rings->size - 1)))
18 else if (head > tail && (tail == (head - 1)))
24 bool ice_fwlog_ring_empty(struct ice_fwlog_ring *rings)
26 return rings->head == rings->tail;
29 void ice_fwlog_ring_increment(u16 *item, u16 size)
31 *item = (*item + 1) & (size - 1);
34 static int ice_fwlog_alloc_ring_buffs(struct ice_fwlog_ring *rings)
39 nr_bytes = rings->size * ICE_AQ_MAX_BUF_LEN;
40 mem = vzalloc(nr_bytes);
44 for (i = 0; i < rings->size; i++) {
45 struct ice_fwlog_data *ring = &rings->rings[i];
47 ring->data_size = ICE_AQ_MAX_BUF_LEN;
49 mem += ICE_AQ_MAX_BUF_LEN;
55 static void ice_fwlog_free_ring_buffs(struct ice_fwlog_ring *rings)
59 for (i = 0; i < rings->size; i++) {
60 struct ice_fwlog_data *ring = &rings->rings[i];
62 /* the first ring is the base memory for the whole range so
73 #define ICE_FWLOG_INDEX_TO_BYTES(n) ((128 * 1024) << (n))
75 * ice_fwlog_realloc_rings - reallocate the FW log rings
76 * @hw: pointer to the HW structure
77 * @index: the new index to use to allocate memory for the log data
80 void ice_fwlog_realloc_rings(struct ice_hw *hw, int index)
82 struct ice_fwlog_ring ring;
83 int status, ring_size;
85 /* convert the number of bytes into a number of 4K buffers. externally
86 * the driver presents the interface to the FW log data as a number of
87 * bytes because that's easy for users to understand. internally the
88 * driver uses a ring of buffers because the driver doesn't know where
89 * the beginning and end of any line of log data is so the driver has
90 * to overwrite data as complete blocks. when the data is returned to
91 * the user the driver knows that the data is correct and the FW log
92 * can be correctly parsed by the tools
94 ring_size = ICE_FWLOG_INDEX_TO_BYTES(index) / ICE_AQ_MAX_BUF_LEN;
95 if (ring_size == hw->fwlog_ring.size)
98 /* allocate space for the new rings and buffers then release the
99 * old rings and buffers. that way if we don't have enough
100 * memory then we at least have what we had before
102 ring.rings = kcalloc(ring_size, sizeof(*ring.rings), GFP_KERNEL);
106 ring.size = ring_size;
108 status = ice_fwlog_alloc_ring_buffs(&ring);
110 dev_warn(ice_hw_to_dev(hw), "Unable to allocate memory for FW log ring data buffers\n");
111 ice_fwlog_free_ring_buffs(&ring);
116 ice_fwlog_free_ring_buffs(&hw->fwlog_ring);
117 kfree(hw->fwlog_ring.rings);
119 hw->fwlog_ring.rings = ring.rings;
120 hw->fwlog_ring.size = ring.size;
121 hw->fwlog_ring.index = index;
122 hw->fwlog_ring.head = 0;
123 hw->fwlog_ring.tail = 0;
127 * ice_fwlog_init - Initialize FW logging configuration
128 * @hw: pointer to the HW structure
130 * This function should be called on driver initialization during
133 int ice_fwlog_init(struct ice_hw *hw)
135 /* only support fw log commands on PF 0 */
139 ice_fwlog_set_supported(hw);
141 if (ice_fwlog_supported(hw)) {
144 /* read the current config from the FW and store it */
145 status = ice_fwlog_get(hw, &hw->fwlog_cfg);
149 hw->fwlog_ring.rings = kcalloc(ICE_FWLOG_RING_SIZE_DFLT,
150 sizeof(*hw->fwlog_ring.rings),
152 if (!hw->fwlog_ring.rings) {
153 dev_warn(ice_hw_to_dev(hw), "Unable to allocate memory for FW log rings\n");
157 hw->fwlog_ring.size = ICE_FWLOG_RING_SIZE_DFLT;
158 hw->fwlog_ring.index = ICE_FWLOG_RING_SIZE_INDEX_DFLT;
160 status = ice_fwlog_alloc_ring_buffs(&hw->fwlog_ring);
162 dev_warn(ice_hw_to_dev(hw), "Unable to allocate memory for FW log ring data buffers\n");
163 ice_fwlog_free_ring_buffs(&hw->fwlog_ring);
164 kfree(hw->fwlog_ring.rings);
168 ice_debugfs_fwlog_init(hw->back);
170 dev_warn(ice_hw_to_dev(hw), "FW logging is not supported in this NVM image. Please update the NVM to get FW log support\n");
177 * ice_fwlog_deinit - unroll FW logging configuration
178 * @hw: pointer to the HW structure
180 * This function should be called in ice_deinit_hw().
182 void ice_fwlog_deinit(struct ice_hw *hw)
184 struct ice_pf *pf = hw->back;
187 /* only support fw log commands on PF 0 */
191 ice_debugfs_pf_deinit(hw->back);
193 /* make sure FW logging is disabled to not put the FW in a weird state
194 * for the next driver load
196 hw->fwlog_cfg.options &= ~ICE_FWLOG_OPTION_ARQ_ENA;
197 status = ice_fwlog_set(hw, &hw->fwlog_cfg);
199 dev_warn(ice_hw_to_dev(hw), "Unable to turn off FW logging, status: %d\n",
202 kfree(pf->ice_debugfs_pf_fwlog_modules);
204 pf->ice_debugfs_pf_fwlog_modules = NULL;
206 status = ice_fwlog_unregister(hw);
208 dev_warn(ice_hw_to_dev(hw), "Unable to unregister FW logging, status: %d\n",
211 if (hw->fwlog_ring.rings) {
212 ice_fwlog_free_ring_buffs(&hw->fwlog_ring);
213 kfree(hw->fwlog_ring.rings);
218 * ice_fwlog_supported - Cached for whether FW supports FW logging or not
219 * @hw: pointer to the HW structure
221 * This will always return false if called before ice_init_hw(), so it must be
222 * called after ice_init_hw().
224 bool ice_fwlog_supported(struct ice_hw *hw)
226 return hw->fwlog_supported;
230 * ice_aq_fwlog_set - Set FW logging configuration AQ command (0xFF30)
231 * @hw: pointer to the HW structure
232 * @entries: entries to configure
233 * @num_entries: number of @entries
234 * @options: options from ice_fwlog_cfg->options structure
235 * @log_resolution: logging resolution
238 ice_aq_fwlog_set(struct ice_hw *hw, struct ice_fwlog_module_entry *entries,
239 u16 num_entries, u16 options, u16 log_resolution)
241 struct ice_aqc_fw_log_cfg_resp *fw_modules;
242 struct ice_aqc_fw_log *cmd;
243 struct ice_aq_desc desc;
247 fw_modules = kcalloc(num_entries, sizeof(*fw_modules), GFP_KERNEL);
251 for (i = 0; i < num_entries; i++) {
252 fw_modules[i].module_identifier =
253 cpu_to_le16(entries[i].module_id);
254 fw_modules[i].log_level = entries[i].log_level;
257 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logs_config);
258 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
260 cmd = &desc.params.fw_log;
262 cmd->cmd_flags = ICE_AQC_FW_LOG_CONF_SET_VALID;
263 cmd->ops.cfg.log_resolution = cpu_to_le16(log_resolution);
264 cmd->ops.cfg.mdl_cnt = cpu_to_le16(num_entries);
266 if (options & ICE_FWLOG_OPTION_ARQ_ENA)
267 cmd->cmd_flags |= ICE_AQC_FW_LOG_CONF_AQ_EN;
268 if (options & ICE_FWLOG_OPTION_UART_ENA)
269 cmd->cmd_flags |= ICE_AQC_FW_LOG_CONF_UART_EN;
271 status = ice_aq_send_cmd(hw, &desc, fw_modules,
272 sizeof(*fw_modules) * num_entries,
281 * ice_fwlog_set - Set the firmware logging settings
282 * @hw: pointer to the HW structure
283 * @cfg: config used to set firmware logging
285 * This function should be called whenever the driver needs to set the firmware
286 * logging configuration. It can be called on initialization, reset, or during
289 * If the PF wishes to receive FW logging then it must register via
290 * ice_fwlog_register. Note, that ice_fwlog_register does not need to be called
293 int ice_fwlog_set(struct ice_hw *hw, struct ice_fwlog_cfg *cfg)
295 if (!ice_fwlog_supported(hw))
298 return ice_aq_fwlog_set(hw, cfg->module_entries,
299 ICE_AQC_FW_LOG_ID_MAX, cfg->options,
300 cfg->log_resolution);
304 * ice_aq_fwlog_get - Get the current firmware logging configuration (0xFF32)
305 * @hw: pointer to the HW structure
306 * @cfg: firmware logging configuration to populate
308 static int ice_aq_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg)
310 struct ice_aqc_fw_log_cfg_resp *fw_modules;
311 struct ice_aqc_fw_log *cmd;
312 struct ice_aq_desc desc;
318 memset(cfg, 0, sizeof(*cfg));
320 buf = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL);
324 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logs_query);
325 cmd = &desc.params.fw_log;
327 cmd->cmd_flags = ICE_AQC_FW_LOG_AQ_QUERY;
329 status = ice_aq_send_cmd(hw, &desc, buf, ICE_AQ_MAX_BUF_LEN, NULL);
331 ice_debug(hw, ICE_DBG_FW_LOG, "Failed to get FW log configuration\n");
335 module_id_cnt = le16_to_cpu(cmd->ops.cfg.mdl_cnt);
336 if (module_id_cnt < ICE_AQC_FW_LOG_ID_MAX) {
337 ice_debug(hw, ICE_DBG_FW_LOG, "FW returned less than the expected number of FW log module IDs\n");
338 } else if (module_id_cnt > ICE_AQC_FW_LOG_ID_MAX) {
339 ice_debug(hw, ICE_DBG_FW_LOG, "FW returned more than expected number of FW log module IDs, setting module_id_cnt to software expected max %u\n",
340 ICE_AQC_FW_LOG_ID_MAX);
341 module_id_cnt = ICE_AQC_FW_LOG_ID_MAX;
344 cfg->log_resolution = le16_to_cpu(cmd->ops.cfg.log_resolution);
345 if (cmd->cmd_flags & ICE_AQC_FW_LOG_CONF_AQ_EN)
346 cfg->options |= ICE_FWLOG_OPTION_ARQ_ENA;
347 if (cmd->cmd_flags & ICE_AQC_FW_LOG_CONF_UART_EN)
348 cfg->options |= ICE_FWLOG_OPTION_UART_ENA;
349 if (cmd->cmd_flags & ICE_AQC_FW_LOG_QUERY_REGISTERED)
350 cfg->options |= ICE_FWLOG_OPTION_IS_REGISTERED;
352 fw_modules = (struct ice_aqc_fw_log_cfg_resp *)buf;
354 for (i = 0; i < module_id_cnt; i++) {
355 struct ice_aqc_fw_log_cfg_resp *fw_module = &fw_modules[i];
357 cfg->module_entries[i].module_id =
358 le16_to_cpu(fw_module->module_identifier);
359 cfg->module_entries[i].log_level = fw_module->log_level;
368 * ice_fwlog_get - Get the firmware logging settings
369 * @hw: pointer to the HW structure
370 * @cfg: config to populate based on current firmware logging settings
372 int ice_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg)
374 if (!ice_fwlog_supported(hw))
377 return ice_aq_fwlog_get(hw, cfg);
381 * ice_aq_fwlog_register - Register PF for firmware logging events (0xFF31)
382 * @hw: pointer to the HW structure
383 * @reg: true to register and false to unregister
385 static int ice_aq_fwlog_register(struct ice_hw *hw, bool reg)
387 struct ice_aq_desc desc;
389 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logs_register);
392 desc.params.fw_log.cmd_flags = ICE_AQC_FW_LOG_AQ_REGISTER;
394 return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
398 * ice_fwlog_register - Register the PF for firmware logging
399 * @hw: pointer to the HW structure
401 * After this call the PF will start to receive firmware logging based on the
402 * configuration set in ice_fwlog_set.
404 int ice_fwlog_register(struct ice_hw *hw)
408 if (!ice_fwlog_supported(hw))
411 status = ice_aq_fwlog_register(hw, true);
413 ice_debug(hw, ICE_DBG_FW_LOG, "Failed to register for firmware logging events over ARQ\n");
415 hw->fwlog_cfg.options |= ICE_FWLOG_OPTION_IS_REGISTERED;
421 * ice_fwlog_unregister - Unregister the PF from firmware logging
422 * @hw: pointer to the HW structure
424 int ice_fwlog_unregister(struct ice_hw *hw)
428 if (!ice_fwlog_supported(hw))
431 status = ice_aq_fwlog_register(hw, false);
433 ice_debug(hw, ICE_DBG_FW_LOG, "Failed to unregister from firmware logging events over ARQ\n");
435 hw->fwlog_cfg.options &= ~ICE_FWLOG_OPTION_IS_REGISTERED;
441 * ice_fwlog_set_supported - Set if FW logging is supported by FW
442 * @hw: pointer to the HW struct
444 * If FW returns success to the ice_aq_fwlog_get call then it supports FW
445 * logging, else it doesn't. Set the fwlog_supported flag accordingly.
447 * This function is only meant to be called during driver init to determine if
448 * the FW support FW logging.
450 void ice_fwlog_set_supported(struct ice_hw *hw)
452 struct ice_fwlog_cfg *cfg;
455 hw->fwlog_supported = false;
457 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
461 /* don't call ice_fwlog_get() because that would check to see if FW
462 * logging is supported which is what the driver is determining now
464 status = ice_aq_fwlog_get(hw, cfg);
466 ice_debug(hw, ICE_DBG_FW_LOG, "ice_aq_fwlog_get failed, FW logging is not supported on this version of FW, status %d\n",
469 hw->fwlog_supported = true;