|
73 | 73 | PD692X0_MSG_SET_PORT_PARAM,
|
74 | 74 | PD692X0_MSG_GET_PORT_STATUS,
|
75 | 75 | PD692X0_MSG_DOWNLOAD_CMD,
|
| 76 | + PD692X0_MSG_GET_PORT_CLASS, |
76 | 77 |
|
77 | 78 | /* add new message above here */
|
78 | 79 | PD692X0_MSG_CNT
|
@@ -149,6 +150,12 @@ static const struct pd692x0_msg pd692x0_msg_template_list[PD692X0_MSG_CNT] = {
|
149 | 150 | .data = {0x16, 0x16, 0x99, 0x4e,
|
150 | 151 | 0x4e, 0x4e, 0x4e, 0x4e},
|
151 | 152 | },
|
| 153 | + [PD692X0_MSG_GET_PORT_CLASS] = { |
| 154 | + .key = PD692X0_KEY_REQ, |
| 155 | + .sub = {0x05, 0xc4}, |
| 156 | + .data = {0x4e, 0x4e, 0x4e, 0x4e, |
| 157 | + 0x4e, 0x4e, 0x4e, 0x4e}, |
| 158 | + }, |
152 | 159 | };
|
153 | 160 |
|
154 | 161 | static u8 pd692x0_build_msg(struct pd692x0_msg *msg, u8 echo)
|
@@ -435,13 +442,92 @@ static int pd692x0_pi_is_enabled(struct pse_controller_dev *pcdev, int id)
|
435 | 442 | }
|
436 | 443 | }
|
437 | 444 |
|
| 445 | +struct pd692x0_pse_ext_state_mapping { |
| 446 | + u32 status_code; |
| 447 | + enum ethtool_c33_pse_ext_state pse_ext_state; |
| 448 | + u32 pse_ext_substate; |
| 449 | +}; |
| 450 | + |
| 451 | +static const struct pd692x0_pse_ext_state_mapping |
| 452 | +pd692x0_pse_ext_state_map[] = { |
| 453 | + {0x06, ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM, |
| 454 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_HIGH_VOLTAGE}, |
| 455 | + {0x07, ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM, |
| 456 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_LOW_VOLTAGE}, |
| 457 | + {0x08, ETHTOOL_C33_PSE_EXT_STATE_MR_PSE_ENABLE, |
| 458 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_PSE_ENABLE_DISABLE_PIN_ACTIVE}, |
| 459 | + {0x0C, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION, |
| 460 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_NON_EXISTING_PORT}, |
| 461 | + {0x11, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION, |
| 462 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNDEFINED_PORT}, |
| 463 | + {0x12, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION, |
| 464 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT}, |
| 465 | + {0x1B, ETHTOOL_C33_PSE_EXT_STATE_OPTION_DETECT_TED, |
| 466 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_DET_IN_PROCESS}, |
| 467 | + {0x1C, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION, |
| 468 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS}, |
| 469 | + {0x1E, ETHTOOL_C33_PSE_EXT_STATE_MR_MPS_VALID, |
| 470 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_DETECTED_UNDERLOAD}, |
| 471 | + {0x1F, ETHTOOL_C33_PSE_EXT_STATE_OVLD_DETECTED, |
| 472 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_OVLD_DETECTED_OVERLOAD}, |
| 473 | + {0x20, ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE, |
| 474 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_BUDGET_EXCEEDED}, |
| 475 | + {0x21, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION, |
| 476 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT}, |
| 477 | + {0x22, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION, |
| 478 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_CONFIG_CHANGE}, |
| 479 | + {0x24, ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM, |
| 480 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_VOLTAGE_INJECTION}, |
| 481 | + {0x25, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION, |
| 482 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS}, |
| 483 | + {0x34, ETHTOOL_C33_PSE_EXT_STATE_SHORT_DETECTED, |
| 484 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_SHORT_DETECTED_SHORT_CONDITION}, |
| 485 | + {0x35, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION, |
| 486 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DETECTED_OVER_TEMP}, |
| 487 | + {0x36, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION, |
| 488 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DETECTED_OVER_TEMP}, |
| 489 | + {0x37, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION, |
| 490 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS}, |
| 491 | + {0x3C, ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE, |
| 492 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PORT_PW_LIMIT_EXCEEDS_CONTROLLER_BUDGET}, |
| 493 | + {0x3D, ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE, |
| 494 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PD_REQUEST_EXCEEDS_PORT_LIMIT}, |
| 495 | + {0x41, ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE, |
| 496 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_HW_PW_LIMIT}, |
| 497 | + {0x43, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION, |
| 498 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS}, |
| 499 | + {0xA7, ETHTOOL_C33_PSE_EXT_STATE_OPTION_DETECT_TED, |
| 500 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_CONNECTION_CHECK_ERROR}, |
| 501 | + {0xA8, ETHTOOL_C33_PSE_EXT_STATE_MR_MPS_VALID, |
| 502 | + ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_CONNECTION_OPEN}, |
| 503 | + { /* sentinel */ } |
| 504 | +}; |
| 505 | + |
| 506 | +static void |
| 507 | +pd692x0_get_ext_state(struct ethtool_c33_pse_ext_state_info *c33_ext_state_info, |
| 508 | + u32 status_code) |
| 509 | +{ |
| 510 | + const struct pd692x0_pse_ext_state_mapping *ext_state_map; |
| 511 | + |
| 512 | + ext_state_map = pd692x0_pse_ext_state_map; |
| 513 | + while (ext_state_map->status_code) { |
| 514 | + if (ext_state_map->status_code == status_code) { |
| 515 | + c33_ext_state_info->c33_pse_ext_state = ext_state_map->pse_ext_state; |
| 516 | + c33_ext_state_info->__c33_pse_ext_substate = ext_state_map->pse_ext_substate; |
| 517 | + return; |
| 518 | + } |
| 519 | + ext_state_map++; |
| 520 | + } |
| 521 | +} |
| 522 | + |
438 | 523 | static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev,
|
439 | 524 | unsigned long id,
|
440 | 525 | struct netlink_ext_ack *extack,
|
441 | 526 | struct pse_control_status *status)
|
442 | 527 | {
|
443 | 528 | struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
|
444 | 529 | struct pd692x0_msg msg, buf = {0};
|
| 530 | + u32 class; |
445 | 531 | int ret;
|
446 | 532 |
|
447 | 533 | ret = pd692x0_fw_unavailable(priv);
|
@@ -471,6 +557,21 @@ static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev,
|
471 | 557 |
|
472 | 558 | priv->admin_state[id] = status->c33_admin_state;
|
473 | 559 |
|
| 560 | + pd692x0_get_ext_state(&status->c33_ext_state_info, buf.sub[0]); |
| 561 | + |
| 562 | + status->c33_actual_pw = (buf.data[0] << 4 | buf.data[1]) * 100; |
| 563 | + |
| 564 | + memset(&buf, 0, sizeof(buf)); |
| 565 | + msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_CLASS]; |
| 566 | + msg.sub[2] = id; |
| 567 | + ret = pd692x0_sendrecv_msg(priv, &msg, &buf); |
| 568 | + if (ret < 0) |
| 569 | + return ret; |
| 570 | + |
| 571 | + class = buf.data[3] >> 4; |
| 572 | + if (class <= 8) |
| 573 | + status->c33_pw_class = class; |
| 574 | + |
474 | 575 | return 0;
|
475 | 576 | }
|
476 | 577 |
|
|
0 commit comments