iPXE
mlx_link_speed.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2015 Mellanox Technologies Ltd.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017  * 02110-1301, USA.
00018  */
00019 
00020 FILE_LICENCE ( GPL2_OR_LATER );
00021 
00022 #include "../../mlx_lib/mlx_link_speed/mlx_link_speed.h"
00023 #include "../../include/public/mlx_memory.h"
00024 #include "../../include/public/mlx_bail.h"
00025 
00026 mlx_status
00027 mlx_set_link_speed(
00028                 IN mlx_utils *utils,
00029                 IN mlx_uint8 port_num,
00030                 IN LINK_SPEED_TYPE type,
00031                 IN LINK_SPEED speed
00032                 )
00033 {
00034         mlx_status status = MLX_SUCCESS;
00035         struct mlx_link_speed link_speed;
00036         mlx_uint32 reg_status;
00037 
00038         if (utils == NULL) {
00039                 status = MLX_INVALID_PARAMETER;
00040                 goto bad_param;
00041         }
00042 
00043         mlx_memory_set(utils, &link_speed, 0, sizeof(link_speed));
00044 
00045         link_speed.loacl_port = port_num;
00046         link_speed.proto_mask = 1 << type;
00047 
00048         status = mlx_reg_access(utils, REG_ID_PTYS, REG_ACCESS_READ, &link_speed,
00049                         sizeof(link_speed), &reg_status);
00050 
00051         MLX_CHECK_STATUS(utils, status, reg_err, "mlx_reg_access failed ");
00052         if (reg_status != 0) {
00053                 MLX_DEBUG_ERROR(utils,"mlx_reg_access failed with status = %d\n", reg_status);
00054                 status = MLX_FAILED;
00055                 goto reg_err;
00056         }
00057         switch (speed) {
00058         case LINK_SPEED_1GB:
00059                 link_speed.eth_proto_admin = link_speed.eth_proto_capability & LINK_SPEED_1GB_MASK;
00060                 break;
00061         case LINK_SPEED_10GB:
00062                 link_speed.eth_proto_admin = link_speed.eth_proto_capability & LINK_SPEED_10GB_MASK;
00063                 break;
00064         case LINK_SPEED_40GB:
00065                 link_speed.eth_proto_admin = link_speed.eth_proto_capability & LINK_SPEED_40GB_MASK;
00066                 break;
00067         case LINK_SPEED_100GB:
00068                 link_speed.eth_proto_admin = link_speed.eth_proto_capability & LINK_SPEED_100GB_MASK;
00069                 break;
00070         case LINK_SPEED_SDR:
00071                 link_speed.ib_proto_admin = link_speed.ib_proto_capability & LINK_SPEED_SDR_MASK;
00072                 break;
00073         case LINK_SPEED_DEFAULT:
00074                 if (type == LINK_SPEED_ETH) {
00075                         link_speed.eth_proto_admin = link_speed.eth_proto_capability;
00076                 } else {
00077                         link_speed.ib_proto_admin = link_speed.ib_proto_capability;
00078                 }
00079                 break;
00080         }
00081         status = mlx_reg_access(utils, REG_ID_PTYS, REG_ACCESS_WRITE, &link_speed,
00082                                 sizeof(link_speed), &reg_status);
00083         MLX_CHECK_STATUS(utils, status, reg_err, "mlx_reg_access failed ");
00084         if (reg_status != 0) {
00085                 MLX_DEBUG_ERROR(utils,"mlx_reg_access failed with status = %d\n", reg_status);
00086                 status = MLX_FAILED;
00087                 goto reg_err;
00088         }
00089 reg_err:
00090 bad_param:
00091         return status;
00092 }
00093 
00094 mlx_status
00095 mlx_get_max_speed(
00096                 IN mlx_utils *utils,
00097                 IN mlx_uint8 port_num,
00098                 IN LINK_SPEED_TYPE type,
00099                 OUT mlx_uint64 *speed
00100                 )
00101 {
00102         mlx_status status = MLX_SUCCESS;
00103         struct mlx_link_speed link_speed;
00104         mlx_uint32 reg_status;
00105         mlx_uint64 speed_giga = 0;
00106         mlx_uint8  lanes_number = 1;
00107 
00108         *speed = 0;
00109         if (utils == NULL) {
00110                 status = MLX_INVALID_PARAMETER;
00111                 goto bad_param;
00112         }
00113 
00114         mlx_memory_set(utils, &link_speed, 0, sizeof(link_speed));
00115 
00116         link_speed.loacl_port = port_num;
00117         link_speed.proto_mask = 1 << type;
00118 
00119         status = mlx_reg_access(utils, REG_ID_PTYS, REG_ACCESS_READ, &link_speed,
00120                         sizeof(link_speed), &reg_status);
00121         MLX_CHECK_STATUS(utils, status, reg_err, "mlx_reg_access failed ");
00122         if (reg_status != 0) {
00123                 MLX_DEBUG_ERROR(utils,"mlx_reg_access failed with status = %d\n", reg_status);
00124                 status = MLX_FAILED;
00125                 goto reg_err;
00126         }
00127 
00128         if ( type == LINK_SPEED_ETH ) {
00129                 if ( link_speed.eth_proto_capability & LINK_SPEED_100GB_MASK ) {
00130                         speed_giga = 100;
00131                 } else if ( link_speed.eth_proto_capability & LINK_SPEED_56GB_MASK ) {
00132                         speed_giga = 56;
00133                 } else if ( link_speed.eth_proto_capability & LINK_SPEED_50GB_MASK ) {
00134                         speed_giga = 50;
00135                 } else if ( link_speed.eth_proto_capability & LINK_SPEED_40GB_MASK ) {
00136                         speed_giga = 40;
00137                 } else if (link_speed.eth_proto_capability & LINK_SPEED_25GB_MASK) {
00138                         speed_giga = 25;
00139                 } else if ( link_speed.eth_proto_capability & LINK_SPEED_20GB_MASK ) {
00140                         speed_giga = 20;
00141                 } else if ( link_speed.eth_proto_capability & LINK_SPEED_10GB_MASK) {
00142                         speed_giga = 10;
00143                 } else if ( link_speed.eth_proto_capability & LINK_SPEED_1GB_MASK ) {
00144                         speed_giga = 1;
00145                 }
00146         } else {
00147                 if ( link_speed.ib_proto_capability & LINK_SPEED_EDR_MASK ) {
00148                         speed_giga = 25;
00149                 } else if ( link_speed.ib_proto_capability & LINK_SPEED_EDR20_MASK ) {
00150                         speed_giga = 20;
00151                 } else if ( link_speed.ib_proto_capability & LINK_SPEED_FDR_MASK ) {
00152                         speed_giga = 14;
00153                 } else if ( link_speed.ib_proto_capability & LINK_SPEED_QDR_MASK ) {
00154                         speed_giga = 10;
00155                 } else if ( link_speed.ib_proto_capability & LINK_SPEED_DDR_MASK ) {
00156                         speed_giga = 5;
00157                 } else if ( link_speed.ib_proto_capability & LINK_SPEED_SDR_MASK ) {
00158                         speed_giga = 2.5;
00159                 }
00160                 if ( link_speed.ib_link_width_capability & LINK_SPEED_WITDH_12_MASK ) {
00161                         lanes_number = 12;
00162                 } else if ( link_speed.ib_link_width_capability & LINK_SPEED_WITDH_8_MASK ) {
00163                         lanes_number = 8;
00164                 } else if (link_speed.ib_link_width_capability & LINK_SPEED_WITDH_4_MASK ) {
00165                         lanes_number = 4;
00166                 } else if (link_speed.ib_link_width_capability & LINK_SPEED_WITDH_2_MASK ) {
00167                         lanes_number = 2;
00168                 } else if (link_speed.ib_link_width_capability & LINK_SPEED_WITDH_1_MASK ) {
00169                         lanes_number = 1;
00170                 }
00171                 speed_giga = speed_giga * lanes_number;
00172         }
00173         // Return data in bits
00174         *speed = speed_giga * GIGA_TO_BIT;
00175 reg_err:
00176 bad_param:
00177         return status;
00178 }
00179 
00180