From aa40a81ee117ed88be5609a875e8a127b4692510 Mon Sep 17 00:00:00 2001 From: jecavil Date: Tue, 17 Jul 2018 18:15:11 +0200 Subject: [PATCH] Link speed, espeed and width change support Support for using 'ibportstate speed/espeed/width' command together with IBSim. After a port change with the mentioned command and reception of trap 144, a heavy sweep will set the enabled speed and width to every port. To avoid sending a trap 144 every time a port is set, the switch sends a trap only when the speed or width has been effectively changed. Active speed, espeed and width port is automatically adjusted when rewriting the enabled speed and enabled width port, respectively. Here it's an example of the new functiolality (suppose that $IBSIM is the path of your ibsim folder): Run in terminal 1: $ ibsim -s $IBSIM/net-examples/net.2sw2path4hca Run in terminal 2: $ export LD_PRELOAD=$IBSIM/umad2sim/libumad2sim.so $ opensm Run in terminal 3: $ export LD_PRELOAD=$IBSIM/umad2sim/libumad2sim.so $ ibportstate -G 0x200000 3 speed 3 When changing the LinkSpeedEnabled in terminal 3, you will see the next change: Initial Switch PortInfo: LinkSpeedEnabled:................2.5 Gbps After PortInfo set: LinkSpeedEnabled:................2.5 Gbps or 5.0 Gbps $ ibportstate -G 0x200000 3 width 3 Initial Switch PortInfo: LinkWidthEnabled:................4X After PortInfo set: LinkWidthEnabled:................1X or 4X $ ibportstate -G 0x200000 3 espeed 3 Initial Switch PortInfo: LinkSpeedExtEnabled:.............0 After PortInfo set: LinkSpeedExtEnabled:.............14.0625 Gbps or 25.78125 Gbps NOTE: force_link_speed, force_link_speed_ext and force_link_width must be 0. Signed-off-by: jecavil --- ibsim/sim.h | 67 ++++++++++----- ibsim/sim_mad.c | 215 +++++++++++++++++++++++++++++++++++++++++++++++- ibsim/sim_net.c | 10 +-- 3 files changed, 263 insertions(+), 29 deletions(-) diff --git a/ibsim/sim.h b/ibsim/sim.h index c57987d..9750664 100644 --- a/ibsim/sim.h +++ b/ibsim/sim.h @@ -48,27 +48,52 @@ #define LASTBLOCK32 (MAXMCASTCAP/32-1) #define MCASTMASKSIZE 16 // linkwidth == 4X - must be one width only 1,2,8 or 16 -#define LINKWIDTH_1x 1 -#define LINKWIDTH_4x 2 -#define LINKWIDTH_8x 4 -#define LINKWIDTH_12x 8 -#define LINKWIDTH_2x 16 -#define LINKWIDTH_1x_4x 3 -#define LINKWIDTH_1x_4x_12x 11 -#define LINKWIDTH_1x_2x_4x_12x 27 - -#define LINKSPEED_SDR 1 -#define LINKSPEED_DDR 2 -#define LINKSPEED_QDR 4 -#define LINKSPEED_SDR_DDR 3 - -#define LINKSPEEDEXT_NONE 0 -#define LINKSPEEDEXT_FDR 1 -#define LINKSPEEDEXT_EDR 2 -#define LINKSPEEDEXT_FDR_EDR 3 -#define LINKSPEEDEXT_HDR 4 -#define LINKSPEEDEXT_HDR_FDR 5 -#define LINKSPEEDEXT_HDR_EDR 6 +#define LINKWIDTH_1x 1 +#define LINKWIDTH_4x 2 +#define LINKWIDTH_1x_4x 3 +#define LINKWIDTH_8x 4 +#define LINKWIDTH_1x_8x 5 +#define LINKWIDTH_4x_8x 6 +#define LINKWIDTH_1x_4x_8x 7 +#define LINKWIDTH_12x 8 +#define LINKWIDTH_1x_12x 9 +#define LINKWIDTH_4x_12x 10 +#define LINKWIDTH_1x_4x_12x 11 +#define LINKWIDTH_8x_12x 12 +#define LINKWIDTH_1x_8x_12x 13 +#define LINKWIDTH_4x_8x_12x 14 +#define LINKWIDTH_1x_4x_8x_12x 15 +#define LINKWIDTH_2x 16 +#define LINKWIDTH_1x_2x 17 +#define LINKWIDTH_2x_4x 18 +#define LINKWIDTH_1x_2x_4x 19 +#define LINKWIDTH_2x_8x 20 +#define LINKWIDTH_1x_2x_8x 21 +#define LINKWIDTH_2x_4x_8x 22 +#define LINKWIDTH_1x_2x_4x_8x 23 +#define LINKWIDTH_2x_12x 24 +#define LINKWIDTH_1x_2x_12x 25 +#define LINKWIDTH_2x_4x_12x 26 +#define LINKWIDTH_1x_2x_4x_12x 27 +#define LINKWIDTH_2x_8x_12x 28 +#define LINKWIDTH_1x_2x_8x_12x 29 +#define LINKWIDTH_2x_4x_8x_12x 30 +#define LINKWIDTH_1x_2x_4x_8x_12x 31 + +#define LINKSPEED_SDR 1 +#define LINKSPEED_DDR 2 +#define LINKSPEED_SDR_DDR 3 +#define LINKSPEED_QDR 4 +#define LINKSPEED_SDR_QDR 5 +#define LINKSPEED_SDR_DDR_QDR 7 + +#define LINKSPEEDEXT_NONE 0 +#define LINKSPEEDEXT_FDR 1 +#define LINKSPEEDEXT_EDR 2 +#define LINKSPEEDEXT_FDR_EDR 3 +#define LINKSPEEDEXT_HDR 4 +#define LINKSPEEDEXT_HDR_FDR 5 +#define LINKSPEEDEXT_HDR_EDR 6 #define LINKSPEEDEXT_HDR_EDR_FDR 7 #define MLNXLINKSPEED_NONE 0 diff --git a/ibsim/sim_mad.c b/ibsim/sim_mad.c index f4e3969..0dadb8c 100644 --- a/ibsim/sim_mad.c +++ b/ibsim/sim_mad.c @@ -483,8 +483,9 @@ static int do_portinfo(Port * port, unsigned op, uint32_t portnum, uint8_t * data) { Node *node = port->node; - Port *p, *rp; + Port *p, *rp = NULL; int r, newlid; + int speed, espeed, width; portnum &= 0x7fffffff; if (portnum > node->numports) @@ -540,7 +541,7 @@ do_portinfo(Port * port, unsigned op, uint32_t portnum, uint8_t * data) return ERR_BAD_PARAM; /* trying to change the state of DOWN port */ if (p->state == 4) { - if (p->lid > 0 && p->lid < maxlinearcap + if (node->type != SWITCH_NODE && p->lid > 0 && p->lid < maxlinearcap && lids[p->lid] != p && lids[p->lid]) IBWARN ("Port %s:%d overwrite lid table entry for lid %u (was %s:%d)", @@ -553,8 +554,218 @@ do_portinfo(Port * port, unsigned op, uint32_t portnum, uint8_t * data) if (val > mad_get_field(data, 0, IB_PORT_VL_CAP_F)) return ERR_BAD_PARAM; p->op_vls = val; + + if(!rp && p->remotenode) + rp = node_get_port(p->remotenode, p->remoteport); + else + goto update_port; + + speed = mad_get_field(data, 0, IB_PORT_LINK_SPEED_ENABLED_F); + switch(speed) { + case LINKSPEED_SDR: + p->linkspeed = LINKSPEED_SDR; + rp->linkspeed = LINKSPEED_SDR; + break; + case LINKSPEED_SDR_DDR: + p->linkspeed = LINKSPEED_DDR; + rp->linkspeed = LINKSPEED_DDR; + break; + case LINKSPEED_SDR_QDR: + p->linkspeed = LINKSPEED_QDR; + rp->linkspeed = LINKSPEED_QDR; + break; + case LINKSPEED_SDR_DDR_QDR: + p->linkspeed = LINKSPEED_QDR; + rp->linkspeed = LINKSPEED_QDR; + break; + default: + speed = 0; + } + + if(speed && speed != p->linkspeedena) + p->linkspeedena = speed; + else + speed = 0; + + espeed = mad_get_field(data, 0, IB_PORT_LINK_SPEED_EXT_ENABLED_F); + switch(espeed) { + case LINKSPEEDEXT_FDR: + p->linkspeedext = LINKSPEEDEXT_FDR; + rp->linkspeedext = LINKSPEEDEXT_FDR; + break; + case LINKSPEEDEXT_EDR: + p->linkspeedext = LINKSPEEDEXT_EDR; + rp->linkspeedext = LINKSPEEDEXT_EDR; + break; + case LINKSPEEDEXT_FDR_EDR: + p->linkspeedext = LINKSPEEDEXT_EDR; + rp->linkspeedext = LINKSPEEDEXT_EDR; + break; + case LINKSPEEDEXT_HDR: + p->linkspeedext = LINKSPEEDEXT_HDR; + rp->linkspeedext = LINKSPEEDEXT_HDR; + break; + case LINKSPEEDEXT_HDR_FDR: + p->linkspeedext = LINKSPEEDEXT_HDR; + rp->linkspeedext = LINKSPEEDEXT_HDR; + break; + case LINKSPEEDEXT_HDR_EDR: + p->linkspeedext = LINKSPEEDEXT_HDR; + rp->linkspeedext = LINKSPEEDEXT_HDR; + break; + case LINKSPEEDEXT_HDR_EDR_FDR: + p->linkspeedext = LINKSPEEDEXT_HDR; + rp->linkspeedext = LINKSPEEDEXT_HDR; + break; + default: + espeed = 0; + } + + if(espeed && espeed != p->linkspeedextena) + p->linkspeedextena = espeed; + else + espeed = 0; + + width = mad_get_field(data, 0, IB_PORT_LINK_WIDTH_ENABLED_F); + switch(width) { + case LINKWIDTH_1x: + p->linkwidth = LINKWIDTH_1x; + rp->linkwidth = LINKWIDTH_1x; + break; + case LINKWIDTH_4x: + p->linkwidth = LINKWIDTH_4x; + rp->linkwidth = LINKWIDTH_4x; + break; + case LINKWIDTH_1x_4x: + p->linkwidth = LINKWIDTH_4x; + rp->linkwidth = LINKWIDTH_4x; + break; + case LINKWIDTH_8x: + p->linkwidth = LINKWIDTH_8x; + rp->linkwidth = LINKWIDTH_8x; + break; + case LINKWIDTH_1x_8x: + p->linkwidth = LINKWIDTH_8x; + rp->linkwidth = LINKWIDTH_8x; + break; + case LINKWIDTH_4x_8x: + p->linkwidth = LINKWIDTH_8x; + rp->linkwidth = LINKWIDTH_8x; + break; + case LINKWIDTH_1x_4x_8x: + p->linkwidth = LINKWIDTH_8x; + rp->linkwidth = LINKWIDTH_8x; + break; + case LINKWIDTH_12x: + p->linkwidth = LINKWIDTH_12x; + rp->linkwidth = LINKWIDTH_12x; + break; + case LINKWIDTH_1x_12x: + p->linkwidth = LINKWIDTH_12x; + rp->linkwidth = LINKWIDTH_12x; + break; + case LINKWIDTH_4x_12x: + p->linkwidth = LINKWIDTH_12x; + rp->linkwidth = LINKWIDTH_12x; + break; + case LINKWIDTH_1x_4x_12x: + p->linkwidth = LINKWIDTH_12x; + rp->linkwidth = LINKWIDTH_12x; + break; + case LINKWIDTH_8x_12x: + p->linkwidth = LINKWIDTH_12x; + rp->linkwidth = LINKWIDTH_12x; + break; + case LINKWIDTH_1x_8x_12x: + p->linkwidth = LINKWIDTH_12x; + rp->linkwidth = LINKWIDTH_12x; + break; + case LINKWIDTH_4x_8x_12x: + p->linkwidth = LINKWIDTH_12x; + rp->linkwidth = LINKWIDTH_12x; + break; + case LINKWIDTH_1x_4x_8x_12x: + p->linkwidth = LINKWIDTH_12x; + rp->linkwidth = LINKWIDTH_12x; + break; + case LINKWIDTH_2x: + p->linkwidth = LINKWIDTH_2x; + rp->linkwidth = LINKWIDTH_2x; + break; + case LINKWIDTH_1x_2x: + p->linkwidth = LINKWIDTH_2x; + rp->linkwidth = LINKWIDTH_2x; + break; + case LINKWIDTH_2x_4x: + p->linkwidth = LINKWIDTH_4x; + rp->linkwidth = LINKWIDTH_4x; + break; + case LINKWIDTH_1x_2x_4x: + p->linkwidth = LINKWIDTH_4x; + rp->linkwidth = LINKWIDTH_4x; + break; + case LINKWIDTH_2x_8x: + p->linkwidth = LINKWIDTH_8x; + rp->linkwidth = LINKWIDTH_8x; + break; + case LINKWIDTH_1x_2x_8x: + p->linkwidth = LINKWIDTH_8x; + rp->linkwidth = LINKWIDTH_8x; + break; + case LINKWIDTH_2x_4x_8x: + p->linkwidth = LINKWIDTH_8x; + rp->linkwidth = LINKWIDTH_8x; + break; + case LINKWIDTH_1x_2x_4x_8x: + p->linkwidth = LINKWIDTH_8x; + rp->linkwidth = LINKWIDTH_8x; + break; + case LINKWIDTH_2x_12x: + p->linkwidth = LINKWIDTH_12x; + rp->linkwidth = LINKWIDTH_12x; + break; + case LINKWIDTH_1x_2x_12x: + p->linkwidth = LINKWIDTH_12x; + rp->linkwidth = LINKWIDTH_12x; + break; + case LINKWIDTH_2x_4x_12x: + p->linkwidth = LINKWIDTH_12x; + rp->linkwidth = LINKWIDTH_12x; + break; + case LINKWIDTH_1x_2x_4x_12x: + p->linkwidth = LINKWIDTH_12x; + rp->linkwidth = LINKWIDTH_12x; + break; + case LINKWIDTH_2x_8x_12x: + p->linkwidth = LINKWIDTH_12x; + rp->linkwidth = LINKWIDTH_12x; + break; + case LINKWIDTH_1x_2x_8x_12x: + p->linkwidth = LINKWIDTH_12x; + rp->linkwidth = LINKWIDTH_12x; + break; + case LINKWIDTH_2x_4x_8x_12x: + p->linkwidth = LINKWIDTH_12x; + rp->linkwidth = LINKWIDTH_12x; + break; + case LINKWIDTH_1x_2x_4x_8x_12x: + p->linkwidth = LINKWIDTH_12x; + rp->linkwidth = LINKWIDTH_12x; + break; + default: + width = 0; + } + + if(width && width != p->linkwidthena) + p->linkwidthena = width; + else + width = 0; + + if(speed || espeed || width) + send_trap(port, TRAP_144); } +update_port: update_portinfo(p); memcpy(data, p->portinfo, IB_SMP_DATA_SIZE); mad_set_field(data, 0, IB_PORT_LOCAL_PORT_F, port->portnum); diff --git a/ibsim/sim_net.c b/ibsim/sim_net.c index 457908d..8695815 100644 --- a/ibsim/sim_net.c +++ b/ibsim/sim_net.c @@ -1275,22 +1275,20 @@ void update_portinfo(Port * p) mad_set_field(pi, 0, IB_PORT_SMLID_F, p->smlid); mad_set_field(pi, 0, IB_PORT_OPER_VLS_F, p->op_vls); mad_set_field(pi, 0, IB_PORT_LINK_WIDTH_ENABLED_F, p->linkwidthena); - mad_set_field(pi, 0, IB_PORT_LINK_WIDTH_SUPPORTED_F, - LINKWIDTH_1x_2x_4x_12x); + mad_set_field(pi, 0, IB_PORT_LINK_WIDTH_SUPPORTED_F, LINKWIDTH_1x_2x_4x_8x_12x); mad_set_field(pi, 0, IB_PORT_LINK_WIDTH_ACTIVE_F, p->linkwidth); mad_set_field(pi, 0, IB_PORT_LINK_SPEED_ENABLED_F, p->linkspeedena); - mad_set_field(pi, 0, IB_PORT_LINK_SPEED_SUPPORTED_F, p->linkspeedena); + mad_set_field(pi, 0, IB_PORT_LINK_SPEED_SUPPORTED_F, LINKSPEED_SDR_DDR_QDR); + mad_set_field(pi, 0, IB_PORT_LINK_SPEED_ACTIVE_F, p->linkspeed); mad_set_field(pi, 0, IB_PORT_LMC_F, p->lmc); mad_set_field(pi, 0, IB_PORT_HOQ_LIFE_F, p->hoqlife); mad_set_field(pi, 0, IB_PORT_PHYS_STATE_F, p->physstate); mad_set_field(pi, 0, IB_PORT_STATE_F, p->state); - mad_set_field(pi, 0, IB_PORT_LINK_SPEED_ACTIVE_F, p->linkspeed); - if (p->linkspeedext) { mad_set_field(pi, 0, IB_PORT_LINK_SPEED_EXT_ENABLED_F, p->linkspeedextena); - mad_set_field(pi, 0, IB_PORT_LINK_SPEED_EXT_SUPPORTED_F, p->linkspeedextena); + mad_set_field(pi, 0, IB_PORT_LINK_SPEED_EXT_SUPPORTED_F, LINKSPEEDEXT_HDR_EDR_FDR); mad_set_field(pi, 0, IB_PORT_LINK_SPEED_EXT_ACTIVE_F, p->linkspeedext); } else { mad_set_field(pi, 0, IB_PORT_LINK_SPEED_EXT_ENABLED_F, 0);