18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 28c2ecf20Sopenharmony_ci/* Copyright (c) 2020 Mellanox Technologies. All rights reserved */ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include "reg.h" 58c2ecf20Sopenharmony_ci#include "core.h" 68c2ecf20Sopenharmony_ci#include "spectrum.h" 78c2ecf20Sopenharmony_ci#include "core_env.h" 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_cistatic const char mlxsw_sp_driver_version[] = "1.0"; 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_cistatic void mlxsw_sp_port_get_drvinfo(struct net_device *dev, 128c2ecf20Sopenharmony_ci struct ethtool_drvinfo *drvinfo) 138c2ecf20Sopenharmony_ci{ 148c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 158c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci strlcpy(drvinfo->driver, mlxsw_sp->bus_info->device_kind, 188c2ecf20Sopenharmony_ci sizeof(drvinfo->driver)); 198c2ecf20Sopenharmony_ci strlcpy(drvinfo->version, mlxsw_sp_driver_version, 208c2ecf20Sopenharmony_ci sizeof(drvinfo->version)); 218c2ecf20Sopenharmony_ci snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), 228c2ecf20Sopenharmony_ci "%d.%d.%d", 238c2ecf20Sopenharmony_ci mlxsw_sp->bus_info->fw_rev.major, 248c2ecf20Sopenharmony_ci mlxsw_sp->bus_info->fw_rev.minor, 258c2ecf20Sopenharmony_ci mlxsw_sp->bus_info->fw_rev.subminor); 268c2ecf20Sopenharmony_ci strlcpy(drvinfo->bus_info, mlxsw_sp->bus_info->device_name, 278c2ecf20Sopenharmony_ci sizeof(drvinfo->bus_info)); 288c2ecf20Sopenharmony_ci} 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cistruct mlxsw_sp_ethtool_link_ext_state_opcode_mapping { 318c2ecf20Sopenharmony_ci u32 status_opcode; 328c2ecf20Sopenharmony_ci enum ethtool_link_ext_state link_ext_state; 338c2ecf20Sopenharmony_ci u8 link_ext_substate; 348c2ecf20Sopenharmony_ci}; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistatic const struct mlxsw_sp_ethtool_link_ext_state_opcode_mapping 378c2ecf20Sopenharmony_cimlxsw_sp_link_ext_state_opcode_map[] = { 388c2ecf20Sopenharmony_ci {2, ETHTOOL_LINK_EXT_STATE_AUTONEG, 398c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED}, 408c2ecf20Sopenharmony_ci {3, ETHTOOL_LINK_EXT_STATE_AUTONEG, 418c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_AN_ACK_NOT_RECEIVED}, 428c2ecf20Sopenharmony_ci {4, ETHTOOL_LINK_EXT_STATE_AUTONEG, 438c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_AN_NEXT_PAGE_EXCHANGE_FAILED}, 448c2ecf20Sopenharmony_ci {36, ETHTOOL_LINK_EXT_STATE_AUTONEG, 458c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED_FORCE_MODE}, 468c2ecf20Sopenharmony_ci {38, ETHTOOL_LINK_EXT_STATE_AUTONEG, 478c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_AN_FEC_MISMATCH_DURING_OVERRIDE}, 488c2ecf20Sopenharmony_ci {39, ETHTOOL_LINK_EXT_STATE_AUTONEG, 498c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_HCD}, 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci {5, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE, 528c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_FRAME_LOCK_NOT_ACQUIRED}, 538c2ecf20Sopenharmony_ci {6, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE, 548c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_INHIBIT_TIMEOUT}, 558c2ecf20Sopenharmony_ci {7, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE, 568c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_PARTNER_DID_NOT_SET_RECEIVER_READY}, 578c2ecf20Sopenharmony_ci {8, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE, 0}, 588c2ecf20Sopenharmony_ci {14, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE, 598c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_LT_REMOTE_FAULT}, 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci {9, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH, 628c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_BLOCK_LOCK}, 638c2ecf20Sopenharmony_ci {10, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH, 648c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_AM_LOCK}, 658c2ecf20Sopenharmony_ci {11, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH, 668c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_GET_ALIGN_STATUS}, 678c2ecf20Sopenharmony_ci {12, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH, 688c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_LLM_FC_FEC_IS_NOT_LOCKED}, 698c2ecf20Sopenharmony_ci {13, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH, 708c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_LLM_RS_FEC_IS_NOT_LOCKED}, 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci {15, ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY, 0}, 738c2ecf20Sopenharmony_ci {17, ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY, 748c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_BSI_LARGE_NUMBER_OF_PHYSICAL_ERRORS}, 758c2ecf20Sopenharmony_ci {42, ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY, 768c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_BSI_UNSUPPORTED_RATE}, 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci {1024, ETHTOOL_LINK_EXT_STATE_NO_CABLE, 0}, 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci {16, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE, 818c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE}, 828c2ecf20Sopenharmony_ci {20, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE, 838c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE}, 848c2ecf20Sopenharmony_ci {29, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE, 858c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE}, 868c2ecf20Sopenharmony_ci {1025, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE, 878c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE}, 888c2ecf20Sopenharmony_ci {1029, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE, 898c2ecf20Sopenharmony_ci ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE}, 908c2ecf20Sopenharmony_ci {1031, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE, 0}, 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci {1027, ETHTOOL_LINK_EXT_STATE_EEPROM_ISSUE, 0}, 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci {23, ETHTOOL_LINK_EXT_STATE_CALIBRATION_FAILURE, 0}, 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci {1032, ETHTOOL_LINK_EXT_STATE_POWER_BUDGET_EXCEEDED, 0}, 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci {1030, ETHTOOL_LINK_EXT_STATE_OVERHEAT, 0}, 998c2ecf20Sopenharmony_ci}; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_cistatic void 1028c2ecf20Sopenharmony_cimlxsw_sp_port_set_link_ext_state(struct mlxsw_sp_ethtool_link_ext_state_opcode_mapping 1038c2ecf20Sopenharmony_ci link_ext_state_mapping, 1048c2ecf20Sopenharmony_ci struct ethtool_link_ext_state_info *link_ext_state_info) 1058c2ecf20Sopenharmony_ci{ 1068c2ecf20Sopenharmony_ci switch (link_ext_state_mapping.link_ext_state) { 1078c2ecf20Sopenharmony_ci case ETHTOOL_LINK_EXT_STATE_AUTONEG: 1088c2ecf20Sopenharmony_ci link_ext_state_info->autoneg = 1098c2ecf20Sopenharmony_ci link_ext_state_mapping.link_ext_substate; 1108c2ecf20Sopenharmony_ci break; 1118c2ecf20Sopenharmony_ci case ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE: 1128c2ecf20Sopenharmony_ci link_ext_state_info->link_training = 1138c2ecf20Sopenharmony_ci link_ext_state_mapping.link_ext_substate; 1148c2ecf20Sopenharmony_ci break; 1158c2ecf20Sopenharmony_ci case ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH: 1168c2ecf20Sopenharmony_ci link_ext_state_info->link_logical_mismatch = 1178c2ecf20Sopenharmony_ci link_ext_state_mapping.link_ext_substate; 1188c2ecf20Sopenharmony_ci break; 1198c2ecf20Sopenharmony_ci case ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY: 1208c2ecf20Sopenharmony_ci link_ext_state_info->bad_signal_integrity = 1218c2ecf20Sopenharmony_ci link_ext_state_mapping.link_ext_substate; 1228c2ecf20Sopenharmony_ci break; 1238c2ecf20Sopenharmony_ci case ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE: 1248c2ecf20Sopenharmony_ci link_ext_state_info->cable_issue = 1258c2ecf20Sopenharmony_ci link_ext_state_mapping.link_ext_substate; 1268c2ecf20Sopenharmony_ci break; 1278c2ecf20Sopenharmony_ci default: 1288c2ecf20Sopenharmony_ci break; 1298c2ecf20Sopenharmony_ci } 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci link_ext_state_info->link_ext_state = link_ext_state_mapping.link_ext_state; 1328c2ecf20Sopenharmony_ci} 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic int 1358c2ecf20Sopenharmony_cimlxsw_sp_port_get_link_ext_state(struct net_device *dev, 1368c2ecf20Sopenharmony_ci struct ethtool_link_ext_state_info *link_ext_state_info) 1378c2ecf20Sopenharmony_ci{ 1388c2ecf20Sopenharmony_ci struct mlxsw_sp_ethtool_link_ext_state_opcode_mapping link_ext_state_mapping; 1398c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 1408c2ecf20Sopenharmony_ci char pddr_pl[MLXSW_REG_PDDR_LEN]; 1418c2ecf20Sopenharmony_ci int opcode, err, i; 1428c2ecf20Sopenharmony_ci u32 status_opcode; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci if (netif_carrier_ok(dev)) 1458c2ecf20Sopenharmony_ci return -ENODATA; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci mlxsw_reg_pddr_pack(pddr_pl, mlxsw_sp_port->local_port, 1488c2ecf20Sopenharmony_ci MLXSW_REG_PDDR_PAGE_SELECT_TROUBLESHOOTING_INFO); 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci opcode = MLXSW_REG_PDDR_TRBLSH_GROUP_OPCODE_MONITOR; 1518c2ecf20Sopenharmony_ci mlxsw_reg_pddr_trblsh_group_opcode_set(pddr_pl, opcode); 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci err = mlxsw_reg_query(mlxsw_sp_port->mlxsw_sp->core, MLXSW_REG(pddr), 1548c2ecf20Sopenharmony_ci pddr_pl); 1558c2ecf20Sopenharmony_ci if (err) 1568c2ecf20Sopenharmony_ci return err; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci status_opcode = mlxsw_reg_pddr_trblsh_status_opcode_get(pddr_pl); 1598c2ecf20Sopenharmony_ci if (!status_opcode) 1608c2ecf20Sopenharmony_ci return -ENODATA; 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(mlxsw_sp_link_ext_state_opcode_map); i++) { 1638c2ecf20Sopenharmony_ci link_ext_state_mapping = mlxsw_sp_link_ext_state_opcode_map[i]; 1648c2ecf20Sopenharmony_ci if (link_ext_state_mapping.status_opcode == status_opcode) { 1658c2ecf20Sopenharmony_ci mlxsw_sp_port_set_link_ext_state(link_ext_state_mapping, 1668c2ecf20Sopenharmony_ci link_ext_state_info); 1678c2ecf20Sopenharmony_ci return 0; 1688c2ecf20Sopenharmony_ci } 1698c2ecf20Sopenharmony_ci } 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci return -ENODATA; 1728c2ecf20Sopenharmony_ci} 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_cistatic void mlxsw_sp_port_get_pauseparam(struct net_device *dev, 1758c2ecf20Sopenharmony_ci struct ethtool_pauseparam *pause) 1768c2ecf20Sopenharmony_ci{ 1778c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci pause->rx_pause = mlxsw_sp_port->link.rx_pause; 1808c2ecf20Sopenharmony_ci pause->tx_pause = mlxsw_sp_port->link.tx_pause; 1818c2ecf20Sopenharmony_ci} 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_cistatic int mlxsw_sp_port_pause_set(struct mlxsw_sp_port *mlxsw_sp_port, 1848c2ecf20Sopenharmony_ci struct ethtool_pauseparam *pause) 1858c2ecf20Sopenharmony_ci{ 1868c2ecf20Sopenharmony_ci char pfcc_pl[MLXSW_REG_PFCC_LEN]; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci mlxsw_reg_pfcc_pack(pfcc_pl, mlxsw_sp_port->local_port); 1898c2ecf20Sopenharmony_ci mlxsw_reg_pfcc_pprx_set(pfcc_pl, pause->rx_pause); 1908c2ecf20Sopenharmony_ci mlxsw_reg_pfcc_pptx_set(pfcc_pl, pause->tx_pause); 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci return mlxsw_reg_write(mlxsw_sp_port->mlxsw_sp->core, MLXSW_REG(pfcc), 1938c2ecf20Sopenharmony_ci pfcc_pl); 1948c2ecf20Sopenharmony_ci} 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci/* Maximum delay buffer needed in case of PAUSE frames. Similar to PFC delay, but is 1978c2ecf20Sopenharmony_ci * measured in bytes. Assumes 100m cable and does not take into account MTU. 1988c2ecf20Sopenharmony_ci */ 1998c2ecf20Sopenharmony_ci#define MLXSW_SP_PAUSE_DELAY_BYTES 19476 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_cistatic int mlxsw_sp_port_set_pauseparam(struct net_device *dev, 2028c2ecf20Sopenharmony_ci struct ethtool_pauseparam *pause) 2038c2ecf20Sopenharmony_ci{ 2048c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 2058c2ecf20Sopenharmony_ci bool pause_en = pause->tx_pause || pause->rx_pause; 2068c2ecf20Sopenharmony_ci struct mlxsw_sp_hdroom orig_hdroom; 2078c2ecf20Sopenharmony_ci struct mlxsw_sp_hdroom hdroom; 2088c2ecf20Sopenharmony_ci int prio; 2098c2ecf20Sopenharmony_ci int err; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci if (mlxsw_sp_port->dcb.pfc && mlxsw_sp_port->dcb.pfc->pfc_en) { 2128c2ecf20Sopenharmony_ci netdev_err(dev, "PFC already enabled on port\n"); 2138c2ecf20Sopenharmony_ci return -EINVAL; 2148c2ecf20Sopenharmony_ci } 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci if (pause->autoneg) { 2178c2ecf20Sopenharmony_ci netdev_err(dev, "PAUSE frames autonegotiation isn't supported\n"); 2188c2ecf20Sopenharmony_ci return -EINVAL; 2198c2ecf20Sopenharmony_ci } 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci orig_hdroom = *mlxsw_sp_port->hdroom; 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci hdroom = orig_hdroom; 2248c2ecf20Sopenharmony_ci if (pause_en) 2258c2ecf20Sopenharmony_ci hdroom.delay_bytes = MLXSW_SP_PAUSE_DELAY_BYTES; 2268c2ecf20Sopenharmony_ci else 2278c2ecf20Sopenharmony_ci hdroom.delay_bytes = 0; 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci for (prio = 0; prio < IEEE_8021QAZ_MAX_TCS; prio++) 2308c2ecf20Sopenharmony_ci hdroom.prios.prio[prio].lossy = !pause_en; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci mlxsw_sp_hdroom_bufs_reset_lossiness(&hdroom); 2338c2ecf20Sopenharmony_ci mlxsw_sp_hdroom_bufs_reset_sizes(mlxsw_sp_port, &hdroom); 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci err = mlxsw_sp_hdroom_configure(mlxsw_sp_port, &hdroom); 2368c2ecf20Sopenharmony_ci if (err) { 2378c2ecf20Sopenharmony_ci netdev_err(dev, "Failed to configure port's headroom\n"); 2388c2ecf20Sopenharmony_ci return err; 2398c2ecf20Sopenharmony_ci } 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci err = mlxsw_sp_port_pause_set(mlxsw_sp_port, pause); 2428c2ecf20Sopenharmony_ci if (err) { 2438c2ecf20Sopenharmony_ci netdev_err(dev, "Failed to set PAUSE parameters\n"); 2448c2ecf20Sopenharmony_ci goto err_port_pause_configure; 2458c2ecf20Sopenharmony_ci } 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci mlxsw_sp_port->link.rx_pause = pause->rx_pause; 2488c2ecf20Sopenharmony_ci mlxsw_sp_port->link.tx_pause = pause->tx_pause; 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci return 0; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_cierr_port_pause_configure: 2538c2ecf20Sopenharmony_ci mlxsw_sp_hdroom_configure(mlxsw_sp_port, &orig_hdroom); 2548c2ecf20Sopenharmony_ci return err; 2558c2ecf20Sopenharmony_ci} 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_cistruct mlxsw_sp_port_hw_stats { 2588c2ecf20Sopenharmony_ci char str[ETH_GSTRING_LEN]; 2598c2ecf20Sopenharmony_ci u64 (*getter)(const char *payload); 2608c2ecf20Sopenharmony_ci bool cells_bytes; 2618c2ecf20Sopenharmony_ci}; 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_cistatic struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_stats[] = { 2648c2ecf20Sopenharmony_ci { 2658c2ecf20Sopenharmony_ci .str = "a_frames_transmitted_ok", 2668c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_frames_transmitted_ok_get, 2678c2ecf20Sopenharmony_ci }, 2688c2ecf20Sopenharmony_ci { 2698c2ecf20Sopenharmony_ci .str = "a_frames_received_ok", 2708c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_frames_received_ok_get, 2718c2ecf20Sopenharmony_ci }, 2728c2ecf20Sopenharmony_ci { 2738c2ecf20Sopenharmony_ci .str = "a_frame_check_sequence_errors", 2748c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_frame_check_sequence_errors_get, 2758c2ecf20Sopenharmony_ci }, 2768c2ecf20Sopenharmony_ci { 2778c2ecf20Sopenharmony_ci .str = "a_alignment_errors", 2788c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_alignment_errors_get, 2798c2ecf20Sopenharmony_ci }, 2808c2ecf20Sopenharmony_ci { 2818c2ecf20Sopenharmony_ci .str = "a_octets_transmitted_ok", 2828c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_octets_transmitted_ok_get, 2838c2ecf20Sopenharmony_ci }, 2848c2ecf20Sopenharmony_ci { 2858c2ecf20Sopenharmony_ci .str = "a_octets_received_ok", 2868c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_octets_received_ok_get, 2878c2ecf20Sopenharmony_ci }, 2888c2ecf20Sopenharmony_ci { 2898c2ecf20Sopenharmony_ci .str = "a_multicast_frames_xmitted_ok", 2908c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_multicast_frames_xmitted_ok_get, 2918c2ecf20Sopenharmony_ci }, 2928c2ecf20Sopenharmony_ci { 2938c2ecf20Sopenharmony_ci .str = "a_broadcast_frames_xmitted_ok", 2948c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_broadcast_frames_xmitted_ok_get, 2958c2ecf20Sopenharmony_ci }, 2968c2ecf20Sopenharmony_ci { 2978c2ecf20Sopenharmony_ci .str = "a_multicast_frames_received_ok", 2988c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_multicast_frames_received_ok_get, 2998c2ecf20Sopenharmony_ci }, 3008c2ecf20Sopenharmony_ci { 3018c2ecf20Sopenharmony_ci .str = "a_broadcast_frames_received_ok", 3028c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_broadcast_frames_received_ok_get, 3038c2ecf20Sopenharmony_ci }, 3048c2ecf20Sopenharmony_ci { 3058c2ecf20Sopenharmony_ci .str = "a_in_range_length_errors", 3068c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_in_range_length_errors_get, 3078c2ecf20Sopenharmony_ci }, 3088c2ecf20Sopenharmony_ci { 3098c2ecf20Sopenharmony_ci .str = "a_out_of_range_length_field", 3108c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_out_of_range_length_field_get, 3118c2ecf20Sopenharmony_ci }, 3128c2ecf20Sopenharmony_ci { 3138c2ecf20Sopenharmony_ci .str = "a_frame_too_long_errors", 3148c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_frame_too_long_errors_get, 3158c2ecf20Sopenharmony_ci }, 3168c2ecf20Sopenharmony_ci { 3178c2ecf20Sopenharmony_ci .str = "a_symbol_error_during_carrier", 3188c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_symbol_error_during_carrier_get, 3198c2ecf20Sopenharmony_ci }, 3208c2ecf20Sopenharmony_ci { 3218c2ecf20Sopenharmony_ci .str = "a_mac_control_frames_transmitted", 3228c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_mac_control_frames_transmitted_get, 3238c2ecf20Sopenharmony_ci }, 3248c2ecf20Sopenharmony_ci { 3258c2ecf20Sopenharmony_ci .str = "a_mac_control_frames_received", 3268c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_mac_control_frames_received_get, 3278c2ecf20Sopenharmony_ci }, 3288c2ecf20Sopenharmony_ci { 3298c2ecf20Sopenharmony_ci .str = "a_unsupported_opcodes_received", 3308c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_unsupported_opcodes_received_get, 3318c2ecf20Sopenharmony_ci }, 3328c2ecf20Sopenharmony_ci { 3338c2ecf20Sopenharmony_ci .str = "a_pause_mac_ctrl_frames_received", 3348c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_pause_mac_ctrl_frames_received_get, 3358c2ecf20Sopenharmony_ci }, 3368c2ecf20Sopenharmony_ci { 3378c2ecf20Sopenharmony_ci .str = "a_pause_mac_ctrl_frames_xmitted", 3388c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_a_pause_mac_ctrl_frames_transmitted_get, 3398c2ecf20Sopenharmony_ci }, 3408c2ecf20Sopenharmony_ci}; 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci#define MLXSW_SP_PORT_HW_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_stats) 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_cistatic struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_rfc_2863_stats[] = { 3458c2ecf20Sopenharmony_ci { 3468c2ecf20Sopenharmony_ci .str = "if_in_discards", 3478c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_if_in_discards_get, 3488c2ecf20Sopenharmony_ci }, 3498c2ecf20Sopenharmony_ci { 3508c2ecf20Sopenharmony_ci .str = "if_out_discards", 3518c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_if_out_discards_get, 3528c2ecf20Sopenharmony_ci }, 3538c2ecf20Sopenharmony_ci { 3548c2ecf20Sopenharmony_ci .str = "if_out_errors", 3558c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_if_out_errors_get, 3568c2ecf20Sopenharmony_ci }, 3578c2ecf20Sopenharmony_ci}; 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_ci#define MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN \ 3608c2ecf20Sopenharmony_ci ARRAY_SIZE(mlxsw_sp_port_hw_rfc_2863_stats) 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_cistatic struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_rfc_2819_stats[] = { 3638c2ecf20Sopenharmony_ci { 3648c2ecf20Sopenharmony_ci .str = "ether_stats_undersize_pkts", 3658c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ether_stats_undersize_pkts_get, 3668c2ecf20Sopenharmony_ci }, 3678c2ecf20Sopenharmony_ci { 3688c2ecf20Sopenharmony_ci .str = "ether_stats_oversize_pkts", 3698c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ether_stats_oversize_pkts_get, 3708c2ecf20Sopenharmony_ci }, 3718c2ecf20Sopenharmony_ci { 3728c2ecf20Sopenharmony_ci .str = "ether_stats_fragments", 3738c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ether_stats_fragments_get, 3748c2ecf20Sopenharmony_ci }, 3758c2ecf20Sopenharmony_ci { 3768c2ecf20Sopenharmony_ci .str = "ether_pkts64octets", 3778c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ether_stats_pkts64octets_get, 3788c2ecf20Sopenharmony_ci }, 3798c2ecf20Sopenharmony_ci { 3808c2ecf20Sopenharmony_ci .str = "ether_pkts65to127octets", 3818c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ether_stats_pkts65to127octets_get, 3828c2ecf20Sopenharmony_ci }, 3838c2ecf20Sopenharmony_ci { 3848c2ecf20Sopenharmony_ci .str = "ether_pkts128to255octets", 3858c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ether_stats_pkts128to255octets_get, 3868c2ecf20Sopenharmony_ci }, 3878c2ecf20Sopenharmony_ci { 3888c2ecf20Sopenharmony_ci .str = "ether_pkts256to511octets", 3898c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ether_stats_pkts256to511octets_get, 3908c2ecf20Sopenharmony_ci }, 3918c2ecf20Sopenharmony_ci { 3928c2ecf20Sopenharmony_ci .str = "ether_pkts512to1023octets", 3938c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ether_stats_pkts512to1023octets_get, 3948c2ecf20Sopenharmony_ci }, 3958c2ecf20Sopenharmony_ci { 3968c2ecf20Sopenharmony_ci .str = "ether_pkts1024to1518octets", 3978c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ether_stats_pkts1024to1518octets_get, 3988c2ecf20Sopenharmony_ci }, 3998c2ecf20Sopenharmony_ci { 4008c2ecf20Sopenharmony_ci .str = "ether_pkts1519to2047octets", 4018c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ether_stats_pkts1519to2047octets_get, 4028c2ecf20Sopenharmony_ci }, 4038c2ecf20Sopenharmony_ci { 4048c2ecf20Sopenharmony_ci .str = "ether_pkts2048to4095octets", 4058c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ether_stats_pkts2048to4095octets_get, 4068c2ecf20Sopenharmony_ci }, 4078c2ecf20Sopenharmony_ci { 4088c2ecf20Sopenharmony_ci .str = "ether_pkts4096to8191octets", 4098c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ether_stats_pkts4096to8191octets_get, 4108c2ecf20Sopenharmony_ci }, 4118c2ecf20Sopenharmony_ci { 4128c2ecf20Sopenharmony_ci .str = "ether_pkts8192to10239octets", 4138c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ether_stats_pkts8192to10239octets_get, 4148c2ecf20Sopenharmony_ci }, 4158c2ecf20Sopenharmony_ci}; 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ci#define MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN \ 4188c2ecf20Sopenharmony_ci ARRAY_SIZE(mlxsw_sp_port_hw_rfc_2819_stats) 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_cistatic struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_rfc_3635_stats[] = { 4218c2ecf20Sopenharmony_ci { 4228c2ecf20Sopenharmony_ci .str = "dot3stats_fcs_errors", 4238c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_dot3stats_fcs_errors_get, 4248c2ecf20Sopenharmony_ci }, 4258c2ecf20Sopenharmony_ci { 4268c2ecf20Sopenharmony_ci .str = "dot3stats_symbol_errors", 4278c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_dot3stats_symbol_errors_get, 4288c2ecf20Sopenharmony_ci }, 4298c2ecf20Sopenharmony_ci { 4308c2ecf20Sopenharmony_ci .str = "dot3control_in_unknown_opcodes", 4318c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_dot3control_in_unknown_opcodes_get, 4328c2ecf20Sopenharmony_ci }, 4338c2ecf20Sopenharmony_ci { 4348c2ecf20Sopenharmony_ci .str = "dot3in_pause_frames", 4358c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_dot3in_pause_frames_get, 4368c2ecf20Sopenharmony_ci }, 4378c2ecf20Sopenharmony_ci}; 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_ci#define MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN \ 4408c2ecf20Sopenharmony_ci ARRAY_SIZE(mlxsw_sp_port_hw_rfc_3635_stats) 4418c2ecf20Sopenharmony_ci 4428c2ecf20Sopenharmony_cistatic struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_ext_stats[] = { 4438c2ecf20Sopenharmony_ci { 4448c2ecf20Sopenharmony_ci .str = "ecn_marked", 4458c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ecn_marked_get, 4468c2ecf20Sopenharmony_ci }, 4478c2ecf20Sopenharmony_ci}; 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_ci#define MLXSW_SP_PORT_HW_EXT_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_ext_stats) 4508c2ecf20Sopenharmony_ci 4518c2ecf20Sopenharmony_cistatic struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_discard_stats[] = { 4528c2ecf20Sopenharmony_ci { 4538c2ecf20Sopenharmony_ci .str = "discard_ingress_general", 4548c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ingress_general_get, 4558c2ecf20Sopenharmony_ci }, 4568c2ecf20Sopenharmony_ci { 4578c2ecf20Sopenharmony_ci .str = "discard_ingress_policy_engine", 4588c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ingress_policy_engine_get, 4598c2ecf20Sopenharmony_ci }, 4608c2ecf20Sopenharmony_ci { 4618c2ecf20Sopenharmony_ci .str = "discard_ingress_vlan_membership", 4628c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ingress_vlan_membership_get, 4638c2ecf20Sopenharmony_ci }, 4648c2ecf20Sopenharmony_ci { 4658c2ecf20Sopenharmony_ci .str = "discard_ingress_tag_frame_type", 4668c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ingress_tag_frame_type_get, 4678c2ecf20Sopenharmony_ci }, 4688c2ecf20Sopenharmony_ci { 4698c2ecf20Sopenharmony_ci .str = "discard_egress_vlan_membership", 4708c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_egress_vlan_membership_get, 4718c2ecf20Sopenharmony_ci }, 4728c2ecf20Sopenharmony_ci { 4738c2ecf20Sopenharmony_ci .str = "discard_loopback_filter", 4748c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_loopback_filter_get, 4758c2ecf20Sopenharmony_ci }, 4768c2ecf20Sopenharmony_ci { 4778c2ecf20Sopenharmony_ci .str = "discard_egress_general", 4788c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_egress_general_get, 4798c2ecf20Sopenharmony_ci }, 4808c2ecf20Sopenharmony_ci { 4818c2ecf20Sopenharmony_ci .str = "discard_egress_hoq", 4828c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_egress_hoq_get, 4838c2ecf20Sopenharmony_ci }, 4848c2ecf20Sopenharmony_ci { 4858c2ecf20Sopenharmony_ci .str = "discard_egress_policy_engine", 4868c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_egress_policy_engine_get, 4878c2ecf20Sopenharmony_ci }, 4888c2ecf20Sopenharmony_ci { 4898c2ecf20Sopenharmony_ci .str = "discard_ingress_tx_link_down", 4908c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_ingress_tx_link_down_get, 4918c2ecf20Sopenharmony_ci }, 4928c2ecf20Sopenharmony_ci { 4938c2ecf20Sopenharmony_ci .str = "discard_egress_stp_filter", 4948c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_egress_stp_filter_get, 4958c2ecf20Sopenharmony_ci }, 4968c2ecf20Sopenharmony_ci { 4978c2ecf20Sopenharmony_ci .str = "discard_egress_sll", 4988c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_egress_sll_get, 4998c2ecf20Sopenharmony_ci }, 5008c2ecf20Sopenharmony_ci}; 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_ci#define MLXSW_SP_PORT_HW_DISCARD_STATS_LEN \ 5038c2ecf20Sopenharmony_ci ARRAY_SIZE(mlxsw_sp_port_hw_discard_stats) 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_cistatic struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_prio_stats[] = { 5068c2ecf20Sopenharmony_ci { 5078c2ecf20Sopenharmony_ci .str = "rx_octets_prio", 5088c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_rx_octets_get, 5098c2ecf20Sopenharmony_ci }, 5108c2ecf20Sopenharmony_ci { 5118c2ecf20Sopenharmony_ci .str = "rx_frames_prio", 5128c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_rx_frames_get, 5138c2ecf20Sopenharmony_ci }, 5148c2ecf20Sopenharmony_ci { 5158c2ecf20Sopenharmony_ci .str = "tx_octets_prio", 5168c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_tx_octets_get, 5178c2ecf20Sopenharmony_ci }, 5188c2ecf20Sopenharmony_ci { 5198c2ecf20Sopenharmony_ci .str = "tx_frames_prio", 5208c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_tx_frames_get, 5218c2ecf20Sopenharmony_ci }, 5228c2ecf20Sopenharmony_ci { 5238c2ecf20Sopenharmony_ci .str = "rx_pause_prio", 5248c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_rx_pause_get, 5258c2ecf20Sopenharmony_ci }, 5268c2ecf20Sopenharmony_ci { 5278c2ecf20Sopenharmony_ci .str = "rx_pause_duration_prio", 5288c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_rx_pause_duration_get, 5298c2ecf20Sopenharmony_ci }, 5308c2ecf20Sopenharmony_ci { 5318c2ecf20Sopenharmony_ci .str = "tx_pause_prio", 5328c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_tx_pause_get, 5338c2ecf20Sopenharmony_ci }, 5348c2ecf20Sopenharmony_ci { 5358c2ecf20Sopenharmony_ci .str = "tx_pause_duration_prio", 5368c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_tx_pause_duration_get, 5378c2ecf20Sopenharmony_ci }, 5388c2ecf20Sopenharmony_ci}; 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci#define MLXSW_SP_PORT_HW_PRIO_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_prio_stats) 5418c2ecf20Sopenharmony_ci 5428c2ecf20Sopenharmony_cistatic struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_tc_stats[] = { 5438c2ecf20Sopenharmony_ci { 5448c2ecf20Sopenharmony_ci .str = "tc_transmit_queue_tc", 5458c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_tc_transmit_queue_get, 5468c2ecf20Sopenharmony_ci .cells_bytes = true, 5478c2ecf20Sopenharmony_ci }, 5488c2ecf20Sopenharmony_ci { 5498c2ecf20Sopenharmony_ci .str = "tc_no_buffer_discard_uc_tc", 5508c2ecf20Sopenharmony_ci .getter = mlxsw_reg_ppcnt_tc_no_buffer_discard_uc_get, 5518c2ecf20Sopenharmony_ci }, 5528c2ecf20Sopenharmony_ci}; 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_ci#define MLXSW_SP_PORT_HW_TC_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_tc_stats) 5558c2ecf20Sopenharmony_ci 5568c2ecf20Sopenharmony_cistruct mlxsw_sp_port_stats { 5578c2ecf20Sopenharmony_ci char str[ETH_GSTRING_LEN]; 5588c2ecf20Sopenharmony_ci u64 (*getter)(struct mlxsw_sp_port *mlxsw_sp_port); 5598c2ecf20Sopenharmony_ci}; 5608c2ecf20Sopenharmony_ci 5618c2ecf20Sopenharmony_cistatic u64 5628c2ecf20Sopenharmony_cimlxsw_sp_port_get_transceiver_overheat_stats(struct mlxsw_sp_port *mlxsw_sp_port) 5638c2ecf20Sopenharmony_ci{ 5648c2ecf20Sopenharmony_ci struct mlxsw_sp_port_mapping port_mapping = mlxsw_sp_port->mapping; 5658c2ecf20Sopenharmony_ci struct mlxsw_core *mlxsw_core = mlxsw_sp_port->mlxsw_sp->core; 5668c2ecf20Sopenharmony_ci u64 stats; 5678c2ecf20Sopenharmony_ci int err; 5688c2ecf20Sopenharmony_ci 5698c2ecf20Sopenharmony_ci err = mlxsw_env_module_overheat_counter_get(mlxsw_core, 5708c2ecf20Sopenharmony_ci port_mapping.module, 5718c2ecf20Sopenharmony_ci &stats); 5728c2ecf20Sopenharmony_ci if (err) 5738c2ecf20Sopenharmony_ci return mlxsw_sp_port->module_overheat_initial_val; 5748c2ecf20Sopenharmony_ci 5758c2ecf20Sopenharmony_ci return stats - mlxsw_sp_port->module_overheat_initial_val; 5768c2ecf20Sopenharmony_ci} 5778c2ecf20Sopenharmony_ci 5788c2ecf20Sopenharmony_cistatic struct mlxsw_sp_port_stats mlxsw_sp_port_transceiver_stats[] = { 5798c2ecf20Sopenharmony_ci { 5808c2ecf20Sopenharmony_ci .str = "transceiver_overheat", 5818c2ecf20Sopenharmony_ci .getter = mlxsw_sp_port_get_transceiver_overheat_stats, 5828c2ecf20Sopenharmony_ci }, 5838c2ecf20Sopenharmony_ci}; 5848c2ecf20Sopenharmony_ci 5858c2ecf20Sopenharmony_ci#define MLXSW_SP_PORT_HW_TRANSCEIVER_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_transceiver_stats) 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_ci#define MLXSW_SP_PORT_ETHTOOL_STATS_LEN (MLXSW_SP_PORT_HW_STATS_LEN + \ 5888c2ecf20Sopenharmony_ci MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN + \ 5898c2ecf20Sopenharmony_ci MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN + \ 5908c2ecf20Sopenharmony_ci MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN + \ 5918c2ecf20Sopenharmony_ci MLXSW_SP_PORT_HW_EXT_STATS_LEN + \ 5928c2ecf20Sopenharmony_ci MLXSW_SP_PORT_HW_DISCARD_STATS_LEN + \ 5938c2ecf20Sopenharmony_ci (MLXSW_SP_PORT_HW_PRIO_STATS_LEN * \ 5948c2ecf20Sopenharmony_ci IEEE_8021QAZ_MAX_TCS) + \ 5958c2ecf20Sopenharmony_ci (MLXSW_SP_PORT_HW_TC_STATS_LEN * \ 5968c2ecf20Sopenharmony_ci TC_MAX_QUEUE) + \ 5978c2ecf20Sopenharmony_ci MLXSW_SP_PORT_HW_TRANSCEIVER_STATS_LEN) 5988c2ecf20Sopenharmony_ci 5998c2ecf20Sopenharmony_cistatic void mlxsw_sp_port_get_prio_strings(u8 **p, int prio) 6008c2ecf20Sopenharmony_ci{ 6018c2ecf20Sopenharmony_ci int i; 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP_PORT_HW_PRIO_STATS_LEN; i++) { 6048c2ecf20Sopenharmony_ci snprintf(*p, ETH_GSTRING_LEN, "%.29s_%.1d", 6058c2ecf20Sopenharmony_ci mlxsw_sp_port_hw_prio_stats[i].str, prio); 6068c2ecf20Sopenharmony_ci *p += ETH_GSTRING_LEN; 6078c2ecf20Sopenharmony_ci } 6088c2ecf20Sopenharmony_ci} 6098c2ecf20Sopenharmony_ci 6108c2ecf20Sopenharmony_cistatic void mlxsw_sp_port_get_tc_strings(u8 **p, int tc) 6118c2ecf20Sopenharmony_ci{ 6128c2ecf20Sopenharmony_ci int i; 6138c2ecf20Sopenharmony_ci 6148c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP_PORT_HW_TC_STATS_LEN; i++) { 6158c2ecf20Sopenharmony_ci snprintf(*p, ETH_GSTRING_LEN, "%.29s_%.1d", 6168c2ecf20Sopenharmony_ci mlxsw_sp_port_hw_tc_stats[i].str, tc); 6178c2ecf20Sopenharmony_ci *p += ETH_GSTRING_LEN; 6188c2ecf20Sopenharmony_ci } 6198c2ecf20Sopenharmony_ci} 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_cistatic void mlxsw_sp_port_get_strings(struct net_device *dev, 6228c2ecf20Sopenharmony_ci u32 stringset, u8 *data) 6238c2ecf20Sopenharmony_ci{ 6248c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 6258c2ecf20Sopenharmony_ci u8 *p = data; 6268c2ecf20Sopenharmony_ci int i; 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_ci switch (stringset) { 6298c2ecf20Sopenharmony_ci case ETH_SS_STATS: 6308c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP_PORT_HW_STATS_LEN; i++) { 6318c2ecf20Sopenharmony_ci memcpy(p, mlxsw_sp_port_hw_stats[i].str, 6328c2ecf20Sopenharmony_ci ETH_GSTRING_LEN); 6338c2ecf20Sopenharmony_ci p += ETH_GSTRING_LEN; 6348c2ecf20Sopenharmony_ci } 6358c2ecf20Sopenharmony_ci 6368c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN; i++) { 6378c2ecf20Sopenharmony_ci memcpy(p, mlxsw_sp_port_hw_rfc_2863_stats[i].str, 6388c2ecf20Sopenharmony_ci ETH_GSTRING_LEN); 6398c2ecf20Sopenharmony_ci p += ETH_GSTRING_LEN; 6408c2ecf20Sopenharmony_ci } 6418c2ecf20Sopenharmony_ci 6428c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN; i++) { 6438c2ecf20Sopenharmony_ci memcpy(p, mlxsw_sp_port_hw_rfc_2819_stats[i].str, 6448c2ecf20Sopenharmony_ci ETH_GSTRING_LEN); 6458c2ecf20Sopenharmony_ci p += ETH_GSTRING_LEN; 6468c2ecf20Sopenharmony_ci } 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN; i++) { 6498c2ecf20Sopenharmony_ci memcpy(p, mlxsw_sp_port_hw_rfc_3635_stats[i].str, 6508c2ecf20Sopenharmony_ci ETH_GSTRING_LEN); 6518c2ecf20Sopenharmony_ci p += ETH_GSTRING_LEN; 6528c2ecf20Sopenharmony_ci } 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP_PORT_HW_EXT_STATS_LEN; i++) { 6558c2ecf20Sopenharmony_ci memcpy(p, mlxsw_sp_port_hw_ext_stats[i].str, 6568c2ecf20Sopenharmony_ci ETH_GSTRING_LEN); 6578c2ecf20Sopenharmony_ci p += ETH_GSTRING_LEN; 6588c2ecf20Sopenharmony_ci } 6598c2ecf20Sopenharmony_ci 6608c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP_PORT_HW_DISCARD_STATS_LEN; i++) { 6618c2ecf20Sopenharmony_ci memcpy(p, mlxsw_sp_port_hw_discard_stats[i].str, 6628c2ecf20Sopenharmony_ci ETH_GSTRING_LEN); 6638c2ecf20Sopenharmony_ci p += ETH_GSTRING_LEN; 6648c2ecf20Sopenharmony_ci } 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_ci for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) 6678c2ecf20Sopenharmony_ci mlxsw_sp_port_get_prio_strings(&p, i); 6688c2ecf20Sopenharmony_ci 6698c2ecf20Sopenharmony_ci for (i = 0; i < TC_MAX_QUEUE; i++) 6708c2ecf20Sopenharmony_ci mlxsw_sp_port_get_tc_strings(&p, i); 6718c2ecf20Sopenharmony_ci 6728c2ecf20Sopenharmony_ci mlxsw_sp_port->mlxsw_sp->ptp_ops->get_stats_strings(&p); 6738c2ecf20Sopenharmony_ci 6748c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP_PORT_HW_TRANSCEIVER_STATS_LEN; i++) { 6758c2ecf20Sopenharmony_ci memcpy(p, mlxsw_sp_port_transceiver_stats[i].str, 6768c2ecf20Sopenharmony_ci ETH_GSTRING_LEN); 6778c2ecf20Sopenharmony_ci p += ETH_GSTRING_LEN; 6788c2ecf20Sopenharmony_ci } 6798c2ecf20Sopenharmony_ci break; 6808c2ecf20Sopenharmony_ci } 6818c2ecf20Sopenharmony_ci} 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_cistatic int mlxsw_sp_port_set_phys_id(struct net_device *dev, 6848c2ecf20Sopenharmony_ci enum ethtool_phys_id_state state) 6858c2ecf20Sopenharmony_ci{ 6868c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 6878c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 6888c2ecf20Sopenharmony_ci char mlcr_pl[MLXSW_REG_MLCR_LEN]; 6898c2ecf20Sopenharmony_ci bool active; 6908c2ecf20Sopenharmony_ci 6918c2ecf20Sopenharmony_ci switch (state) { 6928c2ecf20Sopenharmony_ci case ETHTOOL_ID_ACTIVE: 6938c2ecf20Sopenharmony_ci active = true; 6948c2ecf20Sopenharmony_ci break; 6958c2ecf20Sopenharmony_ci case ETHTOOL_ID_INACTIVE: 6968c2ecf20Sopenharmony_ci active = false; 6978c2ecf20Sopenharmony_ci break; 6988c2ecf20Sopenharmony_ci default: 6998c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 7008c2ecf20Sopenharmony_ci } 7018c2ecf20Sopenharmony_ci 7028c2ecf20Sopenharmony_ci mlxsw_reg_mlcr_pack(mlcr_pl, mlxsw_sp_port->local_port, active); 7038c2ecf20Sopenharmony_ci return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mlcr), mlcr_pl); 7048c2ecf20Sopenharmony_ci} 7058c2ecf20Sopenharmony_ci 7068c2ecf20Sopenharmony_cistatic int 7078c2ecf20Sopenharmony_cimlxsw_sp_get_hw_stats_by_group(struct mlxsw_sp_port_hw_stats **p_hw_stats, 7088c2ecf20Sopenharmony_ci int *p_len, enum mlxsw_reg_ppcnt_grp grp) 7098c2ecf20Sopenharmony_ci{ 7108c2ecf20Sopenharmony_ci switch (grp) { 7118c2ecf20Sopenharmony_ci case MLXSW_REG_PPCNT_IEEE_8023_CNT: 7128c2ecf20Sopenharmony_ci *p_hw_stats = mlxsw_sp_port_hw_stats; 7138c2ecf20Sopenharmony_ci *p_len = MLXSW_SP_PORT_HW_STATS_LEN; 7148c2ecf20Sopenharmony_ci break; 7158c2ecf20Sopenharmony_ci case MLXSW_REG_PPCNT_RFC_2863_CNT: 7168c2ecf20Sopenharmony_ci *p_hw_stats = mlxsw_sp_port_hw_rfc_2863_stats; 7178c2ecf20Sopenharmony_ci *p_len = MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN; 7188c2ecf20Sopenharmony_ci break; 7198c2ecf20Sopenharmony_ci case MLXSW_REG_PPCNT_RFC_2819_CNT: 7208c2ecf20Sopenharmony_ci *p_hw_stats = mlxsw_sp_port_hw_rfc_2819_stats; 7218c2ecf20Sopenharmony_ci *p_len = MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN; 7228c2ecf20Sopenharmony_ci break; 7238c2ecf20Sopenharmony_ci case MLXSW_REG_PPCNT_RFC_3635_CNT: 7248c2ecf20Sopenharmony_ci *p_hw_stats = mlxsw_sp_port_hw_rfc_3635_stats; 7258c2ecf20Sopenharmony_ci *p_len = MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN; 7268c2ecf20Sopenharmony_ci break; 7278c2ecf20Sopenharmony_ci case MLXSW_REG_PPCNT_EXT_CNT: 7288c2ecf20Sopenharmony_ci *p_hw_stats = mlxsw_sp_port_hw_ext_stats; 7298c2ecf20Sopenharmony_ci *p_len = MLXSW_SP_PORT_HW_EXT_STATS_LEN; 7308c2ecf20Sopenharmony_ci break; 7318c2ecf20Sopenharmony_ci case MLXSW_REG_PPCNT_DISCARD_CNT: 7328c2ecf20Sopenharmony_ci *p_hw_stats = mlxsw_sp_port_hw_discard_stats; 7338c2ecf20Sopenharmony_ci *p_len = MLXSW_SP_PORT_HW_DISCARD_STATS_LEN; 7348c2ecf20Sopenharmony_ci break; 7358c2ecf20Sopenharmony_ci case MLXSW_REG_PPCNT_PRIO_CNT: 7368c2ecf20Sopenharmony_ci *p_hw_stats = mlxsw_sp_port_hw_prio_stats; 7378c2ecf20Sopenharmony_ci *p_len = MLXSW_SP_PORT_HW_PRIO_STATS_LEN; 7388c2ecf20Sopenharmony_ci break; 7398c2ecf20Sopenharmony_ci case MLXSW_REG_PPCNT_TC_CNT: 7408c2ecf20Sopenharmony_ci *p_hw_stats = mlxsw_sp_port_hw_tc_stats; 7418c2ecf20Sopenharmony_ci *p_len = MLXSW_SP_PORT_HW_TC_STATS_LEN; 7428c2ecf20Sopenharmony_ci break; 7438c2ecf20Sopenharmony_ci default: 7448c2ecf20Sopenharmony_ci WARN_ON(1); 7458c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 7468c2ecf20Sopenharmony_ci } 7478c2ecf20Sopenharmony_ci return 0; 7488c2ecf20Sopenharmony_ci} 7498c2ecf20Sopenharmony_ci 7508c2ecf20Sopenharmony_cistatic void __mlxsw_sp_port_get_stats(struct net_device *dev, 7518c2ecf20Sopenharmony_ci enum mlxsw_reg_ppcnt_grp grp, int prio, 7528c2ecf20Sopenharmony_ci u64 *data, int data_index) 7538c2ecf20Sopenharmony_ci{ 7548c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 7558c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 7568c2ecf20Sopenharmony_ci struct mlxsw_sp_port_hw_stats *hw_stats; 7578c2ecf20Sopenharmony_ci char ppcnt_pl[MLXSW_REG_PPCNT_LEN]; 7588c2ecf20Sopenharmony_ci int i, len; 7598c2ecf20Sopenharmony_ci int err; 7608c2ecf20Sopenharmony_ci 7618c2ecf20Sopenharmony_ci err = mlxsw_sp_get_hw_stats_by_group(&hw_stats, &len, grp); 7628c2ecf20Sopenharmony_ci if (err) 7638c2ecf20Sopenharmony_ci return; 7648c2ecf20Sopenharmony_ci mlxsw_sp_port_get_stats_raw(dev, grp, prio, ppcnt_pl); 7658c2ecf20Sopenharmony_ci for (i = 0; i < len; i++) { 7668c2ecf20Sopenharmony_ci data[data_index + i] = hw_stats[i].getter(ppcnt_pl); 7678c2ecf20Sopenharmony_ci if (!hw_stats[i].cells_bytes) 7688c2ecf20Sopenharmony_ci continue; 7698c2ecf20Sopenharmony_ci data[data_index + i] = mlxsw_sp_cells_bytes(mlxsw_sp, 7708c2ecf20Sopenharmony_ci data[data_index + i]); 7718c2ecf20Sopenharmony_ci } 7728c2ecf20Sopenharmony_ci} 7738c2ecf20Sopenharmony_ci 7748c2ecf20Sopenharmony_cistatic void __mlxsw_sp_port_get_env_stats(struct net_device *dev, u64 *data, int data_index, 7758c2ecf20Sopenharmony_ci struct mlxsw_sp_port_stats *port_stats, 7768c2ecf20Sopenharmony_ci int len) 7778c2ecf20Sopenharmony_ci{ 7788c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 7798c2ecf20Sopenharmony_ci int i; 7808c2ecf20Sopenharmony_ci 7818c2ecf20Sopenharmony_ci for (i = 0; i < len; i++) 7828c2ecf20Sopenharmony_ci data[data_index + i] = port_stats[i].getter(mlxsw_sp_port); 7838c2ecf20Sopenharmony_ci} 7848c2ecf20Sopenharmony_ci 7858c2ecf20Sopenharmony_cistatic void mlxsw_sp_port_get_stats(struct net_device *dev, 7868c2ecf20Sopenharmony_ci struct ethtool_stats *stats, u64 *data) 7878c2ecf20Sopenharmony_ci{ 7888c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 7898c2ecf20Sopenharmony_ci int i, data_index = 0; 7908c2ecf20Sopenharmony_ci 7918c2ecf20Sopenharmony_ci /* IEEE 802.3 Counters */ 7928c2ecf20Sopenharmony_ci __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_IEEE_8023_CNT, 0, 7938c2ecf20Sopenharmony_ci data, data_index); 7948c2ecf20Sopenharmony_ci data_index = MLXSW_SP_PORT_HW_STATS_LEN; 7958c2ecf20Sopenharmony_ci 7968c2ecf20Sopenharmony_ci /* RFC 2863 Counters */ 7978c2ecf20Sopenharmony_ci __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_RFC_2863_CNT, 0, 7988c2ecf20Sopenharmony_ci data, data_index); 7998c2ecf20Sopenharmony_ci data_index += MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN; 8008c2ecf20Sopenharmony_ci 8018c2ecf20Sopenharmony_ci /* RFC 2819 Counters */ 8028c2ecf20Sopenharmony_ci __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_RFC_2819_CNT, 0, 8038c2ecf20Sopenharmony_ci data, data_index); 8048c2ecf20Sopenharmony_ci data_index += MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN; 8058c2ecf20Sopenharmony_ci 8068c2ecf20Sopenharmony_ci /* RFC 3635 Counters */ 8078c2ecf20Sopenharmony_ci __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_RFC_3635_CNT, 0, 8088c2ecf20Sopenharmony_ci data, data_index); 8098c2ecf20Sopenharmony_ci data_index += MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN; 8108c2ecf20Sopenharmony_ci 8118c2ecf20Sopenharmony_ci /* Extended Counters */ 8128c2ecf20Sopenharmony_ci __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_EXT_CNT, 0, 8138c2ecf20Sopenharmony_ci data, data_index); 8148c2ecf20Sopenharmony_ci data_index += MLXSW_SP_PORT_HW_EXT_STATS_LEN; 8158c2ecf20Sopenharmony_ci 8168c2ecf20Sopenharmony_ci /* Discard Counters */ 8178c2ecf20Sopenharmony_ci __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_DISCARD_CNT, 0, 8188c2ecf20Sopenharmony_ci data, data_index); 8198c2ecf20Sopenharmony_ci data_index += MLXSW_SP_PORT_HW_DISCARD_STATS_LEN; 8208c2ecf20Sopenharmony_ci 8218c2ecf20Sopenharmony_ci /* Per-Priority Counters */ 8228c2ecf20Sopenharmony_ci for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 8238c2ecf20Sopenharmony_ci __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_PRIO_CNT, i, 8248c2ecf20Sopenharmony_ci data, data_index); 8258c2ecf20Sopenharmony_ci data_index += MLXSW_SP_PORT_HW_PRIO_STATS_LEN; 8268c2ecf20Sopenharmony_ci } 8278c2ecf20Sopenharmony_ci 8288c2ecf20Sopenharmony_ci /* Per-TC Counters */ 8298c2ecf20Sopenharmony_ci for (i = 0; i < TC_MAX_QUEUE; i++) { 8308c2ecf20Sopenharmony_ci __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_TC_CNT, i, 8318c2ecf20Sopenharmony_ci data, data_index); 8328c2ecf20Sopenharmony_ci data_index += MLXSW_SP_PORT_HW_TC_STATS_LEN; 8338c2ecf20Sopenharmony_ci } 8348c2ecf20Sopenharmony_ci 8358c2ecf20Sopenharmony_ci /* PTP counters */ 8368c2ecf20Sopenharmony_ci mlxsw_sp_port->mlxsw_sp->ptp_ops->get_stats(mlxsw_sp_port, 8378c2ecf20Sopenharmony_ci data, data_index); 8388c2ecf20Sopenharmony_ci data_index += mlxsw_sp_port->mlxsw_sp->ptp_ops->get_stats_count(); 8398c2ecf20Sopenharmony_ci 8408c2ecf20Sopenharmony_ci /* Transceiver counters */ 8418c2ecf20Sopenharmony_ci __mlxsw_sp_port_get_env_stats(dev, data, data_index, mlxsw_sp_port_transceiver_stats, 8428c2ecf20Sopenharmony_ci MLXSW_SP_PORT_HW_TRANSCEIVER_STATS_LEN); 8438c2ecf20Sopenharmony_ci data_index += MLXSW_SP_PORT_HW_TRANSCEIVER_STATS_LEN; 8448c2ecf20Sopenharmony_ci} 8458c2ecf20Sopenharmony_ci 8468c2ecf20Sopenharmony_cistatic int mlxsw_sp_port_get_sset_count(struct net_device *dev, int sset) 8478c2ecf20Sopenharmony_ci{ 8488c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 8498c2ecf20Sopenharmony_ci 8508c2ecf20Sopenharmony_ci switch (sset) { 8518c2ecf20Sopenharmony_ci case ETH_SS_STATS: 8528c2ecf20Sopenharmony_ci return MLXSW_SP_PORT_ETHTOOL_STATS_LEN + 8538c2ecf20Sopenharmony_ci mlxsw_sp_port->mlxsw_sp->ptp_ops->get_stats_count(); 8548c2ecf20Sopenharmony_ci default: 8558c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 8568c2ecf20Sopenharmony_ci } 8578c2ecf20Sopenharmony_ci} 8588c2ecf20Sopenharmony_ci 8598c2ecf20Sopenharmony_cistatic void 8608c2ecf20Sopenharmony_cimlxsw_sp_port_get_link_supported(struct mlxsw_sp *mlxsw_sp, u32 eth_proto_cap, 8618c2ecf20Sopenharmony_ci u8 width, struct ethtool_link_ksettings *cmd) 8628c2ecf20Sopenharmony_ci{ 8638c2ecf20Sopenharmony_ci const struct mlxsw_sp_port_type_speed_ops *ops; 8648c2ecf20Sopenharmony_ci 8658c2ecf20Sopenharmony_ci ops = mlxsw_sp->port_type_speed_ops; 8668c2ecf20Sopenharmony_ci 8678c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(cmd, supported, Asym_Pause); 8688c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg); 8698c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(cmd, supported, Pause); 8708c2ecf20Sopenharmony_ci 8718c2ecf20Sopenharmony_ci ops->from_ptys_supported_port(mlxsw_sp, eth_proto_cap, cmd); 8728c2ecf20Sopenharmony_ci ops->from_ptys_link(mlxsw_sp, eth_proto_cap, width, 8738c2ecf20Sopenharmony_ci cmd->link_modes.supported); 8748c2ecf20Sopenharmony_ci} 8758c2ecf20Sopenharmony_ci 8768c2ecf20Sopenharmony_cistatic void 8778c2ecf20Sopenharmony_cimlxsw_sp_port_get_link_advertise(struct mlxsw_sp *mlxsw_sp, 8788c2ecf20Sopenharmony_ci u32 eth_proto_admin, bool autoneg, u8 width, 8798c2ecf20Sopenharmony_ci struct ethtool_link_ksettings *cmd) 8808c2ecf20Sopenharmony_ci{ 8818c2ecf20Sopenharmony_ci const struct mlxsw_sp_port_type_speed_ops *ops; 8828c2ecf20Sopenharmony_ci 8838c2ecf20Sopenharmony_ci ops = mlxsw_sp->port_type_speed_ops; 8848c2ecf20Sopenharmony_ci 8858c2ecf20Sopenharmony_ci if (!autoneg) 8868c2ecf20Sopenharmony_ci return; 8878c2ecf20Sopenharmony_ci 8888c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg); 8898c2ecf20Sopenharmony_ci ops->from_ptys_link(mlxsw_sp, eth_proto_admin, width, 8908c2ecf20Sopenharmony_ci cmd->link_modes.advertising); 8918c2ecf20Sopenharmony_ci} 8928c2ecf20Sopenharmony_ci 8938c2ecf20Sopenharmony_cistatic u8 8948c2ecf20Sopenharmony_cimlxsw_sp_port_connector_port(enum mlxsw_reg_ptys_connector_type connector_type) 8958c2ecf20Sopenharmony_ci{ 8968c2ecf20Sopenharmony_ci switch (connector_type) { 8978c2ecf20Sopenharmony_ci case MLXSW_REG_PTYS_CONNECTOR_TYPE_UNKNOWN_OR_NO_CONNECTOR: 8988c2ecf20Sopenharmony_ci return PORT_OTHER; 8998c2ecf20Sopenharmony_ci case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_NONE: 9008c2ecf20Sopenharmony_ci return PORT_NONE; 9018c2ecf20Sopenharmony_ci case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_TP: 9028c2ecf20Sopenharmony_ci return PORT_TP; 9038c2ecf20Sopenharmony_ci case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_AUI: 9048c2ecf20Sopenharmony_ci return PORT_AUI; 9058c2ecf20Sopenharmony_ci case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_BNC: 9068c2ecf20Sopenharmony_ci return PORT_BNC; 9078c2ecf20Sopenharmony_ci case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_MII: 9088c2ecf20Sopenharmony_ci return PORT_MII; 9098c2ecf20Sopenharmony_ci case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_FIBRE: 9108c2ecf20Sopenharmony_ci return PORT_FIBRE; 9118c2ecf20Sopenharmony_ci case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_DA: 9128c2ecf20Sopenharmony_ci return PORT_DA; 9138c2ecf20Sopenharmony_ci case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_OTHER: 9148c2ecf20Sopenharmony_ci return PORT_OTHER; 9158c2ecf20Sopenharmony_ci default: 9168c2ecf20Sopenharmony_ci WARN_ON_ONCE(1); 9178c2ecf20Sopenharmony_ci return PORT_OTHER; 9188c2ecf20Sopenharmony_ci } 9198c2ecf20Sopenharmony_ci} 9208c2ecf20Sopenharmony_ci 9218c2ecf20Sopenharmony_cistatic int mlxsw_sp_port_ptys_query(struct mlxsw_sp_port *mlxsw_sp_port, 9228c2ecf20Sopenharmony_ci u32 *p_eth_proto_cap, u32 *p_eth_proto_admin, 9238c2ecf20Sopenharmony_ci u32 *p_eth_proto_oper, u8 *p_connector_type) 9248c2ecf20Sopenharmony_ci{ 9258c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 9268c2ecf20Sopenharmony_ci const struct mlxsw_sp_port_type_speed_ops *ops; 9278c2ecf20Sopenharmony_ci char ptys_pl[MLXSW_REG_PTYS_LEN]; 9288c2ecf20Sopenharmony_ci int err; 9298c2ecf20Sopenharmony_ci 9308c2ecf20Sopenharmony_ci ops = mlxsw_sp->port_type_speed_ops; 9318c2ecf20Sopenharmony_ci 9328c2ecf20Sopenharmony_ci ops->reg_ptys_eth_pack(mlxsw_sp, ptys_pl, mlxsw_sp_port->local_port, 0, false); 9338c2ecf20Sopenharmony_ci err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl); 9348c2ecf20Sopenharmony_ci if (err) 9358c2ecf20Sopenharmony_ci return err; 9368c2ecf20Sopenharmony_ci 9378c2ecf20Sopenharmony_ci ops->reg_ptys_eth_unpack(mlxsw_sp, ptys_pl, p_eth_proto_cap, p_eth_proto_admin, 9388c2ecf20Sopenharmony_ci p_eth_proto_oper); 9398c2ecf20Sopenharmony_ci if (p_connector_type) 9408c2ecf20Sopenharmony_ci *p_connector_type = mlxsw_reg_ptys_connector_type_get(ptys_pl); 9418c2ecf20Sopenharmony_ci return 0; 9428c2ecf20Sopenharmony_ci} 9438c2ecf20Sopenharmony_ci 9448c2ecf20Sopenharmony_cistatic int mlxsw_sp_port_get_link_ksettings(struct net_device *dev, 9458c2ecf20Sopenharmony_ci struct ethtool_link_ksettings *cmd) 9468c2ecf20Sopenharmony_ci{ 9478c2ecf20Sopenharmony_ci u32 eth_proto_cap, eth_proto_admin, eth_proto_oper; 9488c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 9498c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 9508c2ecf20Sopenharmony_ci const struct mlxsw_sp_port_type_speed_ops *ops; 9518c2ecf20Sopenharmony_ci u8 connector_type; 9528c2ecf20Sopenharmony_ci bool autoneg; 9538c2ecf20Sopenharmony_ci int err; 9548c2ecf20Sopenharmony_ci 9558c2ecf20Sopenharmony_ci err = mlxsw_sp_port_ptys_query(mlxsw_sp_port, ð_proto_cap, ð_proto_admin, 9568c2ecf20Sopenharmony_ci ð_proto_oper, &connector_type); 9578c2ecf20Sopenharmony_ci if (err) 9588c2ecf20Sopenharmony_ci return err; 9598c2ecf20Sopenharmony_ci 9608c2ecf20Sopenharmony_ci ops = mlxsw_sp->port_type_speed_ops; 9618c2ecf20Sopenharmony_ci autoneg = mlxsw_sp_port->link.autoneg; 9628c2ecf20Sopenharmony_ci 9638c2ecf20Sopenharmony_ci mlxsw_sp_port_get_link_supported(mlxsw_sp, eth_proto_cap, 9648c2ecf20Sopenharmony_ci mlxsw_sp_port->mapping.width, cmd); 9658c2ecf20Sopenharmony_ci 9668c2ecf20Sopenharmony_ci mlxsw_sp_port_get_link_advertise(mlxsw_sp, eth_proto_admin, autoneg, 9678c2ecf20Sopenharmony_ci mlxsw_sp_port->mapping.width, cmd); 9688c2ecf20Sopenharmony_ci 9698c2ecf20Sopenharmony_ci cmd->base.autoneg = autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE; 9708c2ecf20Sopenharmony_ci cmd->base.port = mlxsw_sp_port_connector_port(connector_type); 9718c2ecf20Sopenharmony_ci ops->from_ptys_speed_duplex(mlxsw_sp, netif_carrier_ok(dev), 9728c2ecf20Sopenharmony_ci eth_proto_oper, cmd); 9738c2ecf20Sopenharmony_ci 9748c2ecf20Sopenharmony_ci return 0; 9758c2ecf20Sopenharmony_ci} 9768c2ecf20Sopenharmony_ci 9778c2ecf20Sopenharmony_cistatic int 9788c2ecf20Sopenharmony_cimlxsw_sp_port_set_link_ksettings(struct net_device *dev, 9798c2ecf20Sopenharmony_ci const struct ethtool_link_ksettings *cmd) 9808c2ecf20Sopenharmony_ci{ 9818c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 9828c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 9838c2ecf20Sopenharmony_ci const struct mlxsw_sp_port_type_speed_ops *ops; 9848c2ecf20Sopenharmony_ci char ptys_pl[MLXSW_REG_PTYS_LEN]; 9858c2ecf20Sopenharmony_ci u32 eth_proto_cap, eth_proto_new; 9868c2ecf20Sopenharmony_ci bool autoneg; 9878c2ecf20Sopenharmony_ci int err; 9888c2ecf20Sopenharmony_ci 9898c2ecf20Sopenharmony_ci ops = mlxsw_sp->port_type_speed_ops; 9908c2ecf20Sopenharmony_ci 9918c2ecf20Sopenharmony_ci ops->reg_ptys_eth_pack(mlxsw_sp, ptys_pl, mlxsw_sp_port->local_port, 9928c2ecf20Sopenharmony_ci 0, false); 9938c2ecf20Sopenharmony_ci err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl); 9948c2ecf20Sopenharmony_ci if (err) 9958c2ecf20Sopenharmony_ci return err; 9968c2ecf20Sopenharmony_ci ops->reg_ptys_eth_unpack(mlxsw_sp, ptys_pl, ð_proto_cap, NULL, NULL); 9978c2ecf20Sopenharmony_ci 9988c2ecf20Sopenharmony_ci autoneg = cmd->base.autoneg == AUTONEG_ENABLE; 9998c2ecf20Sopenharmony_ci eth_proto_new = autoneg ? 10008c2ecf20Sopenharmony_ci ops->to_ptys_advert_link(mlxsw_sp, mlxsw_sp_port->mapping.width, 10018c2ecf20Sopenharmony_ci cmd) : 10028c2ecf20Sopenharmony_ci ops->to_ptys_speed(mlxsw_sp, mlxsw_sp_port->mapping.width, 10038c2ecf20Sopenharmony_ci cmd->base.speed); 10048c2ecf20Sopenharmony_ci 10058c2ecf20Sopenharmony_ci eth_proto_new = eth_proto_new & eth_proto_cap; 10068c2ecf20Sopenharmony_ci if (!eth_proto_new) { 10078c2ecf20Sopenharmony_ci netdev_err(dev, "No supported speed requested\n"); 10088c2ecf20Sopenharmony_ci return -EINVAL; 10098c2ecf20Sopenharmony_ci } 10108c2ecf20Sopenharmony_ci 10118c2ecf20Sopenharmony_ci ops->reg_ptys_eth_pack(mlxsw_sp, ptys_pl, mlxsw_sp_port->local_port, 10128c2ecf20Sopenharmony_ci eth_proto_new, autoneg); 10138c2ecf20Sopenharmony_ci err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl); 10148c2ecf20Sopenharmony_ci if (err) 10158c2ecf20Sopenharmony_ci return err; 10168c2ecf20Sopenharmony_ci 10178c2ecf20Sopenharmony_ci mlxsw_sp_port->link.autoneg = autoneg; 10188c2ecf20Sopenharmony_ci 10198c2ecf20Sopenharmony_ci if (!netif_running(dev)) 10208c2ecf20Sopenharmony_ci return 0; 10218c2ecf20Sopenharmony_ci 10228c2ecf20Sopenharmony_ci mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false); 10238c2ecf20Sopenharmony_ci mlxsw_sp_port_admin_status_set(mlxsw_sp_port, true); 10248c2ecf20Sopenharmony_ci 10258c2ecf20Sopenharmony_ci return 0; 10268c2ecf20Sopenharmony_ci} 10278c2ecf20Sopenharmony_ci 10288c2ecf20Sopenharmony_cistatic int mlxsw_sp_get_module_info(struct net_device *netdev, 10298c2ecf20Sopenharmony_ci struct ethtool_modinfo *modinfo) 10308c2ecf20Sopenharmony_ci{ 10318c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(netdev); 10328c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 10338c2ecf20Sopenharmony_ci int err; 10348c2ecf20Sopenharmony_ci 10358c2ecf20Sopenharmony_ci err = mlxsw_env_get_module_info(mlxsw_sp->core, 10368c2ecf20Sopenharmony_ci mlxsw_sp_port->mapping.module, 10378c2ecf20Sopenharmony_ci modinfo); 10388c2ecf20Sopenharmony_ci 10398c2ecf20Sopenharmony_ci return err; 10408c2ecf20Sopenharmony_ci} 10418c2ecf20Sopenharmony_ci 10428c2ecf20Sopenharmony_cistatic int mlxsw_sp_get_module_eeprom(struct net_device *netdev, 10438c2ecf20Sopenharmony_ci struct ethtool_eeprom *ee, u8 *data) 10448c2ecf20Sopenharmony_ci{ 10458c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(netdev); 10468c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 10478c2ecf20Sopenharmony_ci int err; 10488c2ecf20Sopenharmony_ci 10498c2ecf20Sopenharmony_ci err = mlxsw_env_get_module_eeprom(netdev, mlxsw_sp->core, 10508c2ecf20Sopenharmony_ci mlxsw_sp_port->mapping.module, ee, 10518c2ecf20Sopenharmony_ci data); 10528c2ecf20Sopenharmony_ci 10538c2ecf20Sopenharmony_ci return err; 10548c2ecf20Sopenharmony_ci} 10558c2ecf20Sopenharmony_ci 10568c2ecf20Sopenharmony_cistatic int 10578c2ecf20Sopenharmony_cimlxsw_sp_get_ts_info(struct net_device *netdev, struct ethtool_ts_info *info) 10588c2ecf20Sopenharmony_ci{ 10598c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(netdev); 10608c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 10618c2ecf20Sopenharmony_ci 10628c2ecf20Sopenharmony_ci return mlxsw_sp->ptp_ops->get_ts_info(mlxsw_sp, info); 10638c2ecf20Sopenharmony_ci} 10648c2ecf20Sopenharmony_ci 10658c2ecf20Sopenharmony_ciconst struct ethtool_ops mlxsw_sp_port_ethtool_ops = { 10668c2ecf20Sopenharmony_ci .get_drvinfo = mlxsw_sp_port_get_drvinfo, 10678c2ecf20Sopenharmony_ci .get_link = ethtool_op_get_link, 10688c2ecf20Sopenharmony_ci .get_link_ext_state = mlxsw_sp_port_get_link_ext_state, 10698c2ecf20Sopenharmony_ci .get_pauseparam = mlxsw_sp_port_get_pauseparam, 10708c2ecf20Sopenharmony_ci .set_pauseparam = mlxsw_sp_port_set_pauseparam, 10718c2ecf20Sopenharmony_ci .get_strings = mlxsw_sp_port_get_strings, 10728c2ecf20Sopenharmony_ci .set_phys_id = mlxsw_sp_port_set_phys_id, 10738c2ecf20Sopenharmony_ci .get_ethtool_stats = mlxsw_sp_port_get_stats, 10748c2ecf20Sopenharmony_ci .get_sset_count = mlxsw_sp_port_get_sset_count, 10758c2ecf20Sopenharmony_ci .get_link_ksettings = mlxsw_sp_port_get_link_ksettings, 10768c2ecf20Sopenharmony_ci .set_link_ksettings = mlxsw_sp_port_set_link_ksettings, 10778c2ecf20Sopenharmony_ci .get_module_info = mlxsw_sp_get_module_info, 10788c2ecf20Sopenharmony_ci .get_module_eeprom = mlxsw_sp_get_module_eeprom, 10798c2ecf20Sopenharmony_ci .get_ts_info = mlxsw_sp_get_ts_info, 10808c2ecf20Sopenharmony_ci}; 10818c2ecf20Sopenharmony_ci 10828c2ecf20Sopenharmony_cistruct mlxsw_sp1_port_link_mode { 10838c2ecf20Sopenharmony_ci enum ethtool_link_mode_bit_indices mask_ethtool; 10848c2ecf20Sopenharmony_ci u32 mask; 10858c2ecf20Sopenharmony_ci u32 speed; 10868c2ecf20Sopenharmony_ci}; 10878c2ecf20Sopenharmony_ci 10888c2ecf20Sopenharmony_cistatic const struct mlxsw_sp1_port_link_mode mlxsw_sp1_port_link_mode[] = { 10898c2ecf20Sopenharmony_ci { 10908c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_ETH_SPEED_SGMII | 10918c2ecf20Sopenharmony_ci MLXSW_REG_PTYS_ETH_SPEED_1000BASE_KX, 10928c2ecf20Sopenharmony_ci .mask_ethtool = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, 10938c2ecf20Sopenharmony_ci .speed = SPEED_1000, 10948c2ecf20Sopenharmony_ci }, 10958c2ecf20Sopenharmony_ci { 10968c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CX4 | 10978c2ecf20Sopenharmony_ci MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KX4, 10988c2ecf20Sopenharmony_ci .mask_ethtool = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, 10998c2ecf20Sopenharmony_ci .speed = SPEED_10000, 11008c2ecf20Sopenharmony_ci }, 11018c2ecf20Sopenharmony_ci { 11028c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KR | 11038c2ecf20Sopenharmony_ci MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CR | 11048c2ecf20Sopenharmony_ci MLXSW_REG_PTYS_ETH_SPEED_10GBASE_SR | 11058c2ecf20Sopenharmony_ci MLXSW_REG_PTYS_ETH_SPEED_10GBASE_ER_LR, 11068c2ecf20Sopenharmony_ci .mask_ethtool = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, 11078c2ecf20Sopenharmony_ci .speed = SPEED_10000, 11088c2ecf20Sopenharmony_ci }, 11098c2ecf20Sopenharmony_ci { 11108c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_CR4, 11118c2ecf20Sopenharmony_ci .mask_ethtool = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, 11128c2ecf20Sopenharmony_ci .speed = SPEED_40000, 11138c2ecf20Sopenharmony_ci }, 11148c2ecf20Sopenharmony_ci { 11158c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_KR4, 11168c2ecf20Sopenharmony_ci .mask_ethtool = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, 11178c2ecf20Sopenharmony_ci .speed = SPEED_40000, 11188c2ecf20Sopenharmony_ci }, 11198c2ecf20Sopenharmony_ci { 11208c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_SR4, 11218c2ecf20Sopenharmony_ci .mask_ethtool = ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT, 11228c2ecf20Sopenharmony_ci .speed = SPEED_40000, 11238c2ecf20Sopenharmony_ci }, 11248c2ecf20Sopenharmony_ci { 11258c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_LR4_ER4, 11268c2ecf20Sopenharmony_ci .mask_ethtool = ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT, 11278c2ecf20Sopenharmony_ci .speed = SPEED_40000, 11288c2ecf20Sopenharmony_ci }, 11298c2ecf20Sopenharmony_ci { 11308c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_ETH_SPEED_25GBASE_CR, 11318c2ecf20Sopenharmony_ci .mask_ethtool = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, 11328c2ecf20Sopenharmony_ci .speed = SPEED_25000, 11338c2ecf20Sopenharmony_ci }, 11348c2ecf20Sopenharmony_ci { 11358c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_ETH_SPEED_25GBASE_KR, 11368c2ecf20Sopenharmony_ci .mask_ethtool = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, 11378c2ecf20Sopenharmony_ci .speed = SPEED_25000, 11388c2ecf20Sopenharmony_ci }, 11398c2ecf20Sopenharmony_ci { 11408c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_ETH_SPEED_25GBASE_SR, 11418c2ecf20Sopenharmony_ci .mask_ethtool = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT, 11428c2ecf20Sopenharmony_ci .speed = SPEED_25000, 11438c2ecf20Sopenharmony_ci }, 11448c2ecf20Sopenharmony_ci { 11458c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_ETH_SPEED_50GBASE_CR2, 11468c2ecf20Sopenharmony_ci .mask_ethtool = ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT, 11478c2ecf20Sopenharmony_ci .speed = SPEED_50000, 11488c2ecf20Sopenharmony_ci }, 11498c2ecf20Sopenharmony_ci { 11508c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_ETH_SPEED_50GBASE_KR2, 11518c2ecf20Sopenharmony_ci .mask_ethtool = ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT, 11528c2ecf20Sopenharmony_ci .speed = SPEED_50000, 11538c2ecf20Sopenharmony_ci }, 11548c2ecf20Sopenharmony_ci { 11558c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_ETH_SPEED_50GBASE_SR2, 11568c2ecf20Sopenharmony_ci .mask_ethtool = ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT, 11578c2ecf20Sopenharmony_ci .speed = SPEED_50000, 11588c2ecf20Sopenharmony_ci }, 11598c2ecf20Sopenharmony_ci { 11608c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_CR4, 11618c2ecf20Sopenharmony_ci .mask_ethtool = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, 11628c2ecf20Sopenharmony_ci .speed = SPEED_100000, 11638c2ecf20Sopenharmony_ci }, 11648c2ecf20Sopenharmony_ci { 11658c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4, 11668c2ecf20Sopenharmony_ci .mask_ethtool = ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, 11678c2ecf20Sopenharmony_ci .speed = SPEED_100000, 11688c2ecf20Sopenharmony_ci }, 11698c2ecf20Sopenharmony_ci { 11708c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4, 11718c2ecf20Sopenharmony_ci .mask_ethtool = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, 11728c2ecf20Sopenharmony_ci .speed = SPEED_100000, 11738c2ecf20Sopenharmony_ci }, 11748c2ecf20Sopenharmony_ci { 11758c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_LR4_ER4, 11768c2ecf20Sopenharmony_ci .mask_ethtool = ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT, 11778c2ecf20Sopenharmony_ci .speed = SPEED_100000, 11788c2ecf20Sopenharmony_ci }, 11798c2ecf20Sopenharmony_ci}; 11808c2ecf20Sopenharmony_ci 11818c2ecf20Sopenharmony_ci#define MLXSW_SP1_PORT_LINK_MODE_LEN ARRAY_SIZE(mlxsw_sp1_port_link_mode) 11828c2ecf20Sopenharmony_ci 11838c2ecf20Sopenharmony_cistatic void 11848c2ecf20Sopenharmony_cimlxsw_sp1_from_ptys_supported_port(struct mlxsw_sp *mlxsw_sp, 11858c2ecf20Sopenharmony_ci u32 ptys_eth_proto, 11868c2ecf20Sopenharmony_ci struct ethtool_link_ksettings *cmd) 11878c2ecf20Sopenharmony_ci{ 11888c2ecf20Sopenharmony_ci if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CR | 11898c2ecf20Sopenharmony_ci MLXSW_REG_PTYS_ETH_SPEED_10GBASE_SR | 11908c2ecf20Sopenharmony_ci MLXSW_REG_PTYS_ETH_SPEED_40GBASE_CR4 | 11918c2ecf20Sopenharmony_ci MLXSW_REG_PTYS_ETH_SPEED_40GBASE_SR4 | 11928c2ecf20Sopenharmony_ci MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4 | 11938c2ecf20Sopenharmony_ci MLXSW_REG_PTYS_ETH_SPEED_SGMII)) 11948c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); 11958c2ecf20Sopenharmony_ci 11968c2ecf20Sopenharmony_ci if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KR | 11978c2ecf20Sopenharmony_ci MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KX4 | 11988c2ecf20Sopenharmony_ci MLXSW_REG_PTYS_ETH_SPEED_40GBASE_KR4 | 11998c2ecf20Sopenharmony_ci MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4 | 12008c2ecf20Sopenharmony_ci MLXSW_REG_PTYS_ETH_SPEED_1000BASE_KX)) 12018c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(cmd, supported, Backplane); 12028c2ecf20Sopenharmony_ci} 12038c2ecf20Sopenharmony_ci 12048c2ecf20Sopenharmony_cistatic void 12058c2ecf20Sopenharmony_cimlxsw_sp1_from_ptys_link(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto, 12068c2ecf20Sopenharmony_ci u8 width, unsigned long *mode) 12078c2ecf20Sopenharmony_ci{ 12088c2ecf20Sopenharmony_ci int i; 12098c2ecf20Sopenharmony_ci 12108c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) { 12118c2ecf20Sopenharmony_ci if (ptys_eth_proto & mlxsw_sp1_port_link_mode[i].mask) 12128c2ecf20Sopenharmony_ci __set_bit(mlxsw_sp1_port_link_mode[i].mask_ethtool, 12138c2ecf20Sopenharmony_ci mode); 12148c2ecf20Sopenharmony_ci } 12158c2ecf20Sopenharmony_ci} 12168c2ecf20Sopenharmony_ci 12178c2ecf20Sopenharmony_cistatic u32 12188c2ecf20Sopenharmony_cimlxsw_sp1_from_ptys_speed(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto) 12198c2ecf20Sopenharmony_ci{ 12208c2ecf20Sopenharmony_ci int i; 12218c2ecf20Sopenharmony_ci 12228c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) { 12238c2ecf20Sopenharmony_ci if (ptys_eth_proto & mlxsw_sp1_port_link_mode[i].mask) 12248c2ecf20Sopenharmony_ci return mlxsw_sp1_port_link_mode[i].speed; 12258c2ecf20Sopenharmony_ci } 12268c2ecf20Sopenharmony_ci 12278c2ecf20Sopenharmony_ci return SPEED_UNKNOWN; 12288c2ecf20Sopenharmony_ci} 12298c2ecf20Sopenharmony_ci 12308c2ecf20Sopenharmony_cistatic void 12318c2ecf20Sopenharmony_cimlxsw_sp1_from_ptys_speed_duplex(struct mlxsw_sp *mlxsw_sp, bool carrier_ok, 12328c2ecf20Sopenharmony_ci u32 ptys_eth_proto, 12338c2ecf20Sopenharmony_ci struct ethtool_link_ksettings *cmd) 12348c2ecf20Sopenharmony_ci{ 12358c2ecf20Sopenharmony_ci cmd->base.speed = SPEED_UNKNOWN; 12368c2ecf20Sopenharmony_ci cmd->base.duplex = DUPLEX_UNKNOWN; 12378c2ecf20Sopenharmony_ci 12388c2ecf20Sopenharmony_ci if (!carrier_ok) 12398c2ecf20Sopenharmony_ci return; 12408c2ecf20Sopenharmony_ci 12418c2ecf20Sopenharmony_ci cmd->base.speed = mlxsw_sp1_from_ptys_speed(mlxsw_sp, ptys_eth_proto); 12428c2ecf20Sopenharmony_ci if (cmd->base.speed != SPEED_UNKNOWN) 12438c2ecf20Sopenharmony_ci cmd->base.duplex = DUPLEX_FULL; 12448c2ecf20Sopenharmony_ci} 12458c2ecf20Sopenharmony_ci 12468c2ecf20Sopenharmony_cistatic int mlxsw_sp1_ptys_max_speed(struct mlxsw_sp_port *mlxsw_sp_port, u32 *p_max_speed) 12478c2ecf20Sopenharmony_ci{ 12488c2ecf20Sopenharmony_ci u32 eth_proto_cap; 12498c2ecf20Sopenharmony_ci u32 max_speed = 0; 12508c2ecf20Sopenharmony_ci int err; 12518c2ecf20Sopenharmony_ci int i; 12528c2ecf20Sopenharmony_ci 12538c2ecf20Sopenharmony_ci err = mlxsw_sp_port_ptys_query(mlxsw_sp_port, ð_proto_cap, NULL, NULL, NULL); 12548c2ecf20Sopenharmony_ci if (err) 12558c2ecf20Sopenharmony_ci return err; 12568c2ecf20Sopenharmony_ci 12578c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) { 12588c2ecf20Sopenharmony_ci if ((eth_proto_cap & mlxsw_sp1_port_link_mode[i].mask) && 12598c2ecf20Sopenharmony_ci mlxsw_sp1_port_link_mode[i].speed > max_speed) 12608c2ecf20Sopenharmony_ci max_speed = mlxsw_sp1_port_link_mode[i].speed; 12618c2ecf20Sopenharmony_ci } 12628c2ecf20Sopenharmony_ci 12638c2ecf20Sopenharmony_ci *p_max_speed = max_speed; 12648c2ecf20Sopenharmony_ci return 0; 12658c2ecf20Sopenharmony_ci} 12668c2ecf20Sopenharmony_ci 12678c2ecf20Sopenharmony_cistatic u32 12688c2ecf20Sopenharmony_cimlxsw_sp1_to_ptys_advert_link(struct mlxsw_sp *mlxsw_sp, u8 width, 12698c2ecf20Sopenharmony_ci const struct ethtool_link_ksettings *cmd) 12708c2ecf20Sopenharmony_ci{ 12718c2ecf20Sopenharmony_ci u32 ptys_proto = 0; 12728c2ecf20Sopenharmony_ci int i; 12738c2ecf20Sopenharmony_ci 12748c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) { 12758c2ecf20Sopenharmony_ci if (test_bit(mlxsw_sp1_port_link_mode[i].mask_ethtool, 12768c2ecf20Sopenharmony_ci cmd->link_modes.advertising)) 12778c2ecf20Sopenharmony_ci ptys_proto |= mlxsw_sp1_port_link_mode[i].mask; 12788c2ecf20Sopenharmony_ci } 12798c2ecf20Sopenharmony_ci return ptys_proto; 12808c2ecf20Sopenharmony_ci} 12818c2ecf20Sopenharmony_ci 12828c2ecf20Sopenharmony_cistatic u32 mlxsw_sp1_to_ptys_speed(struct mlxsw_sp *mlxsw_sp, u8 width, 12838c2ecf20Sopenharmony_ci u32 speed) 12848c2ecf20Sopenharmony_ci{ 12858c2ecf20Sopenharmony_ci u32 ptys_proto = 0; 12868c2ecf20Sopenharmony_ci int i; 12878c2ecf20Sopenharmony_ci 12888c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) { 12898c2ecf20Sopenharmony_ci if (speed == mlxsw_sp1_port_link_mode[i].speed) 12908c2ecf20Sopenharmony_ci ptys_proto |= mlxsw_sp1_port_link_mode[i].mask; 12918c2ecf20Sopenharmony_ci } 12928c2ecf20Sopenharmony_ci return ptys_proto; 12938c2ecf20Sopenharmony_ci} 12948c2ecf20Sopenharmony_ci 12958c2ecf20Sopenharmony_cistatic void 12968c2ecf20Sopenharmony_cimlxsw_sp1_reg_ptys_eth_pack(struct mlxsw_sp *mlxsw_sp, char *payload, 12978c2ecf20Sopenharmony_ci u8 local_port, u32 proto_admin, bool autoneg) 12988c2ecf20Sopenharmony_ci{ 12998c2ecf20Sopenharmony_ci mlxsw_reg_ptys_eth_pack(payload, local_port, proto_admin, autoneg); 13008c2ecf20Sopenharmony_ci} 13018c2ecf20Sopenharmony_ci 13028c2ecf20Sopenharmony_cistatic void 13038c2ecf20Sopenharmony_cimlxsw_sp1_reg_ptys_eth_unpack(struct mlxsw_sp *mlxsw_sp, char *payload, 13048c2ecf20Sopenharmony_ci u32 *p_eth_proto_cap, u32 *p_eth_proto_admin, 13058c2ecf20Sopenharmony_ci u32 *p_eth_proto_oper) 13068c2ecf20Sopenharmony_ci{ 13078c2ecf20Sopenharmony_ci mlxsw_reg_ptys_eth_unpack(payload, p_eth_proto_cap, p_eth_proto_admin, 13088c2ecf20Sopenharmony_ci p_eth_proto_oper); 13098c2ecf20Sopenharmony_ci} 13108c2ecf20Sopenharmony_ci 13118c2ecf20Sopenharmony_cistatic u32 mlxsw_sp1_ptys_proto_cap_masked_get(u32 eth_proto_cap) 13128c2ecf20Sopenharmony_ci{ 13138c2ecf20Sopenharmony_ci u32 ptys_proto_cap_masked = 0; 13148c2ecf20Sopenharmony_ci int i; 13158c2ecf20Sopenharmony_ci 13168c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) { 13178c2ecf20Sopenharmony_ci if (mlxsw_sp1_port_link_mode[i].mask & eth_proto_cap) 13188c2ecf20Sopenharmony_ci ptys_proto_cap_masked |= 13198c2ecf20Sopenharmony_ci mlxsw_sp1_port_link_mode[i].mask; 13208c2ecf20Sopenharmony_ci } 13218c2ecf20Sopenharmony_ci 13228c2ecf20Sopenharmony_ci return ptys_proto_cap_masked; 13238c2ecf20Sopenharmony_ci} 13248c2ecf20Sopenharmony_ci 13258c2ecf20Sopenharmony_ciconst struct mlxsw_sp_port_type_speed_ops mlxsw_sp1_port_type_speed_ops = { 13268c2ecf20Sopenharmony_ci .from_ptys_supported_port = mlxsw_sp1_from_ptys_supported_port, 13278c2ecf20Sopenharmony_ci .from_ptys_link = mlxsw_sp1_from_ptys_link, 13288c2ecf20Sopenharmony_ci .from_ptys_speed = mlxsw_sp1_from_ptys_speed, 13298c2ecf20Sopenharmony_ci .from_ptys_speed_duplex = mlxsw_sp1_from_ptys_speed_duplex, 13308c2ecf20Sopenharmony_ci .ptys_max_speed = mlxsw_sp1_ptys_max_speed, 13318c2ecf20Sopenharmony_ci .to_ptys_advert_link = mlxsw_sp1_to_ptys_advert_link, 13328c2ecf20Sopenharmony_ci .to_ptys_speed = mlxsw_sp1_to_ptys_speed, 13338c2ecf20Sopenharmony_ci .reg_ptys_eth_pack = mlxsw_sp1_reg_ptys_eth_pack, 13348c2ecf20Sopenharmony_ci .reg_ptys_eth_unpack = mlxsw_sp1_reg_ptys_eth_unpack, 13358c2ecf20Sopenharmony_ci .ptys_proto_cap_masked_get = mlxsw_sp1_ptys_proto_cap_masked_get, 13368c2ecf20Sopenharmony_ci}; 13378c2ecf20Sopenharmony_ci 13388c2ecf20Sopenharmony_cistatic const enum ethtool_link_mode_bit_indices 13398c2ecf20Sopenharmony_cimlxsw_sp2_mask_ethtool_sgmii_100m[] = { 13408c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_100baseT_Full_BIT, 13418c2ecf20Sopenharmony_ci}; 13428c2ecf20Sopenharmony_ci 13438c2ecf20Sopenharmony_ci#define MLXSW_SP2_MASK_ETHTOOL_SGMII_100M_LEN \ 13448c2ecf20Sopenharmony_ci ARRAY_SIZE(mlxsw_sp2_mask_ethtool_sgmii_100m) 13458c2ecf20Sopenharmony_ci 13468c2ecf20Sopenharmony_cistatic const enum ethtool_link_mode_bit_indices 13478c2ecf20Sopenharmony_cimlxsw_sp2_mask_ethtool_1000base_x_sgmii[] = { 13488c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_1000baseT_Full_BIT, 13498c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, 13508c2ecf20Sopenharmony_ci}; 13518c2ecf20Sopenharmony_ci 13528c2ecf20Sopenharmony_ci#define MLXSW_SP2_MASK_ETHTOOL_1000BASE_X_SGMII_LEN \ 13538c2ecf20Sopenharmony_ci ARRAY_SIZE(mlxsw_sp2_mask_ethtool_1000base_x_sgmii) 13548c2ecf20Sopenharmony_ci 13558c2ecf20Sopenharmony_cistatic const enum ethtool_link_mode_bit_indices 13568c2ecf20Sopenharmony_cimlxsw_sp2_mask_ethtool_5gbase_r[] = { 13578c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_5000baseT_Full_BIT, 13588c2ecf20Sopenharmony_ci}; 13598c2ecf20Sopenharmony_ci 13608c2ecf20Sopenharmony_ci#define MLXSW_SP2_MASK_ETHTOOL_5GBASE_R_LEN \ 13618c2ecf20Sopenharmony_ci ARRAY_SIZE(mlxsw_sp2_mask_ethtool_5gbase_r) 13628c2ecf20Sopenharmony_ci 13638c2ecf20Sopenharmony_cistatic const enum ethtool_link_mode_bit_indices 13648c2ecf20Sopenharmony_cimlxsw_sp2_mask_ethtool_xfi_xaui_1_10g[] = { 13658c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_10000baseT_Full_BIT, 13668c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, 13678c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_10000baseR_FEC_BIT, 13688c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_10000baseCR_Full_BIT, 13698c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, 13708c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, 13718c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_10000baseER_Full_BIT, 13728c2ecf20Sopenharmony_ci}; 13738c2ecf20Sopenharmony_ci 13748c2ecf20Sopenharmony_ci#define MLXSW_SP2_MASK_ETHTOOL_XFI_XAUI_1_10G_LEN \ 13758c2ecf20Sopenharmony_ci ARRAY_SIZE(mlxsw_sp2_mask_ethtool_xfi_xaui_1_10g) 13768c2ecf20Sopenharmony_ci 13778c2ecf20Sopenharmony_cistatic const enum ethtool_link_mode_bit_indices 13788c2ecf20Sopenharmony_cimlxsw_sp2_mask_ethtool_xlaui_4_xlppi_4_40g[] = { 13798c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, 13808c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, 13818c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT, 13828c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT, 13838c2ecf20Sopenharmony_ci}; 13848c2ecf20Sopenharmony_ci 13858c2ecf20Sopenharmony_ci#define MLXSW_SP2_MASK_ETHTOOL_XLAUI_4_XLPPI_4_40G_LEN \ 13868c2ecf20Sopenharmony_ci ARRAY_SIZE(mlxsw_sp2_mask_ethtool_xlaui_4_xlppi_4_40g) 13878c2ecf20Sopenharmony_ci 13888c2ecf20Sopenharmony_cistatic const enum ethtool_link_mode_bit_indices 13898c2ecf20Sopenharmony_cimlxsw_sp2_mask_ethtool_25gaui_1_25gbase_cr_kr[] = { 13908c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, 13918c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, 13928c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_25000baseSR_Full_BIT, 13938c2ecf20Sopenharmony_ci}; 13948c2ecf20Sopenharmony_ci 13958c2ecf20Sopenharmony_ci#define MLXSW_SP2_MASK_ETHTOOL_25GAUI_1_25GBASE_CR_KR_LEN \ 13968c2ecf20Sopenharmony_ci ARRAY_SIZE(mlxsw_sp2_mask_ethtool_25gaui_1_25gbase_cr_kr) 13978c2ecf20Sopenharmony_ci 13988c2ecf20Sopenharmony_cistatic const enum ethtool_link_mode_bit_indices 13998c2ecf20Sopenharmony_cimlxsw_sp2_mask_ethtool_50gaui_2_laui_2_50gbase_cr2_kr2[] = { 14008c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT, 14018c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT, 14028c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT, 14038c2ecf20Sopenharmony_ci}; 14048c2ecf20Sopenharmony_ci 14058c2ecf20Sopenharmony_ci#define MLXSW_SP2_MASK_ETHTOOL_50GAUI_2_LAUI_2_50GBASE_CR2_KR2_LEN \ 14068c2ecf20Sopenharmony_ci ARRAY_SIZE(mlxsw_sp2_mask_ethtool_50gaui_2_laui_2_50gbase_cr2_kr2) 14078c2ecf20Sopenharmony_ci 14088c2ecf20Sopenharmony_cistatic const enum ethtool_link_mode_bit_indices 14098c2ecf20Sopenharmony_cimlxsw_sp2_mask_ethtool_50gaui_1_laui_1_50gbase_cr_kr[] = { 14108c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_50000baseKR_Full_BIT, 14118c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_50000baseSR_Full_BIT, 14128c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_50000baseCR_Full_BIT, 14138c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT, 14148c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_50000baseDR_Full_BIT, 14158c2ecf20Sopenharmony_ci}; 14168c2ecf20Sopenharmony_ci 14178c2ecf20Sopenharmony_ci#define MLXSW_SP2_MASK_ETHTOOL_50GAUI_1_LAUI_1_50GBASE_CR_KR_LEN \ 14188c2ecf20Sopenharmony_ci ARRAY_SIZE(mlxsw_sp2_mask_ethtool_50gaui_1_laui_1_50gbase_cr_kr) 14198c2ecf20Sopenharmony_ci 14208c2ecf20Sopenharmony_cistatic const enum ethtool_link_mode_bit_indices 14218c2ecf20Sopenharmony_cimlxsw_sp2_mask_ethtool_caui_4_100gbase_cr4_kr4[] = { 14228c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, 14238c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, 14248c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, 14258c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT, 14268c2ecf20Sopenharmony_ci}; 14278c2ecf20Sopenharmony_ci 14288c2ecf20Sopenharmony_ci#define MLXSW_SP2_MASK_ETHTOOL_CAUI_4_100GBASE_CR4_KR4_LEN \ 14298c2ecf20Sopenharmony_ci ARRAY_SIZE(mlxsw_sp2_mask_ethtool_caui_4_100gbase_cr4_kr4) 14308c2ecf20Sopenharmony_ci 14318c2ecf20Sopenharmony_cistatic const enum ethtool_link_mode_bit_indices 14328c2ecf20Sopenharmony_cimlxsw_sp2_mask_ethtool_100gaui_2_100gbase_cr2_kr2[] = { 14338c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT, 14348c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT, 14358c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT, 14368c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT, 14378c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT, 14388c2ecf20Sopenharmony_ci}; 14398c2ecf20Sopenharmony_ci 14408c2ecf20Sopenharmony_ci#define MLXSW_SP2_MASK_ETHTOOL_100GAUI_2_100GBASE_CR2_KR2_LEN \ 14418c2ecf20Sopenharmony_ci ARRAY_SIZE(mlxsw_sp2_mask_ethtool_100gaui_2_100gbase_cr2_kr2) 14428c2ecf20Sopenharmony_ci 14438c2ecf20Sopenharmony_cistatic const enum ethtool_link_mode_bit_indices 14448c2ecf20Sopenharmony_cimlxsw_sp2_mask_ethtool_200gaui_4_200gbase_cr4_kr4[] = { 14458c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT, 14468c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT, 14478c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT, 14488c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT, 14498c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT, 14508c2ecf20Sopenharmony_ci}; 14518c2ecf20Sopenharmony_ci 14528c2ecf20Sopenharmony_ci#define MLXSW_SP2_MASK_ETHTOOL_200GAUI_4_200GBASE_CR4_KR4_LEN \ 14538c2ecf20Sopenharmony_ci ARRAY_SIZE(mlxsw_sp2_mask_ethtool_200gaui_4_200gbase_cr4_kr4) 14548c2ecf20Sopenharmony_ci 14558c2ecf20Sopenharmony_cistatic const enum ethtool_link_mode_bit_indices 14568c2ecf20Sopenharmony_cimlxsw_sp2_mask_ethtool_400gaui_8[] = { 14578c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT, 14588c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT, 14598c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT, 14608c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT, 14618c2ecf20Sopenharmony_ci ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT, 14628c2ecf20Sopenharmony_ci}; 14638c2ecf20Sopenharmony_ci 14648c2ecf20Sopenharmony_ci#define MLXSW_SP2_MASK_ETHTOOL_400GAUI_8_LEN \ 14658c2ecf20Sopenharmony_ci ARRAY_SIZE(mlxsw_sp2_mask_ethtool_400gaui_8) 14668c2ecf20Sopenharmony_ci 14678c2ecf20Sopenharmony_ci#define MLXSW_SP_PORT_MASK_WIDTH_1X BIT(0) 14688c2ecf20Sopenharmony_ci#define MLXSW_SP_PORT_MASK_WIDTH_2X BIT(1) 14698c2ecf20Sopenharmony_ci#define MLXSW_SP_PORT_MASK_WIDTH_4X BIT(2) 14708c2ecf20Sopenharmony_ci#define MLXSW_SP_PORT_MASK_WIDTH_8X BIT(3) 14718c2ecf20Sopenharmony_ci 14728c2ecf20Sopenharmony_cistatic u8 mlxsw_sp_port_mask_width_get(u8 width) 14738c2ecf20Sopenharmony_ci{ 14748c2ecf20Sopenharmony_ci switch (width) { 14758c2ecf20Sopenharmony_ci case 1: 14768c2ecf20Sopenharmony_ci return MLXSW_SP_PORT_MASK_WIDTH_1X; 14778c2ecf20Sopenharmony_ci case 2: 14788c2ecf20Sopenharmony_ci return MLXSW_SP_PORT_MASK_WIDTH_2X; 14798c2ecf20Sopenharmony_ci case 4: 14808c2ecf20Sopenharmony_ci return MLXSW_SP_PORT_MASK_WIDTH_4X; 14818c2ecf20Sopenharmony_ci case 8: 14828c2ecf20Sopenharmony_ci return MLXSW_SP_PORT_MASK_WIDTH_8X; 14838c2ecf20Sopenharmony_ci default: 14848c2ecf20Sopenharmony_ci WARN_ON_ONCE(1); 14858c2ecf20Sopenharmony_ci return 0; 14868c2ecf20Sopenharmony_ci } 14878c2ecf20Sopenharmony_ci} 14888c2ecf20Sopenharmony_ci 14898c2ecf20Sopenharmony_cistruct mlxsw_sp2_port_link_mode { 14908c2ecf20Sopenharmony_ci const enum ethtool_link_mode_bit_indices *mask_ethtool; 14918c2ecf20Sopenharmony_ci int m_ethtool_len; 14928c2ecf20Sopenharmony_ci u32 mask; 14938c2ecf20Sopenharmony_ci u32 speed; 14948c2ecf20Sopenharmony_ci u8 mask_width; 14958c2ecf20Sopenharmony_ci}; 14968c2ecf20Sopenharmony_ci 14978c2ecf20Sopenharmony_cistatic const struct mlxsw_sp2_port_link_mode mlxsw_sp2_port_link_mode[] = { 14988c2ecf20Sopenharmony_ci { 14998c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_SGMII_100M, 15008c2ecf20Sopenharmony_ci .mask_ethtool = mlxsw_sp2_mask_ethtool_sgmii_100m, 15018c2ecf20Sopenharmony_ci .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_SGMII_100M_LEN, 15028c2ecf20Sopenharmony_ci .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X | 15038c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_2X | 15048c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_4X | 15058c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_8X, 15068c2ecf20Sopenharmony_ci .speed = SPEED_100, 15078c2ecf20Sopenharmony_ci }, 15088c2ecf20Sopenharmony_ci { 15098c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_1000BASE_X_SGMII, 15108c2ecf20Sopenharmony_ci .mask_ethtool = mlxsw_sp2_mask_ethtool_1000base_x_sgmii, 15118c2ecf20Sopenharmony_ci .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_1000BASE_X_SGMII_LEN, 15128c2ecf20Sopenharmony_ci .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X | 15138c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_2X | 15148c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_4X | 15158c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_8X, 15168c2ecf20Sopenharmony_ci .speed = SPEED_1000, 15178c2ecf20Sopenharmony_ci }, 15188c2ecf20Sopenharmony_ci { 15198c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_5GBASE_R, 15208c2ecf20Sopenharmony_ci .mask_ethtool = mlxsw_sp2_mask_ethtool_5gbase_r, 15218c2ecf20Sopenharmony_ci .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_5GBASE_R_LEN, 15228c2ecf20Sopenharmony_ci .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X | 15238c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_2X | 15248c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_4X | 15258c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_8X, 15268c2ecf20Sopenharmony_ci .speed = SPEED_5000, 15278c2ecf20Sopenharmony_ci }, 15288c2ecf20Sopenharmony_ci { 15298c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_XFI_XAUI_1_10G, 15308c2ecf20Sopenharmony_ci .mask_ethtool = mlxsw_sp2_mask_ethtool_xfi_xaui_1_10g, 15318c2ecf20Sopenharmony_ci .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_XFI_XAUI_1_10G_LEN, 15328c2ecf20Sopenharmony_ci .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X | 15338c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_2X | 15348c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_4X | 15358c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_8X, 15368c2ecf20Sopenharmony_ci .speed = SPEED_10000, 15378c2ecf20Sopenharmony_ci }, 15388c2ecf20Sopenharmony_ci { 15398c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_XLAUI_4_XLPPI_4_40G, 15408c2ecf20Sopenharmony_ci .mask_ethtool = mlxsw_sp2_mask_ethtool_xlaui_4_xlppi_4_40g, 15418c2ecf20Sopenharmony_ci .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_XLAUI_4_XLPPI_4_40G_LEN, 15428c2ecf20Sopenharmony_ci .mask_width = MLXSW_SP_PORT_MASK_WIDTH_4X | 15438c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_8X, 15448c2ecf20Sopenharmony_ci .speed = SPEED_40000, 15458c2ecf20Sopenharmony_ci }, 15468c2ecf20Sopenharmony_ci { 15478c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_25GAUI_1_25GBASE_CR_KR, 15488c2ecf20Sopenharmony_ci .mask_ethtool = mlxsw_sp2_mask_ethtool_25gaui_1_25gbase_cr_kr, 15498c2ecf20Sopenharmony_ci .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_25GAUI_1_25GBASE_CR_KR_LEN, 15508c2ecf20Sopenharmony_ci .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X | 15518c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_2X | 15528c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_4X | 15538c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_8X, 15548c2ecf20Sopenharmony_ci .speed = SPEED_25000, 15558c2ecf20Sopenharmony_ci }, 15568c2ecf20Sopenharmony_ci { 15578c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_50GAUI_2_LAUI_2_50GBASE_CR2_KR2, 15588c2ecf20Sopenharmony_ci .mask_ethtool = mlxsw_sp2_mask_ethtool_50gaui_2_laui_2_50gbase_cr2_kr2, 15598c2ecf20Sopenharmony_ci .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_50GAUI_2_LAUI_2_50GBASE_CR2_KR2_LEN, 15608c2ecf20Sopenharmony_ci .mask_width = MLXSW_SP_PORT_MASK_WIDTH_2X | 15618c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_4X | 15628c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_8X, 15638c2ecf20Sopenharmony_ci .speed = SPEED_50000, 15648c2ecf20Sopenharmony_ci }, 15658c2ecf20Sopenharmony_ci { 15668c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_50GAUI_1_LAUI_1_50GBASE_CR_KR, 15678c2ecf20Sopenharmony_ci .mask_ethtool = mlxsw_sp2_mask_ethtool_50gaui_1_laui_1_50gbase_cr_kr, 15688c2ecf20Sopenharmony_ci .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_50GAUI_1_LAUI_1_50GBASE_CR_KR_LEN, 15698c2ecf20Sopenharmony_ci .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X, 15708c2ecf20Sopenharmony_ci .speed = SPEED_50000, 15718c2ecf20Sopenharmony_ci }, 15728c2ecf20Sopenharmony_ci { 15738c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_CAUI_4_100GBASE_CR4_KR4, 15748c2ecf20Sopenharmony_ci .mask_ethtool = mlxsw_sp2_mask_ethtool_caui_4_100gbase_cr4_kr4, 15758c2ecf20Sopenharmony_ci .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_CAUI_4_100GBASE_CR4_KR4_LEN, 15768c2ecf20Sopenharmony_ci .mask_width = MLXSW_SP_PORT_MASK_WIDTH_4X | 15778c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_8X, 15788c2ecf20Sopenharmony_ci .speed = SPEED_100000, 15798c2ecf20Sopenharmony_ci }, 15808c2ecf20Sopenharmony_ci { 15818c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_100GAUI_2_100GBASE_CR2_KR2, 15828c2ecf20Sopenharmony_ci .mask_ethtool = mlxsw_sp2_mask_ethtool_100gaui_2_100gbase_cr2_kr2, 15838c2ecf20Sopenharmony_ci .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_100GAUI_2_100GBASE_CR2_KR2_LEN, 15848c2ecf20Sopenharmony_ci .mask_width = MLXSW_SP_PORT_MASK_WIDTH_2X, 15858c2ecf20Sopenharmony_ci .speed = SPEED_100000, 15868c2ecf20Sopenharmony_ci }, 15878c2ecf20Sopenharmony_ci { 15888c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_200GAUI_4_200GBASE_CR4_KR4, 15898c2ecf20Sopenharmony_ci .mask_ethtool = mlxsw_sp2_mask_ethtool_200gaui_4_200gbase_cr4_kr4, 15908c2ecf20Sopenharmony_ci .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_200GAUI_4_200GBASE_CR4_KR4_LEN, 15918c2ecf20Sopenharmony_ci .mask_width = MLXSW_SP_PORT_MASK_WIDTH_4X | 15928c2ecf20Sopenharmony_ci MLXSW_SP_PORT_MASK_WIDTH_8X, 15938c2ecf20Sopenharmony_ci .speed = SPEED_200000, 15948c2ecf20Sopenharmony_ci }, 15958c2ecf20Sopenharmony_ci { 15968c2ecf20Sopenharmony_ci .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_400GAUI_8, 15978c2ecf20Sopenharmony_ci .mask_ethtool = mlxsw_sp2_mask_ethtool_400gaui_8, 15988c2ecf20Sopenharmony_ci .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_400GAUI_8_LEN, 15998c2ecf20Sopenharmony_ci .mask_width = MLXSW_SP_PORT_MASK_WIDTH_8X, 16008c2ecf20Sopenharmony_ci .speed = SPEED_400000, 16018c2ecf20Sopenharmony_ci }, 16028c2ecf20Sopenharmony_ci}; 16038c2ecf20Sopenharmony_ci 16048c2ecf20Sopenharmony_ci#define MLXSW_SP2_PORT_LINK_MODE_LEN ARRAY_SIZE(mlxsw_sp2_port_link_mode) 16058c2ecf20Sopenharmony_ci 16068c2ecf20Sopenharmony_cistatic void 16078c2ecf20Sopenharmony_cimlxsw_sp2_from_ptys_supported_port(struct mlxsw_sp *mlxsw_sp, 16088c2ecf20Sopenharmony_ci u32 ptys_eth_proto, 16098c2ecf20Sopenharmony_ci struct ethtool_link_ksettings *cmd) 16108c2ecf20Sopenharmony_ci{ 16118c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); 16128c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(cmd, supported, Backplane); 16138c2ecf20Sopenharmony_ci} 16148c2ecf20Sopenharmony_ci 16158c2ecf20Sopenharmony_cistatic void 16168c2ecf20Sopenharmony_cimlxsw_sp2_set_bit_ethtool(const struct mlxsw_sp2_port_link_mode *link_mode, 16178c2ecf20Sopenharmony_ci unsigned long *mode) 16188c2ecf20Sopenharmony_ci{ 16198c2ecf20Sopenharmony_ci int i; 16208c2ecf20Sopenharmony_ci 16218c2ecf20Sopenharmony_ci for (i = 0; i < link_mode->m_ethtool_len; i++) 16228c2ecf20Sopenharmony_ci __set_bit(link_mode->mask_ethtool[i], mode); 16238c2ecf20Sopenharmony_ci} 16248c2ecf20Sopenharmony_ci 16258c2ecf20Sopenharmony_cistatic void 16268c2ecf20Sopenharmony_cimlxsw_sp2_from_ptys_link(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto, 16278c2ecf20Sopenharmony_ci u8 width, unsigned long *mode) 16288c2ecf20Sopenharmony_ci{ 16298c2ecf20Sopenharmony_ci u8 mask_width = mlxsw_sp_port_mask_width_get(width); 16308c2ecf20Sopenharmony_ci int i; 16318c2ecf20Sopenharmony_ci 16328c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) { 16338c2ecf20Sopenharmony_ci if ((ptys_eth_proto & mlxsw_sp2_port_link_mode[i].mask) && 16348c2ecf20Sopenharmony_ci (mask_width & mlxsw_sp2_port_link_mode[i].mask_width)) 16358c2ecf20Sopenharmony_ci mlxsw_sp2_set_bit_ethtool(&mlxsw_sp2_port_link_mode[i], 16368c2ecf20Sopenharmony_ci mode); 16378c2ecf20Sopenharmony_ci } 16388c2ecf20Sopenharmony_ci} 16398c2ecf20Sopenharmony_ci 16408c2ecf20Sopenharmony_cistatic u32 16418c2ecf20Sopenharmony_cimlxsw_sp2_from_ptys_speed(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto) 16428c2ecf20Sopenharmony_ci{ 16438c2ecf20Sopenharmony_ci int i; 16448c2ecf20Sopenharmony_ci 16458c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) { 16468c2ecf20Sopenharmony_ci if (ptys_eth_proto & mlxsw_sp2_port_link_mode[i].mask) 16478c2ecf20Sopenharmony_ci return mlxsw_sp2_port_link_mode[i].speed; 16488c2ecf20Sopenharmony_ci } 16498c2ecf20Sopenharmony_ci 16508c2ecf20Sopenharmony_ci return SPEED_UNKNOWN; 16518c2ecf20Sopenharmony_ci} 16528c2ecf20Sopenharmony_ci 16538c2ecf20Sopenharmony_cistatic void 16548c2ecf20Sopenharmony_cimlxsw_sp2_from_ptys_speed_duplex(struct mlxsw_sp *mlxsw_sp, bool carrier_ok, 16558c2ecf20Sopenharmony_ci u32 ptys_eth_proto, 16568c2ecf20Sopenharmony_ci struct ethtool_link_ksettings *cmd) 16578c2ecf20Sopenharmony_ci{ 16588c2ecf20Sopenharmony_ci cmd->base.speed = SPEED_UNKNOWN; 16598c2ecf20Sopenharmony_ci cmd->base.duplex = DUPLEX_UNKNOWN; 16608c2ecf20Sopenharmony_ci 16618c2ecf20Sopenharmony_ci if (!carrier_ok) 16628c2ecf20Sopenharmony_ci return; 16638c2ecf20Sopenharmony_ci 16648c2ecf20Sopenharmony_ci cmd->base.speed = mlxsw_sp2_from_ptys_speed(mlxsw_sp, ptys_eth_proto); 16658c2ecf20Sopenharmony_ci if (cmd->base.speed != SPEED_UNKNOWN) 16668c2ecf20Sopenharmony_ci cmd->base.duplex = DUPLEX_FULL; 16678c2ecf20Sopenharmony_ci} 16688c2ecf20Sopenharmony_ci 16698c2ecf20Sopenharmony_cistatic int mlxsw_sp2_ptys_max_speed(struct mlxsw_sp_port *mlxsw_sp_port, u32 *p_max_speed) 16708c2ecf20Sopenharmony_ci{ 16718c2ecf20Sopenharmony_ci u32 eth_proto_cap; 16728c2ecf20Sopenharmony_ci u32 max_speed = 0; 16738c2ecf20Sopenharmony_ci int err; 16748c2ecf20Sopenharmony_ci int i; 16758c2ecf20Sopenharmony_ci 16768c2ecf20Sopenharmony_ci err = mlxsw_sp_port_ptys_query(mlxsw_sp_port, ð_proto_cap, NULL, NULL, NULL); 16778c2ecf20Sopenharmony_ci if (err) 16788c2ecf20Sopenharmony_ci return err; 16798c2ecf20Sopenharmony_ci 16808c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) { 16818c2ecf20Sopenharmony_ci if ((eth_proto_cap & mlxsw_sp2_port_link_mode[i].mask) && 16828c2ecf20Sopenharmony_ci mlxsw_sp2_port_link_mode[i].speed > max_speed) 16838c2ecf20Sopenharmony_ci max_speed = mlxsw_sp2_port_link_mode[i].speed; 16848c2ecf20Sopenharmony_ci } 16858c2ecf20Sopenharmony_ci 16868c2ecf20Sopenharmony_ci *p_max_speed = max_speed; 16878c2ecf20Sopenharmony_ci return 0; 16888c2ecf20Sopenharmony_ci} 16898c2ecf20Sopenharmony_ci 16908c2ecf20Sopenharmony_cistatic bool 16918c2ecf20Sopenharmony_cimlxsw_sp2_test_bit_ethtool(const struct mlxsw_sp2_port_link_mode *link_mode, 16928c2ecf20Sopenharmony_ci const unsigned long *mode) 16938c2ecf20Sopenharmony_ci{ 16948c2ecf20Sopenharmony_ci int cnt = 0; 16958c2ecf20Sopenharmony_ci int i; 16968c2ecf20Sopenharmony_ci 16978c2ecf20Sopenharmony_ci for (i = 0; i < link_mode->m_ethtool_len; i++) { 16988c2ecf20Sopenharmony_ci if (test_bit(link_mode->mask_ethtool[i], mode)) 16998c2ecf20Sopenharmony_ci cnt++; 17008c2ecf20Sopenharmony_ci } 17018c2ecf20Sopenharmony_ci 17028c2ecf20Sopenharmony_ci return cnt == link_mode->m_ethtool_len; 17038c2ecf20Sopenharmony_ci} 17048c2ecf20Sopenharmony_ci 17058c2ecf20Sopenharmony_cistatic u32 17068c2ecf20Sopenharmony_cimlxsw_sp2_to_ptys_advert_link(struct mlxsw_sp *mlxsw_sp, u8 width, 17078c2ecf20Sopenharmony_ci const struct ethtool_link_ksettings *cmd) 17088c2ecf20Sopenharmony_ci{ 17098c2ecf20Sopenharmony_ci u8 mask_width = mlxsw_sp_port_mask_width_get(width); 17108c2ecf20Sopenharmony_ci u32 ptys_proto = 0; 17118c2ecf20Sopenharmony_ci int i; 17128c2ecf20Sopenharmony_ci 17138c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) { 17148c2ecf20Sopenharmony_ci if ((mask_width & mlxsw_sp2_port_link_mode[i].mask_width) && 17158c2ecf20Sopenharmony_ci mlxsw_sp2_test_bit_ethtool(&mlxsw_sp2_port_link_mode[i], 17168c2ecf20Sopenharmony_ci cmd->link_modes.advertising)) 17178c2ecf20Sopenharmony_ci ptys_proto |= mlxsw_sp2_port_link_mode[i].mask; 17188c2ecf20Sopenharmony_ci } 17198c2ecf20Sopenharmony_ci return ptys_proto; 17208c2ecf20Sopenharmony_ci} 17218c2ecf20Sopenharmony_ci 17228c2ecf20Sopenharmony_cistatic u32 mlxsw_sp2_to_ptys_speed(struct mlxsw_sp *mlxsw_sp, 17238c2ecf20Sopenharmony_ci u8 width, u32 speed) 17248c2ecf20Sopenharmony_ci{ 17258c2ecf20Sopenharmony_ci u8 mask_width = mlxsw_sp_port_mask_width_get(width); 17268c2ecf20Sopenharmony_ci u32 ptys_proto = 0; 17278c2ecf20Sopenharmony_ci int i; 17288c2ecf20Sopenharmony_ci 17298c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) { 17308c2ecf20Sopenharmony_ci if ((speed == mlxsw_sp2_port_link_mode[i].speed) && 17318c2ecf20Sopenharmony_ci (mask_width & mlxsw_sp2_port_link_mode[i].mask_width)) 17328c2ecf20Sopenharmony_ci ptys_proto |= mlxsw_sp2_port_link_mode[i].mask; 17338c2ecf20Sopenharmony_ci } 17348c2ecf20Sopenharmony_ci return ptys_proto; 17358c2ecf20Sopenharmony_ci} 17368c2ecf20Sopenharmony_ci 17378c2ecf20Sopenharmony_cistatic void 17388c2ecf20Sopenharmony_cimlxsw_sp2_reg_ptys_eth_pack(struct mlxsw_sp *mlxsw_sp, char *payload, 17398c2ecf20Sopenharmony_ci u8 local_port, u32 proto_admin, 17408c2ecf20Sopenharmony_ci bool autoneg) 17418c2ecf20Sopenharmony_ci{ 17428c2ecf20Sopenharmony_ci mlxsw_reg_ptys_ext_eth_pack(payload, local_port, proto_admin, autoneg); 17438c2ecf20Sopenharmony_ci} 17448c2ecf20Sopenharmony_ci 17458c2ecf20Sopenharmony_cistatic void 17468c2ecf20Sopenharmony_cimlxsw_sp2_reg_ptys_eth_unpack(struct mlxsw_sp *mlxsw_sp, char *payload, 17478c2ecf20Sopenharmony_ci u32 *p_eth_proto_cap, u32 *p_eth_proto_admin, 17488c2ecf20Sopenharmony_ci u32 *p_eth_proto_oper) 17498c2ecf20Sopenharmony_ci{ 17508c2ecf20Sopenharmony_ci mlxsw_reg_ptys_ext_eth_unpack(payload, p_eth_proto_cap, 17518c2ecf20Sopenharmony_ci p_eth_proto_admin, p_eth_proto_oper); 17528c2ecf20Sopenharmony_ci} 17538c2ecf20Sopenharmony_ci 17548c2ecf20Sopenharmony_cistatic u32 mlxsw_sp2_ptys_proto_cap_masked_get(u32 eth_proto_cap) 17558c2ecf20Sopenharmony_ci{ 17568c2ecf20Sopenharmony_ci u32 ptys_proto_cap_masked = 0; 17578c2ecf20Sopenharmony_ci int i; 17588c2ecf20Sopenharmony_ci 17598c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) { 17608c2ecf20Sopenharmony_ci if (mlxsw_sp2_port_link_mode[i].mask & eth_proto_cap) 17618c2ecf20Sopenharmony_ci ptys_proto_cap_masked |= 17628c2ecf20Sopenharmony_ci mlxsw_sp2_port_link_mode[i].mask; 17638c2ecf20Sopenharmony_ci } 17648c2ecf20Sopenharmony_ci 17658c2ecf20Sopenharmony_ci return ptys_proto_cap_masked; 17668c2ecf20Sopenharmony_ci} 17678c2ecf20Sopenharmony_ci 17688c2ecf20Sopenharmony_ciconst struct mlxsw_sp_port_type_speed_ops mlxsw_sp2_port_type_speed_ops = { 17698c2ecf20Sopenharmony_ci .from_ptys_supported_port = mlxsw_sp2_from_ptys_supported_port, 17708c2ecf20Sopenharmony_ci .from_ptys_link = mlxsw_sp2_from_ptys_link, 17718c2ecf20Sopenharmony_ci .from_ptys_speed = mlxsw_sp2_from_ptys_speed, 17728c2ecf20Sopenharmony_ci .from_ptys_speed_duplex = mlxsw_sp2_from_ptys_speed_duplex, 17738c2ecf20Sopenharmony_ci .ptys_max_speed = mlxsw_sp2_ptys_max_speed, 17748c2ecf20Sopenharmony_ci .to_ptys_advert_link = mlxsw_sp2_to_ptys_advert_link, 17758c2ecf20Sopenharmony_ci .to_ptys_speed = mlxsw_sp2_to_ptys_speed, 17768c2ecf20Sopenharmony_ci .reg_ptys_eth_pack = mlxsw_sp2_reg_ptys_eth_pack, 17778c2ecf20Sopenharmony_ci .reg_ptys_eth_unpack = mlxsw_sp2_reg_ptys_eth_unpack, 17788c2ecf20Sopenharmony_ci .ptys_proto_cap_masked_get = mlxsw_sp2_ptys_proto_cap_masked_get, 17798c2ecf20Sopenharmony_ci}; 1780