/*
 * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
 * Copyright (c) 2007 Xsigo Systems Inc.  All rights reserved.
 * Copyright (c) 2008 Lawrence Livermore National Lab.  All rights reserved.
 * Copyright (c) 2009 HNR Consulting.  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
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

#include <config.h>

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <time.h>
#include <string.h>
#include <errno.h>
#include <inttypes.h>

#include <util/node_name_map.h>
#include <infiniband/ibnetdisc.h>
#include <infiniband/mad.h>

#include "ibdiag_common.h"
#include "ibdiag_sa.h"

static struct ibmad_port *ibmad_port;
static struct ibmad_ports_pair *ibmad_ports;
static char *node_name_map_file = NULL;
static nn_map_t *node_name_map = NULL;
static char *load_cache_file = NULL;
static uint16_t lid2sl_table[sizeof(uint8_t) * 1024 * 48] = { 0 };
static int obtain_sl = 1;

static int data_counters;
static int data_counters_only;
static int port_config;
static uint64_t port_guid;
static char *port_guid_str;
#define SUP_MAX 64
static int sup_total;
static enum MAD_FIELDS suppressed_fields[SUP_MAX];
static char *dr_path;
static uint8_t node_type_to_print;
static unsigned clear_errors, clear_counts, details;

#define PRINT_SWITCH 0x1
#define PRINT_CA     0x2
#define PRINT_ROUTER 0x4
#define PRINT_ALL 0xFF		/* all nodes default flag */

#define DEFAULT_HALF_WORLD_PR_TIMEOUT (3000)

static struct {
	int nodes_checked;
	int bad_nodes;
	int ports_checked;
	int bad_ports;
	int pma_query_failures;
} summary;

#define DEF_THRES_FILE IBDIAG_CONFIG_PATH"/error_thresholds"
static const char *threshold_file = DEF_THRES_FILE;

/* define a "packet" with threshold values in it */
static uint8_t thresholds[1204];
static char *threshold_str;

static unsigned valid_gid(ib_gid_t * gid)
{
	ib_gid_t zero_gid;
	memset(&zero_gid, 0, sizeof zero_gid);
	return memcmp(&zero_gid, gid, sizeof(*gid));
}

static void set_thres(char *name, uint64_t val)
{
	int f;
	int n;
	char tmp[256];
	for (f = IB_PC_EXT_ERR_SYM_F; f <= IB_PC_EXT_XMT_WAIT_F; f++) {
		if (strcmp(name, mad_field_name(f)) == 0) {
			mad_encode_field(thresholds, f, &val);
			snprintf(tmp, 255, "[%s = %" PRIu64 "]", name, val);
			threshold_str = realloc(threshold_str,
					strlen(threshold_str)+strlen(tmp)+1);
			if (!threshold_str) {
				fprintf(stderr, "Failed to allocate memory: "
					"%s\n", strerror(errno));
				exit(1);
			}
			n = strlen(threshold_str);
			strcpy(threshold_str+n, tmp);
		}
	}
}

static void set_thresholds(void)
{
	char buf[1024];
	uint64_t val = 0;
	FILE *thresf = fopen(threshold_file, "r");
	char *p_prefix, *p_last;
	char *name;
	char *val_str;
	char str[64];

	if (!thresf)
		return;

	snprintf(str, 63, "Thresholds: ");
	threshold_str = malloc(strlen(str)+1);
	if (!threshold_str) {
		fprintf(stderr, "Failed to allocate memory: %s\n",
			strerror(errno));
		exit(1);
	}
	strcpy(threshold_str, str);
	while (fgets(buf, sizeof buf, thresf) != NULL) {
		p_prefix = strtok_r(buf, "\n", &p_last);
		if (!p_prefix)
			continue; /* ignore blank lines */

		if (*p_prefix == '#')
			continue; /* ignore comment lines */

		name = strtok_r(p_prefix, "=", &p_last);
		val_str = strtok_r(NULL, "\n", &p_last);

		val = strtoul(val_str, NULL, 0);
		set_thres(name, val);
	}

	fclose(thresf);
}

static int exceeds_threshold(int field, uint64_t val)
{
	uint64_t thres = 0;
	mad_decode_field(thresholds, field, &thres);
	return (val > thres);
}

static void print_port_config(ibnd_node_t * node, int portnum)
{
	char width[64], speed[64], state[64], physstate[64];
	char remote_str[256];
	char link_str[256];
	char width_msg[256];
	char speed_msg[256];
	char ext_port_str[256];
	int iwidth, ispeed, fdr10, espeed, istate, iphystate;
	uint8_t *info;
	int rc;

	ibnd_port_t *port = node->ports[portnum];

	if (!port)
		return;

	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) & FDR10;

	if (port->node->type == IB_NODE_SWITCH)
		info = (uint8_t *)&port->node->ports[0]->info;
	else
		info = (uint8_t *)&port->info;

	espeed = ibnd_get_agg_linkspeedext(info, port->info);

	istate = mad_get_field(port->info, 0, IB_PORT_STATE_F);
	iphystate = mad_get_field(port->info, 0, IB_PORT_PHYS_STATE_F);

	remote_str[0] = '\0';
	link_str[0] = '\0';
	width_msg[0] = '\0';
	speed_msg[0] = '\0';

	/* C14-24.2.1 states that a down port allows for invalid data to be
	 * returned for all PortInfo components except PortState and
	 * PortPhysicalState */
	if (istate != IB_LINK_DOWN) {
		if (!espeed) {
			if (fdr10)
				sprintf(speed, "10.0 Gbps (FDR10)");
			else
				mad_dump_val(IB_PORT_LINK_SPEED_ACTIVE_F, speed, 64, &ispeed);
		} else
			ibnd_dump_agg_linkspeedext(speed, 64, espeed);

		snprintf(link_str, 256, "(%3s %18s %6s/%8s)",
			 mad_dump_val(IB_PORT_LINK_WIDTH_ACTIVE_F, width, 64, &iwidth),
			 speed,
			 mad_dump_val(IB_PORT_STATE_F, state, 64, &istate),
			 mad_dump_val(IB_PORT_PHYS_STATE_F, physstate, 64, &iphystate));
	} else {
		snprintf(link_str, 256, "(              %6s/%8s)",
			 mad_dump_val(IB_PORT_STATE_F, state, 64, &istate),
			 mad_dump_val(IB_PORT_PHYS_STATE_F, physstate, 64, &iphystate));
	}

	if (port->remoteport) {
		char *rem_node_name = NULL;

		if (port->remoteport->ext_portnum)
			snprintf(ext_port_str, 256, "%d",
				 port->remoteport->ext_portnum);
		else
			ext_port_str[0] = '\0';

		get_max_msg(width_msg, speed_msg, 256, port);

		rem_node_name = remap_node_name(node_name_map,
						port->remoteport->node->guid,
						port->remoteport->node->
						nodedesc);

		rc = snprintf(remote_str, sizeof(remote_str),
			 "0x%016" PRIx64 " %6d %4d[%2s] \"%s\" (%s %s)\n",
			 port->remoteport->guid,
			 port->remoteport->base_lid ? port->remoteport->
			 base_lid : port->remoteport->node->smalid,
			 port->remoteport->portnum, ext_port_str, rem_node_name,
			 width_msg, speed_msg);
		if (rc > sizeof(remote_str))
			fprintf(stderr, "WARN: string buffer overflow\n");

		free(rem_node_name);
	} else
		snprintf(remote_str, 256, "           [  ] \"\" ( )\n");

	if (port->ext_portnum)
		snprintf(ext_port_str, 256, "%d", port->ext_portnum);
	else
		ext_port_str[0] = '\0';

	if (node->type == IB_NODE_SWITCH)
		printf("       Link info: %6d", node->smalid);
	else
		printf("       Link info: %6d", port->base_lid);

	printf("%4d[%2s] ==%s==>  %s",
	       port->portnum, ext_port_str, link_str, remote_str);
}

static int suppress(enum MAD_FIELDS field)
{
	int i = 0;
	for (i = 0; i < sup_total; i++)
		if (field == suppressed_fields[i])
			return 1;
	return 0;
}

static void report_suppressed(void)
{
	int i = 0;
	printf("## Suppressed:");
	for (i = 0; i < sup_total; i++)
		printf(" %s", mad_field_name(suppressed_fields[i]));
	printf("\n");
}

static int print_summary(void)
{
	printf("\n## Summary: %d nodes checked, %d bad nodes found\n",
		summary.nodes_checked, summary.bad_nodes);
	printf("##          %d ports checked, %d ports have errors beyond threshold\n",
		summary.ports_checked, summary.bad_ports);
	printf("## %s\n", threshold_str);
	if (summary.pma_query_failures)
		printf("##          %d PMA query failures\n", summary.pma_query_failures);
	report_suppressed();
	return (summary.bad_ports);
}

static void insert_lid2sl_table(struct sa_query_result *r)
{
    unsigned int i;
    for (i = 0; i < r->result_cnt; i++) {
	    ib_path_rec_t *p_pr = (ib_path_rec_t *)sa_get_query_rec(r->p_result_madw, i);
	    lid2sl_table[be16toh(p_pr->dlid)] = ib_path_rec_sl(p_pr);
    }
}

static int path_record_query(ib_gid_t sgid,uint64_t dguid)
{
     ib_path_rec_t pr;
     __be64 comp_mask = 0;
     uint8_t reversible = 0;
     struct sa_handle *h;

	h = sa_get_handle(ibmad_ports->gsi.ca_name);
	if (!h)
	return -1;

     ibd_timeout = DEFAULT_HALF_WORLD_PR_TIMEOUT;
     memset(&pr, 0, sizeof(pr));

     CHECK_AND_SET_GID(sgid, pr.sgid, PR, SGID);
     if(dguid) {
	     mad_encode_field(sgid.raw, IB_GID_GUID_F, &dguid);
	     CHECK_AND_SET_GID(sgid, pr.dgid, PR, DGID);
     }

     CHECK_AND_SET_VAL(1, 8, -1, pr.num_path, PR, NUMBPATH);/*to get only one PathRecord for each source and destination pair*/
     CHECK_AND_SET_VAL(1, 8, -1, reversible, PR, REVERSIBLE);/*for a reversible path*/
     pr.num_path |= reversible << 7;
     struct sa_query_result result;
     int ret = sa_query(h, IB_MAD_METHOD_GET_TABLE,
                        (uint16_t)IB_SA_ATTR_PATHRECORD,0,be64toh(comp_mask),ibd_sakey,
                        &pr, sizeof(pr), &result);
     if (ret) {
             sa_free_handle(h);
             fprintf(stderr, "Query SA failed: %s; sa call path_query failed\n", strerror(ret));
             return ret;
     }
     if (result.status != IB_SA_MAD_STATUS_SUCCESS) {
             sa_report_err(result.status);
             ret = EIO;
             goto Exit;
     }

     insert_lid2sl_table(&result);
Exit:
     sa_free_handle(h);
     sa_free_result_mad(&result);
     return ret;
}

static int query_and_dump(char *buf, size_t size, ib_portid_t * portid,
			  char *node_name, int portnum,
			  const char *attr_name, uint16_t attr_id,
			  int start_field, int end_field)
{
	uint8_t pc[1024];
	uint32_t val = 0;
	int i, n;

	memset(pc, 0, sizeof(pc));

	if (!pma_query_via(pc, portid, portnum, ibd_timeout, attr_id,
			   ibmad_port)) {
		IBWARN("%s query failed on %s, %s port %d", attr_name,
		       node_name, portid2str(portid), portnum);
		summary.pma_query_failures++;
		return 0;
	}

	for (n = 0, i = start_field; i < end_field; i++) {
		mad_decode_field(pc, i, (void *)&val);
		if (val)
			n += snprintf(buf + n, size - n, " [%s == %u]",
				      mad_field_name(i), val);
	}

	return n;
}

static int check_threshold(uint8_t *pc, uint8_t *pce, uint32_t cap_mask2,
			 int i, int ext_i, int *n, char *str, size_t size)
{
	uint32_t val32 = 0;
	uint64_t val64 = 0;
	int is_exceeds = 0;
	float val = 0;
	const char *unit = "";

	if (htonl(cap_mask2) & IB_PM_IS_ADDL_PORT_CTRS_EXT_SUP) {
		mad_decode_field(pce, ext_i, (void *)&val64);
		if (exceeds_threshold(ext_i, val64)) {
			unit = conv_cnt_human_readable(val64, &val, 0);
			*n += snprintf(str + *n, size - *n,
				       " [%s == %" PRIu64 " (%5.3f%s)]",
				       mad_field_name(ext_i), val64, val, unit);
			is_exceeds = 1;
		}

	} else {
		mad_decode_field(pc, i, (void *)&val32);
		if (exceeds_threshold(ext_i, val32)) {
			*n += snprintf(str + *n, size - *n, " [%s == %u]",
					  mad_field_name(i), val32);
			is_exceeds = 1;
		}
	}

	return is_exceeds;
}

static int print_results(ib_portid_t * portid, char *node_name,
			 ibnd_node_t * node, uint8_t * pc, int portnum,
			 int *header_printed, uint8_t *pce, __be16 cap_mask,
			 uint32_t cap_mask2)
{
	char buf[2048];
	char *str = buf;
	int i, ext_i, n;

	for (n = 0, i = IB_PC_ERR_SYM_F, ext_i = IB_PC_EXT_ERR_SYM_F;
			i <= IB_PC_VL15_DROPPED_F; i++, ext_i++ ) {
		if (suppress(i))
			continue;

		/* this is not a counter, skip it */
		if (i == IB_PC_COUNTER_SELECT2_F) {
			ext_i--;
			continue;
		}

		if (check_threshold(pc, pce, cap_mask2, i, ext_i, &n, str, sizeof(buf))) {

			/* If there are PortXmitDiscards, get details (if supported) */
			if (i == IB_PC_XMT_DISCARDS_F && details) {
				n += query_and_dump(str + n, sizeof(buf) - n, portid,
						    node_name, portnum,
						    "PortXmitDiscardDetails",
						    IB_GSI_PORT_XMIT_DISCARD_DETAILS,
						    IB_PC_RCV_LOCAL_PHY_ERR_F,
						    IB_PC_RCV_ERR_LAST_F);
				/* If there are PortRcvErrors, get details (if supported) */
			} else if (i == IB_PC_ERR_RCV_F && details) {
				n += query_and_dump(str + n, sizeof(buf) - n, portid,
						    node_name, portnum,
						    "PortRcvErrorDetails",
						    IB_GSI_PORT_RCV_ERROR_DETAILS,
						    IB_PC_XMT_INACT_DISC_F,
						    IB_PC_XMT_DISC_LAST_F);
			}
		}
	}

	if (!suppress(IB_PC_XMT_WAIT_F)) {
		check_threshold(pc, pce, cap_mask2, IB_PC_XMT_WAIT_F,
				IB_PC_EXT_XMT_WAIT_F, &n, str, sizeof(buf));
	}

	/* if we found errors. */
	if (n != 0) {
		if (data_counters) {
			uint8_t *pkt = pc;
			int start_field = IB_PC_XMT_BYTES_F;
			int end_field = IB_PC_RCV_PKTS_F;

			if (pce) {
				pkt = pce;
				start_field = IB_PC_EXT_XMT_BYTES_F;
				if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED)
					end_field = IB_PC_EXT_RCV_MPKTS_F;
				else
					end_field = IB_PC_EXT_RCV_PKTS_F;
			}

			for (i = start_field; i <= end_field; i++) {
				uint64_t val64 = 0;
				float val = 0;
				const char *unit = "";
				mad_decode_field(pkt, i, (void *)&val64);
				if (val64) {
					int data = 0;
					if (i == IB_PC_EXT_XMT_BYTES_F ||
					    i == IB_PC_EXT_RCV_BYTES_F ||
					    i == IB_PC_XMT_BYTES_F ||
					    i == IB_PC_RCV_BYTES_F)
						data = 1;
					unit = conv_cnt_human_readable(val64,
								&val, data);
					n += snprintf(str + n, sizeof(buf) - n,
						" [%s == %" PRIu64
						" (%5.3f%s)]",
						mad_field_name(i), val64, val,
						unit);
				}
			}
		}

		if (!*header_printed) {
			if (node->type == IB_NODE_SWITCH)
				printf("Errors for 0x%" PRIx64 " \"%s\"\n",
					node->ports[0]->guid, node_name);
			else
				printf("Errors for \"%s\"\n", node_name);
			*header_printed = 1;
			summary.bad_nodes++;
		}

		if (portnum == 0xFF) {
			if (node->type == IB_NODE_SWITCH)
				printf("   GUID 0x%" PRIx64 " port ALL:%s\n",
				       node->ports[0]->guid, str);
		} else {
			printf("   GUID 0x%" PRIx64 " port %d:%s\n",
			       node->ports[portnum]->guid, portnum, str);
			if (port_config)
				print_port_config(node, portnum);
			summary.bad_ports++;
		}
	}
	return (n);
}

static int query_cap_mask(ib_portid_t * portid, char *node_name, int portnum,
			  __be16 * cap_mask, uint32_t * cap_mask2)
{
	uint8_t pc[1024] = { 0 };
	__be16 rc_cap_mask;
	__be32 rc_cap_mask2;

	portid->sl = lid2sl_table[portid->lid];

	/* PerfMgt ClassPortInfo is a required attribute */
	if (!pma_query_via(pc, portid, portnum, ibd_timeout, CLASS_PORT_INFO,
			   ibmad_port)) {
		IBWARN("classportinfo query failed on %s, %s port %d",
		       node_name, portid2str(portid), portnum);
		summary.pma_query_failures++;
		return -1;
	}

	/* ClassPortInfo should be supported as part of libibmad */
	memcpy(&rc_cap_mask, pc + 2, sizeof(rc_cap_mask));	/* CapabilityMask */
	memcpy(&rc_cap_mask2, pc + 4, sizeof(rc_cap_mask2));	/* CapabilityMask2 */

	*cap_mask = rc_cap_mask;
	*cap_mask2 = ntohl(rc_cap_mask2) >> 5;
	return 0;
}

static int print_data_cnts(ib_portid_t * portid, __be16 cap_mask,
			   char *node_name, ibnd_node_t * node, int portnum,
			   int *header_printed)
{
	uint8_t pc[1024];
	int i;
	int start_field = IB_PC_XMT_BYTES_F;
	int end_field = IB_PC_RCV_PKTS_F;

	memset(pc, 0, 1024);

	portid->sl = lid2sl_table[portid->lid];

	if (cap_mask & (IB_PM_EXT_WIDTH_SUPPORTED | IB_PM_EXT_WIDTH_NOIETF_SUP)) {
		if (!pma_query_via(pc, portid, portnum, ibd_timeout,
				   IB_GSI_PORT_COUNTERS_EXT, ibmad_port)) {
			IBWARN("IB_GSI_PORT_COUNTERS_EXT query failed on %s, %s port %d",
			       node_name, portid2str(portid), portnum);
			summary.pma_query_failures++;
			return (1);
		}
		start_field = IB_PC_EXT_XMT_BYTES_F;
		if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED)
			end_field = IB_PC_EXT_RCV_MPKTS_F;
		else
			end_field = IB_PC_EXT_RCV_PKTS_F;
	} else {
		if (!pma_query_via(pc, portid, portnum, ibd_timeout,
				   IB_GSI_PORT_COUNTERS, ibmad_port)) {
			IBWARN("IB_GSI_PORT_COUNTERS query failed on %s, %s port %d",
			       node_name, portid2str(portid), portnum);
			summary.pma_query_failures++;
			return (1);
		}
		start_field = IB_PC_XMT_BYTES_F;
		end_field = IB_PC_RCV_PKTS_F;
	}

	if (!*header_printed) {
		printf("Data Counters for 0x%" PRIx64 " \"%s\"\n", node->guid,
		       node_name);
		*header_printed = 1;
	}

	if (portnum == 0xFF)
		printf("   GUID 0x%" PRIx64 " port ALL:", node->guid);
	else
		printf("   GUID 0x%" PRIx64 " port %d:",
		       node->guid, portnum);

	for (i = start_field; i <= end_field; i++) {
		uint64_t val64 = 0;
		float val = 0;
		const char *unit = "";
		int data = 0;
		mad_decode_field(pc, i, (void *)&val64);
		if (i == IB_PC_EXT_XMT_BYTES_F || i == IB_PC_EXT_RCV_BYTES_F ||
		    i == IB_PC_XMT_BYTES_F || i == IB_PC_RCV_BYTES_F)
			data = 1;
		unit = conv_cnt_human_readable(val64, &val, data);
		printf(" [%s == %" PRIu64 " (%5.3f%s)]", mad_field_name(i),
			val64, val, unit);
	}
	printf("\n");

	if (portnum != 0xFF && port_config)
		print_port_config(node, portnum);

	return (0);
}

static int print_errors(ib_portid_t * portid, __be16 cap_mask, uint32_t cap_mask2,
			char *node_name, ibnd_node_t * node, int portnum,
			int *header_printed)
{
	uint8_t pc[1024];
	uint8_t pce[1024];
	uint8_t *pc_ext = NULL;

	memset(pc, 0, 1024);
	memset(pce, 0, 1024);

	portid->sl = lid2sl_table[portid->lid];

	if (!pma_query_via(pc, portid, portnum, ibd_timeout,
			   IB_GSI_PORT_COUNTERS, ibmad_port)) {
		IBWARN("IB_GSI_PORT_COUNTERS query failed on %s, %s port %d",
		       node_name, portid2str(portid), portnum);
		summary.pma_query_failures++;
		return (0);
	}

	if (cap_mask & (IB_PM_EXT_WIDTH_SUPPORTED | IB_PM_EXT_WIDTH_NOIETF_SUP)) {
		if (!pma_query_via(pce, portid, portnum, ibd_timeout,
		    IB_GSI_PORT_COUNTERS_EXT, ibmad_port)) {
			IBWARN("IB_GSI_PORT_COUNTERS_EXT query failed on %s, %s port %d",
			       node_name, portid2str(portid), portnum);
			summary.pma_query_failures++;
			return (0);
		}
		pc_ext = pce;
	}

	if (!(cap_mask & IB_PM_PC_XMIT_WAIT_SUP)) {
		/* if PortCounters:PortXmitWait not supported clear this counter */
		uint32_t foo = 0;
		mad_encode_field(pc, IB_PC_XMT_WAIT_F, &foo);
	}
	return (print_results(portid, node_name, node, pc, portnum,
			      header_printed, pc_ext, cap_mask, cap_mask2));
}

static uint8_t *reset_pc_ext(void *rcvbuf, ib_portid_t *dest, int port,
			     unsigned mask, unsigned timeout,
			     const struct ibmad_port *srcport)
{
	ib_rpc_t rpc = { 0 };
	int lid = dest->lid;

	DEBUG("lid %u port %d mask 0x%x", lid, port, mask);

	if (lid == -1) {
		IBWARN("only lid routed is supported");
		return NULL;
	}

	if (!mask)
		mask = ~0;

	rpc.mgtclass = IB_PERFORMANCE_CLASS;
	rpc.method = IB_MAD_METHOD_SET;
	rpc.attr.id = IB_GSI_PORT_COUNTERS_EXT;

	memset(rcvbuf, 0, IB_MAD_SIZE);

	/* Same for attribute IDs */
	mad_set_field(rcvbuf, 0, IB_PC_EXT_PORT_SELECT_F, port);
	mad_set_field(rcvbuf, 0, IB_PC_EXT_COUNTER_SELECT_F, mask);
	mask = mask >> 16;
	mad_set_field(rcvbuf, 0, IB_PC_EXT_COUNTER_SELECT2_F, mask);
	rpc.attr.mod = 0;
	rpc.timeout = timeout;
	rpc.datasz = IB_PC_DATA_SZ;
	rpc.dataoffs = IB_PC_DATA_OFFS;
	if (!dest->qp)
		dest->qp = 1;
	if (!dest->qkey)
		dest->qkey = IB_DEFAULT_QP1_QKEY;

	return mad_rpc(srcport, &rpc, dest, rcvbuf, rcvbuf);
}

static void clear_port(ib_portid_t * portid, __be16 cap_mask, uint32_t cap_mask2,
		       char *node_name, int port)
{
	uint8_t pc[1024] = { 0 };
	/* bits defined in Table 228 PortCounters CounterSelect and
	 * CounterSelect2
	 */
	uint32_t mask = 0;

	if (clear_errors) {
		mask |= 0xFFF;
		if (cap_mask & IB_PM_PC_XMIT_WAIT_SUP)
			mask |= 0x10000;
	}
	if (clear_counts)
		mask |= 0xF000;

	if (mask)
		if (!performance_reset_via(pc, portid, port, mask, ibd_timeout,
					   IB_GSI_PORT_COUNTERS, ibmad_port))
			fprintf(stderr, "Failed to reset errors %s port %d\n", node_name,
				port);

	if (clear_errors && details) {
		memset(pc, 0, 1024);
		performance_reset_via(pc, portid, port, 0xf, ibd_timeout,
				      IB_GSI_PORT_XMIT_DISCARD_DETAILS,
				      ibmad_port);
		memset(pc, 0, 1024);
		performance_reset_via(pc, portid, port, 0x3f, ibd_timeout,
				      IB_GSI_PORT_RCV_ERROR_DETAILS,
				      ibmad_port);
	}

	if (cap_mask & (IB_PM_EXT_WIDTH_SUPPORTED | IB_PM_EXT_WIDTH_NOIETF_SUP)) {
		mask = 0;
		if (clear_counts) {
			if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED)
				mask = 0xFF;
			else
				mask = 0x0F;
		}

		if (clear_errors && (htonl(cap_mask2) & IB_PM_IS_ADDL_PORT_CTRS_EXT_SUP)) {
			mask |= 0xfff0000;
			if (cap_mask & IB_PM_PC_XMIT_WAIT_SUP)
				mask |= (1 << 28);
		}

		if (mask && !reset_pc_ext(pc, portid, port, mask, ibd_timeout,
		    ibmad_port))
			fprintf(stderr, "Failed to reset extended data counters %s, "
				"%s port %d\n", node_name, portid2str(portid),
				port);
	}
}

static void print_node(ibnd_node_t *node, void *user_data)
{
	int header_printed = 0;
	int p = 0;
	int startport = 1;
	int type = 0;
	int all_port_sup = 0;
	ib_portid_t portid = { 0 };
	__be16 cap_mask = 0;
	uint32_t cap_mask2 = 0;
	char *node_name = NULL;

	switch (node->type) {
	case IB_NODE_SWITCH:
		type = PRINT_SWITCH;
		break;
	case IB_NODE_CA:
		type = PRINT_CA;
		break;
	case IB_NODE_ROUTER:
		type = PRINT_ROUTER;
		break;
	}

	if ((type & node_type_to_print) == 0)
		return;

	if (node->type == IB_NODE_SWITCH && node->smaenhsp0)
		startport = 0;

	node_name = remap_node_name(node_name_map, node->guid, node->nodedesc);

	if (node->type == IB_NODE_SWITCH) {
		ib_portid_set(&portid, node->smalid, 0, 0);
		p = 0;
	} else {
		for (p = 1; p <= node->numports; p++) {
			if (node->ports[p]) {
				ib_portid_set(&portid,
					      node->ports[p]->base_lid,
					      0, 0);
				break;
			}
		}
	}

	if ((query_cap_mask(&portid, node_name, p, &cap_mask, &cap_mask2) == 0) &&
	    (cap_mask & IB_PM_ALL_PORT_SELECT))
		all_port_sup = 1;

	if (data_counters_only) {
		for (p = startport; p <= node->numports; p++) {
			if (node->ports[p]) {
				if (node->type == IB_NODE_SWITCH)
					ib_portid_set(&portid, node->smalid, 0, 0);
				else
					ib_portid_set(&portid, node->ports[p]->base_lid,
						      0, 0);

				print_data_cnts(&portid, cap_mask, node_name, node, p,
						&header_printed);
				summary.ports_checked++;
				if (!all_port_sup)
					clear_port(&portid, cap_mask, cap_mask2, node_name, p);
			}
		}
	} else {
		if (all_port_sup)
			if (!print_errors(&portid, cap_mask, cap_mask2, node_name, node,
					  0xFF, &header_printed)) {
				summary.ports_checked += node->numports;
				goto clear;
			}

		for (p = startport; p <= node->numports; p++) {
			if (node->ports[p]) {
				if (node->type == IB_NODE_SWITCH)
					ib_portid_set(&portid, node->smalid, 0, 0);
				else
					ib_portid_set(&portid, node->ports[p]->base_lid,
						      0, 0);

				print_errors(&portid, cap_mask, cap_mask2, node_name, node, p,
					     &header_printed);
				summary.ports_checked++;
				if (!all_port_sup)
					clear_port(&portid, cap_mask, cap_mask2, node_name, p);
			}
		}
	}

clear:
	summary.nodes_checked++;
	if (all_port_sup)
		clear_port(&portid, cap_mask, cap_mask2, node_name, 0xFF);

	free(node_name);
}

static void add_suppressed(enum MAD_FIELDS field)
{
	if (sup_total >= SUP_MAX) {
		IBWARN("Maximum (%d) fields have been suppressed; skipping %s",
		       sup_total, mad_field_name(field));
		return;
	}
	suppressed_fields[sup_total++] = field;
}

static void calculate_suppressed_fields(char *str)
{
	enum MAD_FIELDS f;
	char *val, *lasts = NULL;
	char *tmp = strdup(str);

	val = strtok_r(tmp, ",", &lasts);
	while (val) {
		for (f = IB_PC_FIRST_F; f <= IB_PC_LAST_F; f++)
			if (strcmp(val, mad_field_name(f)) == 0)
				add_suppressed(f);
		val = strtok_r(NULL, ",", &lasts);
	}

	free(tmp);
}

static int process_opt(void *context, int ch)
{
	struct ibnd_config *cfg = context;
	switch (ch) {
	case 's':
		calculate_suppressed_fields(optarg);
		break;
	case 'c':
		/* Right now this is the only "common" error */
		add_suppressed(IB_PC_ERR_SWITCH_REL_F);
		break;
	case 1:
		node_name_map_file = strdup(optarg);
		if (node_name_map_file == NULL)
			IBEXIT("out of memory, strdup for node_name_map_file name failed");
		break;
	case 2:
		data_counters++;
		break;
	case 3:
		node_type_to_print |= PRINT_SWITCH;
		break;
	case 4:
		node_type_to_print |= PRINT_CA;
		break;
	case 5:
		node_type_to_print |= PRINT_ROUTER;
		break;
	case 6:
		details = 1;
		break;
	case 7:
		load_cache_file = strdup(optarg);
		break;
	case 8:
		threshold_file = strdup(optarg);
		break;
	case 9:
		data_counters_only = 1;
		break;
	case 10:
		obtain_sl = 0;
		break;
	case 'G':
	case 'S':
		port_guid_str = optarg;
		port_guid = strtoull(optarg, NULL, 0);
		break;
	case 'D':
		dr_path = strdup(optarg);
		break;
	case 'r':
		port_config++;
		break;
	case 'R':		/* nop */
		break;
	case 'k':
		clear_errors = 1;
		break;
	case 'K':
		clear_counts = 1;
		break;
	case 'o':
		cfg->max_smps = strtoul(optarg, NULL, 0);
		break;
	default:
		return -1;
	}

	return 0;
}

int main(int argc, char **argv)
{
	struct ibnd_config config = { 0 };
	int resolved = -1;
	ib_portid_t portid = { 0 };
	ib_portid_t self_portid = { 0 };
	int rc = 0;
	ibnd_fabric_t *fabric = NULL;
	ib_gid_t self_gid;
	int port = 0;

	int mgmt_classes[4] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS,
		IB_PERFORMANCE_CLASS
	};

	const struct ibdiag_opt opts[] = {
		{"suppress", 's', 1, "<err1,err2,...>",
		 "suppress errors listed"},
		{"suppress-common", 'c', 0, NULL,
		 "suppress some of the common counters"},
		{"node-name-map", 1, 1, "<file>", "node name map file"},
		{"port-guid", 'G', 1, "<port_guid>",
		 "report the node containing the port specified by <port_guid>"},
		{"", 'S', 1, "<port_guid>",
		 "Same as \"-G\" for backward compatibility"},
		{"Direct", 'D', 1, "<dr_path>",
		 "report the node containing the port specified by <dr_path>"},
		{"skip-sl", 10, 0, NULL,"don't obtain SL to all destinations"},
		{"report-port", 'r', 0, NULL,
		 "report port link information"},
		{"threshold-file", 8, 1, NULL,
		 "specify an alternate threshold file, default: " DEF_THRES_FILE},
		{"GNDN", 'R', 0, NULL,
		 "(This option is obsolete and does nothing)"},
		{"data", 2, 0, NULL, "include data counters for ports with errors"},
		{"switch", 3, 0, NULL, "print data for switches only"},
		{"ca", 4, 0, NULL, "print data for CA's only"},
		{"router", 5, 0, NULL, "print data for routers only"},
		{"details", 6, 0, NULL, "include transmit discard details"},
		{"counters", 9, 0, NULL, "print data counters only"},
		{"clear-errors", 'k', 0, NULL,
		 "Clear error counters after read"},
		{"clear-counts", 'K', 0, NULL,
		 "Clear data counters after read"},
		{"load-cache", 7, 1, "<file>",
		 "filename of ibnetdiscover cache to load"},
		{"outstanding_smps", 'o', 1, NULL,
		 "specify the number of outstanding SMP's which should be "
		 "issued during the scan"},
		{}
	};
	char usage_args[] = "";

	memset(suppressed_fields, 0, sizeof suppressed_fields);
	ibdiag_process_opts(argc, argv, &config, "cDGKLnRrSs", opts, process_opt,
			    usage_args, NULL);

	argc -= optind;
	argv += optind;

	if (!node_type_to_print)
		node_type_to_print = PRINT_ALL;

	ibmad_ports = mad_rpc_open_port2(ibd_ca, ibd_ca_port, mgmt_classes, 4, 0);
	if (!ibmad_ports)
		IBEXIT("Failed to open port; %s:%d\n", ibd_ca, ibd_ca_port);

	ibmad_port = ibmad_ports->gsi.port;

	smp_mkey_set(ibmad_port, ibd_mkey);

	if (ibd_timeout) {
		mad_rpc_set_timeout(ibmad_port, ibd_timeout);
		config.timeout_ms = ibd_timeout;
	}

	config.flags = ibd_ibnetdisc_flags;
	config.mkey = ibd_mkey;

	if (dr_path && load_cache_file) {
		mad_rpc_close_port2(ibmad_ports);
		fprintf(stderr, "Cannot specify cache and direct route path\n");
		exit(-1);
	}

	if (resolve_self(ibmad_ports->gsi.ca_name, ibd_ca_port,
			&self_portid, &port, &self_gid.raw) < 0) {
		mad_rpc_close_port2(ibmad_ports);
		IBEXIT("can't resolve self port %s", argv[0]);
	}

	node_name_map = open_node_name_map(node_name_map_file);

	/* limit the scan the fabric around the target */
	if (dr_path) {
		if ((resolved =
		     resolve_portid_str(ibmad_ports->gsi.ca_name, ibd_ca_port, &portid, dr_path,
					IB_DEST_DRPATH, NULL, ibmad_port)) < 0)
			IBWARN("Failed to resolve %s; attempting full scan",
			       dr_path);
	} else if (port_guid_str) {
		if ((resolved =
		     resolve_portid_str(ibmad_ports->gsi.ca_name, ibd_ca_port, &portid,
					port_guid_str, IB_DEST_GUID, ibd_sm_id,
					       ibmad_port)) < 0)
			IBWARN("Failed to resolve %s; attempting full scan",
			       port_guid_str);
		if(obtain_sl)
			lid2sl_table[portid.lid] = portid.sl;
	}

	mad_rpc_close_port2(ibmad_ports);

	if (load_cache_file) {
		if ((fabric = ibnd_load_fabric(load_cache_file, 0)) == NULL) {
			fprintf(stderr, "loading cached fabric failed\n");
			rc = -1;
			goto close_name_map;
		}
	} else {
		if (resolved >= 0) {
			if (!config.max_hops)
				config.max_hops = 1;
			if (!(fabric = ibnd_discover_fabric(ibd_ca, ibd_ca_port,
						    &portid, &config)))
				IBWARN("Single node discover failed;"
				       " attempting full scan");
		}

		if (!fabric && !(fabric = ibnd_discover_fabric(ibd_ca,
							       ibd_ca_port,
							       NULL,
							       &config))) {
			fprintf(stderr, "discover failed\n");
			rc = -1;
			goto close_name_map;
		}
	}

	set_thresholds();

	/* reopen the global ibmad_port */
	ibmad_ports = mad_rpc_open_port2(ibd_ca, ibd_ca_port,
				       mgmt_classes, 4, dr_path ? 1 : 0);
	if (!ibmad_ports) {
		ibnd_destroy_fabric(fabric);
		close_node_name_map(node_name_map);
		IBEXIT("Failed to reopen port: %s:%d\n",
			ibd_ca, ibd_ca_port);
	}

	ibmad_port = ibmad_ports->gsi.port;
	if (!ibmad_port) {
		ibnd_destroy_fabric(fabric);
		close_node_name_map(node_name_map);
		IBEXIT("Failed to reopen port: %s:%d\n",
			ibd_ca, ibd_ca_port);
	}

	smp_mkey_set(ibmad_port, ibd_mkey);

	if (ibd_timeout)
		mad_rpc_set_timeout(ibmad_port, ibd_timeout);

	if (port_guid_str) {
		ibnd_port_t *ndport = ibnd_find_port_guid(fabric, port_guid);
		if (ndport)
			print_node(ndport->node, NULL);
		else
			fprintf(stderr, "Failed to find node: %s\n",
				port_guid_str);
	} else if (dr_path) {
		ibnd_port_t *ndport;

		uint8_t ni[IB_SMP_DATA_SIZE] = { 0 };
		if (!smp_query_via(ni, &portid, IB_ATTR_NODE_INFO, 0,
			   ibd_timeout, ibmad_port)) {
				fprintf(stderr, "Failed to query local Node Info\n");
				goto close_port;
		}

		mad_decode_field(ni, IB_NODE_PORT_GUID_F, &(port_guid));

		ndport = ibnd_find_port_guid(fabric, port_guid);
		if (ndport) {
			if(obtain_sl)
				if(path_record_query(self_gid,ndport->guid))
					goto close_port;
			print_node(ndport->node, NULL);
		} else
			fprintf(stderr, "Failed to find node: %s\n", dr_path);
	} else {
		if(obtain_sl)
			if(path_record_query(self_gid,0))
				goto close_port;

		ibnd_iter_nodes(fabric, print_node, NULL);
	}

	rc = print_summary();
	if (rc)
		rc = 1;

close_port:
	mad_rpc_close_port2(ibmad_ports);
	ibnd_destroy_fabric(fabric);

close_name_map:
	close_node_name_map(node_name_map);
	exit(rc);
}
