/*
 * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <byteswap.h>
#include <ipxe/infiniband.h>
#include <ipxe/ib_smc.h>

/**
 * @file
 *
 * Infiniband Subnet Management Client
 *
 */

/**
 * Issue local MAD
 *
 * @v ibdev		Infiniband device
 * @v attr_id		Attribute ID, in network byte order
 * @v attr_mod		Attribute modifier, in network byte order
 * @v local_mad		Method for issuing local MADs
 * @v mad		Management datagram to fill in
 * @ret rc		Return status code
 */
static int ib_smc_mad ( struct ib_device *ibdev, uint16_t attr_id,
			uint32_t attr_mod, ib_local_mad_t local_mad,
			union ib_mad *mad ) {
	int rc;

	/* Construct MAD */
	memset ( mad, 0, sizeof ( *mad ) );
	mad->hdr.base_version = IB_MGMT_BASE_VERSION;
	mad->hdr.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
	mad->hdr.class_version = 1;
	mad->hdr.method = IB_MGMT_METHOD_GET;
	mad->hdr.attr_id = attr_id;
	mad->hdr.attr_mod = attr_mod;

	/* Issue MAD */
	if ( ( rc = local_mad ( ibdev, mad ) ) != 0 )
		return rc;

	return 0;
}

/**
 * Get node information
 *
 * @v ibdev		Infiniband device
 * @v local_mad		Method for issuing local MADs
 * @v mad		Management datagram to fill in
 * @ret rc		Return status code
 */
static int ib_smc_get_node_info ( struct ib_device *ibdev,
				  ib_local_mad_t local_mad,
				  union ib_mad *mad ) {
	int rc;

	/* Issue MAD */
	if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_NODE_INFO ), 0,
				 local_mad, mad ) ) != 0 ) {
		DBGC ( ibdev, "IBDEV %s could not get node info: %s\n",
		       ibdev->name, strerror ( rc ) );
		return rc;
	}
	return 0;
}

/**
 * Get port information
 *
 * @v ibdev		Infiniband device
 * @v local_mad		Method for issuing local MADs
 * @v mad		Management datagram to fill in
 * @ret rc		Return status code
 */
static int ib_smc_get_port_info ( struct ib_device *ibdev,
				  ib_local_mad_t local_mad,
				  union ib_mad *mad ) {
	int rc;

	/* Issue MAD */
	if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_PORT_INFO ),
				 htonl ( ibdev->port ), local_mad, mad )) !=0){
		DBGC ( ibdev, "IBDEV %s could not get port info: %s\n",
		       ibdev->name, strerror ( rc ) );
		return rc;
	}
	return 0;
}

/**
 * Get GUID information
 *
 * @v ibdev		Infiniband device
 * @v local_mad		Method for issuing local MADs
 * @v mad		Management datagram to fill in
 * @ret rc		Return status code
 */
static int ib_smc_get_guid_info ( struct ib_device *ibdev,
				  ib_local_mad_t local_mad,
				  union ib_mad *mad ) {
	int rc;

	/* Issue MAD */
	if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_GUID_INFO ), 0,
				 local_mad, mad ) ) != 0 ) {
		DBGC ( ibdev, "IBDEV %s could not get GUID info: %s\n",
		       ibdev->name, strerror ( rc ) );
		return rc;
	}
	return 0;
}

/**
 * Get partition key table
 *
 * @v ibdev		Infiniband device
 * @v local_mad		Method for issuing local MADs
 * @v mad		Management datagram to fill in
 * @ret rc		Return status code
 */
static int ib_smc_get_pkey_table ( struct ib_device *ibdev,
				   ib_local_mad_t local_mad,
				   union ib_mad *mad ) {
	int rc;

	/* Issue MAD */
	if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_PKEY_TABLE ), 0,
				 local_mad, mad ) ) != 0 ) {
		DBGC ( ibdev, "IBDEV %s could not get pkey table: %s\n",
		       ibdev->name, strerror ( rc ) );
		return rc;
	}
	return 0;
}

/**
 * Get Infiniband parameters using SMC
 *
 * @v ibdev		Infiniband device
 * @v local_mad		Method for issuing local MADs
 * @ret rc		Return status code
 */
static int ib_smc_get ( struct ib_device *ibdev, ib_local_mad_t local_mad ) {
	union ib_mad mad;
	struct ib_node_info *node_info = &mad.smp.smp_data.node_info;
	struct ib_port_info *port_info = &mad.smp.smp_data.port_info;
	struct ib_guid_info *guid_info = &mad.smp.smp_data.guid_info;
	struct ib_pkey_table *pkey_table = &mad.smp.smp_data.pkey_table;
	int rc;

	/* Node info gives us the node GUID */
	if ( ( rc = ib_smc_get_node_info ( ibdev, local_mad, &mad ) ) != 0 )
		return rc;
	memcpy ( &ibdev->node_guid, &node_info->node_guid,
		 sizeof ( ibdev->node_guid ) );

	/* Port info gives us the link state, the first half of the
	 * port GID and the SM LID.
	 */
	if ( ( rc = ib_smc_get_port_info ( ibdev, local_mad, &mad ) ) != 0 )
		return rc;
	memcpy ( &ibdev->gid.s.prefix, port_info->gid_prefix,
		 sizeof ( ibdev->gid.s.prefix ) );
	ibdev->lid = ntohs ( port_info->lid );
	ibdev->sm_lid = ntohs ( port_info->mastersm_lid );
	ibdev->link_width_enabled = port_info->link_width_enabled;
	ibdev->link_width_supported = port_info->link_width_supported;
	ibdev->link_width_active = port_info->link_width_active;
	ibdev->link_speed_supported =
		( port_info->link_speed_supported__port_state >> 4 );
	ibdev->port_state =
		( port_info->link_speed_supported__port_state & 0xf );
	ibdev->link_speed_active =
		( port_info->link_speed_active__link_speed_enabled >> 4 );
	ibdev->link_speed_enabled =
		( port_info->link_speed_active__link_speed_enabled & 0xf );
	ibdev->sm_sl = ( port_info->neighbour_mtu__mastersm_sl & 0xf );

	/* GUID info gives us the second half of the port GID */
	if ( ( rc = ib_smc_get_guid_info ( ibdev, local_mad, &mad ) ) != 0 )
		return rc;
	memcpy ( &ibdev->gid.s.guid, guid_info->guid[0],
		 sizeof ( ibdev->gid.s.guid ) );

	/* Get partition key */
	if ( ( rc = ib_smc_get_pkey_table ( ibdev, local_mad, &mad ) ) != 0 )
		return rc;
	ibdev->pkey = ntohs ( pkey_table->pkey[0] );

	DBGC ( ibdev, "IBDEV %s port GID is " IB_GID_FMT "\n",
	       ibdev->name, IB_GID_ARGS ( &ibdev->gid ) );

	return 0;
}

/**
 * Initialise Infiniband parameters using SMC
 *
 * @v ibdev		Infiniband device
 * @v local_mad		Method for issuing local MADs
 * @ret rc		Return status code
 */
int ib_smc_init ( struct ib_device *ibdev, ib_local_mad_t local_mad ) {
	int rc;

	/* Get MAD parameters */
	if ( ( rc = ib_smc_get ( ibdev, local_mad ) ) != 0 )
		return rc;

	return 0;
}

/**
 * Update Infiniband parameters using SMC
 *
 * @v ibdev		Infiniband device
 * @v local_mad		Method for issuing local MADs
 * @ret rc		Return status code
 */
int ib_smc_update ( struct ib_device *ibdev, ib_local_mad_t local_mad ) {
	int rc;

	/* Get MAD parameters */
	if ( ( rc = ib_smc_get ( ibdev, local_mad ) ) != 0 )
		return rc;

	/* Notify Infiniband core of potential link state change */
	ib_link_state_changed ( ibdev );

	return 0;
}
