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 ice_debugfs_pf_deinit(hw->back); 192 193 /* make sure FW logging is disabled to not put the FW in a weird state 194 * for the next driver load 195 */ 196 hw->fwlog_cfg.options &= ~ICE_FWLOG_OPTION_ARQ_ENA; 197 status = ice_fwlog_set(hw, &hw->fwlog_cfg); 198 if (status) 199 dev_warn(ice_hw_to_dev(hw), "Unable to turn off FW logging, status: %d\n", 200 status); 201 202 kfree(pf->ice_debugfs_pf_fwlog_modules); 203 204 pf->ice_debugfs_pf_fwlog_modules = NULL; 205 206 status = ice_fwlog_unregister(hw); 207 if (status) 208 dev_warn(ice_hw_to_dev(hw), "Unable to unregister FW logging, status: %d\n", 209 status); 210 211 if (hw->fwlog_ring.rings) { 212 ice_fwlog_free_ring_buffs(&hw->fwlog_ring); 213 kfree(hw->fwlog_ring.rings); 214 } 215 } 216 217 /** 218 * ice_fwlog_supported - Cached for whether FW supports FW logging or not 219 * @hw: pointer to the HW structure 220 * 221 * This will always return false if called before ice_init_hw(), so it must be 222 * called after ice_init_hw(). 223 */ 224 bool ice_fwlog_supported(struct ice_hw *hw) 225 { 226 return hw->fwlog_supported; 227 } 228 229 /** 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 236 */ 237 static int 238 ice_aq_fwlog_set(struct ice_hw *hw, struct ice_fwlog_module_entry *entries, 239 u16 num_entries, u16 options, u16 log_resolution) 240 { 241 struct ice_aqc_fw_log_cfg_resp *fw_modules; 242 struct ice_aqc_fw_log *cmd; 243 struct ice_aq_desc desc; 244 int status; 245 int i; 246 247 fw_modules = kcalloc(num_entries, sizeof(*fw_modules), GFP_KERNEL); 248 if (!fw_modules) 249 return -ENOMEM; 250 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; 255 } 256 257 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logs_config); 258 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 259 260 cmd = &desc.params.fw_log; 261 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); 265 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; 270 271 status = ice_aq_send_cmd(hw, &desc, fw_modules, 272 sizeof(*fw_modules) * num_entries, 273 NULL); 274 275 kfree(fw_modules); 276 277 return status; 278 } 279 280 /** 281 * ice_fwlog_set - Set the firmware logging settings 282 * @hw: pointer to the HW structure 283 * @cfg: config used to set firmware logging 284 * 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 287 * runtime. 288 * 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 291 * for init. 292 */ 293 int ice_fwlog_set(struct ice_hw *hw, struct ice_fwlog_cfg *cfg) 294 { 295 if (!ice_fwlog_supported(hw)) 296 return -EOPNOTSUPP; 297 298 return ice_aq_fwlog_set(hw, cfg->module_entries, 299 ICE_AQC_FW_LOG_ID_MAX, cfg->options, 300 cfg->log_resolution); 301 } 302 303 /** 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 307 */ 308 static int ice_aq_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg) 309 { 310 struct ice_aqc_fw_log_cfg_resp *fw_modules; 311 struct ice_aqc_fw_log *cmd; 312 struct ice_aq_desc desc; 313 u16 module_id_cnt; 314 int status; 315 void *buf; 316 int i; 317 318 memset(cfg, 0, sizeof(*cfg)); 319 320 buf = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL); 321 if (!buf) 322 return -ENOMEM; 323 324 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logs_query); 325 cmd = &desc.params.fw_log; 326 327 cmd->cmd_flags = ICE_AQC_FW_LOG_AQ_QUERY; 328 329 status = ice_aq_send_cmd(hw, &desc, buf, ICE_AQ_MAX_BUF_LEN, NULL); 330 if (status) { 331 ice_debug(hw, ICE_DBG_FW_LOG, "Failed to get FW log configuration\n"); 332 goto status_out; 333 } 334 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; 342 } 343 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; 351 352 fw_modules = (struct ice_aqc_fw_log_cfg_resp *)buf; 353 354 for (i = 0; i < module_id_cnt; i++) { 355 struct ice_aqc_fw_log_cfg_resp *fw_module = &fw_modules[i]; 356 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; 360 } 361 362 status_out: 363 kfree(buf); 364 return status; 365 } 366 367 /** 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 371 */ 372 int ice_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg) 373 { 374 if (!ice_fwlog_supported(hw)) 375 return -EOPNOTSUPP; 376 377 return ice_aq_fwlog_get(hw, cfg); 378 } 379 380 /** 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 384 */ 385 static int ice_aq_fwlog_register(struct ice_hw *hw, bool reg) 386 { 387 struct ice_aq_desc desc; 388 389 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logs_register); 390 391 if (reg) 392 desc.params.fw_log.cmd_flags = ICE_AQC_FW_LOG_AQ_REGISTER; 393 394 return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); 395 } 396 397 /** 398 * ice_fwlog_register - Register the PF for firmware logging 399 * @hw: pointer to the HW structure 400 * 401 * After this call the PF will start to receive firmware logging based on the 402 * configuration set in ice_fwlog_set. 403 */ 404 int ice_fwlog_register(struct ice_hw *hw) 405 { 406 int status; 407 408 if (!ice_fwlog_supported(hw)) 409 return -EOPNOTSUPP; 410 411 status = ice_aq_fwlog_register(hw, true); 412 if (status) 413 ice_debug(hw, ICE_DBG_FW_LOG, "Failed to register for firmware logging events over ARQ\n"); 414 else 415 hw->fwlog_cfg.options |= ICE_FWLOG_OPTION_IS_REGISTERED; 416 417 return status; 418 } 419 420 /** 421 * ice_fwlog_unregister - Unregister the PF from firmware logging 422 * @hw: pointer to the HW structure 423 */ 424 int ice_fwlog_unregister(struct ice_hw *hw) 425 { 426 int status; 427 428 if (!ice_fwlog_supported(hw)) 429 return -EOPNOTSUPP; 430 431 status = ice_aq_fwlog_register(hw, false); 432 if (status) 433 ice_debug(hw, ICE_DBG_FW_LOG, "Failed to unregister from firmware logging events over ARQ\n"); 434 else 435 hw->fwlog_cfg.options &= ~ICE_FWLOG_OPTION_IS_REGISTERED; 436 437 return status; 438 } 439 440 /** 441 * ice_fwlog_set_supported - Set if FW logging is supported by FW 442 * @hw: pointer to the HW struct 443 * 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. 446 * 447 * This function is only meant to be called during driver init to determine if 448 * the FW support FW logging. 449 */ 450 void ice_fwlog_set_supported(struct ice_hw *hw) 451 { 452 struct ice_fwlog_cfg *cfg; 453 int status; 454 455 hw->fwlog_supported = false; 456 457 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); 458 if (!cfg) 459 return; 460 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 463 */ 464 status = ice_aq_fwlog_get(hw, cfg); 465 if (status) 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", 467 status); 468 else 469 hw->fwlog_supported = true; 470 471 kfree(cfg); 472 } 473