/*
 * Copyright (c) 2012 Mellanox Technologies LTD.  All rights reserved.
 * Copyright (c) 2004-2009 Voltaire Inc.  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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>

#include <infiniband/umad.h>
#include <infiniband/mad.h>

#include "ibdiag_common.h"

#define IS3_DEVICE_ID			47396

#define IB_MLX_VENDOR_CLASS		10
/* Vendor specific Attribute IDs */
#define IB_MLX_IS3_GENERAL_INFO		0x17
#define IB_MLX_IS3_CONFIG_SPACE_ACCESS	0x50
#define IB_MLX_IS4_COUNTER_GROUP_INFO   0x90
#define IB_MLX_IS4_CONFIG_COUNTER_GROUP 0x91
/* Config space addresses */
#define IB_MLX_IS3_PORT_XMIT_WAIT	0x10013C


static struct ibmad_port *srcport;

typedef struct {
	__be16 hw_revision;
	__be16 device_id;
	uint8_t reserved[24];
	__be32 uptime;
} is3_hw_info_t;

typedef struct {
	uint8_t resv1;
	uint8_t major;
	uint8_t minor;
	uint8_t sub_minor;
	__be32 build_id;
	uint8_t month;
	uint8_t day;
	__be16 year;
	__be16 resv2;
	__be16 hour;
	uint8_t psid[16];
	__be32 ini_file_version;
} is3_fw_info_t;

typedef struct {
	__be32 ext_major;
	__be32 ext_minor;
	__be32 ext_sub_minor;
	__be32 reserved[4];
} is4_fw_ext_info_t;

typedef struct {
	uint8_t resv1;
	uint8_t major;
	uint8_t minor;
	uint8_t sub_minor;
	uint8_t resv2[28];
} is3_sw_info_t;

typedef struct {
	uint8_t reserved[8];
	is3_hw_info_t hw_info;
	is3_fw_info_t fw_info;
	is3_sw_info_t sw_info;
} is3_general_info_t;

typedef struct {
	uint8_t reserved[8];
	is3_hw_info_t hw_info;
	is3_fw_info_t fw_info;
	is4_fw_ext_info_t ext_fw_info;
	is3_sw_info_t sw_info;
} is4_general_info_t;

typedef struct {
	uint8_t reserved[8];
	struct is3_record {
		__be32 address;
		__be32 data;
		__be32 mask;
	} record[18];
} is3_config_space_t;

#define COUNTER_GROUPS_NUM 2

typedef struct {
	uint8_t reserved1[8];
	uint8_t reserved[3];
	uint8_t num_of_counter_groups;
	__be32 group_masks[COUNTER_GROUPS_NUM];
} is4_counter_group_info_t;

typedef struct {
	uint8_t reserved[3];
	uint8_t group_select;
} is4_group_select_t;

typedef struct {
	uint8_t reserved1[8];
	uint8_t reserved[4];
	is4_group_select_t group_selects[COUNTER_GROUPS_NUM];
} is4_config_counter_groups_t;

static uint16_t ext_fw_info_device[][2] = {
	{0x0245, 0x0245},	/* Switch-X */
	{0xc738, 0xc73b},	/* Switch-X */
	{0xcb20, 0xcb20},	/* Switch-IB */
	{0xcf08, 0xcf08},	/* Switch-IB2 */
	{0xd2f0, 0xd2f0},	/* Quantum */
	{0x01b3, 0x01b3},	/* IS-4 */
	{0x1003, 0x101b},	/* Connect-X */
	{0xa2d2, 0xa2d2},	/* BlueField */
	{0x1b02, 0x1b02},	/* Bull SwitchX */
	{0x1b50, 0x1b50},	/* Bull SwitchX */
	{0x1ba0, 0x1ba0},	/* Bull SwitchIB */
	{0x1bd0, 0x1bd5},	/* Bull SwitchIB and SwitchIB2 */
	{0x1bf0, 0x1bf0},	/* Bull Sequana Quantum */
	{0x1b33, 0x1b33},	/* Bull ConnectX3 */
	{0x1b73, 0x1b73},	/* Bull ConnectX3 */
	{0x1b40, 0x1b41},	/* Bull ConnectX3 */
	{0x1b60, 0x1b61},	/* Bull ConnectX3 */
	{0x1b83, 0x1b83},	/* Bull ConnectIB */
	{0x1b93, 0x1b94},	/* Bull ConnectIB */
	{0x1bb4, 0x1bb5},	/* Bull ConnectX4 */
	{0x1bc4, 0x1bc6},	/* Bull ConnectX4, Sequana HDR and HDR100 */
	{0x0000, 0x0000}};

static int is_ext_fw_info_supported(uint16_t device_id) {
	int i;
	for (i = 0; ext_fw_info_device[i][0]; i++)
		if (ext_fw_info_device[i][0] <= device_id &&
		    device_id <= ext_fw_info_device[i][1])
			return 1;
	return 0;
}

static int do_vendor(ib_portid_t *portid, uint8_t class, uint8_t method,
		     uint16_t attr_id, uint32_t attr_mod, void *data)
{
	ib_vendor_call_t call;

	memset(&call, 0, sizeof(call));
	call.mgmt_class = class;
	call.method = method;
	call.timeout = ibd_timeout;
	call.attrid = attr_id;
	call.mod = attr_mod;

	if (!ib_vendor_call_via(data, portid, &call, srcport)) {
		fprintf(stderr,"vendstat: method %u, attribute %u failure\n", method, attr_id);
		return -1;
	}
	return 0;
}

static int do_config_space_records(ib_portid_t *portid, unsigned set,
				    is3_config_space_t *cs, unsigned records)
{
	unsigned i;

	if (records > 18)
		records = 18;

	if (do_vendor(portid, IB_MLX_VENDOR_CLASS,
		      set ? IB_MAD_METHOD_SET : IB_MAD_METHOD_GET,
		      IB_MLX_IS3_CONFIG_SPACE_ACCESS, 2 << 22 | records << 16,
		      cs)) {
		fprintf(stderr,"cannot %s config space records\n", set ? "set" : "get");
		return -1;
	}
	for (i = 0; i < records; i++) {
		printf("Config space record at 0x%x: 0x%x\n",
		       ntohl(cs->record[i].address),
		       ntohl(cs->record[i].data & cs->record[i].mask));
	}
	return 0;
}

static int counter_groups_info(ib_portid_t * portid, int port)
{
	char buf[1024];
	is4_counter_group_info_t *cg_info;
	int i, num_cg;

	/* Counter Group Info */
	memset(&buf, 0, sizeof(buf));
	if (do_vendor(portid, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
		      IB_MLX_IS4_COUNTER_GROUP_INFO, port, buf)) {
		fprintf(stderr,"counter group info query failure\n");
		return -1;
	}
	cg_info = (is4_counter_group_info_t *) & buf;
	num_cg = cg_info->num_of_counter_groups;
	printf("counter_group_info:\n");
	printf("%d counter groups\n", num_cg);
	for (i = 0; i < num_cg; i++)
		printf("group%d mask %#x\n", i, ntohl(cg_info->group_masks[i]));
	return 0;
}

/* Group0 counter config values */
#define IS4_G0_PortXmtDataSL_0_7  0
#define IS4_G0_PortXmtDataSL_8_15 1
#define IS4_G0_PortRcvDataSL_0_7  2

/* Group1 counter config values */
#define IS4_G1_PortXmtDataSL_8_15 1
#define IS4_G1_PortRcvDataSL_0_7  2
#define IS4_G1_PortRcvDataSL_8_15 8

static int cg0, cg1;

static int config_counter_groups(ib_portid_t * portid, int port)
{
	char buf[1024];
	is4_config_counter_groups_t *cg_config;

	/* configure counter groups for groups 0 and 1 */
	memset(&buf, 0, sizeof(buf));
	cg_config = (is4_config_counter_groups_t *) & buf;

	printf("counter_groups_config: configuring group0 %d group1 %d\n", cg0,
	       cg1);
	cg_config->group_selects[0].group_select = (uint8_t) cg0;
	cg_config->group_selects[1].group_select = (uint8_t) cg1;

	if (do_vendor(portid, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_SET,
		      IB_MLX_IS4_CONFIG_COUNTER_GROUP, port, buf)) {
		fprintf(stderr, "config counter group set failure\n");
		return -1;
	}
	/* get config counter groups */
	memset(&buf, 0, sizeof(buf));

	if (do_vendor(portid, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
		      IB_MLX_IS4_CONFIG_COUNTER_GROUP, port, buf)) {
		fprintf(stderr, "config counter group query failure\n");
		return -1;
	}
	return 0;
}

static int general_info, xmit_wait, counter_group_info, config_counter_group;
static is3_config_space_t write_cs, read_cs;
static unsigned write_cs_records, read_cs_records;


static int process_opt(void *context, int ch)
{
	int ret;
	unsigned int address, data, mask;

	switch (ch) {
	case 'N':
		general_info = 1;
		break;
	case 'w':
		xmit_wait = 1;
		break;
	case 'i':
		counter_group_info = 1;
		break;
	case 'c':
		config_counter_group = 1;
		ret = sscanf(optarg, "%d,%d", &cg0, &cg1);
		if (ret != 2)
			return -1;
		break;
	case 'R':
		if (read_cs_records >= 18)
			break;
		ret = sscanf(optarg, "%x,%x", &address, &mask);
		if (ret < 1)
			return -1;
		else if (ret == 1)
			mask = 0xffffffff;
		read_cs.record[read_cs_records].address = htobe32(address);
		read_cs.record[read_cs_records].mask = htobe32(mask);
		read_cs_records++;
		break;
	case 'W':
		if (write_cs_records >= 18)
			break;
		ret = sscanf(optarg, "%x,%x,%x", &address, &data, &mask);
		if (ret < 2)
			return -1;
		else if (ret == 2)
			mask = 0xffffffff;
		write_cs.record[write_cs_records].address = htobe32(address);
		write_cs.record[write_cs_records].data = htobe32(data);
		write_cs.record[write_cs_records].mask = htobe32(mask);
		write_cs_records++;
		break;
	default:
		return -1;
	}
	return 0;
}

int main(int argc, char **argv)
{
	int mgmt_classes[2] = { IB_SA_CLASS, IB_MLX_VENDOR_CLASS };
	ib_portid_t portid = { 0 };
	int port = 0;
	char buf[1024];
	uint32_t fw_ver_major = 0;
	uint32_t fw_ver_minor = 0;
	uint32_t fw_ver_sub_minor = 0;
	uint8_t sw_ver_major = 0, sw_ver_minor = 0, sw_ver_sub_minor = 0;
	is3_general_info_t *gi_is3;
	is4_general_info_t *gi_is4;
	const struct ibdiag_opt opts[] = {
		{"N", 'N', 0, NULL, "show IS3 or IS4 general information"},
		{"w", 'w', 0, NULL, "show IS3 port xmit wait counters"},
		{"i", 'i', 0, NULL, "show IS4 counter group info"},
		{"c", 'c', 1, "<num,num>", "configure IS4 counter groups"},
		{"Read", 'R', 1, "<addr,mask>", "Read configuration space record at addr"},
		{"Write", 'W', 1, "<addr,val,mask>", "Write configuration space record at addr"},
		{}
	};

	char usage_args[] = "<lid|guid> [port]";
	const char *usage_examples[] = {
		"-N 6\t\t# read IS3 or IS4 general information",
		"-w 6\t\t# read IS3 port xmit wait counters",
		"-i 6 12\t# read IS4 port 12 counter group info",
		"-c 0,1 6 12\t# configure IS4 port 12 counter groups for PortXmitDataSL",
		"-c 2,8 6 12\t# configure IS4 port 12 counter groups for PortRcvDataSL",
		NULL
	};

	ibdiag_process_opts(argc, argv, NULL, "DKy", opts, process_opt,
			    usage_args, usage_examples);

	argc -= optind;
	argv += optind;

	if (argc > 1)
		port = strtoul(argv[1], NULL, 0);

	srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 2);
	if (!srcport)
		IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);

	if (argc) {
		if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[0],
				       ibd_dest_type, ibd_sm_id, srcport) < 0) {
			mad_rpc_close_port(srcport);
			IBEXIT("can't resolve destination port %s", argv[0]);
		}
	} else {
		if (resolve_self(ibd_ca, ibd_ca_port, &portid, &port, NULL) < 0) {
			mad_rpc_close_port(srcport);
			IBEXIT("can't resolve self port %s", argv[0]);
		}
	}

	if (counter_group_info) {
		counter_groups_info(&portid, port);
		mad_rpc_close_port(srcport);
		exit(0);
	}

	if (config_counter_group) {
		config_counter_groups(&portid, port);
		mad_rpc_close_port(srcport);
		exit(0);
	}

	if (read_cs_records || write_cs_records) {
		if (read_cs_records)
			do_config_space_records(&portid, 0, &read_cs,
						read_cs_records);
		if (write_cs_records)
			do_config_space_records(&portid, 1, &write_cs,
						write_cs_records);
		mad_rpc_close_port(srcport);
		exit(0);
	}

	/* These are Mellanox specific vendor MADs */
	/* but vendors change the VendorId so how know for sure ? */
	/* Only General Info and Port Xmit Wait Counters */
	/* queries are currently supported */
	if (!general_info && !xmit_wait) {
		mad_rpc_close_port(srcport);
		IBEXIT("at least one of -N and -w must be specified");
	}
	/* Would need a list of these and it might not be complete */
	/* so for right now, punt on this */

	/* vendor ClassPortInfo is required attribute if class supported */
	memset(&buf, 0, sizeof(buf));
	if (do_vendor(&portid, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
		      CLASS_PORT_INFO, 0, buf)) {
		mad_rpc_close_port(srcport);
		IBEXIT("classportinfo query");
	}
	memset(&buf, 0, sizeof(buf));
	gi_is3 = (is3_general_info_t *) &buf;
	if (do_vendor(&portid, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
		      IB_MLX_IS3_GENERAL_INFO, 0, gi_is3)) {
		mad_rpc_close_port(srcport);
		IBEXIT("generalinfo query");
	}

	if (is_ext_fw_info_supported(ntohs(gi_is3->hw_info.device_id))) {
		gi_is4 = (is4_general_info_t *) &buf;
		fw_ver_major = ntohl(gi_is4->ext_fw_info.ext_major);
		fw_ver_minor = ntohl(gi_is4->ext_fw_info.ext_minor);
		fw_ver_sub_minor = ntohl(gi_is4->ext_fw_info.ext_sub_minor);
		sw_ver_major = gi_is4->sw_info.major;
		sw_ver_minor = gi_is4->sw_info.minor;
		sw_ver_sub_minor = gi_is4->sw_info.sub_minor;
	} else {
		fw_ver_major = gi_is3->fw_info.major;
		fw_ver_minor = gi_is3->fw_info.minor;
		fw_ver_sub_minor = gi_is3->fw_info.sub_minor;
		sw_ver_major = gi_is3->sw_info.major;
		sw_ver_minor = gi_is3->sw_info.minor;
		sw_ver_sub_minor = gi_is3->sw_info.sub_minor;
	}

	if (general_info) {
		/* dump IS3 or IS4 general info here */
		printf("hw_dev_rev:  0x%04x\n", ntohs(gi_is3->hw_info.hw_revision));
		printf("hw_dev_id:   0x%04x\n", ntohs(gi_is3->hw_info.device_id));
		printf("hw_uptime:   0x%08x\n", ntohl(gi_is3->hw_info.uptime));
		printf("fw_version:  %02d.%02d.%02d\n",
		       fw_ver_major, fw_ver_minor, fw_ver_sub_minor);
		printf("fw_build_id: 0x%04x\n", ntohl(gi_is3->fw_info.build_id));
		printf("fw_date:     %02x/%02x/%04x\n",
		       gi_is3->fw_info.month, gi_is3->fw_info.day,
		       ntohs(gi_is3->fw_info.year));
		printf("fw_psid:     '%s'\n", gi_is3->fw_info.psid);
		printf("fw_ini_ver:  %d\n",
		       ntohl(gi_is3->fw_info.ini_file_version));
		printf("sw_version:  %02d.%02d.%02d\n", sw_ver_major,
		       sw_ver_minor, sw_ver_sub_minor);
	}

	if (xmit_wait) {
		is3_config_space_t *cs;
		unsigned i;

		if (ntohs(gi_is3->hw_info.device_id) != IS3_DEVICE_ID) {
			mad_rpc_close_port(srcport);
			IBEXIT("Unsupported device ID 0x%x",
				ntohs(gi_is3->hw_info.device_id));
		}
		memset(&buf, 0, sizeof(buf));
		/* Set record addresses for each port */
		cs = (is3_config_space_t *) & buf;
		for (i = 0; i < 16; i++)
			cs->record[i].address =
			    htonl(IB_MLX_IS3_PORT_XMIT_WAIT + ((i + 1) << 12));
		if (do_vendor(&portid, IB_MLX_VENDOR_CLASS,
			      IB_MAD_METHOD_GET, IB_MLX_IS3_CONFIG_SPACE_ACCESS,
			      2 << 22 | 16 << 16, cs)) {
			mad_rpc_close_port(srcport);
			IBEXIT("vendstat");
		}
		for (i = 0; i < 16; i++)
			if (cs->record[i].data)	/* PortXmitWait is 32 bit counter */
				printf("Port %d: PortXmitWait 0x%x\n", i + 4, ntohl(cs->record[i].data));	/* port 4 is first port */

		/* Last 8 ports is another query */
		memset(&buf, 0, sizeof(buf));
		/* Set record addresses for each port */
		cs = (is3_config_space_t *) & buf;
		for (i = 0; i < 8; i++)
			cs->record[i].address =
			    htonl(IB_MLX_IS3_PORT_XMIT_WAIT + ((i + 17) << 12));
		if (do_vendor(&portid, IB_MLX_VENDOR_CLASS,
			      IB_MAD_METHOD_GET, IB_MLX_IS3_CONFIG_SPACE_ACCESS,
			      2 << 22 | 8 << 16, cs)) {
			mad_rpc_close_port(srcport);
			IBEXIT("vendstat");
		}

		for (i = 0; i < 8; i++)
			if (cs->record[i].data)	/* PortXmitWait is 32 bit counter */
				printf("Port %d: PortXmitWait 0x%x\n",
				       i < 4 ? i + 21 : i - 3,
				       ntohl(cs->record[i].data));
	}

	mad_rpc_close_port(srcport);
	exit(0);
}
