On Sun, Aug 21, 2011 at 11:36 PM, Ira Weiny <[email protected]> wrote:
> On Fri, 19 Aug 2011 09:54:01 -0700
> Hal Rosenstock <[email protected]> wrote:
>
>>
>> Signed-off-by: Hal Rosenstock <[email protected]>
>> ---
>> libibnetdisc/include/infiniband/ibnetdisc.h | 3 +-
>> libibnetdisc/src/ibnetdisc.c | 148
>> ++++++++++++++++++++++++++-
>> libibnetdisc/src/query_smp.c | 10 ++
>> src/ibnetdiscover.c | 21 +++-
>> 4 files changed, 173 insertions(+), 9 deletions(-)
>>
>> diff --git a/libibnetdisc/include/infiniband/ibnetdisc.h
>> b/libibnetdisc/include/infiniband/ibnetdisc.h
>> index 300094e..59c5606 100644
>> --- a/libibnetdisc/include/infiniband/ibnetdisc.h
>> +++ b/libibnetdisc/include/infiniband/ibnetdisc.h
>> @@ -1,7 +1,7 @@
>> /*
>> * Copyright (c) 2009 Voltaire, Inc. All rights reserved.
>> * Copyright (c) 2008 Lawrence Livermore National Lab. All rights reserved.
>> - * Copyright (c) 2010 Mellanox Technologies LTD. All rights reserved.
>> + * Copyright (c) 2010-2011 Mellanox Technologies LTD. All rights reserved.
>> *
>> * This software is available to you under a choice of one of two
>> * licenses. You may choose to be licensed under the terms of the GNU
>> @@ -109,6 +109,7 @@ typedef struct ibnd_port {
>> uint8_t lmc;
>> /* use libibmad decoder functions for info */
>> uint8_t info[IB_SMP_DATA_SIZE];
>> + uint8_t ext_info[IB_SMP_DATA_SIZE];
>>
>> /* internal use only */
>> struct ibnd_port *htnext;
>> diff --git a/libibnetdisc/src/ibnetdisc.c b/libibnetdisc/src/ibnetdisc.c
>> index e9dbaf9..60bd28d 100644
>> --- a/libibnetdisc/src/ibnetdisc.c
>> +++ b/libibnetdisc/src/ibnetdisc.c
>> @@ -170,12 +170,14 @@ static void debug_port(ib_portid_t * portid,
>> ibnd_port_t * port)
>> {
>> char width[64], speed[64];
>> int iwidth;
>> - int ispeed, espeed;
>> + int ispeed, fdr10, espeed;
>> uint8_t *info;
>> uint32_t cap_mask;
>>
>> iwidth = mad_get_field(port->info, 0, IB_PORT_LINK_WIDTH_ACTIVE_F);
>> ispeed = mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_ACTIVE_F);
>> + fdr10 = mad_get_field(port->ext_info, 0,
>> + IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F);
>>
>> if (port->node->type == IB_NODE_SWITCH)
>> info = (uint8_t *)&port->node->ports[0]->info;
>> @@ -187,15 +189,132 @@ static void debug_port(ib_portid_t * portid,
>> ibnd_port_t * port)
>> else
>> espeed = 0;
>> IBND_DEBUG
>> - ("portid %s portnum %d: base lid %d state %d physstate %d %s %s
>> %s\n",
>> + ("portid %s portnum %d: base lid %d state %d physstate %d %s %s
>> %s %s\n",
>> portid2str(portid), port->portnum, port->base_lid,
>> mad_get_field(port->info, 0, IB_PORT_STATE_F),
>> mad_get_field(port->info, 0, IB_PORT_PHYS_STATE_F),
>> mad_dump_val(IB_PORT_LINK_WIDTH_ACTIVE_F, width, 64, &iwidth),
>> mad_dump_val(IB_PORT_LINK_SPEED_ACTIVE_F, speed, 64, &ispeed),
>> + (fdr10 & FDR10) ? "FDR10" : "",
>> mad_dump_val(IB_PORT_LINK_SPEED_EXT_ACTIVE_F, speed, 64,
>> &espeed));
>
> FDR10 is not defined? I seem to recall a thread discussing the value (0x1)
> and you adding the #define in libibmad but I don't see it now. :-/
FDR10 is defined in ib_types.h so these patches are all dependent on:
[PATCH] opensm: Add FDR10 support
-- Hal
>
> Ira
>
>> }
>>
>> +static int is_mlnx_ext_port_info_supported(ibnd_port_t * port)
>> +{
>> + uint16_t devid = mad_get_field(port->node->info, 0, IB_NODE_DEVID_F);
>> +
>> + if (devid == 0xc738)
>> + return 1;
>> + if (devid >= 0x1003 && devid <= 0x1010)
>> + return 1;
>> + return 0;
>> +}
>> +
>> +int mlnx_ext_port_info_err(smp_engine_t * engine, ibnd_smp_t * smp,
>> + uint8_t * mad, void *cb_data)
>> +{
>> + ibnd_fabric_t *fabric = ((ibnd_scan_t *) engine->user_data)->fabric;
>> + ibnd_node_t *node = cb_data;
>> + ibnd_port_t *port;
>> + uint8_t port_num, local_port;
>> +
>> + port_num = (uint8_t) mad_get_field(mad, 0, IB_MAD_ATTRMOD_F);
>> + port = node->ports[port_num];
>> + if (!port) {
>> + IBND_ERROR("Failed to find 0x%" PRIx64 " port %u\n",
>> + node->guid, port_num);
>> + return -1;
>> + }
>> +
>> + local_port = (uint8_t) mad_get_field(port->info, 0,
>> IB_PORT_LOCAL_PORT_F);
>> + debug_port(&smp->path, port);
>> +
>> + if (port_num && mad_get_field(port->info, 0, IB_PORT_PHYS_STATE_F)
>> + == IB_PORT_PHYS_STATE_LINKUP
>> + && ((node->type == IB_NODE_SWITCH && port_num != local_port) ||
>> + (node == fabric->from_node && port_num ==
>> fabric->from_portnum))) {
>> + int rc = 0;
>> + ib_portid_t path = smp->path;
>> +
>> + if (node->type != IB_NODE_SWITCH &&
>> + node == fabric->from_node &&
>> + path.drpath.cnt > 1)
>> + rc = retract_dpath(engine, &path);
>> + else {
>> + /* we can't proceed through an HCA with DR */
>> + if (path.lid == 0 || node->type == IB_NODE_SWITCH)
>> + rc = extend_dpath(engine, &path, port_num);
>> + }
>> +
>> + if (rc > 0) {
>> + struct ni_cbdata * cbdata = malloc(sizeof(*cbdata));
>> + cbdata->node = node;
>> + cbdata->port_num = port_num;
>> + query_node_info(engine, &path, cbdata);
>> + }
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int recv_mlnx_ext_port_info(smp_engine_t * engine, ibnd_smp_t * smp,
>> + uint8_t * mad, void *cb_data)
>> +{
>> + ibnd_fabric_t *fabric = ((ibnd_scan_t *) engine->user_data)->fabric;
>> + ibnd_node_t *node = cb_data;
>> + ibnd_port_t *port;
>> + uint8_t *ext_port_info = mad + IB_SMP_DATA_OFFS;
>> + uint8_t port_num, local_port;
>> +
>> + port_num = (uint8_t) mad_get_field(mad, 0, IB_MAD_ATTRMOD_F);
>> + port = node->ports[port_num];
>> + if (!port) {
>> + IBND_ERROR("Failed to find 0x%" PRIx64 " port %u\n",
>> + node->guid, port_num);
>> + return -1;
>> + }
>> +
>> + memcpy(port->ext_info, ext_port_info, sizeof(port->ext_info));
>> + local_port = (uint8_t) mad_get_field(port->info, 0,
>> IB_PORT_LOCAL_PORT_F);
>> + debug_port(&smp->path, port);
>> +
>> + if (port_num && mad_get_field(port->info, 0, IB_PORT_PHYS_STATE_F)
>> + == IB_PORT_PHYS_STATE_LINKUP
>> + && ((node->type == IB_NODE_SWITCH && port_num != local_port) ||
>> + (node == fabric->from_node && port_num ==
>> fabric->from_portnum))) {
>> + int rc = 0;
>> + ib_portid_t path = smp->path;
>> +
>> + if (node->type != IB_NODE_SWITCH &&
>> + node == fabric->from_node &&
>> + path.drpath.cnt > 1)
>> + rc = retract_dpath(engine, &path);
>> + else {
>> + /* we can't proceed through an HCA with DR */
>> + if (path.lid == 0 || node->type == IB_NODE_SWITCH)
>> + rc = extend_dpath(engine, &path, port_num);
>> + }
>> +
>> + if (rc > 0) {
>> + struct ni_cbdata * cbdata = malloc(sizeof(*cbdata));
>> + cbdata->node = node;
>> + cbdata->port_num = port_num;
>> + query_node_info(engine, &path, cbdata);
>> + }
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int query_mlnx_ext_port_info(smp_engine_t * engine, ib_portid_t *
>> portid,
>> + ibnd_node_t * node, int portnum)
>> +{
>> + IBND_DEBUG("Query MLNX Extended Port Info; %s (0x%" PRIx64 "):%d\n",
>> + portid2str(portid), node->guid, portnum);
>> + return issue_smp(engine, portid, IB_ATTR_MLNX_EXT_PORT_INFO, portnum,
>> + recv_mlnx_ext_port_info, node);
>> +}
>> +
>> static int recv_port_info(smp_engine_t * engine, ibnd_smp_t * smp,
>> uint8_t * mad, void *cb_data)
>> {
>> @@ -204,6 +323,9 @@ static int recv_port_info(smp_engine_t * engine,
>> ibnd_smp_t * smp,
>> ibnd_port_t *port;
>> uint8_t *port_info = mad + IB_SMP_DATA_OFFS;
>> uint8_t port_num, local_port;
>> + int phystate, ispeed, espeed;
>> + uint8_t *info;
>> + uint32_t cap_mask;
>>
>> port_num = (uint8_t) mad_get_field(mad, 0, IB_MAD_ATTRMOD_F);
>> local_port = (uint8_t) mad_get_field(port_info, 0,
>> IB_PORT_LOCAL_PORT_F);
>> @@ -238,6 +360,28 @@ static int recv_port_info(smp_engine_t * engine,
>> ibnd_smp_t * smp,
>>
>> add_to_portguid_hash(port, fabric->portstbl);
>>
>> + if (is_mlnx_ext_port_info_supported(port)) {
>> + phystate = mad_get_field(port->info, 0,
>> IB_PORT_PHYS_STATE_F);
>> + ispeed = mad_get_field(port->info, 0,
>> IB_PORT_LINK_SPEED_ACTIVE_F);
>> + if (port->node->type == IB_NODE_SWITCH)
>> + info = (uint8_t *)&port->node->ports[0]->info;
>> + else
>> + info = (uint8_t *)&port->info;
>> + cap_mask = mad_get_field(info, 0, IB_PORT_CAPMASK_F);
>> + if (cap_mask & IB_PORT_CAP_HAS_EXT_SPEEDS)
>> + espeed = mad_get_field(port->info, 0,
>> IB_PORT_LINK_SPEED_EXT_ACTIVE_F);
>> + else
>> + espeed = 0;
>> +
>> + if (phystate == IB_PORT_PHYS_STATE_LINKUP &&
>> + ispeed == IB_LINK_SPEED_ACTIVE_10 &&
>> + espeed == IB_LINK_SPEED_EXT_ACTIVE_NONE) { /*
>> LinkUp/QDR */
>> + query_mlnx_ext_port_info(engine, &smp->path,
>> + node, port_num);
>> + return 0;
>> + }
>> + }
>> +
>> debug_port(&smp->path, port);
>>
>> if (port_num && mad_get_field(port->info, 0, IB_PORT_PHYS_STATE_F)
>> diff --git a/libibnetdisc/src/query_smp.c b/libibnetdisc/src/query_smp.c
>> index 5fb3e18..f4beb39 100644
>> --- a/libibnetdisc/src/query_smp.c
>> +++ b/libibnetdisc/src/query_smp.c
>> @@ -1,5 +1,6 @@
>> /*
>> * Copyright (c) 2010 Lawrence Livermore National Laboratory
>> + * Copyright (c) 2011 Mellanox Technologies LTD. All rights reserved.
>> *
>> * This software is available to you under a choice of one of two
>> * licenses. You may choose to be licensed under the terms of the GNU
>> @@ -40,6 +41,9 @@
>> #include <infiniband/umad.h>
>> #include "internal.h"
>>
>> +extern int mlnx_ext_port_info_err(smp_engine_t * engine, ibnd_smp_t * smp,
>> + uint8_t * mad, void *cb_data);
>> +
>> static void queue_smp(smp_engine_t * engine, ibnd_smp_t * smp)
>> {
>> smp->qnext = NULL;
>> @@ -190,10 +194,16 @@ static int process_one_recv(smp_engine_t * engine)
>> IBND_ERROR("umad (%s Attr 0x%x:%u) bad status %d; %s\n",
>> portid2str(&smp->path), smp->rpc.attr.id,
>> smp->rpc.attr.mod, status, strerror(status));
>> + if (smp->rpc.attr.id == IB_ATTR_MLNX_EXT_PORT_INFO)
>> + rc = mlnx_ext_port_info_err(engine, smp, mad,
>> + smp->cb_data);
>> } else if ((status = mad_get_field(mad, 0, IB_DRSMP_STATUS_F))) {
>> IBND_ERROR("mad (%s Attr 0x%x:%u) bad status 0x%x\n",
>> portid2str(&smp->path), smp->rpc.attr.id,
>> smp->rpc.attr.mod, status);
>> + if (smp->rpc.attr.id == IB_ATTR_MLNX_EXT_PORT_INFO)
>> + rc = mlnx_ext_port_info_err(engine, smp, mad,
>> + smp->cb_data);
>> } else
>> rc = smp->cb(engine, smp, mad, smp->cb_data);
>>
>> diff --git a/src/ibnetdiscover.c b/src/ibnetdiscover.c
>> index 0966217..ed41e0d 100644
>> --- a/src/ibnetdiscover.c
>> +++ b/src/ibnetdiscover.c
>> @@ -100,11 +100,14 @@ char *dump_linkspeed_compat(uint32_t speed)
>> return ("???");
>> }
>>
>> -char *dump_linkspeedext_compat(uint32_t espeed, uint32_t speed)
>> +char *dump_linkspeedext_compat(uint32_t espeed, uint32_t speed, uint32_t
>> fdr10)
>> {
>> switch (espeed) {
>> case 0:
>> - return dump_linkspeed_compat(speed);
>> + if (fdr10 & FDR10)
>> + return ("FDR10");
>> + else
>> + return dump_linkspeed_compat(speed);
>> break;
>> case 1:
>> return ("FDR");
>> @@ -358,6 +361,8 @@ void out_switch_port(ibnd_port_t * port, int group, char
>> *out_prefix)
>> IB_PORT_LINK_WIDTH_ACTIVE_F);
>> uint32_t ispeed = mad_get_field(port->info, 0,
>> IB_PORT_LINK_SPEED_ACTIVE_F);
>> + uint32_t fdr10 = mad_get_field(port->ext_info, 0,
>> + IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F);
>> uint32_t cap_mask, espeed;
>>
>> DEBUG("port %p:%d remoteport %p\n", port, port->portnum,
>> @@ -393,7 +398,7 @@ void out_switch_port(ibnd_port_t * port, int group, char
>> *out_prefix)
>> dump_linkwidth_compat(iwidth),
>> (ispeed != 4 && !espeed) ?
>> dump_linkspeed_compat(ispeed) :
>> - dump_linkspeedext_compat(espeed, ispeed));
>> + dump_linkspeedext_compat(espeed, ispeed, fdr10));
>>
>> if (full_info)
>> fprintf(f, " s=%d w=%d", ispeed, iwidth);
>> @@ -415,6 +420,8 @@ void out_ca_port(ibnd_port_t * port, int group, char
>> *out_prefix)
>> IB_PORT_LINK_WIDTH_ACTIVE_F);
>> uint32_t ispeed = mad_get_field(port->info, 0,
>> IB_PORT_LINK_SPEED_ACTIVE_F);
>> + uint32_t fdr10 = mad_get_field(port->ext_info, 0,
>> + IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F);
>> uint32_t cap_mask, espeed;
>>
>> fprintf(f, "%s[%d]", out_prefix ? out_prefix : "", port->portnum);
>> @@ -447,7 +454,7 @@ void out_ca_port(ibnd_port_t * port, int group, char
>> *out_prefix)
>> dump_linkwidth_compat(iwidth),
>> (ispeed != 4 && !espeed) ?
>> dump_linkspeed_compat(ispeed) :
>> - dump_linkspeedext_compat(espeed, ispeed));
>> + dump_linkspeedext_compat(espeed, ispeed, fdr10));
>>
>> if (full_info)
>> fprintf(f, " s=%d w=%d", ispeed, iwidth);
>> @@ -671,7 +678,7 @@ void dump_ports_report(ibnd_node_t * node, void
>> *user_data)
>> /* for each port */
>> for (p = node->numports, port = node->ports[p]; p > 0;
>> port = node->ports[--p]) {
>> - uint32_t iwidth, ispeed, espeed, cap_mask;
>> + uint32_t iwidth, ispeed, fdr10, espeed, cap_mask;
>> uint8_t *info;
>> if (port == NULL)
>> continue;
>> @@ -689,6 +696,8 @@ void dump_ports_report(ibnd_node_t * node, void
>> *user_data)
>>
>> IB_PORT_LINK_SPEED_EXT_ACTIVE_F);
>> else
>> espeed = 0;
>> + fdr10 = mad_get_field(port->ext_info, 0,
>> + IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F);
>> nodename = remap_node_name(node_name_map,
>> port->node->guid,
>> port->node->nodedesc);
>> @@ -700,7 +709,7 @@ void dump_ports_report(ibnd_node_t * node, void
>> *user_data)
>> dump_linkwidth_compat(iwidth),
>> (ispeed != 4 && !espeed) ?
>> dump_linkspeed_compat(ispeed) :
>> - dump_linkspeedext_compat(espeed, ispeed));
>> + dump_linkspeedext_compat(espeed, ispeed,
>> fdr10));
>> if (port->remoteport) {
>> rem_nodename = remap_node_name(node_name_map,
>> port->remoteport->node->guid,
>> --
>> 1.5.3
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
>> the body of a message to [email protected]
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
> --
> Ira Weiny
> Math Programmer/Computer Scientist
> Lawrence Livermore National Lab
> 925-423-8008
> [email protected]
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
N�����r��y����b�X��ǧv�^�){.n�+����{��ٚ�{ay�ʇڙ�,j��f���h���z��w���
���j:+v���w�j�m��������zZ+�����ݢj"��!�i