1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2022, Intel Corporation. */ 3 4 #include <linux/vmalloc.h> 5 #include "ice.h" 6 #include "ice_common.h" 7 #include "ice_fwlog.h" 8 9 bool ice_fwlog_ring_full(struct ice_fwlog_ring *rings) 10 { 11 u16 head, tail; 12 13 head = rings->head; 14 tail = rings->tail; 15 16 if (head < tail && (tail - head == (rings->size - 1))) 17 return true; 18 else if (head > tail && (tail == (head - 1))) 19 return true; 20 21 return false; 22 } 23 24 bool ice_fwlog_ring_empty(struct ice_fwlog_ring *rings) 25 { 26 return rings->head == rings->tail; 27 } 28 29 void ice_fwlog_ring_increment(u16 *item, u16 size) 30 { 31 *item = (*item + 1) & (size - 1); 32 } 33 34 static int ice_fwlog_alloc_ring_buffs(struct ice_fwlog_ring *rings) 35 { 36 int i, nr_bytes; 37 u8 *mem; 38 39 nr_bytes = rings->size * ICE_AQ_MAX_BUF_LEN; 40 mem = vzalloc(nr_bytes); 41 if (!mem) 42 return -ENOMEM; 43 44 for (i = 0; i < rings->size; i++) { 45 struct ice_fwlog_data *ring = &rings->rings[i]; 46 47 ring->data_size = ICE_AQ_MAX_BUF_LEN; 48 ring->data = mem; 49 mem += ICE_AQ_MAX_BUF_LEN; 50 } 51 52 return 0; 53 } 54 55 static void ice_fwlog_free_ring_buffs(struct ice_fwlog_ring *rings) 56 { 57 int i; 58 59 for (i = 0; i < rings->size; i++) { 60 struct ice_fwlog_data *ring = &rings->rings[i]; 61 62 /* the first ring is the base memory for the whole range so 63 * free it 64 */ 65 if (!i) 66 vfree(ring->data); 67 68 ring->data = NULL; 69 ring->data_size = 0; 70 } 71 } 72 73 #define ICE_FWLOG_INDEX_TO_BYTES(n) ((128 * 1024) << (n)) 74 /** 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 78 * 79 */ 80 void ice_fwlog_realloc_rings(struct ice_hw *hw, int index) 81 { 82 struct ice_fwlog_ring ring; 83 int status, ring_size; 84 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 93 */ 94 ring_size = ICE_FWLOG_INDEX_TO_BYTES(index) / ICE_AQ_MAX_BUF_LEN; 95 if (ring_size == hw->fwlog_ring.size) 96 return; 97 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 101 */ 102 ring.rings = kcalloc(ring_size, sizeof(*ring.rings), GFP_KERNEL); 103 if (!ring.rings) 104 return; 105 106 ring.size = ring_size; 107 108 status = ice_fwlog_alloc_ring_buffs(&ring); 109 if (status) { 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); 112 kfree(ring.rings); 113 return; 114 } 115 116 ice_fwlog_free_ring_buffs(&hw->fwlog_ring); 117 kfree(hw->fwlog_ring.rings); 118 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; 124 } 125 126 /** 127 * ice_fwlog_init - Initialize FW logging configuration 128 * @hw: pointer to the HW structure 129 * 130 * This function should be called on driver initialization during 131 * ice_init_hw(). 132 */ 133 int ice_fwlog_init(struct ice_hw *hw) 134 { 135 /* only support fw log commands on PF 0 */ 136 if (hw->bus.func) 137 return -EINVAL; 138 139 ice_fwlog_set_supported(hw); 140 141 if (ice_fwlog_supported(hw)) { 142 int status; 143 144 /* read the current config from the FW and store it */ 145 status = ice_fwlog_get(hw, &hw->fwlog_cfg); 146 if (status) 147 return status; 148 149 hw->fwlog_ring.rings = kcalloc(ICE_FWLOG_RING_SIZE_DFLT, 150 sizeof(*hw->fwlog_ring.rings), 151 GFP_KERNEL); 152 if (!hw->fwlog_ring.rings) { 153 dev_warn(ice_hw_to_dev(hw), "Unable to allocate memory for FW log rings\n"); 154 return -ENOMEM; 155 } 156 157 hw->fwlog_ring.size = ICE_FWLOG_RING_SIZE_DFLT; 158 hw->fwlog_ring.index = ICE_FWLOG_RING_SIZE_INDEX_DFLT; 159 160 status = ice_fwlog_alloc_ring_buffs(&hw->fwlog_ring); 161 if (status) { 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); 165 return status; 166 } 167 168 ice_debugfs_fwlog_init(hw->back); 169 } else { 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"); 171 } 172 173 return 0; 174 } 175 176 /** 177 * ice_fwlog_deinit - unroll FW logging configuration 178 * @hw: pointer to the HW structure 179 * 180 * This function should be called in ice_deinit_hw(). 181 */ 182 void ice_fwlog_deinit(struct ice_hw *hw) 183 { 184 struct ice_pf *pf = hw->back; 185 int status; 186 187 /* only support fw log commands on PF 0 */ 188 if (hw->bus.func) 189 return; 190 191 /* make sure FW logging is disabled to not put the FW in a weird state 192 * for the next driver load 193 */ 194 hw->fwlog_cfg.options &= ~ICE_FWLOG_OPTION_ARQ_ENA; 195 status = ice_fwlog_set(hw, &hw->fwlog_cfg); 196 if (status) 197 dev_warn(ice_hw_to_dev(hw), "Unable to turn off FW logging, status: %d\n", 198 status); 199 200 kfree(pf->ice_debugfs_pf_fwlog_modules); 201 202 pf->ice_debugfs_pf_fwlog_modules = NULL; 203 204 status = ice_fwlog_unregister(hw); 205 if (status) 206 dev_warn(ice_hw_to_dev(hw), "Unable to unregister FW logging, status: %d\n", 207 status); 208 209 if (hw->fwlog_ring.rings) { 210 ice_fwlog_free_ring_buffs(&hw->fwlog_ring); 211 kfree(hw->fwlog_ring.rings); 212 } 213 } 214 215 /** 216 * ice_fwlog_supported - Cached for whether FW supports FW logging or not 217 * @hw: pointer to the HW structure 218 * 219 * This will always return false if called before ice_init_hw(), so it must be 220 * called after ice_init_hw(). 221 */ 222 bool ice_fwlog_supported(struct ice_hw *hw) 223 { 224 return hw->fwlog_supported; 225 } 226 227 /** 228 * ice_aq_fwlog_set - Set FW logging configuration AQ command (0xFF30) 229 * @hw: pointer to the HW structure 230 * @entries: entries to configure 231 * @num_entries: number of @entries 232 * @options: options from ice_fwlog_cfg->options structure 233 * @log_resolution: logging resolution 234 */ 235 static int 236 ice_aq_fwlog_set(struct ice_hw *hw, struct ice_fwlog_module_entry *entries, 237 u16 num_entries, u16 options, u16 log_resolution) 238 { 239 struct ice_aqc_fw_log_cfg_resp *fw_modules; 240 struct ice_aqc_fw_log *cmd; 241 struct ice_aq_desc desc; 242 int status; 243 int i; 244 245 fw_modules = kcalloc(num_entries, sizeof(*fw_modules), GFP_KERNEL); 246 if (!fw_modules) 247 return -ENOMEM; 248 249 for (i = 0; i < num_entries; i++) { 250 fw_modules[i].module_identifier = 251 cpu_to_le16(entries[i].module_id); 252 fw_modules[i].log_level = entries[i].log_level; 253 } 254 255 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logs_config); 256 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 257 258 cmd = &desc.params.fw_log; 259 260 cmd->cmd_flags = ICE_AQC_FW_LOG_CONF_SET_VALID; 261 cmd->ops.cfg.log_resolution = cpu_to_le16(log_resolution); 262 cmd->ops.cfg.mdl_cnt = cpu_to_le16(num_entries); 263 264 if (options & ICE_FWLOG_OPTION_ARQ_ENA) 265 cmd->cmd_flags |= ICE_AQC_FW_LOG_CONF_AQ_EN; 266 if (options & ICE_FWLOG_OPTION_UART_ENA) 267 cmd->cmd_flags |= ICE_AQC_FW_LOG_CONF_UART_EN; 268 269 status = ice_aq_send_cmd(hw, &desc, fw_modules, 270 sizeof(*fw_modules) * num_entries, 271 NULL); 272 273 kfree(fw_modules); 274 275 return status; 276 } 277 278 /** 279 * ice_fwlog_set - Set the firmware logging settings 280 * @hw: pointer to the HW structure 281 * @cfg: config used to set firmware logging 282 * 283 * This function should be called whenever the driver needs to set the firmware 284 * logging configuration. It can be called on initialization, reset, or during 285 * runtime. 286 * 287 * If the PF wishes to receive FW logging then it must register via 288 * ice_fwlog_register. Note, that ice_fwlog_register does not need to be called 289 * for init. 290 */ 291 int ice_fwlog_set(struct ice_hw *hw, struct ice_fwlog_cfg *cfg) 292 { 293 if (!ice_fwlog_supported(hw)) 294 return -EOPNOTSUPP; 295 296 return ice_aq_fwlog_set(hw, cfg->module_entries, 297 ICE_AQC_FW_LOG_ID_MAX, cfg->options, 298 cfg->log_resolution); 299 } 300 301 /** 302 * ice_aq_fwlog_get - Get the current firmware logging configuration (0xFF32) 303 * @hw: pointer to the HW structure 304 * @cfg: firmware logging configuration to populate 305 */ 306 static int ice_aq_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg) 307 { 308 struct ice_aqc_fw_log_cfg_resp *fw_modules; 309 struct ice_aqc_fw_log *cmd; 310 struct ice_aq_desc desc; 311 u16 module_id_cnt; 312 int status; 313 void *buf; 314 int i; 315 316 memset(cfg, 0, sizeof(*cfg)); 317 318 buf = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL); 319 if (!buf) 320 return -ENOMEM; 321 322 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logs_query); 323 cmd = &desc.params.fw_log; 324 325 cmd->cmd_flags = ICE_AQC_FW_LOG_AQ_QUERY; 326 327 status = ice_aq_send_cmd(hw, &desc, buf, ICE_AQ_MAX_BUF_LEN, NULL); 328 if (status) { 329 ice_debug(hw, ICE_DBG_FW_LOG, "Failed to get FW log configuration\n"); 330 goto status_out; 331 } 332 333 module_id_cnt = le16_to_cpu(cmd->ops.cfg.mdl_cnt); 334 if (module_id_cnt < ICE_AQC_FW_LOG_ID_MAX) { 335 ice_debug(hw, ICE_DBG_FW_LOG, "FW returned less than the expected number of FW log module IDs\n"); 336 } else if (module_id_cnt > ICE_AQC_FW_LOG_ID_MAX) { 337 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", 338 ICE_AQC_FW_LOG_ID_MAX); 339 module_id_cnt = ICE_AQC_FW_LOG_ID_MAX; 340 } 341 342 cfg->log_resolution = le16_to_cpu(cmd->ops.cfg.log_resolution); 343 if (cmd->cmd_flags & ICE_AQC_FW_LOG_CONF_AQ_EN) 344 cfg->options |= ICE_FWLOG_OPTION_ARQ_ENA; 345 if (cmd->cmd_flags & ICE_AQC_FW_LOG_CONF_UART_EN) 346 cfg->options |= ICE_FWLOG_OPTION_UART_ENA; 347 if (cmd->cmd_flags & ICE_AQC_FW_LOG_QUERY_REGISTERED) 348 cfg->options |= ICE_FWLOG_OPTION_IS_REGISTERED; 349 350 fw_modules = (struct ice_aqc_fw_log_cfg_resp *)buf; 351 352 for (i = 0; i < module_id_cnt; i++) { 353 struct ice_aqc_fw_log_cfg_resp *fw_module = &fw_modules[i]; 354 355 cfg->module_entries[i].module_id = 356 le16_to_cpu(fw_module->module_identifier); 357 cfg->module_entries[i].log_level = fw_module->log_level; 358 } 359 360 status_out: 361 kfree(buf); 362 return status; 363 } 364 365 /** 366 * ice_fwlog_get - Get the firmware logging settings 367 * @hw: pointer to the HW structure 368 * @cfg: config to populate based on current firmware logging settings 369 */ 370 int ice_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg) 371 { 372 if (!ice_fwlog_supported(hw)) 373 return -EOPNOTSUPP; 374 375 return ice_aq_fwlog_get(hw, cfg); 376 } 377 378 /** 379 * ice_aq_fwlog_register - Register PF for firmware logging events (0xFF31) 380 * @hw: pointer to the HW structure 381 * @reg: true to register and false to unregister 382 */ 383 static int ice_aq_fwlog_register(struct ice_hw *hw, bool reg) 384 { 385 struct ice_aq_desc desc; 386 387 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logs_register); 388 389 if (reg) 390 desc.params.fw_log.cmd_flags = ICE_AQC_FW_LOG_AQ_REGISTER; 391 392 return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); 393 } 394 395 /** 396 * ice_fwlog_register - Register the PF for firmware logging 397 * @hw: pointer to the HW structure 398 * 399 * After this call the PF will start to receive firmware logging based on the 400 * configuration set in ice_fwlog_set. 401 */ 402 int ice_fwlog_register(struct ice_hw *hw) 403 { 404 int status; 405 406 if (!ice_fwlog_supported(hw)) 407 return -EOPNOTSUPP; 408 409 status = ice_aq_fwlog_register(hw, true); 410 if (status) 411 ice_debug(hw, ICE_DBG_FW_LOG, "Failed to register for firmware logging events over ARQ\n"); 412 else 413 hw->fwlog_cfg.options |= ICE_FWLOG_OPTION_IS_REGISTERED; 414 415 return status; 416 } 417 418 /** 419 * ice_fwlog_unregister - Unregister the PF from firmware logging 420 * @hw: pointer to the HW structure 421 */ 422 int ice_fwlog_unregister(struct ice_hw *hw) 423 { 424 int status; 425 426 if (!ice_fwlog_supported(hw)) 427 return -EOPNOTSUPP; 428 429 status = ice_aq_fwlog_register(hw, false); 430 if (status) 431 ice_debug(hw, ICE_DBG_FW_LOG, "Failed to unregister from firmware logging events over ARQ\n"); 432 else 433 hw->fwlog_cfg.options &= ~ICE_FWLOG_OPTION_IS_REGISTERED; 434 435 return status; 436 } 437 438 /** 439 * ice_fwlog_set_supported - Set if FW logging is supported by FW 440 * @hw: pointer to the HW struct 441 * 442 * If FW returns success to the ice_aq_fwlog_get call then it supports FW 443 * logging, else it doesn't. Set the fwlog_supported flag accordingly. 444 * 445 * This function is only meant to be called during driver init to determine if 446 * the FW support FW logging. 447 */ 448 void ice_fwlog_set_supported(struct ice_hw *hw) 449 { 450 struct ice_fwlog_cfg *cfg; 451 int status; 452 453 hw->fwlog_supported = false; 454 455 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); 456 if (!cfg) 457 return; 458 459 /* don't call ice_fwlog_get() because that would check to see if FW 460 * logging is supported which is what the driver is determining now 461 */ 462 status = ice_aq_fwlog_get(hw, cfg); 463 if (status) 464 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", 465 status); 466 else 467 hw->fwlog_supported = true; 468 469 kfree(cfg); 470 } 471