1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2024, Intel Corporation. */ 3 4 #include "ice.h" 5 #include "ice_adminq_cmd.h" /* for enum ice_aqc_health_status_elem */ 6 #include "health.h" 7 8 #define ICE_DEVLINK_FMSG_PUT_FIELD(fmsg, obj, name) \ 9 devlink_fmsg_put(fmsg, #name, (obj)->name) 10 11 #define ICE_HEALTH_STATUS_DATA_SIZE 2 12 13 struct ice_health_status { 14 enum ice_aqc_health_status code; 15 const char *description; 16 const char *solution; 17 const char *data_label[ICE_HEALTH_STATUS_DATA_SIZE]; 18 }; 19 20 /* 21 * In addition to the health status codes provided below, the firmware might 22 * generate Health Status Codes that are not pertinent to the end-user. 23 * For instance, Health Code 0x1002 is triggered when the command fails. 24 * Such codes should be disregarded by the end-user. 25 * The below lookup requires to be sorted by code. 26 */ 27 28 static const char *const ice_common_port_solutions = 29 "Check your cable connection. Change or replace the module or cable. Manually set speed and duplex."; 30 static const char *const ice_port_number_label = "Port Number"; 31 static const char *const ice_update_nvm_solution = "Update to the latest NVM image."; 32 33 static const struct ice_health_status ice_health_status_lookup[] = { 34 {ICE_AQC_HEALTH_STATUS_ERR_UNKNOWN_MOD_STRICT, "An unsupported module was detected.", 35 ice_common_port_solutions, {ice_port_number_label}}, 36 {ICE_AQC_HEALTH_STATUS_ERR_MOD_TYPE, "Module type is not supported.", 37 "Change or replace the module or cable.", {ice_port_number_label}}, 38 {ICE_AQC_HEALTH_STATUS_ERR_MOD_QUAL, "Module is not qualified.", 39 ice_common_port_solutions, {ice_port_number_label}}, 40 {ICE_AQC_HEALTH_STATUS_ERR_MOD_COMM, 41 "Device cannot communicate with the module.", 42 "Check your cable connection. Change or replace the module or cable. Manually set speed and duplex.", 43 {ice_port_number_label}}, 44 {ICE_AQC_HEALTH_STATUS_ERR_MOD_CONFLICT, "Unresolved module conflict.", 45 "Manually set speed/duplex or change the port option. If the problem persists, use a cable/module that is found in the supported modules and cables list for this device.", 46 {ice_port_number_label}}, 47 {ICE_AQC_HEALTH_STATUS_ERR_MOD_NOT_PRESENT, "Module is not present.", 48 "Check that the module is inserted correctly. If the problem persists, use a cable/module that is found in the supported modules and cables list for this device.", 49 {ice_port_number_label}}, 50 {ICE_AQC_HEALTH_STATUS_INFO_MOD_UNDERUTILIZED, "Underutilized module.", 51 "Change or replace the module or cable. Change the port option.", 52 {ice_port_number_label}}, 53 {ICE_AQC_HEALTH_STATUS_ERR_UNKNOWN_MOD_LENIENT, "An unsupported module was detected.", 54 ice_common_port_solutions, {ice_port_number_label}}, 55 {ICE_AQC_HEALTH_STATUS_ERR_INVALID_LINK_CFG, "Invalid link configuration.", 56 NULL, {ice_port_number_label}}, 57 {ICE_AQC_HEALTH_STATUS_ERR_PORT_ACCESS, "Port hardware access error.", 58 ice_update_nvm_solution, {ice_port_number_label}}, 59 {ICE_AQC_HEALTH_STATUS_ERR_PORT_UNREACHABLE, "A port is unreachable.", 60 "Change the port option. Update to the latest NVM image."}, 61 {ICE_AQC_HEALTH_STATUS_INFO_PORT_SPEED_MOD_LIMITED, "Port speed is limited due to module.", 62 "Change the module or configure the port option to match the current module speed. Change the port option.", 63 {ice_port_number_label}}, 64 {ICE_AQC_HEALTH_STATUS_ERR_PARALLEL_FAULT, 65 "All configured link modes were attempted but failed to establish link. The device will restart the process to establish link.", 66 "Check link partner connection and configuration.", 67 {ice_port_number_label}}, 68 {ICE_AQC_HEALTH_STATUS_INFO_PORT_SPEED_PHY_LIMITED, 69 "Port speed is limited by PHY capabilities.", 70 "Change the module to align to port option.", {ice_port_number_label}}, 71 {ICE_AQC_HEALTH_STATUS_ERR_NETLIST_TOPO, "LOM topology netlist is corrupted.", 72 ice_update_nvm_solution, {ice_port_number_label}}, 73 {ICE_AQC_HEALTH_STATUS_ERR_NETLIST, "Unrecoverable netlist error.", 74 ice_update_nvm_solution, {ice_port_number_label}}, 75 {ICE_AQC_HEALTH_STATUS_ERR_TOPO_CONFLICT, "Port topology conflict.", 76 "Change the port option. Update to the latest NVM image."}, 77 {ICE_AQC_HEALTH_STATUS_ERR_LINK_HW_ACCESS, "Unrecoverable hardware access error.", 78 ice_update_nvm_solution, {ice_port_number_label}}, 79 {ICE_AQC_HEALTH_STATUS_ERR_LINK_RUNTIME, "Unrecoverable runtime error.", 80 ice_update_nvm_solution, {ice_port_number_label}}, 81 {ICE_AQC_HEALTH_STATUS_ERR_DNL_INIT, "Link management engine failed to initialize.", 82 ice_update_nvm_solution, {ice_port_number_label}}, 83 {ICE_AQC_HEALTH_STATUS_ERR_PHY_FW_LOAD, 84 "Failed to load the firmware image in the external PHY.", 85 ice_update_nvm_solution, {ice_port_number_label}}, 86 {ICE_AQC_HEALTH_STATUS_INFO_RECOVERY, "The device is in firmware recovery mode.", 87 ice_update_nvm_solution, {"Extended Error"}}, 88 {ICE_AQC_HEALTH_STATUS_ERR_FLASH_ACCESS, "The flash chip cannot be accessed.", 89 "If issue persists, call customer support.", {"Access Type"}}, 90 {ICE_AQC_HEALTH_STATUS_ERR_NVM_AUTH, "NVM authentication failed.", 91 ice_update_nvm_solution}, 92 {ICE_AQC_HEALTH_STATUS_ERR_OROM_AUTH, "Option ROM authentication failed.", 93 ice_update_nvm_solution}, 94 {ICE_AQC_HEALTH_STATUS_ERR_DDP_AUTH, "DDP package authentication failed.", 95 "Update to latest base driver and DDP package."}, 96 {ICE_AQC_HEALTH_STATUS_ERR_NVM_COMPAT, "NVM image is incompatible.", 97 ice_update_nvm_solution}, 98 {ICE_AQC_HEALTH_STATUS_ERR_OROM_COMPAT, "Option ROM is incompatible.", 99 ice_update_nvm_solution, {"Expected PCI Device ID", "Expected Module ID"}}, 100 {ICE_AQC_HEALTH_STATUS_ERR_DCB_MIB, 101 "Supplied MIB file is invalid. DCB reverted to default configuration.", 102 "Disable FW-LLDP and check DCBx system configuration.", 103 {ice_port_number_label, "MIB ID"}}, 104 }; 105 106 static int ice_health_status_lookup_compare(const void *a, const void *b) 107 { 108 return ((struct ice_health_status *)a)->code - ((struct ice_health_status *)b)->code; 109 } 110 111 static const struct ice_health_status *ice_get_health_status(u16 code) 112 { 113 struct ice_health_status key = { .code = code }; 114 115 return bsearch(&key, ice_health_status_lookup, ARRAY_SIZE(ice_health_status_lookup), 116 sizeof(struct ice_health_status), ice_health_status_lookup_compare); 117 } 118 119 static void ice_describe_status_code(struct devlink_fmsg *fmsg, 120 struct ice_aqc_health_status_elem *hse) 121 { 122 static const char *const aux_label[] = { "Aux Data 1", "Aux Data 2" }; 123 const struct ice_health_status *health_code; 124 u32 internal_data[2]; 125 u16 status_code; 126 127 status_code = le16_to_cpu(hse->health_status_code); 128 129 devlink_fmsg_put(fmsg, "Syndrome", status_code); 130 if (status_code) { 131 internal_data[0] = le32_to_cpu(hse->internal_data1); 132 internal_data[1] = le32_to_cpu(hse->internal_data2); 133 134 health_code = ice_get_health_status(status_code); 135 if (!health_code) 136 return; 137 138 devlink_fmsg_string_pair_put(fmsg, "Description", health_code->description); 139 if (health_code->solution) 140 devlink_fmsg_string_pair_put(fmsg, "Possible Solution", 141 health_code->solution); 142 143 for (size_t i = 0; i < ICE_HEALTH_STATUS_DATA_SIZE; i++) { 144 if (internal_data[i] != ICE_AQC_HEALTH_STATUS_UNDEFINED_DATA) 145 devlink_fmsg_u32_pair_put(fmsg, 146 health_code->data_label[i] ? 147 health_code->data_label[i] : 148 aux_label[i], 149 internal_data[i]); 150 } 151 } 152 } 153 154 static int 155 ice_port_reporter_diagnose(struct devlink_health_reporter *reporter, struct devlink_fmsg *fmsg, 156 struct netlink_ext_ack *extack) 157 { 158 struct ice_pf *pf = devlink_health_reporter_priv(reporter); 159 160 ice_describe_status_code(fmsg, &pf->health_reporters.port_status); 161 return 0; 162 } 163 164 static int 165 ice_port_reporter_dump(struct devlink_health_reporter *reporter, struct devlink_fmsg *fmsg, 166 void *priv_ctx, struct netlink_ext_ack __always_unused *extack) 167 { 168 struct ice_pf *pf = devlink_health_reporter_priv(reporter); 169 170 ice_describe_status_code(fmsg, &pf->health_reporters.port_status); 171 return 0; 172 } 173 174 static int 175 ice_fw_reporter_diagnose(struct devlink_health_reporter *reporter, struct devlink_fmsg *fmsg, 176 struct netlink_ext_ack *extack) 177 { 178 struct ice_pf *pf = devlink_health_reporter_priv(reporter); 179 180 ice_describe_status_code(fmsg, &pf->health_reporters.fw_status); 181 return 0; 182 } 183 184 static int 185 ice_fw_reporter_dump(struct devlink_health_reporter *reporter, struct devlink_fmsg *fmsg, 186 void *priv_ctx, struct netlink_ext_ack *extack) 187 { 188 struct ice_pf *pf = devlink_health_reporter_priv(reporter); 189 190 ice_describe_status_code(fmsg, &pf->health_reporters.fw_status); 191 return 0; 192 } 193 194 static void ice_config_health_events(struct ice_pf *pf, bool enable) 195 { 196 u8 enable_bits = 0; 197 int ret; 198 199 if (enable) 200 enable_bits = ICE_AQC_HEALTH_STATUS_SET_PF_SPECIFIC_MASK | 201 ICE_AQC_HEALTH_STATUS_SET_GLOBAL_MASK; 202 203 ret = ice_aq_set_health_status_cfg(&pf->hw, enable_bits); 204 if (ret) 205 dev_err(ice_pf_to_dev(pf), "Failed to %s firmware health events, err %d aq_err %s\n", 206 str_enable_disable(enable), ret, 207 ice_aq_str(pf->hw.adminq.sq_last_status)); 208 } 209 210 /** 211 * ice_process_health_status_event - Process the health status event from FW 212 * @pf: pointer to the PF structure 213 * @event: event structure containing the Health Status Event opcode 214 * 215 * Decode the Health Status Events and print the associated messages 216 */ 217 void ice_process_health_status_event(struct ice_pf *pf, struct ice_rq_event_info *event) 218 { 219 const struct ice_aqc_health_status_elem *health_info; 220 u16 count; 221 222 health_info = (struct ice_aqc_health_status_elem *)event->msg_buf; 223 count = le16_to_cpu(event->desc.params.get_health_status.health_status_count); 224 225 if (count > (event->buf_len / sizeof(*health_info))) { 226 dev_err(ice_pf_to_dev(pf), "Received a health status event with invalid element count\n"); 227 return; 228 } 229 230 for (size_t i = 0; i < count; i++) { 231 const struct ice_health_status *health_code; 232 u16 status_code; 233 234 status_code = le16_to_cpu(health_info->health_status_code); 235 health_code = ice_get_health_status(status_code); 236 237 if (health_code) { 238 switch (le16_to_cpu(health_info->event_source)) { 239 case ICE_AQC_HEALTH_STATUS_GLOBAL: 240 pf->health_reporters.fw_status = *health_info; 241 devlink_health_report(pf->health_reporters.fw, 242 "FW syndrome reported", NULL); 243 break; 244 case ICE_AQC_HEALTH_STATUS_PF: 245 case ICE_AQC_HEALTH_STATUS_PORT: 246 pf->health_reporters.port_status = *health_info; 247 devlink_health_report(pf->health_reporters.port, 248 "Port syndrome reported", NULL); 249 break; 250 default: 251 dev_err(ice_pf_to_dev(pf), "Health code with unknown source\n"); 252 } 253 } else { 254 u32 data1, data2; 255 u16 source; 256 257 source = le16_to_cpu(health_info->event_source); 258 data1 = le32_to_cpu(health_info->internal_data1); 259 data2 = le32_to_cpu(health_info->internal_data2); 260 dev_dbg(ice_pf_to_dev(pf), 261 "Received internal health status code 0x%08x, source: 0x%08x, data1: 0x%08x, data2: 0x%08x", 262 status_code, source, data1, data2); 263 } 264 health_info++; 265 } 266 } 267 268 /** 269 * ice_devlink_health_report - boilerplate to call given @reporter 270 * 271 * @reporter: devlink health reporter to call, do nothing on NULL 272 * @msg: message to pass up, "event name" is fine 273 * @priv_ctx: typically some event struct 274 */ 275 static void ice_devlink_health_report(struct devlink_health_reporter *reporter, 276 const char *msg, void *priv_ctx) 277 { 278 if (!reporter) 279 return; 280 281 /* We do not do auto recovering, so return value of the below function 282 * will always be 0, thus we do ignore it. 283 */ 284 devlink_health_report(reporter, msg, priv_ctx); 285 } 286 287 struct ice_mdd_event { 288 enum ice_mdd_src src; 289 u16 vf_num; 290 u16 queue; 291 u8 pf_num; 292 u8 event; 293 }; 294 295 static const char *ice_mdd_src_to_str(enum ice_mdd_src src) 296 { 297 switch (src) { 298 case ICE_MDD_SRC_TX_PQM: 299 return "tx_pqm"; 300 case ICE_MDD_SRC_TX_TCLAN: 301 return "tx_tclan"; 302 case ICE_MDD_SRC_TX_TDPU: 303 return "tx_tdpu"; 304 case ICE_MDD_SRC_RX: 305 return "rx"; 306 default: 307 return "invalid"; 308 } 309 } 310 311 static int 312 ice_mdd_reporter_dump(struct devlink_health_reporter *reporter, 313 struct devlink_fmsg *fmsg, void *priv_ctx, 314 struct netlink_ext_ack *extack) 315 { 316 struct ice_mdd_event *mdd_event = priv_ctx; 317 const char *src; 318 319 if (!mdd_event) 320 return 0; 321 322 src = ice_mdd_src_to_str(mdd_event->src); 323 324 devlink_fmsg_obj_nest_start(fmsg); 325 devlink_fmsg_put(fmsg, "src", src); 326 ICE_DEVLINK_FMSG_PUT_FIELD(fmsg, mdd_event, pf_num); 327 ICE_DEVLINK_FMSG_PUT_FIELD(fmsg, mdd_event, vf_num); 328 ICE_DEVLINK_FMSG_PUT_FIELD(fmsg, mdd_event, event); 329 ICE_DEVLINK_FMSG_PUT_FIELD(fmsg, mdd_event, queue); 330 devlink_fmsg_obj_nest_end(fmsg); 331 332 return 0; 333 } 334 335 /** 336 * ice_report_mdd_event - Report an MDD event through devlink health 337 * @pf: the PF device structure 338 * @src: the HW block that was the source of this MDD event 339 * @pf_num: the pf_num on which the MDD event occurred 340 * @vf_num: the vf_num on which the MDD event occurred 341 * @event: the event type of the MDD event 342 * @queue: the queue on which the MDD event occurred 343 * 344 * Report an MDD event that has occurred on this PF. 345 */ 346 void ice_report_mdd_event(struct ice_pf *pf, enum ice_mdd_src src, u8 pf_num, 347 u16 vf_num, u8 event, u16 queue) 348 { 349 struct ice_mdd_event ev = { 350 .src = src, 351 .pf_num = pf_num, 352 .vf_num = vf_num, 353 .event = event, 354 .queue = queue, 355 }; 356 357 ice_devlink_health_report(pf->health_reporters.mdd, "MDD event", &ev); 358 } 359 360 /** 361 * ice_fmsg_put_ptr - put hex value of pointer into fmsg 362 * 363 * @fmsg: devlink fmsg under construction 364 * @name: name to pass 365 * @ptr: 64 bit value to print as hex and put into fmsg 366 */ 367 static void ice_fmsg_put_ptr(struct devlink_fmsg *fmsg, const char *name, 368 void *ptr) 369 { 370 char buf[sizeof(ptr) * 3]; 371 372 sprintf(buf, "%p", ptr); 373 devlink_fmsg_put(fmsg, name, buf); 374 } 375 376 struct ice_tx_hang_event { 377 u32 head; 378 u32 intr; 379 u16 vsi_num; 380 u16 queue; 381 u16 next_to_clean; 382 u16 next_to_use; 383 struct ice_tx_ring *tx_ring; 384 }; 385 386 static int ice_tx_hang_reporter_dump(struct devlink_health_reporter *reporter, 387 struct devlink_fmsg *fmsg, void *priv_ctx, 388 struct netlink_ext_ack *extack) 389 { 390 struct ice_tx_hang_event *event = priv_ctx; 391 struct sk_buff *skb; 392 393 if (!event) 394 return 0; 395 396 skb = event->tx_ring->tx_buf->skb; 397 devlink_fmsg_obj_nest_start(fmsg); 398 ICE_DEVLINK_FMSG_PUT_FIELD(fmsg, event, head); 399 ICE_DEVLINK_FMSG_PUT_FIELD(fmsg, event, intr); 400 ICE_DEVLINK_FMSG_PUT_FIELD(fmsg, event, vsi_num); 401 ICE_DEVLINK_FMSG_PUT_FIELD(fmsg, event, queue); 402 ICE_DEVLINK_FMSG_PUT_FIELD(fmsg, event, next_to_clean); 403 ICE_DEVLINK_FMSG_PUT_FIELD(fmsg, event, next_to_use); 404 devlink_fmsg_put(fmsg, "irq-mapping", event->tx_ring->q_vector->name); 405 ice_fmsg_put_ptr(fmsg, "desc-ptr", event->tx_ring->desc); 406 ice_fmsg_put_ptr(fmsg, "dma-ptr", (void *)(long)event->tx_ring->dma); 407 ice_fmsg_put_ptr(fmsg, "skb-ptr", skb); 408 devlink_fmsg_binary_pair_put(fmsg, "desc", event->tx_ring->desc, 409 event->tx_ring->count * sizeof(struct ice_tx_desc)); 410 devlink_fmsg_dump_skb(fmsg, skb); 411 devlink_fmsg_obj_nest_end(fmsg); 412 413 return 0; 414 } 415 416 void ice_prep_tx_hang_report(struct ice_pf *pf, struct ice_tx_ring *tx_ring, 417 u16 vsi_num, u32 head, u32 intr) 418 { 419 struct ice_health_tx_hang_buf *buf = &pf->health_reporters.tx_hang_buf; 420 421 buf->tx_ring = tx_ring; 422 buf->vsi_num = vsi_num; 423 buf->head = head; 424 buf->intr = intr; 425 } 426 427 void ice_report_tx_hang(struct ice_pf *pf) 428 { 429 struct ice_health_tx_hang_buf *buf = &pf->health_reporters.tx_hang_buf; 430 struct ice_tx_ring *tx_ring = buf->tx_ring; 431 432 struct ice_tx_hang_event ev = { 433 .head = buf->head, 434 .intr = buf->intr, 435 .vsi_num = buf->vsi_num, 436 .queue = tx_ring->q_index, 437 .next_to_clean = tx_ring->next_to_clean, 438 .next_to_use = tx_ring->next_to_use, 439 .tx_ring = tx_ring, 440 }; 441 442 ice_devlink_health_report(pf->health_reporters.tx_hang, "Tx hang", &ev); 443 } 444 445 static struct devlink_health_reporter * 446 ice_init_devlink_rep(struct ice_pf *pf, 447 const struct devlink_health_reporter_ops *ops) 448 { 449 struct devlink *devlink = priv_to_devlink(pf); 450 struct devlink_health_reporter *rep; 451 const u64 graceful_period = 0; 452 453 rep = devl_health_reporter_create(devlink, ops, graceful_period, pf); 454 if (IS_ERR(rep)) { 455 struct device *dev = ice_pf_to_dev(pf); 456 457 dev_err(dev, "failed to create devlink %s health report er", 458 ops->name); 459 return NULL; 460 } 461 return rep; 462 } 463 464 #define ICE_HEALTH_REPORTER_OPS_FIELD(_name, _field) \ 465 ._field = ice_##_name##_reporter_##_field, 466 467 #define ICE_DEFINE_HEALTH_REPORTER_OPS_1(_name, _field1) \ 468 static const struct devlink_health_reporter_ops ice_##_name##_reporter_ops = { \ 469 .name = #_name, \ 470 ICE_HEALTH_REPORTER_OPS_FIELD(_name, _field1) \ 471 } 472 473 #define ICE_DEFINE_HEALTH_REPORTER_OPS_2(_name, _field1, _field2) \ 474 static const struct devlink_health_reporter_ops ice_##_name##_reporter_ops = { \ 475 .name = #_name, \ 476 ICE_HEALTH_REPORTER_OPS_FIELD(_name, _field1) \ 477 ICE_HEALTH_REPORTER_OPS_FIELD(_name, _field2) \ 478 } 479 480 ICE_DEFINE_HEALTH_REPORTER_OPS_1(mdd, dump); 481 ICE_DEFINE_HEALTH_REPORTER_OPS_1(tx_hang, dump); 482 ICE_DEFINE_HEALTH_REPORTER_OPS_2(fw, dump, diagnose); 483 ICE_DEFINE_HEALTH_REPORTER_OPS_2(port, dump, diagnose); 484 485 /** 486 * ice_health_init - allocate and init all ice devlink health reporters and 487 * accompanied data 488 * 489 * @pf: PF struct 490 */ 491 void ice_health_init(struct ice_pf *pf) 492 { 493 struct ice_health *reps = &pf->health_reporters; 494 495 reps->mdd = ice_init_devlink_rep(pf, &ice_mdd_reporter_ops); 496 reps->tx_hang = ice_init_devlink_rep(pf, &ice_tx_hang_reporter_ops); 497 498 if (ice_is_fw_health_report_supported(&pf->hw)) { 499 reps->fw = ice_init_devlink_rep(pf, &ice_fw_reporter_ops); 500 reps->port = ice_init_devlink_rep(pf, &ice_port_reporter_ops); 501 ice_config_health_events(pf, true); 502 } 503 } 504 505 /** 506 * ice_deinit_devl_reporter - destroy given devlink health reporter 507 * @reporter: reporter to destroy 508 */ 509 static void ice_deinit_devl_reporter(struct devlink_health_reporter *reporter) 510 { 511 if (reporter) 512 devl_health_reporter_destroy(reporter); 513 } 514 515 /** 516 * ice_health_deinit - deallocate all ice devlink health reporters and 517 * accompanied data 518 * 519 * @pf: PF struct 520 */ 521 void ice_health_deinit(struct ice_pf *pf) 522 { 523 ice_deinit_devl_reporter(pf->health_reporters.mdd); 524 ice_deinit_devl_reporter(pf->health_reporters.tx_hang); 525 if (ice_is_fw_health_report_supported(&pf->hw)) { 526 ice_deinit_devl_reporter(pf->health_reporters.fw); 527 ice_deinit_devl_reporter(pf->health_reporters.port); 528 ice_config_health_events(pf, false); 529 } 530 } 531 532 static 533 void ice_health_assign_healthy_state(struct devlink_health_reporter *reporter) 534 { 535 if (reporter) 536 devlink_health_reporter_state_update(reporter, 537 DEVLINK_HEALTH_REPORTER_STATE_HEALTHY); 538 } 539 540 /** 541 * ice_health_clear - clear devlink health issues after a reset 542 * @pf: the PF device structure 543 * 544 * Mark the PF in healthy state again after a reset has completed. 545 */ 546 void ice_health_clear(struct ice_pf *pf) 547 { 548 ice_health_assign_healthy_state(pf->health_reporters.mdd); 549 ice_health_assign_healthy_state(pf->health_reporters.tx_hang); 550 } 551