/*
 * Copyright 2012 Tilera Corporation. All Rights Reserved.
 *
 *   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, version 2.
 *
 *   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, GOOD TITLE or
 *   NON INFRINGEMENT.  See the GNU General Public License for
 *   more details.
 */

/* This file is machine-generated; DO NOT EDIT! */
#include "gxio/iorpc_mpipe_info.h"


struct instance_aux_param {
	_gxio_mpipe_link_name_t name;
};

int gxio_mpipe_info_instance_aux(gxio_mpipe_info_context_t * context,
				 _gxio_mpipe_link_name_t name)
{
	struct instance_aux_param temp;
	struct instance_aux_param *params = &temp;

	params->name = name;

	return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
			     sizeof(*params), GXIO_MPIPE_INFO_OP_INSTANCE_AUX);
}

EXPORT_SYMBOL(gxio_mpipe_info_instance_aux);

struct enumerate_aux_param {
	_gxio_mpipe_link_name_t name;
	_gxio_mpipe_link_mac_t mac;
};

int gxio_mpipe_info_enumerate_aux(gxio_mpipe_info_context_t * context,
				  unsigned int idx,
				  _gxio_mpipe_link_name_t * name,
				  _gxio_mpipe_link_mac_t * mac)
{
	int __result;
	struct enumerate_aux_param temp;
	struct enumerate_aux_param *params = &temp;

	__result =
	    hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
			 (((uint64_t) idx << 32) |
			  GXIO_MPIPE_INFO_OP_ENUMERATE_AUX));
	*name = params->name;
	*mac = params->mac;

	return __result;
}

EXPORT_SYMBOL(gxio_mpipe_info_enumerate_aux);

struct get_mmio_base_param {
	HV_PTE base;
};

int gxio_mpipe_info_get_mmio_base(gxio_mpipe_info_context_t * context,
				  HV_PTE *base)
{
	int __result;
	struct get_mmio_base_param temp;
	struct get_mmio_base_param *params = &temp;

	__result =
	    hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
			 GXIO_MPIPE_INFO_OP_GET_MMIO_BASE);
	*base = params->base;

	return __result;
}

EXPORT_SYMBOL(gxio_mpipe_info_get_mmio_base);

struct check_mmio_offset_param {
	unsigned long offset;
	unsigned long size;
};

int gxio_mpipe_info_check_mmio_offset(gxio_mpipe_info_context_t * context,
				      unsigned long offset, unsigned long size)
{
	struct check_mmio_offset_param temp;
	struct check_mmio_offset_param *params = &temp;

	params->offset = offset;
	params->size = size;

	return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
			     sizeof(*params),
			     GXIO_MPIPE_INFO_OP_CHECK_MMIO_OFFSET);
}

EXPORT_SYMBOL(gxio_mpipe_info_check_mmio_offset);
