12c81bfd5SHuy Nguyen /* 22c81bfd5SHuy Nguyen * Copyright (c) 2018, Mellanox Technologies. All rights reserved. 32c81bfd5SHuy Nguyen * 42c81bfd5SHuy Nguyen * This software is available to you under a choice of one of two 52c81bfd5SHuy Nguyen * licenses. You may choose to be licensed under the terms of the GNU 62c81bfd5SHuy Nguyen * General Public License (GPL) Version 2, available from the file 72c81bfd5SHuy Nguyen * COPYING in the main directory of this source tree, or the 82c81bfd5SHuy Nguyen * OpenIB.org BSD license below: 92c81bfd5SHuy Nguyen * 102c81bfd5SHuy Nguyen * Redistribution and use in source and binary forms, with or 112c81bfd5SHuy Nguyen * without modification, are permitted provided that the following 122c81bfd5SHuy Nguyen * conditions are met: 132c81bfd5SHuy Nguyen * 142c81bfd5SHuy Nguyen * - Redistributions of source code must retain the above 152c81bfd5SHuy Nguyen * copyright notice, this list of conditions and the following 162c81bfd5SHuy Nguyen * disclaimer. 172c81bfd5SHuy Nguyen * 182c81bfd5SHuy Nguyen * - Redistributions in binary form must reproduce the above 192c81bfd5SHuy Nguyen * copyright notice, this list of conditions and the following 202c81bfd5SHuy Nguyen * disclaimer in the documentation and/or other materials 212c81bfd5SHuy Nguyen * provided with the distribution. 222c81bfd5SHuy Nguyen * 232c81bfd5SHuy Nguyen * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 242c81bfd5SHuy Nguyen * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 252c81bfd5SHuy Nguyen * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 262c81bfd5SHuy Nguyen * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 272c81bfd5SHuy Nguyen * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 282c81bfd5SHuy Nguyen * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 292c81bfd5SHuy Nguyen * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 302c81bfd5SHuy Nguyen * SOFTWARE. 312c81bfd5SHuy Nguyen */ 322c81bfd5SHuy Nguyen 332c81bfd5SHuy Nguyen #include "port.h" 342c81bfd5SHuy Nguyen 352c81bfd5SHuy Nguyen /* speed in units of 1Mb */ 362c81bfd5SHuy Nguyen static const u32 mlx5e_link_speed[MLX5E_LINK_MODES_NUMBER] = { 372c81bfd5SHuy Nguyen [MLX5E_1000BASE_CX_SGMII] = 1000, 382c81bfd5SHuy Nguyen [MLX5E_1000BASE_KX] = 1000, 392c81bfd5SHuy Nguyen [MLX5E_10GBASE_CX4] = 10000, 402c81bfd5SHuy Nguyen [MLX5E_10GBASE_KX4] = 10000, 412c81bfd5SHuy Nguyen [MLX5E_10GBASE_KR] = 10000, 422c81bfd5SHuy Nguyen [MLX5E_20GBASE_KR2] = 20000, 432c81bfd5SHuy Nguyen [MLX5E_40GBASE_CR4] = 40000, 442c81bfd5SHuy Nguyen [MLX5E_40GBASE_KR4] = 40000, 452c81bfd5SHuy Nguyen [MLX5E_56GBASE_R4] = 56000, 462c81bfd5SHuy Nguyen [MLX5E_10GBASE_CR] = 10000, 472c81bfd5SHuy Nguyen [MLX5E_10GBASE_SR] = 10000, 482c81bfd5SHuy Nguyen [MLX5E_10GBASE_ER] = 10000, 492c81bfd5SHuy Nguyen [MLX5E_40GBASE_SR4] = 40000, 502c81bfd5SHuy Nguyen [MLX5E_40GBASE_LR4] = 40000, 512c81bfd5SHuy Nguyen [MLX5E_50GBASE_SR2] = 50000, 522c81bfd5SHuy Nguyen [MLX5E_100GBASE_CR4] = 100000, 532c81bfd5SHuy Nguyen [MLX5E_100GBASE_SR4] = 100000, 542c81bfd5SHuy Nguyen [MLX5E_100GBASE_KR4] = 100000, 552c81bfd5SHuy Nguyen [MLX5E_100GBASE_LR4] = 100000, 562c81bfd5SHuy Nguyen [MLX5E_100BASE_TX] = 100, 572c81bfd5SHuy Nguyen [MLX5E_1000BASE_T] = 1000, 582c81bfd5SHuy Nguyen [MLX5E_10GBASE_T] = 10000, 592c81bfd5SHuy Nguyen [MLX5E_25GBASE_CR] = 25000, 602c81bfd5SHuy Nguyen [MLX5E_25GBASE_KR] = 25000, 612c81bfd5SHuy Nguyen [MLX5E_25GBASE_SR] = 25000, 622c81bfd5SHuy Nguyen [MLX5E_50GBASE_CR2] = 50000, 632c81bfd5SHuy Nguyen [MLX5E_50GBASE_KR2] = 50000, 642c81bfd5SHuy Nguyen }; 652c81bfd5SHuy Nguyen 662c81bfd5SHuy Nguyen u32 mlx5e_port_ptys2speed(u32 eth_proto_oper) 672c81bfd5SHuy Nguyen { 682c81bfd5SHuy Nguyen unsigned long temp = eth_proto_oper; 692c81bfd5SHuy Nguyen u32 speed = 0; 702c81bfd5SHuy Nguyen int i; 712c81bfd5SHuy Nguyen 722c81bfd5SHuy Nguyen i = find_first_bit(&temp, MLX5E_LINK_MODES_NUMBER); 732c81bfd5SHuy Nguyen if (i < MLX5E_LINK_MODES_NUMBER) 742c81bfd5SHuy Nguyen speed = mlx5e_link_speed[i]; 752c81bfd5SHuy Nguyen 762c81bfd5SHuy Nguyen return speed; 772c81bfd5SHuy Nguyen } 782c81bfd5SHuy Nguyen 792c81bfd5SHuy Nguyen int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed) 802c81bfd5SHuy Nguyen { 812c81bfd5SHuy Nguyen u32 out[MLX5_ST_SZ_DW(ptys_reg)] = {}; 822c81bfd5SHuy Nguyen u32 eth_proto_oper; 832c81bfd5SHuy Nguyen int err; 842c81bfd5SHuy Nguyen 852c81bfd5SHuy Nguyen err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN, 1); 862c81bfd5SHuy Nguyen if (err) 872c81bfd5SHuy Nguyen return err; 882c81bfd5SHuy Nguyen 892c81bfd5SHuy Nguyen eth_proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper); 902c81bfd5SHuy Nguyen *speed = mlx5e_port_ptys2speed(eth_proto_oper); 912c81bfd5SHuy Nguyen if (!(*speed)) { 922c81bfd5SHuy Nguyen mlx5_core_warn(mdev, "cannot get port speed\n"); 932c81bfd5SHuy Nguyen err = -EINVAL; 942c81bfd5SHuy Nguyen } 952c81bfd5SHuy Nguyen 962c81bfd5SHuy Nguyen return err; 972c81bfd5SHuy Nguyen } 982c81bfd5SHuy Nguyen 992c81bfd5SHuy Nguyen int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed) 1002c81bfd5SHuy Nguyen { 1012c81bfd5SHuy Nguyen u32 max_speed = 0; 1022c81bfd5SHuy Nguyen u32 proto_cap; 1032c81bfd5SHuy Nguyen int err; 1042c81bfd5SHuy Nguyen int i; 1052c81bfd5SHuy Nguyen 1062c81bfd5SHuy Nguyen err = mlx5_query_port_proto_cap(mdev, &proto_cap, MLX5_PTYS_EN); 1072c81bfd5SHuy Nguyen if (err) 1082c81bfd5SHuy Nguyen return err; 1092c81bfd5SHuy Nguyen 1102c81bfd5SHuy Nguyen for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) 1112c81bfd5SHuy Nguyen if (proto_cap & MLX5E_PROT_MASK(i)) 1122c81bfd5SHuy Nguyen max_speed = max(max_speed, mlx5e_link_speed[i]); 1132c81bfd5SHuy Nguyen 1142c81bfd5SHuy Nguyen *speed = max_speed; 1152c81bfd5SHuy Nguyen return 0; 1162c81bfd5SHuy Nguyen } 1172c81bfd5SHuy Nguyen 1182c81bfd5SHuy Nguyen u32 mlx5e_port_speed2linkmodes(u32 speed) 1192c81bfd5SHuy Nguyen { 1202c81bfd5SHuy Nguyen u32 link_modes = 0; 1212c81bfd5SHuy Nguyen int i; 1222c81bfd5SHuy Nguyen 1232c81bfd5SHuy Nguyen for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) { 1242c81bfd5SHuy Nguyen if (mlx5e_link_speed[i] == speed) 1252c81bfd5SHuy Nguyen link_modes |= MLX5E_PROT_MASK(i); 1262c81bfd5SHuy Nguyen } 1272c81bfd5SHuy Nguyen 1282c81bfd5SHuy Nguyen return link_modes; 1292c81bfd5SHuy Nguyen } 130