pd692x0.c (a6a6a98094116b60e5523a571d9443c53325f5b1) | pd692x0.c (ae37dc574259f2750e9e2666591b752678fcd7cc) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Driver for the Microchip PD692X0 PoE PSE Controller driver (I2C bus) 4 * 5 * Copyright (c) 2023 Bootlin, Kory Maincent <kory.maincent@bootlin.com> 6 */ 7 8#include <linux/delay.h> --- 59 unchanged lines hidden (view full) --- 68 PD692X0_MSG_RESET, 69 PD692X0_MSG_GET_SYS_STATUS, 70 PD692X0_MSG_GET_SW_VER, 71 PD692X0_MSG_SET_TMP_PORT_MATRIX, 72 PD692X0_MSG_PRG_PORT_MATRIX, 73 PD692X0_MSG_SET_PORT_PARAM, 74 PD692X0_MSG_GET_PORT_STATUS, 75 PD692X0_MSG_DOWNLOAD_CMD, | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Driver for the Microchip PD692X0 PoE PSE Controller driver (I2C bus) 4 * 5 * Copyright (c) 2023 Bootlin, Kory Maincent <kory.maincent@bootlin.com> 6 */ 7 8#include <linux/delay.h> --- 59 unchanged lines hidden (view full) --- 68 PD692X0_MSG_RESET, 69 PD692X0_MSG_GET_SYS_STATUS, 70 PD692X0_MSG_GET_SW_VER, 71 PD692X0_MSG_SET_TMP_PORT_MATRIX, 72 PD692X0_MSG_PRG_PORT_MATRIX, 73 PD692X0_MSG_SET_PORT_PARAM, 74 PD692X0_MSG_GET_PORT_STATUS, 75 PD692X0_MSG_DOWNLOAD_CMD, |
76 PD692X0_MSG_GET_PORT_CLASS, |
|
76 77 /* add new message above here */ 78 PD692X0_MSG_CNT 79}; 80 81struct pd692x0_priv { 82 struct i2c_client *client; 83 struct pse_controller_dev pcdev; --- 60 unchanged lines hidden (view full) --- 144 0x4e, 0x4e, 0x4e, 0x4e}, 145 }, 146 [PD692X0_MSG_DOWNLOAD_CMD] = { 147 .key = PD692X0_KEY_PRG, 148 .sub = {0xff, 0x99, 0x15}, 149 .data = {0x16, 0x16, 0x99, 0x4e, 150 0x4e, 0x4e, 0x4e, 0x4e}, 151 }, | 77 78 /* add new message above here */ 79 PD692X0_MSG_CNT 80}; 81 82struct pd692x0_priv { 83 struct i2c_client *client; 84 struct pse_controller_dev pcdev; --- 60 unchanged lines hidden (view full) --- 145 0x4e, 0x4e, 0x4e, 0x4e}, 146 }, 147 [PD692X0_MSG_DOWNLOAD_CMD] = { 148 .key = PD692X0_KEY_PRG, 149 .sub = {0xff, 0x99, 0x15}, 150 .data = {0x16, 0x16, 0x99, 0x4e, 151 0x4e, 0x4e, 0x4e, 0x4e}, 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}; 153 154static u8 pd692x0_build_msg(struct pd692x0_msg *msg, u8 echo) 155{ 156 u8 *data = (u8 *)msg; 157 u16 chksum = 0; 158 int i; 159 --- 270 unchanged lines hidden (view full) --- 430 priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED; 431 return 1; 432 } else { 433 priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED; 434 return 0; 435 } 436} 437 | 159}; 160 161static u8 pd692x0_build_msg(struct pd692x0_msg *msg, u8 echo) 162{ 163 u8 *data = (u8 *)msg; 164 u16 chksum = 0; 165 int i; 166 --- 270 unchanged lines hidden (view full) --- 437 priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED; 438 return 1; 439 } else { 440 priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED; 441 return 0; 442 } 443} 444 |
445struct 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 451static const struct pd692x0_pse_ext_state_mapping 452pd692x0_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 506static void 507pd692x0_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 |
|
438static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev, 439 unsigned long id, 440 struct netlink_ext_ack *extack, 441 struct pse_control_status *status) 442{ 443 struct pd692x0_priv *priv = to_pd692x0_priv(pcdev); 444 struct pd692x0_msg msg, buf = {0}; | 523static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev, 524 unsigned long id, 525 struct netlink_ext_ack *extack, 526 struct pse_control_status *status) 527{ 528 struct pd692x0_priv *priv = to_pd692x0_priv(pcdev); 529 struct pd692x0_msg msg, buf = {0}; |
530 u32 class; |
|
445 int ret; 446 447 ret = pd692x0_fw_unavailable(priv); 448 if (ret) 449 return ret; 450 451 msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_STATUS]; 452 msg.sub[2] = id; --- 13 unchanged lines hidden (view full) --- 466 467 if (buf.sub[1]) 468 status->c33_admin_state = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED; 469 else 470 status->c33_admin_state = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED; 471 472 priv->admin_state[id] = status->c33_admin_state; 473 | 531 int ret; 532 533 ret = pd692x0_fw_unavailable(priv); 534 if (ret) 535 return ret; 536 537 msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_STATUS]; 538 msg.sub[2] = id; --- 13 unchanged lines hidden (view full) --- 552 553 if (buf.sub[1]) 554 status->c33_admin_state = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED; 555 else 556 status->c33_admin_state = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED; 557 558 priv->admin_state[id] = status->c33_admin_state; 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 return 0; 475} 476 477static struct pd692x0_msg_ver pd692x0_get_sw_version(struct pd692x0_priv *priv) 478{ 479 struct device *dev = &priv->client->dev; 480 struct pd692x0_msg msg, buf = {0}; 481 struct pd692x0_msg_ver ver = {0}; --- 742 unchanged lines hidden --- | 575 return 0; 576} 577 578static struct pd692x0_msg_ver pd692x0_get_sw_version(struct pd692x0_priv *priv) 579{ 580 struct device *dev = &priv->client->dev; 581 struct pd692x0_msg msg, buf = {0}; 582 struct pd692x0_msg_ver ver = {0}; --- 742 unchanged lines hidden --- |